Windows窗体中的TopMost属性真的很烦人

时间:2010-05-06 00:51:42

标签: c# winforms topmost always-on-top

我有这个Windows窗体应用程序,它位于通知区域中。单击图标将其显示在前面,再次单击它(或单击应用程序X图标)将其发回。这是通过单击图标(虽然它是可选的)显示窗口始终位于顶部的应用程序类型。

右键单击该图标将显示一个上下文菜单,您可以选择是否启用“始终在线”选项。当应用程序首次启动时,应用程序设置将从XML文件中读取,我99%认为这是正常工作的,TopMost属性已正确读取(和写入)。

经过一段时间(几分钟,几小时,几天,无论如何;我通常休眠并很少关机)TopMost 停止工作。我没有更改选项,我不认为有什么改变选项值,但我点击通知区域图标和应用程序没有提前。它显示但它在背景上(它显示在Alt + Tab上),它不应该“始终在顶部”。我打开上下文菜单,禁用该选项(使其启用)并启用它,然后它开始工作。该应用程序现在“始终在顶部”。但是,它可能会在一段时间后随时失去这种能力。

我无法理解为什么会发生这种情况以及如何发生这种情况。有谁知道为什么?如果没有,任何想法我怎么能尝试调试这种行为?

修改
我添加了一段代码来显示一个MessageBox,当TopMost属性被更改时,看看我是否能注意到任何奇怪的行为,但这并不好。它没有帮助,因为表格是TopMost = true,但它仍然在后台......

2 个答案:

答案 0 :(得分:5)

不仅仅有一个“最顶层”窗口。最顶层只是说“在所有非最顶层的窗户之前”。

我非常确定桌面的重新初始化(例如休眠时)需要另一个SetWindowPos(hwnd, HWND_TOPMOST, ...)(这是底层的Win32 API调用)。

作为解决方法,您可以在显示窗口时重置并重新设置属性。

另一种可能性是隐藏窗口也会改变Z顺序 - 无论是Win32如何实现它,还是以WinForms调用隐藏/显示窗口的方式明确地改变。

答案 1 :(得分:1)

像peterchen一样,我也不知道如何找到根本原因。但为什么不让它变得更简单呢?

当您点击图标时,您将显示窗口并依赖TopMost仍处于活动状态。为什么不在显示窗口之前使用当前设置调用SetWindowPos()。这不会产生任何性能问题(仅在用户单击图标时发生)或任何其他副作用。

我知道,找出根本原因会很棒,但如果你能用这么一点的解决方法解决它,那也许不值得。