【问题标题】:How can I bring a window to the foreground in Vista using C++?如何使用 C++ 在 Vista 中将窗口置于前台?
【发布时间】:2010-10-06 18:17:17
【问题描述】:

我有一段代码使用 WinXP 的 SetForegroundWindow API 将光标下的窗口置于前台。我一直在为 Vista 测试它,但 API 似乎不再正确地完成这项工作。

AllowSetForeground 没有帮助,我的进程是后台进程。

我可以用什么来完成这项工作?

【问题讨论】:

    标签: c++ winapi window


    【解决方案1】:

    试试下面的代码,看看它是否适合你:

    SetWindowPos(WndHandle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
    SetWindowPos(WndHandle,HWND_NOTOPMOST,0,0,0,0,SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
    

    【讨论】:

    • 这对我有用 - 并且是唯一具有将窗口置于前面的效果(没有使用 MINIMIZE 调用 ShowWindow,然后使用 RESTORE 调用 ShowWindow)。其他尝试,包括 SetForegroundWindow 和 BringWindowToFront Just-Dont-Work,but This-Approach-Does。
    【解决方案2】:

    只是一个警告:有一个公共 API 可以做到这一点 (SetForegroundWindow),现在它不再将窗口置于前台。

    现在窗口只是闪烁。

    但这是有原因的。这样做的应用程序从当前窗口“窃取”焦点(通常没有充分的理由),并可能导致各种问题。

    因此,在尝试规避操作系统针对此类行为设置的保护措施之前,请确保您不会惹恼您的用户。问问自己:“即使我的应用程序在后台,我真的——真的必须跳到我的用户面前吗?”

    【讨论】:

    • 无意冒犯,但我个人不喜欢这样的答案。他不是就如何设计他的程序征求意见,他想要一个特定技术问题的答案。
    • 好吧,我会坚持这个答案!答案可以做的最有帮助的事情之一就是向最初的提问者表明他们提出的问题可能表明他们做错了。
    • 同意。答案不是题外话,而且是相关的:)
    • 我同意@korona。这应该是一个评论,因为它根本不回答问题(“如何......”)。 (作为评论,我也同意@Mihai Nita)
    【解决方案3】:

    如果使用 MFC,这在 Windows 7 x64 中对我有用:

        RECT rc;
        m_pMainWnd->GetWindowRect(&rc);
    
        int nBoxWidth = rc.left-rc.right;
        int nBoxHeight = rc.bottom-rc.top;
        int nBoxTop = rc.top;
        int nBoxLeft = rc.left;
    
        SetWindowPos(m_pMainWnd->GetSafeHwnd(), HWND_TOPMOST,
                        nBoxLeft, nBoxTop, nBoxWidth, nBoxHeight,
                        SWP_NOMOVE || SWP_NOSIZE);
        SetWindowPos(m_pMainWnd->GetSafeHwnd(), HWND_NOTOPMOST,
                        nBoxLeft, nBoxTop, nBoxWidth, nBoxHeight,
                        SWP_SHOWWINDOW || SWP_NOMOVE || SWP_NOSIZE);
    

    【讨论】:

      【解决方案4】:

      将当前线程设置为睡眠对我来说是这样做的,以及之前将其设置为非最顶层:

      OS.SetWindowPos(handle, OS.HWND_NOTOPMOST, 0, 0, 0, 0, OS.SWP_NOMOVE | OS.SWP_NOSIZE);
      try {
          Thread.sleep(100);
      } catch (InterruptedException e) {
          LOG.error("sleeping thread was interrupted", e);
      }
      OS.SetWindowPos(handle, OS.HWND_TOPMOST, 0, 0, 0, 0, OS.SWP_NOMOVE | OS.SWP_NOSIZE);
      

      【讨论】:

        【解决方案5】:

        如果SetForegroundWindow() 失败,您是否尝试过设置窗口WS_EX_TOPMOST,然后在调用SetForegroundWindow() 后立即非最右边?

        这可能与人们理所当然地抱怨应用程序在您最意想不到的时候到处出现有关。

        【讨论】:

          【解决方案6】:
          VOID SwitchToThisWindow(HWND hWnd, BOOL fAltTab);
          

          适用于 XP 到 Windows 7 http://msdn.microsoft.com/en-us/library/ms633553.aspx

          【讨论】:

          • 不幸的是“[此功能不适合一般用途。它可能会在后续版本的 Windows 中更改或不可用。]”:(
          【解决方案7】:

          使用windows powertoys的tweakui程序来改变焦点的权限状态。

          选择“常规”,然后选择“焦点”,然后取消选中允许其他程序获得焦点的复选框。

          当每个人的建议似乎都不起作用时,这很有效,(实际上他们都这样做了)。

          微软以其无穷的智慧决定,对 setforegrondwindow 等的调用的响应现在将为空。

          他们懒得说你仍然可以通过tweakui恢复原状!!!

          享受.....

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-17
            • 2021-03-10
            • 2012-10-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多