代码之家  ›  专栏  ›  技术社区  ›  G S

使用SetParent()时定位窗口时出现问题

  •  3
  • G S  · 技术社区  · 15 年前

    我正在准备 childForm 作为通过PInvoke使用SetParent API的主Excel窗口的子窗口:

    Form childForm = new MyForm();
    IntPtr excelHandle = (IntPtr) excelApplication.Hwnd;
    SetParent(childForm.Handle, excelHandle);
    childForm.StartPosition = FormStartPosition.Manual;
    childForm.Left = 0;
    childForm.Top = 0;
    

    正如您在上面所看到的,我的目的也是将孩子放在Excel窗口的左上角。但是,由于某种原因 儿童型 总是在一个奇怪的地方结束。

    我做错什么了?

    5 回复  |  直到 15 年前
        1
  •  7
  •   G S    15 年前

    虽然这里所有的答案都是完美的逻辑方法,但没有一个对我有效。然后我试着移动窗户。因为某种原因我不明白,它起作用了。

    代码如下:

    [DllImport("user32.dll", SetLastError = true)]
    internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
    
    ...
    
    Form childForm = new MyForm();
    IntPtr excelHandle = (IntPtr) excelApplication.Hwnd;
    SetParent(childForm.Handle, excelHandle);
    MoveWindow(childForm.Handle, 0, 0, childForm.Width, childForm.Height, true);
    
        2
  •  5
  •   Cody Gray Felix    15 年前

    使用时 SetParent 在当前是桌面子级的窗体上(换句话说,没有父级的窗体 WS_CHILD 设置样式并删除 WS_POPUP 风格。(参见 MSDN 远景儿童 SetWindowLong 设置父级 ,但在尝试设置位置之前:

    //Remove WS_POPUP style and add WS_CHILD style
    const UInt32 WS_POPUP = 0x80000000;
    const UInt32 WS_CHILD = 0x40000000;
    int style = GetWindowLong(this.Handle, GWL_STYLE);
    style = (style & ~(WS_POPUP)) | WS_CHILD;
    SetWindowLong(this.Handle, GWL_STYLE, style);
    
        3
  •  1
  •   testalino    15 年前

    您可以创建一个实现IWin32Window并将HWND返回到excel的包装类。然后可以将其传递给childForm的ShowDialog调用。

    您也可以使用GetWindowPos查询excel应用程序的位置,然后相应地设置childForm。

        4
  •  0
  •   jonathanpeppers    15 年前

    • 设置Left后放置断点 顶部,左边和顶部的读数是零吗?
    • 最后调用SetParent。
    • 创建一个设置左上角的方法
    • 确保你的孩子窗口 显示对话框,并尝试单击 父窗口。确保窗户 防止聚焦到父窗口。
        5
  •  0
  •   dexter    15 年前

    假设您知道如何获取要设置z顺序的窗口的hwnd,可以使用以下pInvoke:

        public stati class WindowsApi 
        {
         [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
            int X, int Y, int cx, int cy, uint uFlags);
        }
    
    
    
        public class WindowZOrderPositioner 
        {
             public void SetZOrder(IntPtr targetHwnd, IntPtr insertAfter)
             {
                 IntPtr nextHwnd = IntPtr.Zero;
    
                 WindowsAPI.SetWindowPos(targetHwnd, insertAfter, 0, 0, 0, 0, SetWindowPosFlags.NoMove | SetWindowPosFlags.NoSize | SetWindowPosFlags.NoActivate);
         }
    
    推荐文章