C++ – Win32: Bring a window to top

c++visual-c++winapi

I have a Windows program which has two 2 windows in it:

hwnd (main interface)

hwnd2 (toplevel window, no parent, created by hwnd)

When I double click on hwnd, I need hwnd2 to pop up and show some data, so I use this function to bring hwnd2 to top:

BringWindowToTop(hwnd2);

hwnd2 is brought to top, but there is one thing odd. When I click on hwnd2 again, hwnd (main interface) pops itself up again automatically.
I tried to use the following function to solve this problem, but non of them works.

SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
                                                                  //doesn't work

BringWindowToTop(hwnd2);    //This is the function brings hwnd2 to top

SetForegroundWindow(hwnd2); //doesn't work

SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
                                                                  //doesn't work

SetWindowPos(hwnd2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
                                       // hwnd2 "always" on top, not what I want

SetActiveWindow(hwnd2); // doesn't work too (for replying to Magnus Skog, thanks)

SwitchToThisWindow(hwnd2, TRUE);// got the same problem with BringWindowToTop function
SwitchToThisWindow(hwnd2, FALSE);

How could I solve this problem?
Thanks in advance.

(for replying to aJ, hwnd2 doesn't have parent because it needs to be a toplevel window so it can be in front/back of other windows)

(hwnd2 is a media player which is composed of several windows, one of the windows is for video dispaly, two other trackbar controls for progress bar and volume bar, one Toolbar control for control panel.)

(There is one this might help, no matter which window I click on hwnd2, hwnd pops up automatically as loong as "the mouse is on top of hwnd in Z-order", including menu bar and non-client area, etc.)

(This media player is writen in Direct Show. I use IVideoWindow::put_Owner to put video window as the video owner, Direct Show internally creates a sub-video window as a child of the video window. Except for this sub-video window which I can't see the source code, I don't see any thing suspicious in hwnd2.)

I found the reason, which is because of Direct Show. I use multithread to execute it, and then the problem's solved. But…why??

This problem can be resolved by using PostMessage (rather than SendMessage).

Best Solution

try this´╝îit is said coming from M$

    HWND hCurWnd = ::GetForegroundWindow();
    DWORD dwMyID = ::GetCurrentThreadId();
    DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
    ::AttachThreadInput(dwCurID, dwMyID, TRUE);
    ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
    ::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
    ::SetForegroundWindow(m_hWnd);
    ::SetFocus(m_hWnd);
    ::SetActiveWindow(m_hWnd);
    ::AttachThreadInput(dwCurID, dwMyID, FALSE);

In order to bring a window to top, you should get your window handle,thread handle, the windows thread handle who is in foreground

then we attach our thread to foreground window thread and get input by AttachThreadInput, then we set our window z order to topmost and then restore its z order to normal, call SetForegroundWindow,SetFocus,SetActiveWindow to make sure our window is brought to top and is active and have focus

then deattach the input queue from the old foreground window thread, make our thread the only one who capture the input events

So why should We call AttachThreadInput, it is because

SetFocus sets the keyboard focus to the specified window. The window must be attached to the calling thread's message queue.

What does AttachThreadInput do?

The AttachThreadInput function can be used to allow a set of threads to share the same input state. By sharing input state, the threads share their concept of the active window. By doing this, one thread can always activate another thread's window. This function is also useful for sharing focus state, mouse capture state, keyboard state, and window Z-order state among windows created by different threads whose input state is shared.

We use SetWindowPos to bring the windows to topmost and show the window if the window is hidding by using SWP_HIDEWINDOW

SetWindowPos function changes the size, position, and Z order of a child, pop-up, or top-level window. These windows are ordered according to their appearance on the screen. The topmost window receives the highest rank and is the first window in the Z order

If your problem is your window is also minimized , you should add one line code to the end

ShowWindow(m_hWnd, SW_RESTORE);
Related Question