SetWindowPostion TOPMOST

915 views Asked by At

I am working with a software developer on a C Program that has a floating preferences window. If I use the Windows taskbar to switch to another program when mine is running, my floating window still resides over the program I switched to. I am not a programmer and I am being told by my programmer that there is no way to prevent this. I am told he is using SetWindowPosition and something called TOPMOST to give this window it's privilege to stay on top. I like it being on top while working in my program but not when I switch to another program.

Is there something I can tell him to do so that this window does not remain topmost when I switch to another program but stays on top when I return to my program?

2

There are 2 answers

0
Lukas Thomsen On BEST ANSWER

You can use the WM_ACTIVATE message. Windows sends this message when a window is activated or deactivated. If the user switches to another application the current window of your application receives a WM_ACTIVATE message telling it that it is being deactivated.

Here is a little example to set/remove the topmost flag when the user switches to another application (considering the hFloatingWindow is the window handle to your floating window):

LRESULT __stdcall YourWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {

    /* ... */

    case WM_ACTIVATE:
        DWORD pid = 0;

        GetWindowThreadProcessId((HWND)lParam, &pid);
        if (pid != GetCurrentProcessId())   /* switch to another task? */
        {
            if ((wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE))
            {
                if (SetWindowPos(hFloatingWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE) == FALSE)
                {
                    /* handle error */
                }
            }
            else
            {
                if (SetWindowPos(hFloatingWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE) == FALSE)
                {
                    /* handle error */
                }
            }
        }
        return (0);  /* message processed */

    /* ... */
}

Note that you have to add the code of WM_ACTIVATE to all window procedures of your application. This is neccessary since the user can switch to another task from any of your windows being active. And if the currently active window does not handle the WM_ACTIVATE message as shown above the topmost flag will not be removed.

2
Jonathan Potter On

One way is to not make the window top-most (i.e. not call SetWindowPos with the HWND_TOPMOST flag, and not set the WS_EX_TOPMOST window style) at all, but to make the window owned by your main window.

To do that, when the floating window is created (using CreateWindowEx), you specify the handle of the main window as its parent.

Owned windows always appear above their owners, but it will still be floating and will go behind the windows of other applications.