C# 如何使窗口始终保持在 .Net 的顶部?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/683330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make a window always stay on top in .Net?
提问by jle
I have a C# winforms app that runs a macro in another program. The other program will continually pop up windows and generally make things look, for lack of a better word, crazy. I want to implement a cancel button that will stop the process from running, but I cannot seem to get the window to stay on top. How do I do this in C#?
我有一个 C# winforms 应用程序,它在另一个程序中运行一个宏。另一个程序会不断弹出窗口,通常会使事情看起来很疯狂,因为没有更好的词。我想实现一个取消按钮来阻止进程运行,但我似乎无法让窗口保持在顶部。我如何在 C# 中做到这一点?
Edit: I have tried TopMost=true; , but the other program keeps popping up its own windows over top. Is there a way to send my window to the top every n milliseconds?
编辑:我试过 TopMost=true; ,但另一个程序不断在顶部弹出自己的窗口。有没有办法每 n 毫秒将我的窗口发送到顶部?
Edit: The way I solved this was by adding a system tray icon that will cancel the process by double-clicking on it. The system tray icon does no get covered up. Thank you to all who responded. I read the article on why there is not a 'super-on-top' window... it logically does not work.
编辑:我解决这个问题的方法是添加一个系统托盘图标,双击它可以取消该过程。系统托盘图标不会被掩盖。感谢所有回复的人。我阅读了关于为什么没有“超级顶部”窗口的文章......它在逻辑上不起作用。
采纳答案by RossFabricant
回答by Reed Copsey
Set Form.TopMost
回答by Joel Coehoorn
Set the form's .TopMost
property to true.
将表单的.TopMost
属性设置为 true。
You probably don't want to leave it this way all the time: set it when your external process starts and put it back when it finishes.
您可能不想一直保持这种状态:在外部进程启动时设置它,并在它完成时将其放回原处。
回答by Pontus Gagge
What is the other application you are trying to suppress the visibility of? Have you investigated other ways of achieving your desired effect? Please do so before subjecting your users to such rogue behaviour as you are describing: what you are trying to do sound rather like what certain naughty sites do with browser windows...
您试图抑制可见性的其他应用程序是什么?您是否研究过其他方式来达到您想要的效果?请在让您的用户遭受您所描述的这种流氓行为之前这样做:您尝试做的事情听起来很像某些顽皮网站对浏览器窗口所做的事情......
At least try to adhere to the rule of Least Surprise. Users expect to be able to determine the z-order of most applications themselves. You don't know what is most important to them, so if you change anything, you should focus on pushing the other application behind everything rather than promoting your own.
至少尽量坚持最少惊喜的规则。用户希望能够自己确定大多数应用程序的 z 顺序。你不知道什么对他们最重要,所以如果你改变任何东西,你应该专注于推动其他应用程序而不是推动你自己的应用程序。
This is of course trickier, since Windows doesn't have a particularly sophisticated window manager. Two approaches suggest themselves:
这当然更棘手,因为 Windows 没有特别复杂的窗口管理器。两种方法建议自己:
- enumerating top-level windowsand checking which process they belong to, dropping their z-order if so. (I'm not sure if there are framework methods for these WinAPI functions.)
- Fiddling with child process permissions to prevent it from accessing the desktop... but I wouldn't try this until the othe approach failed, as the child process might end up in a zombie state while requiring user interaction.
- 枚举顶级窗口并检查它们属于哪个进程,如果是,则删除它们的 z 顺序。(我不确定这些 WinAPI 函数是否有框架方法。)
- 摆弄子进程权限以防止它访问桌面......但我不会尝试这个,直到其他方法失败,因为子进程可能会在需要用户交互时最终处于僵尸状态。
回答by jle
The way i solved this was by making a system tray icon that had a cancel option.
我解决这个问题的方法是制作一个带有取消选项的系统托盘图标。
回答by Victor Stoddard
If by "going crazy" you mean that each window keeps stealing focus from the other, TopMost will not solve the problem.
如果“发疯”是指每个窗口不断从另一个窗口窃取焦点,则 TopMost 将无法解决问题。
Instead, try:
相反,请尝试:
CalledForm.Owner = CallerForm;
CalledForm.Show();
This will show the 'child' form without it stealing focus. The child form will also stay on top of its parent even if the parent is activated or focused. This code only works easily if you've created an instance of the child form from within the owner form. Otherwise, you might have to set the owner using the API.
这将显示“子”表单而不会窃取焦点。即使父表单被激活或聚焦,子表单也将保持在其父表单的顶部。仅当您从所有者表单中创建了子表单的实例时,此代码才能轻松工作。否则,您可能必须使用 API 设置所有者。
回答by Salim
Why not making your form a dialogue box:
为什么不让你的表单成为一个对话框:
myForm.ShowDialog();
回答by Dave
I had a momentary 5 minute lapse and I forgot to specify the form in full like this:
我有一个短暂的 5 分钟失误,我忘了像这样完整地指定表格:
myformName.ActiveForm.TopMost = true;
But what I really wanted was THIS!
但我真正想要的是这个!
this.TopMost = true;
回答by clamum
I was searching to make my WinForms application "Always on Top" but setting "TopMost" did not do anything for me. I knew it was possible because WinAmp does this (along with a host of other applications).
我正在寻找使我的 WinForms 应用程序“始终处于顶部”但设置“TopMost”对我没有任何作用。我知道这是可能的,因为 WinAmp 做到了这一点(以及许多其他应用程序)。
What I did was make a call to "user32.dll." I had no qualms about doing so and it works great. It's an option, anyway.
我所做的是调用“user32.dll”。我对这样做没有任何疑虑,而且效果很好。无论如何,这是一个选择。
First, import the following namespace:
首先,导入以下命名空间:
using System.Runtime.InteropServices;
Add a few variables to your class declaration:
在类声明中添加一些变量:
private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
private const UInt32 SWP_NOSIZE = 0x0001;
private const UInt32 SWP_NOMOVE = 0x0002;
private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
Add prototype for user32.dll function:
为 user32.dll 函数添加原型:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
Then in your code (I added the call in Form_Load()), add the call:
然后在您的代码中(我在 Form_Load() 中添加了调用),添加调用:
SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
Hope that helps. Reference
希望有帮助。参考
回答by user2070066
Here is the SetForegroundWindow equivalent:
这是 SetForegroundWindow 等效项:
form.Activate();
I have seen people doing weird things like:
我见过人们做一些奇怪的事情,例如:
this.TopMost = true;
this.Focus();
this.BringToFront();
this.TopMost = false;
http://blog.jorgearimany.com/2010/10/win32-setforegroundwindow-equivalent-in.html
http://blog.jorgearimany.com/2010/10/win32-setforegroundwindow-equivalent-in.html