删除窗口或表单的父级

时间:2014-02-07 18:46:15

标签: process window pinvoke parent-child

如何创建一个进程,其父级已设置为我的应用程序的控件"弹出"我的应用程序,并成为顶级窗口?

我尝试过使用SetParent(WindowHandle, null);,但IntPtr表示它是一种不可空的类型。

2 个答案:

答案 0 :(得分:4)

您正在尝试修改窗口的父级。您需要的功能是SetParent。你的p / invoke看起来像这样:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

来自文档:

  

<强> hWndNewParent

     

新父窗口的句柄。如果此参数为NULL,则   桌面窗口成为新的父窗口。

因此,您只需将NULL作为hWndNewParent传递即可。在C#术语中,这样做:

SetParent(hWnd, IntPtr.Zero);

然而,还有更多。在备注中,您将找到以下文字:

  

出于兼容性原因,SetParent不会修改WS_CHILD或   正在更改父级的窗口的WS_POPUP窗口样式。   因此,如果hWndNewParent为NULL,您还应该清除   WS_CHILD位并在调用SetParent后设置WS_POPUP样式。   相反,如果hWndNewParent不是NULL并且之前是窗口   桌面的一个孩子,你应该清除WS_POPUP样式并设置   调用SetParent之前的WS_CHILD样式。

因此,在您的情况下,您需要修改窗口的窗口样式。您需要清除WS_CHILD,然后设置WS_POPUP

uint style = GetWindowLong(hWnd, GWL_STYLE);
style = (style | WS_POPUP) & (~WS_CHILD);
SetWindowLong(hWnd, GWL_STYLE, style);

答案 1 :(得分:1)

检查任何顶级窗口的父级使用以下内容:

    [DllImport("User32.dll", SetLastError = true)]
    public static extern IntPtr GetParent(IntPtr hWnd);

结果为'0'。

因此,您可以使您的流程成为顶级窗口,如下所示:

    SetParent(WindowHandle, IntPtr.Zero);