什么时候在窗口上设置最顶层不起作用?
Posted
技术标签:
【中文标题】什么时候在窗口上设置最顶层不起作用?【英文标题】:When does setting topmost on a window fail to work? 【发布时间】:2010-11-08 05:06:22 【问题描述】:我有一个 C++ 应用程序,我需要在其中创建最顶层的窗口。有时它有效,但经常失败。在应用程序的一部分中,我创建了一个后台线程来显示最顶层的信息窗口。用户关闭窗口后,线程消失。应用程序第一次创建线程并显示窗口时,窗口位于最顶层。但是,所有后续线程都无法在其窗口上设置最顶层。我尝试使用 WS_EX_TOPMOST 样式创建窗口,并在创建窗口后调用 SetWindowPos。这些方法都不起作用。我查看并找不到任何关于无法将窗口设置为最顶部的问题的任何人的参考。
在我运行的一项测试中,我调用了 SetWindowPos,在它返回后我检查了窗口的样式,即使 SetWindowPos 返回成功,它也没有设置为最顶层。我还使用 Spy++ 来检查窗口的样式,它确认没有设置样式。
【问题讨论】:
您的代码中似乎有一些错误。你介意把它贴在这里吗? 【参考方案1】:SetWindowPos 设置 WS_EX_TOPMOST 的一种方法是当进程在创建窗口或调用 SetWindowPos 时没有对 SetForegroundWindow 的权限。这可以说是您希望窗口最顶部的时间之一(并且可以说是您不应该被允许的时间之一)。
有传言说微软自 Vista 以来堵住了这个漏洞。
这个限制是可以理解的——你不希望来自随机进程的最顶层窗口在它们也没有业务时窃取焦点。
当一个进程间接启动辅助进程(例如在父进程中启动安装,然后从 msiexec 启动辅助进程)并且助手然后想要成为最顶层甚至抓取输入时,一种合理用例的解决方法是使用 AllowSetForegroundWindow。
显然,你需要有专注的权利才能放弃它。
【讨论】:
【参考方案2】:我在使用 Borland C++ Builder 时遇到了类似的问题。在创建和显示窗口后,我通过将 FormStyle 设置为 fsStayOnTop 来实现这一点。我认为诀窍是只有在窗口完全显示后才这样做。
*visibleForm = new TForm3(Form3);
(*visibleForm)->FormStyle = fsStayOnTop;
【讨论】:
【参考方案3】:SetWindowPos(_hYourWindow, HWND_TOPMOST, 0, 0, 0, 0,
SWP_ASYNCWINDOWPOS|SWP_NOSIZE|SWP_SHOWWINDOW|SWP_NOMOVE);
应该可以!
【讨论】:
为什么?你能解释一下为什么它应该解决这个问题吗?【参考方案4】:不知道我遇到的问题是否与您的问题相同,但至少它具有相同的症状。通过将this->TopMost = true
从InitializeComponent
移动到Form_Load
来解决它。
【讨论】:
【参考方案5】:你为什么不直接使用SetForegroundWindow()。出错的可能性要小得多..
【讨论】:
SetForegroundWindow() 将激活窗口。也许他不想那样。以上是关于什么时候在窗口上设置最顶层不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
border-collapse 为collapse的时候,为什么最外面框的padding不起作用了