Best way to hide a window from the Alt-Tab program switcher?

I have been a .NET developer for several years, and this is still one of those things that I don’t know how to work properly. It is easy to hide a window from the taskbar using the property in both Windows Forms and WPF, but, as far as I can tell, this does not guarantee (or necessarily affects) its hiding from the Alt + ↹Tab dialog. I saw invisible windows in Alt + ↹Tab , and I'm just wondering what is the best way to ensure that the window never appears (visible or not) in the Alt + ↹Tab dialog box.

Update:. See below for my solution. I cannot mark my own answers as a solution, but so far this is the only thing that works.

Update 2: There is now the right solution from Franci Penov, which looks pretty good, but did not try on its own. Involves some Win32, but avoids the lame creation of off-screen windows.

+81
winforms wpf alt-tab
Dec 10 '08 at 18:31
source share
13 answers

Update:

According to @donovan, these days WPF supports this initially by setting ShowInTaskbar="False" and Visibility="Hidden" in XAML. (I have not tested this yet, but nevertheless decided to emphasize the visibility of the comment)

Original answer:

There are two ways to hide the window from the task switcher in the Win32 API:

  • add style WS_EX_TOOLWINDOW extended window - the right approach.
  • to make it a child window of another window.

Unfortunately, WPF does not support flexible control over the window style as Win32, so the window with WindowStyle=ToolWindow ends with the default styles WS_CAPTION and WS_SYSMENU , which forces it to have a signature and close the button. On the other hand, you can remove these two styles by setting WindowStyle=None , however this will not set the extended style to WS_EX_TOOLWINDOW , and the window will not be hidden from the task switcher.

To have a WPF window with WindowStyle=None , which is also hidden from the task switcher, you can use one of two ways:

  • go with the code example above and make the window a child window of a small hidden tool window
  • change the window style to include the advanced style WS_EX_TOOLWINDOW .

I personally prefer the second approach. Again, I am doing some advanced things, such as expanding the glass in the client area and including the WPF drawing in the signature anyway, so a bit of interaction is not a big problem.

Here is a sample code to solve the Win32 interop solution. First, part of XAML:

 <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300" ShowInTaskbar="False" WindowStyle="None" Loaded="Window_Loaded" > 

Nothing special here, we just declare a window with WindowStyle=None and ShowInTaskbar=False . We also add a Loaded event handler, where we will change the extended window style. We cannot do this work in the constructor, because at this moment there is no window handle. The event handler itself is very simple:

  private void Window_Loaded(object sender, RoutedEventArgs e) { WindowInteropHelper wndHelper = new WindowInteropHelper(this); int exStyle = (int)GetWindowLong(wndHelper.Handle, (int)GetWindowLongFields.GWL_EXSTYLE); exStyle |= (int)ExtendedWindowStyles.WS_EX_TOOLWINDOW; SetWindowLong(wndHelper.Handle, (int)GetWindowLongFields.GWL_EXSTYLE, (IntPtr)exStyle); } 

And Win32 interop announcements. I removed all unnecessary styles from the enumerations in order to save the sample code here. Unfortunately, the SetWindowLongPtr entry SetWindowLongPtr not found in user32.dll in Windows XP, hence the trick of routing the call through SetWindowLong .

  #region Window styles [Flags] public enum ExtendedWindowStyles { // ... WS_EX_TOOLWINDOW = 0x00000080, // ... } public enum GetWindowLongFields { // ... GWL_EXSTYLE = (-20), // ... } [DllImport("user32.dll")] public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex); public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong) { int error = 0; IntPtr result = IntPtr.Zero; // Win32 SetWindowLong doesn't clear error on success SetLastError(0); if (IntPtr.Size == 4) { // use SetWindowLong Int32 tempResult = IntSetWindowLong(hWnd, nIndex, IntPtrToInt32(dwNewLong)); error = Marshal.GetLastWin32Error(); result = new IntPtr(tempResult); } else { // use SetWindowLongPtr result = IntSetWindowLongPtr(hWnd, nIndex, dwNewLong); error = Marshal.GetLastWin32Error(); } if ((result == IntPtr.Zero) && (error != 0)) { throw new System.ComponentModel.Win32Exception(error); } return result; } [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)] private static extern IntPtr IntSetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)] private static extern Int32 IntSetWindowLong(IntPtr hWnd, int nIndex, Int32 dwNewLong); private static int IntPtrToInt32(IntPtr intPtr) { return unchecked((int)intPtr.ToInt64()); } [DllImport("kernel32.dll", EntryPoint = "SetLastError")] public static extern void SetLastError(int dwErrorCode); #endregion 
+81
Feb 15 '09 at 23:36
source share

Inside the form class, add the following:

 protected override CreateParams CreateParams { get { var Params = base.CreateParams; Params.ExStyle |= 0x80; return Params; } } 

It is so simple; the charm works!

+28
Jul 27 '13 at 2:19
source share

I found a solution, but it is not very. So far, this is the only thing I've tried that actually works:

 Window w = new Window(); // Create helper window w.Top = -100; // Location of new window is outside of visible part of screen w.Left = -100; w.Width = 1; // size of window is enough small to avoid its appearance at the beginning w.Height = 1; w.WindowStyle = WindowStyle.ToolWindow; // Set window style as ToolWindow to avoid its icon in AltTab w.Show(); // We need to show window before set is as owner to our main window this.Owner = w; // Okey, this will result to disappear icon for main window. w.Hide(); // Hide helper window just in case 

