Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 顶部窗口有时位于非顶部全屏窗口的后面_C#_.net_Wpf_Winforms - Fatal编程技术网

C# 顶部窗口有时位于非顶部全屏窗口的后面

C# 顶部窗口有时位于非顶部全屏窗口的后面,c#,.net,wpf,winforms,C#,.net,Wpf,Winforms,我有一个“控制工具栏”应用程序,它需要浮动在双显示器系统主屏幕上的所有其他应用程序之上。它将自身定位在主屏幕的顶部,并将TopMost设置为true 此控制工具栏可用于启动另外两个进程,它们运行全屏但不是最顶层,双监视器系统上的每个监视器上各有一个进程。通过将BorderStyle设置为None并将窗口的边界设置为完全适合屏幕尺寸,这些窗口被设置为全屏运行。全屏窗口覆盖任务栏没有问题,我可以全天关注主显示器上的全屏窗口并与之交互,而工具栏保持在顶部 然而,在软件王国里,一切都不尽如人意——某些动

我有一个“控制工具栏”应用程序,它需要浮动在双显示器系统主屏幕上的所有其他应用程序之上。它将自身定位在主屏幕的顶部,并将TopMost设置为true

此控制工具栏可用于启动另外两个进程,它们运行全屏但不是最顶层,双监视器系统上的每个监视器上各有一个进程。通过将BorderStyle设置为None并将窗口的边界设置为完全适合屏幕尺寸,这些窗口被设置为全屏运行。全屏窗口覆盖任务栏没有问题,我可以全天关注主显示器上的全屏窗口并与之交互,而工具栏保持在顶部

然而,在软件王国里,一切都不尽如人意——某些动作会使最顶端的工具栏在非最顶端的全屏窗口下弹出。其中一个操作是在辅助监视器上聚焦全屏应用程序,然后在主监视器上聚焦全屏应用程序。这是最容易重现的情况,因为每次我遵循这个顺序时都会发生这种情况。我很难可靠地再现其他场景,但如果我按windows键调出“开始”菜单并开始在Internet Explorer中浏览,有时当我完成浏览并关闭IE并将焦点返回到主监视器全屏应用程序时,它会弹出最顶部的窗口

你知道如何保持最上面的窗口在顶部,而不允许它在非最上面的全屏窗口下弹出吗?我不介意每秒轮询WindowFromPoint一次,看看工具栏是否仍在顶部,如果没有,然后以某种方式将其弹出,但如果用户正在使用全屏应用程序,我不想将注意力从全屏应用程序移开,因此Activate()不是一个特别好的解决方案

我认为这并不重要,但工具栏是一个WPF窗口,全屏应用程序是WinForms

更新:

测试这一点最简单的方法是按F11键在每个显示器的两个浏览器窗口中全屏显示,以模拟全屏应用程序,然后让最上面的窗口浮动在任何位置。在两个全屏窗口之间单击,您将看到最上面的窗口在它们下面弹出。我在一个显示器上打开IE,在另一个显示器上打开Chrome,因为IE不允许我打开两个全屏窗口


我现在实现了Activate()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找到了解决此问题的修补程序:


我在代码中保留了我的黑客技能,以防客户无法/没有运行修补程序作为解决办法。

谢谢Hans,这是一个救命稻草!修补了我的系统,效果很好……现在只需修补我所有客户的系统:/在下面我的答案中添加了您的链接。