Win32 :: SetForegroundWindow()不能一直工作

sam*_*ani 6 c++ windows winapi visual-studio-2010

我正在研究一种消息传递工具.消息传递窗口是整个应用程序的一部分.当有一些消息传来时,我需要窗口转到前面.我正在使用这段代码:

    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;
Run Code Online (Sandbox Code Playgroud)

我甚至试图做一个TOPMOST但仍然在某些情况下它不起作用.我还尝试了:: BringToFront().

任何人都可以帮助或解释为什么它不起作用?这是一个已知的微软限制.

Jon*_*ter 8

系统限制哪些进程可以设置前景窗口.仅当满足下列条件之一时,进程才能设置前台窗口:

  • 该过程是前台过程.
  • 该过程由前台进程启动.
  • 该过程收到了最后一个输入事件.
  • 没有前台进程.
  • 正在调试前台进程.
  • 前景未锁定(请参阅LockSetForegroundWindow).
  • 前台锁定超时已到期(请参阅SystemParametersInfo中的SPI_GETFOREGROUNDLOCKTIMEOUT).
  • 没有菜单处于活动状态

有关更多详细信息,请参阅SetForegroundWindow()文档.

  • 实现此目的的另一个技巧是模拟“ALT”按键。[方法如下](http://stackoverflow.com/a/13881647/843732)。 (3认同)
  • 我找到的解决方案是将窗口放在最上面,然后将其删除。 (2认同)
  • 这将把它带到顶部,但不一定使它活跃(即它不会是前景窗口),但如果这就是你想要的那么好. (2认同)

hun*_*175 5

在Win32 API的官方文档中,有备注:

备注 系统限制了哪些进程可以设置前台窗口。仅当以下条件之一为真时,进程才能设置前台窗口:

  • 该进程是前台进程。
  • 该进程由前台进程启动。
  • 进程接收到最后一个输入事件。
  • 没有前台进程。
  • 进程正在调试中。
  • 前台进程不是现代应用程序或开始屏幕。
  • 前景未锁定(请参阅 LockSetForegroundWindow)。
  • 前台锁超时已过期(请参阅 SystemParametersInfo 中的 SPI_GETFOREGROUNDLOCKTIMEOUT)。
  • 没有菜单处于活动状态。

但是有一个技巧可以将窗口强制为前景:

诀窍是通过附加线程(使用 AttachThreadInput API)和使用替代 API:BringWindowToTop,让窗口“认为”我们的进程和目标窗口(hwnd)是相关的。

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);
}
Run Code Online (Sandbox Code Playgroud)

原答案在这里

PS:如果有消息出现,我也不认为你应该把你的消息应用程序放在最上面,但仍然......这是适用于我在 Windows 10 上的 Qt 应用程序的解决方案