10

I'm working on a messenging tool. The messaging window is part of a whole application. I need the window to go to the front when there are some messages coming. I'am using this code :

    if( m_hwnd == NULL || !::IsWindow(m_hwnd) )
        return E_UNEXPECTED;

    if(::IsIconic(m_hwnd))
    {
        ::ShowWindowAsync( m_hwnd, SW_RESTORE );
    }
    ::SetWindowPos(m_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    ::SetForegroundWindow(m_hwnd);
    if( pvbProcessed != NULL )
        *pvbProcessed = VARIANT_TRUE;

    return S_OK;

I even tried to do a TOPMOST but still in some cases it does not work. I also Tried a ::BringToFront().

Anyone can help or give an explanation on why it doen not work ? Is it a known microsoft limitation.

samitriani
  • 103
  • 1
  • 1
  • 4
  • 9
    Ah yes! another annoying application that just goes to the top when a message arrives... Can't you just flash the taskbar and not be so intrusive? – RedX Oct 02 '13 at 12:07
  • 1
    See my answer here: http://stackoverflow.com/questions/17451033/give-focus-to-a-window-launched-from-a-system-service-using-createprocessasuser/17456056#17456056 – manuell Oct 02 '13 at 14:33

2 Answers2

12

In the official document of Win32 API, there are remarks:

Remarks The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

  • The process is the foreground process.
  • The process was started by the foreground process.
  • The process received the last input event.
  • There is no foreground process.
  • The process is being debugged.
  • The foreground process is not a Modern Application or the Start Screen.
  • The foreground is not locked (see LockSetForegroundWindow).
  • The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
  • No menus are active.

But there is a trick to force a window to foreground:

The trick is to make windows ‘think’ that our process and the target window (hwnd) are related by attaching the threads (using AttachThreadInput API) and using an alternative API: BringWindowToTop.

void CommonHelpers::forceForegroundWindow(HWND hwnd) {
    DWORD windowThreadProcessId = GetWindowThreadProcessId(GetForegroundWindow(),LPDWORD(0));
    DWORD currentThreadId = GetCurrentThreadId();
    DWORD CONST_SW_SHOW = 5;
    AttachThreadInput(windowThreadProcessId, currentThreadId, true);
    BringWindowToTop(hwnd);
    ShowWindow(hwnd, CONST_SW_SHOW);
    AttachThreadInput(windowThreadProcessId,currentThreadId, false);
}

The original answer is here

P.S: I also dont think you should bring your message app to top if some message is coming up, but still ... this is the solution that working for my Qt App on Windows 10

hungson175
  • 4,373
  • 6
  • 22
  • 21
11

The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

  • The process is the foreground process.
  • The process was started by the foreground process.
  • The process received the last input event.
  • There is no foreground process.
  • The foreground process is being debugged.
  • The foreground is not locked (see LockSetForegroundWindow).
  • The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
  • No menus are active.

See the SetForegroundWindow() docs for more details.

Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
  • 2
    The solution that I found is that I put the window on TOPMOST then remove it. – samitriani Oct 22 '13 at 11:04
  • 3
    That will bring it to the top but not necessarily make it active (i.e. it won't be the foreground window), but if that's all you want then great. – Jonathan Potter Oct 22 '13 at 11:30
  • I should maybe add the activate explicitly. The window is already flashing, but the "Managers" want it to be put on Foreground. – samitriani Oct 28 '13 at 11:24
  • 2
    Another hack to make this work is to simulate `ALT` key press. [Here's how](http://stackoverflow.com/a/13881647/843732). – c00000fd Jan 18 '17 at 07:20
  • It's so important to notice point 5 on the list, which can lead the developer to believe that the implementation is working because it's working in debug. This does _not_ mean it will necessarily work in release. – Alexander Høst Aug 16 '21 at 19:02