我有一个C#winforms应用程序在另一个程序中运行一个宏 . 另一个程序将不断弹出窗口,通常会让事情看起来,因为缺乏一个更好的词,疯狂 . 我想实现一个取消按钮来阻止进程运行,但我似乎无法让窗口保持在最顶层 . 我如何在C#中执行此操作?
编辑:我试过TopMost = true; ,但另一个程序不断在顶部弹出自己的窗口 . 有没有办法每隔n毫秒将窗口发送到顶部?
编辑:我解决这个问题的方法是添加一个系统托盘图标,通过双击取消该过程 . 系统托盘图标不会被遮盖 . 感谢所有回复的人 . 我读过有关为什么没有“超级顶级”窗口的文章......它在逻辑上不起作用 .
12 回答
您试图压制其他应用程序的可见性是什么?你有没有调查过其他方法来达到你想要的效果?请在您的用户遇到如您描述的流氓行为之前这样做:您尝试做的事情听起来更像是某些顽皮网站对浏览器窗口所做的事情......
至少试着遵守Least Surprise的规则 . 用户希望能够确定大多数应用程序本身的z顺序 . 你不知道什么对他们来说最重要,所以如果你改变了什么,你应该专注于推动其他应用程序,而不是推广自己的应用程序 .
这当然比较棘手,因为Windows没有特别复杂的窗口管理器 . 两种方法表明自己:
enumerating top-level windows并检查which process they belong to,dropping their z-order if so . (我不确定这些WinAPI函数是否有框架方法 . )
摆弄子进程权限以防止它访问桌面...但我不会尝试这个,直到其他方法失败,因为子进程可能在需要用户交互时最终处于僵尸状态 .
如果通过“疯狂”意味着每个窗口都不断地从另一个窗口窃取焦点,TopMost将无法解决问题 .
相反,尝试:
这将显示“儿童”形式,而不会窃取焦点 . 即使父母被激活或专注,子表单也将保留在其父表单之上 . 如果您已在所有者表单中创建子表单的实例,则此代码仅适用 . 否则,您可能必须使用API设置所有者 .
将窗体的
.TopMost
属性设置为true .您可能不希望一直保持这种状态:在外部进程启动时设置它并在完成时将其放回原处 .
这是SetForegroundWindow的等价物:
我看到人们在做奇怪的事情,比如:
http://blog.jorgearimany.com/2010/10/win32-setforegroundwindow-equivalent-in.html
Form.TopMost
将起作用,除非其他程序正在创建最顶层的窗口 .无法创建另一个进程的新最顶层窗口未覆盖的窗口 . Raymond Chen explained为什么 .
我解决这个问题的方法是制作一个具有取消选项的系统托盘图标 .
以下代码使窗口始终保持在顶部并使其无框架 .
设置Form.TopMost
我知道这是旧的,但我没有看到这种反应 .
在窗口(xaml)中添加:
在Window_Deactivated的代码中:
这将使您的窗口保持在最顶层 .
我有一个短暂的5分钟失误,我忘了像这样完整地指定表格:
但我真正想要的就是这个!
我正在寻找使我的WinForms应用程序“永远在顶部”,但设置“TopMost”对我没有任何作用 . 我知道这是可能的,因为WinAmp会这样做(以及许多其他应用程序) .
我做的是打电话给“user32.dll” . 我对此没有任何疑虑,而且效果很好 . 无论如何,这是一个选择 .
首先,导入以下命名空间:
在类声明中添加一些变量:
为user32.dll函数添加原型:
然后在你的代码中(我在Form_Load()中添加了调用),添加调用:
希望有所帮助 . Reference
为什么不将表单设为对话框: