如何使用C++将窗口置于Vista前台?

4
我有一段代码,它使用WinXP的SetForegroundWindow API将鼠标下的窗口置于前景。我已经测试了Vista,但是该API似乎不能正确完成任务。
AllowSetForeground没有帮助,我的进程是后台进程。
我应该使用什么来完成这个任务?
7个回答

8

尝试以下代码,看看它是否适用于您:

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都不起作用,但这种方法可以。 - user166390

1
如果SetForegroundWindow()失败了,你尝试过在调用SetForegroundWindow()之后立即将窗口WS_EX_TOPMOST设置为非最顶层吗?
这可能与人们有理地抱怨应用程序在最不希望的时候弹出窗口有关。

1
如果使用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);

0

1
很遗憾 "[此函数不适用于一般使用。在后续的Windows版本中可能会被修改或不可用。]" :( - user166390

0

将当前线程设置为睡眠状态,再将其设置为非最顶层的状态,这对我很有帮助:

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);

-2

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

现在窗口只会闪烁。

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

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


7
不冒犯,但我个人不喜欢这样的回答。他不是在寻求有关如何设计程序的建议,而是想要得到一个特定技术问题的答案。 - korona
4
好的,我要为这个答案辩护!一个回答最有帮助的事情之一就是向提问者表明,也许他们所问的问题表明他们正在做错事。 - DavidK
1
同意。答案并不离题,而且很相关 :) - Thomas Bratt
3
我同意@korona的观点。这应该是一条评论而不是答案,因为它根本没有回答问题(“如何...”)。作为一条评论,我也同意@Mihai Nita的看法。 - kizzx2

-4
使用Windows Powertoys TweakUI程序更改焦点权限状态。
选择“常规”,然后选择“焦点”,取消选中允许其他程序获取焦点的框。
当所有人的建议似乎都无效时,这个方法仍然有效(实际上它们都可以)。
微软在他们的智慧之中决定对于调用setforegrondwindow等操作的响应现在将为空。
他们没有提到你仍然可以通过TweakUI回到原始状态!
享受吧.....

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接