Question

How can I make a process whose parent has been set to a control of my application "pop-out" of my application and become a top-level window?

I've tried using SetParent(WindowHandle, null); but IntPtr it says that it is a non-nullable type.

Was it helpful?

Solution

You are trying to modify the parent of a window. The function you need is SetParent. Your p/invoke looks like this:

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

From the documentation:

hWndNewParent

A handle to the new parent window. If this parameter is NULL, the desktop window becomes the new parent window.

So, you simply pass NULL as hWndNewParent. In C# terms, that is done like this:

SetParent(hWnd, IntPtr.Zero);

However, there is more. In the remarks you will find this text:

For compatibility reasons, SetParent does not modify the WS_CHILD or WS_POPUP window styles of the window whose parent is being changed. Therefore, if hWndNewParent is NULL, you should also clear the WS_CHILD bit and set the WS_POPUP style after calling SetParent. Conversely, if hWndNewParent is not NULL and the window was previously a child of the desktop, you should clear the WS_POPUP style and set the WS_CHILD style before calling SetParent.

So, in your case you do need to modify the window style for the window. You need to clear WS_CHILD, and set WS_POPUP.

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

OTHER TIPS

Check what the parent of any top-level window is using the following:

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

The result is '0'.

Thus you can make your process become a top-level window like so:

    SetParent(WindowHandle, IntPtr.Zero);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top