Found here .

A more general, reusable solution would be nice. I suppose you could create one “w” window and reuse it for all windows of your application that should be hidden from Alt + ↹Tab .

Update: Okay, so what I did is move the code above, minus the this.Owner = w bit (and move w.Hide() right after w.Show() , which works fine) in my application constructor, creating a public static Window called OwnerWindow . Whenever I want a window to display this behavior, I simply set this.Owner = App.OwnerWindow . Works great and only includes the creation of one additional (and invisible) window. You can even set this.Owner = null if you want the window to reappear in the Alt + ↹Tab dialog box.

Thanks to Ivan Onuchin on the MSDN forums for the solution.

Update 2: You should also set ShowInTaskBar=false to w so that it does not ShowInTaskBar=false briefly on the taskbar when shown.

+17
Dec 10 '08 at 21:00
source share

Why is it so complicated? Try the following:

 me.FormBorderStyle = FormBorderStyle.SizableToolWindow me.ShowInTaskbar = false 

The idea is taken here: http://www.csharp411.com/hide-form-from-alttab/

+10
Apr 23 '10 at 11:35
source share

This is what the trick does, regardless of the window style you are trying to hide from Alt + ↹Tab .

Put the following in the constructor of your form:

 // Keep this program out of the Alt-Tab menu ShowInTaskbar = false; Form form1 = new Form ( ); form1.FormBorderStyle = FormBorderStyle.FixedToolWindow; form1.ShowInTaskbar = false; Owner = form1; 

Essentially, you make your form a child of an invisible window that has the correct style and ShowInTaskbar so that it doesn't get into the Alt-Tab list. You must also set the ShowInTaskbar property to false for your form. Best of all, it just doesn't matter what style your main form has, and any tweaking to do the hiding is just a few lines in the constructor code.

+8
Apr 30 '10 at 3:33
source share

Why try so many codes? Just set FormBorderStyle propety to FixedToolWindow . Hope this helps.

+3
Feb 22 '12 at 11:21
source share

see it: (from http://bytes.com/topic/c-sharp/answers/442047-hide-alt-tab-list#post1683880 )

 [DllImport("user32.dll")] public static extern int SetWindowLong( IntPtr window, int index, int value); [DllImport("user32.dll")] public static extern int GetWindowLong( IntPtr window, int index); const int GWL_EXSTYLE = -20; const int WS_EX_TOOLWINDOW = 0x00000080; const int WS_EX_APPWINDOW = 0x00040000; private System.Windows.Forms.NotifyIcon notifyIcon1; // I use two icons depending of the status of the app normalIcon = new Icon(this.GetType(),"Normal.ico"); alertIcon = new Icon(this.GetType(),"Alert.ico"); notifyIcon1.Icon = normalIcon; this.WindowState = System.Windows.Forms.FormWindowState.Minimized; this.Visible = false; this.ShowInTaskbar = false; iconTimer.Start(); //Make it gone frmo the ALT+TAB int windowStyle = GetWindowLong(Handle, GWL_EXSTYLE); SetWindowLong(Handle, GWL_EXSTYLE, windowStyle | WS_EX_TOOLWINDOW); 
+2
May 11 '10 at
source share

In XAML, set ShowInTaskbar = "False":

 <Window x:Class="WpfApplication5.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ShowInTaskbar="False" Title="Window1" Height="300" Width="300"> <Grid> </Grid> </Window> 

Edit: this is still displayed in Alt + Tab, I think, just not in the taskbar.

+1
Dec 10 '08 at 19:25
source share

I tried to set the visibility of the main form to false when it automatically changes to true:

 private void Form1_VisibleChanged(object sender, EventArgs e) { if (this.Visible) { this.Visible = false; } } 

It works great :)

+1
Jan 02 '10 at 16:27
source share

Do not show the form. Use invisibility.

More details here: http://code.msdn.microsoft.com/TheNotifyIconExample

0
Dec 29 '09 at 16:32
source share

Form1 Properties:
FormBorderStyle: meaningful
WindowState: minimized ShowInTaskbar: False

 private void Form1_Load(object sender, EventArgs e) { // Making the window invisible forces it to not show up in the ALT+TAB this.Visible = false; }> 
0
Apr 23 '09 at 20:38
source share

if you want the form to be borderless, you need to add the following instructions to the form constructor:

 this.FormBorderStyle = FormBorderStyle.None; this.ShowInTaskbar = false; 

And you should add the following method to your derived Form class:

 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; // turn on WS_EX_TOOLWINDOW style bit cp.ExStyle |= 0x80; return cp; } } 

more details

0
Sep 27 '12 at 18:50
source share

Personally, as far as I know, this is impossible without being tied to windows in any way, I don’t even know how it will 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 work without being displayed in ALT + TAB. HOWEVER, if you open a form, this form will still conform to standard functionality.

I can dig out my blog article on creating an application, which by default is NotifyIcon, if you want.

-one
Dec 10 '08 at 19:02
source share



All Articles