从 Alt-Tab 程序切换器隐藏窗口的最佳方法?
我已经成为 .NET 开发人员好几年了,但这仍然是我不知道如何正确做的事情之一。 通过 Windows 窗体和 WPF 中的属性从任务栏隐藏窗口很容易,但据我所知,这并不能保证(甚至不一定影响)它从 Alt+↹选项卡 对话框。 我见过 不可见 窗口出现在 Alt+↹Tab 中,我只是想知道保证窗口的最佳方法是什么将永远出现在Alt+↹Tab对话框中(可见或不可见)。
更新:请参阅下面我发布的解决方案。 我不允许将自己的答案标记为解决方案,但到目前为止,这是唯一有效的答案。
更新 2: 现在 Franci Penov 提出了一个看起来不错的解决方案,但我自己还没有尝试过。 涉及一些 Win32,但避免了屏幕外窗口的蹩脚创建。
I've been a .NET developer for several years now and this is still one of those things I don't know how to do properly. It's easy to hide a window from the taskbar via a property in both Windows Forms and WPF, but as far as I can tell, this doesn't guarantee (or necessarily even affect) it being hidden from the Alt+↹Tab dialog. I've seen invisible windows show up in Alt+↹Tab, and I'm just wondering what is the best way to guarantee a window will never appear (visible or not) in the Alt+↹Tab dialog.
Update: Please see my posted solution below. I'm not allowed to mark my own answers as the solution, but so far it's the only one that works.
Update 2: There's now a proper solution by Franci Penov that looks pretty good, but haven't tried it out myself. Involves some Win32, but avoids the lame creation of off-screen windows.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
我发现使用 WPF 执行此操作的最简单方法(尽管到目前为止仅进行了相当简单的测试)就是将所有者设置为新窗口中的主窗口。 这本质上使窗口看起来像一种模式对话框或覆盖层,而不出现在任务栏或 alt-tab 中。
示例:
在窗口的代码隐藏中:
以及在窗口的 XAML 中:
然后可以使用标准 ShowDialog() 方法从其他地方调用上面的窗口,如下所示如下(或 Show() 如果不视为对话框):
对于上面的示例,在一个非常基本的测试应用程序中,应该显示如下所示:
The simplest way that I found to do this with WPF (although only fairly briefly tested so far) was just to set the owner to the main window within the new Window. This essentially makes the Window appear like a sort of modal dialog or overlay without it appearing in the taskbar or from alt-tab.
Example:
In code behind for the Window:
And in the XAML for the Window:
The Window above could then be called from elsewhere simply with the standard ShowDialog() method as follows (or Show() if not treating as a dialog):
With the example above in a very basic test app, this should appear something like this:
据我个人所知,如果不以某种方式连接到窗口,这是不可能的,我什至不确定如何做到这一点或者是否可能。
根据您的需求,将应用程序上下文开发为 NotifyIcon(系统托盘)应用程序将允许其运行而无需在 ALT + TAB 中显示。 但是,如果您打开一个表单,该表单仍将遵循标准功能。
如果您愿意,我可以挖掘我的博客文章,介绍创建默认情况下仅是 NotifyIcon 的应用程序。
Personally as far as I know this is not possible without hooking into windows in some fashion, I'm not even sure how that would be done or if it is possible.
Depending on your needs, developing your application context as a NotifyIcon (system tray) application will allow it to be running without showing in ALT + TAB. HOWEVER, if you open a form, that form will still follow the standard functionality.
I can dig up my blog article about creating an application that is ONLY a NotifyIcon by default if you want.
Form1 属性:
FormBorderStyle:大小
窗口状态:最小化
在任务栏显示:False
Form1 Properties:
FormBorderStyle: Sizable
WindowState: Minimized
ShowInTaskbar: False
更新: [已验证且不起作用,忽略编辑]
根据@donovan,现代 WPF 通过设置原生支持此功能
XAML 中的
ShowInTaskbar="False"
和Visibility="Hidden"
。 (我还没有对此进行测试,但仍然决定提高注释可见性)原始答案:
在 Win32 API 中从任务切换器隐藏窗口有两种方法:
WS_EX_TOOLWINDOW
扩展窗口样式 - 这是正确的方法。不幸的是,WPF 不支持像 Win32 那样灵活地控制窗口样式,因此带有
WindowStyle=ToolWindow
的窗口最终会使用默认的WS_CAPTION
和WS_SYSMENU
code> styles,这会导致它有一个标题和一个关闭按钮。 另一方面,您可以通过设置 WindowStyle=None 来删除这两种样式,但这不会设置 WS_EX_TOOLWINDOW 扩展样式,并且窗口不会从任务中隐藏切换器。要使
WindowStyle=None
的 WPF 窗口也对任务切换器隐藏,可以采用以下两种方法之一:WS_EX_TOOLWINDOW
扩展样式。我个人更喜欢第二种方法。 话又说回来,我做了一些高级的事情,比如在客户端区域扩展玻璃并在标题中启用 WPF 绘图,因此一点点互操作并不是一个大问题。
下面是 Win32 互操作解决方案方法的示例代码。 首先,XAML 部分:
这里没什么特别的,我们只是用
WindowStyle=None
和ShowInTaskbar=False
声明一个窗口。 我们还向 Loaded 事件添加一个处理程序,我们将在其中修改扩展窗口样式。 我们无法在构造函数中完成这项工作,因为此时还没有窗口句柄。 事件处理程序本身非常简单:以及 Win32 互操作声明。 我已经从枚举中删除了所有不必要的样式,只是为了保持此处的示例代码较小。 另外,不幸的是,在 Windows XP 上的 user32.dll 中找不到 SetWindowLongPtr 入口点,因此需要通过 SetWindowLong 来路由调用。
Update: [Verified and is not working, ignore the edit]
According to @donovan, modern days WPF supports this natively, through setting
ShowInTaskbar="False"
andVisibility="Hidden"
in the XAML. (I haven't tested this yet, but nevertheless decided to bump the comment visibility)Original answer:
There are two ways of hiding a window from the task switcher in Win32 API:
WS_EX_TOOLWINDOW
extended window style - that's the right approach.Unfortunately, WPF does not support as flexible control over the window style as Win32, thus a window with
WindowStyle=ToolWindow
ends up with the defaultWS_CAPTION
andWS_SYSMENU
styles, which causes it to have a caption and a close button. On the other hand, you can remove these two styles by settingWindowStyle=None
, however that will not set theWS_EX_TOOLWINDOW
extended style and the window will not be hidden from the task switcher.To have a WPF window with
WindowStyle=None
that is also hidden from the task switcher, one can either of two ways:WS_EX_TOOLWINDOW
extended style.I personally prefer the second approach. Then again, I do some advanced stuff like extending the glass in the client area and enabling WPF drawing in the caption anyway, so a little bit of interop is not a big problem.
Here's the sample code for the Win32 interop solution approach. First, the XAML part:
Nothing too fancy here, we just declare a window with
WindowStyle=None
andShowInTaskbar=False
. We also add a handler to the Loaded event where we will modify the extended window style. We can't do that work in the constructor, as there's no window handle at that point yet. The event handler itself is very simple:And the Win32 interop declarations. I've removed all unnecessary styles from the enums, just to keep the sample code here small. Also, unfortunately the
SetWindowLongPtr
entry point is not found in user32.dll on Windows XP, hence the trick with routing the call through theSetWindowLong
instead.在您的表单类中,添加以下内容:
就这么简单; 很有魅力!
Inside your form class, add this:
It's as easy as that; works a charm!
我找到了一个解决方案,但它并不漂亮。 到目前为止,这是我尝试过的唯一有效的方法:
找到它此处。
一个更通用、可重用的解决方案会很好。 我想您可以创建一个窗口“w”并将其重用于应用程序中需要从 Alt+↹Tab 隐藏的所有窗口。
更新:好吧,我所做的就是移动上面的代码,减去
this.Owner = w
位(并移动w.Hide()
紧接着w.Show()
(工作正常)进入我的应用程序的构造函数,创建一个名为OwnerWindow
的公共静态Window
。 每当我想要一个窗口表现出这种行为时,我只需设置this.Owner = App.OwnerWindow
即可。 效果很好,只需要创建一个额外的(且不可见的)窗口。 如果您希望窗口重新出现在 Alt+↹Tab 对话框中,您甚至可以设置this.Owner = null
。感谢 Ivan Onuchin 在 MSDN 论坛上提供的解决方案。
更新 2: 您还应该在
w
上设置ShowInTaskBar=false
,以防止它在显示时在任务栏中短暂闪烁。I've found a solution, but it's not pretty. So far this is the only thing I've tried that actually works:
Found it here.
A more general, reusable solution would be nice. I suppose you could create a single window 'w' and reuse it for all windows in your app that need to be hidden from the Alt+↹Tab.
Update: Ok so what I did was move the above code, minus the
this.Owner = w
bit (and movingw.Hide()
immediately afterw.Show()
, which works fine) into my application's constructor, creating a public staticWindow
calledOwnerWindow
. Whenever I want a window to exhibit this behavior, I simply setthis.Owner = App.OwnerWindow
. Works great, and only involves creating one extra (and invisible) window. You can even setthis.Owner = null
if you want the window to reappear in the Alt+↹Tab dialog.Thanks to Ivan Onuchin over on MSDN forums for the solution.
Update 2: You should also set
ShowInTaskBar=false
onw
to prevent it from flashing briefly in the taskbar when shown.无论您试图从 Alt+↹Tab 隐藏的窗口样式如何,技巧如下。
将以下内容放入表单的构造函数中:
本质上,您使表单成为不可见窗口的子窗口,该窗口具有正确的样式和 ShowInTaskbar 设置以防止出现在 Alt-Tab 列表中。 您还必须将自己的窗体的 ShowInTaskbar 属性设置为 false。 最重要的是,主窗体的样式并不重要,并且完成隐藏的所有调整都只需构造函数代码中的几行。
Here's what does the trick, regardless of the style of the window your are trying to hide from Alt+↹Tab.
Place the following into the constructor of your form:
Essentially, you make your form a child of an invisible window which has the correct style and ShowInTaskbar setting to keep out of the Alt-Tab list. You must also set your own form's ShowInTaskbar property to false. Best of all, it simply doesn't matter what style your main form has, and all tweaking to accomplish the hiding is just a few lines in the constructor code.
为什么这么复杂?
试试这个:
想法取自这里:http://www.csharp411.com/hide -form-from-alttab/
Why so complex?
Try this:
Idea taken from here:http://www.csharp411.com/hide-form-from-alttab/
看到它:(来自 http://bytes .com/topic/c-sharp/answers/442047-hide-alt-tab-list#post1683880)
see it:(from http://bytes.com/topic/c-sharp/answers/442047-hide-alt-tab-list#post1683880)
为什么要尝试这么多代码?
只需将
FormBorderStyle
属性设置为FixedToolWindow
即可。希望能帮助到你。
Why trying so much codes?
Just set the
FormBorderStyle
propety toFixedToolWindow
.Hope it helps.
我尝试将主窗体的可见性设置为 false,每当它自动更改为 true 时:
它工作得很好:)
I tried setting the main form's visibility to false whenever it is automatically changed to true:
It works perfectly :)
如果您希望表单无边框,则需要将以下语句添加到表单的构造函数中:
并且必须将以下方法添加到派生的 Form 类中:
更多详细信息
if you want the form to be borderless, then you need to add the following statements to the form’s constructor:
AND you must add the following method to your derived Form class:
more details
在 XAML 中设置 ShowInTaskbar="False":
编辑:我猜这仍然在 Alt+Tab 中显示,只是不在任务栏中显示。
In XAML set ShowInTaskbar="False":
Edit: That still shows it in Alt+Tab I guess, just not in the taskbar.
我试过这个。 这个对我有用
I tried This. It works for me
不要显示表格。 使用隐形。
更多信息请参见:http://code.msdn.microsoft.com/TheNotifyIconExample
Don't show a form. Use invisibility.
More here: http://code.msdn.microsoft.com/TheNotifyIconExample
对于那些希望 WPF 窗口在 Alt+Tab 切换器中隐藏时保持可见的解决方案:
通过 Alt+Tab 隐藏 WPF 窗口
Solution for those who want a WPF window to stay visible while hidden from the Alt+Tab switcher:
Hide a WPF window from Alt+Tab