Meilleur moyen de masquer une fenêtre du sélecteur de programme Alt-Tab?

Je suis développeur .NET depuis plusieurs années et c’est encore une de ces choses que je ne sais pas faire correctement. Il est facile de cacher une fenêtre de la barre des tâches via une propriété à la fois dans Windows Forms et WPF, mais pour autant que je sache, cela ne garantit pas (ou n’affecte pas nécessairement) le fait qu’elle soit masquée dans la boîte de dialog Alt + Tab . J’ai vu des fenêtres invisibles apparaître dans Alt + Tab , et je me demande quel est le meilleur moyen de garantir qu’une fenêtre n’apparaîtra jamais (visible ou non) dans la boîte de dialog Alt + Tab .

Mise à jour: S’il vous plaît voir ma solution affichée ci-dessous. Je n’ai pas le droit de marquer mes propres réponses comme solution, mais jusqu’à présent, c’est la seule qui fonctionne.

Mise à jour 2: Il y a maintenant une solution appropriée de Franci Penov qui a l’air bien, mais je ne l’ai pas essayée moi-même. Implique certains Win32, mais évite la création boiteuse de fenêtres hors écran.

Mettre à jour:

Selon @donovan, les jours modernes, WPF le supporte en natif, en définissant ShowInTaskbar="False" et Visibility="Hidden" dans XAML. (Je n’ai pas encore testé cela, mais j’ai néanmoins décidé de dépasser la visibilité des commentaires)

Réponse originale:

Il existe deux manières de masquer une fenêtre à partir du commutateur de tâches dans l’API Win32:

  1. append le style de fenêtre étendu WS_EX_TOOLWINDOW – c’est la bonne approche.
  2. pour en faire une fenêtre enfant d’une autre fenêtre.

Malheureusement, WPF ne prend pas en charge le contrôle flexible du style de fenêtre comme Win32. Ainsi, une fenêtre avec WindowStyle=ToolWindow se retrouve avec les styles WS_CAPTION et WS_SYSMENU par défaut, ce qui entraîne une légende et un bouton de fermeture. D’autre part, vous pouvez supprimer ces deux styles en définissant WindowStyle=None , mais cela ne définira pas le style étendu WS_EX_TOOLWINDOW et la fenêtre ne sera pas masquée dans le sélecteur de tâches.

Pour avoir une fenêtre WPF avec WindowStyle=None qui est également masquée par le sélecteur de tâches, on peut procéder de deux manières:

  • aller avec l’exemple de code ci-dessus et faire de la fenêtre une fenêtre enfant d’une petite fenêtre d’outil masquée
  • modifiez le style de la fenêtre pour inclure également le style étendu WS_EX_TOOLWINDOW .

Personnellement, je préfère la deuxième approche. Là encore, je fais des choses avancées comme étendre la vitre dans la zone client et activer le dessin WPF dans la légende de toute façon, donc un peu d’interopérabilité n’est pas un gros problème.

Voici l’exemple de code pour l’approche de la solution Win32 Interop. Tout d’abord, la partie XAML:

  

Rien de très compliqué ici, nous déclarons simplement une fenêtre avec WindowStyle=None et ShowInTaskbar=False . Nous ajoutons également un gestionnaire à l’événement Loaded pour modifier le style de la fenêtre étendue. Nous ne pouvons pas faire ce travail dans le constructeur, car il n’y a pas encore de handle de fenêtre à ce stade. Le gestionnaire d’événements lui-même est très 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); } 

Et les déclarations d’interopérabilité Win32. J’ai supprimé tous les styles inutiles des énumérations, juste pour que l’exemple de code rest petit. En outre, malheureusement, le point d’entrée SetWindowLongPtr ne se trouve pas dans user32.dll sur Windows XP, d’où l’astuce avec le routage de l’appel via 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 

Dans votre classe de formulaire, ajoutez ceci:

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

C’est aussi simple que ça; travaille un charme!

J’ai trouvé une solution, mais ce n’est pas joli. Jusqu’à présent, c’est la seule chose que j’ai essayée qui fonctionne réellement:

 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 

Je l’ai trouvé ici .

Une solution plus générale et réutilisable serait bien. Je suppose que vous pouvez créer une seule fenêtre «w» et la réutiliser pour toutes les fenêtres de votre application qui doivent être masquées par les touches Alt + .Tab .

Mise à jour: Ok donc ce que j’ai fait a été de déplacer le code ci-dessus, moins le this.Owner = w (et de déplacer w.Hide() immédiatement après w.Show() , qui fonctionne bien) dans le constructeur de mon application, créant un statique public Window appelée OwnerWindow . Chaque fois que je veux une fenêtre pour afficher ce comportement, je définis simplement this.Owner = App.OwnerWindow . Fonctionne très bien et implique uniquement la création d’une fenêtre supplémentaire (et invisible). Vous pouvez même définir this.Owner = null si vous voulez que la fenêtre réapparaisse dans la boîte de dialog Alt + abTab .

Merci à Ivan Onuchin pour les solutions MSDN sur les forums.

Mise à jour 2: vous devez également définir ShowInTaskBar=false sur w pour éviter qu’il ne clignote brièvement dans la barre des tâches lorsqu’il est affiché.

Pourquoi si complexe? Essaye ça:

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

Idée tirée d’ici: http://www.csharp411.com/hide-form-from-alttab/

Voici ce que fait le tour, quel que soit le style de la fenêtre que vous essayez de masquer avec Alt + Tab .

Placez les éléments suivants dans le constructeur de votre formulaire:

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

Essentiellement, vous faites de votre formulaire un enfant d’une fenêtre invisible dont le style et le paramètre ShowInTaskbar sont corrects pour restr en dehors de la liste Alt-Tab. Vous devez également définir la propriété ShowInTaskbar de votre propre formulaire sur false. Mieux encore, le style de votre formulaire principal importe peu, et toutes les modifications nécessaires pour le masquer ne sont que quelques lignes dans le code constructeur.

Pourquoi essayer tant de codes? Il suffit de définir la FormBorderStyle FormBorderStyle sur FixedToolWindow . J’espère que cela aide.

voir: (à partir de 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); 

Dans XAML, définissez ShowInTaskbar = “False”:

     

Edit: Cela apparaît toujours dans Alt + Tab je suppose, juste pas dans la barre des tâches.

J’ai essayé de définir la visibilité du formulaire principal sur false chaque fois qu’il est automatiquement modifié à true:

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

Cela fonctionne parfaitement 🙂

Ne montre pas de formulaire. Utilisez l’invisibilité.

Plus ici: http://code.msdn.microsoft.com/TheNotifyIconExample

Propriétés de Form1:
FormBorderStyle: Taille importante
WindowState: minimisé
ShowInTaskbar: Faux

 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; }> 

Si vous voulez que le formulaire soit sans bordure, vous devez append les instructions suivantes au constructeur du formulaire:

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

ET vous devez append la méthode suivante à votre classe de formulaire dérivée:

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

plus de détails

Personnellement, pour autant que je sache, ce n’est pas possible sans se twigr à Windows d’une manière ou d’une autre, je ne suis même pas sûr de savoir comment cela se ferait ou si c’est possible.

Selon vos besoins, le développement de votre contexte d’application en tant qu’application NotifyIcon (barre d’état système) lui permettra de s’exécuter sans afficher ALT + TAB. Cependant, si vous ouvrez un formulaire, ce formulaire suivra toujours les fonctionnalités standard.

Je peux déterrer mon article de blog sur la création d’une application qui est UNIQUEMENT un NotifyIcon par défaut si vous le souhaitez.