最热门的窗口有时会落在非最热门的全屏窗口后面
本文关键字:窗口 最热 热门 | 更新日期: 2023-09-27 18:11:01
我有一个"控制工具栏"应用程序,它需要漂浮在双显示器系统主屏幕上的所有其他内容之上。它将自己定位在主屏幕的顶部,并设置TopMost=true。
这个控制工具栏可以用来启动另外两个全屏运行的进程,而不是TopMost,在双监视器系统的每个监视器上一个。将这些窗口设置为全屏运行,方法是将BorderStyle设置为None,并将窗口的边界设置为完全适合屏幕尺寸。全屏窗口完全可以覆盖任务栏,我可以整天在主显示器上集中注意力并与全屏窗口交互,而工具栏则保持在顶部。
在软件王国中,一切都不是桃色的-某些操作使TopMost工具栏在非TopMost全屏窗口下弹出。其中一个动作是把焦点给第二显示器上的全屏应用,然后把焦点还给主显示器上的全屏应用。这是最容易重现的情况,因为每次我遵循这个顺序都会发生这种情况。我很难可靠地再现其他场景,但如果我按下windows键拉出开始菜单并开始在Internet Explorer中浏览,有时当我完成浏览并关闭IE并将焦点放回主监视器全屏应用程序时,它会弹出TopMost窗口。
任何想法如何保持TopMost窗口在顶部,而不允许它弹出下一个非TopMost全屏窗口?我不介意做一些事情,比如每秒轮询一次WindowFromPoint,看看工具栏是否仍然在顶部,如果不是,然后以某种方式弹出它,但我不想把焦点从全屏应用程序,如果这是用户正在使用,所以激活()不是一个特别好的解决方案。
我不认为这真的很重要,但是工具栏是一个WPF窗口,全屏应用程序是WinForms。
更新:最简单的测试方法是按F11在每个监视器上的两个浏览器窗口中进入全屏,以模拟全屏应用程序,然后在任何地方有一个TopMost窗口浮动。在两个全屏窗口之间单击,您将看到TopMost窗口在它们下面弹出。我在一台显示器上打开IE,在另一台显示器上打开Chrome,因为IE不允许我打开两个全屏窗口。
我现在实现了Activate() hack,但这是一个相当难看的解决方案,因为它激活了工具栏应用程序,使全屏应用程序失去焦点,这反过来又使任务栏弹出全屏应用程序。当你想做的只是切换全屏应用程序有焦点时,有点hack。
好吧,这是我最后做的…在我打算放弃之前,我又想出了一个主意,这个主意很有效。在工具栏窗口中,我有一个计时器,每秒轮询一次工具栏区域最上方的窗口,如下所示:
var topMostHandle = WindowFromPoint((int)(Left + ActualWidth / 2), (int)ActualHeight / 2);
if (topMostHandle != new WindowInteropHelper(this).Handle)
{
Topmost = false;
Topmost = true;
}
我基本上只是在工具栏的中间取一个点然后测试看看工具栏是否在顶部。如果不是,我将TopMost设置为false并返回为true,这似乎使它回到顶部而不需要激活它。闪光消失一秒钟有点烦人,但我不希望这种情况经常发生。
感谢Hans Passant为Win7 SP1找到了一个解决问题的修复程序:http://support.microsoft.com/kb/2733420
我在代码中保留了我的hack,以防客户端不能/不运行hotfix作为解决方案。