104 votes

La meilleure façon de cacher une fenêtre de l'Alt-Tab programme de switcher?

J'ai été un .NET développeur depuis plusieurs années maintenant, et c'est encore une de ces choses je ne sais pas comment le faire correctement. Il est facile de cacher une fenêtre à partir de la barre des tâches par l'intermédiaire d'une propriété dans les deux Windows Forms et WPF, mais autant que je peux dire, ce n'est pas une garantie (ou nécessairement la même affecter), il est caché de l'Alt-Tab boîte de dialogue. J'ai vu invisible windows apparaître dans Alt-Tab, et je me demande quelle est la meilleure façon de garantir une fenêtre sera jamais apparaître (visible ou non) dans le Alt-Tab boîte de dialogue.

Mise à jour: Merci de voir mes posté solution ci-dessous. Je ne suis pas autorisé à marquer mes propres réponses comme la solution, mais pour l'instant c'est le seul qui fonctionne.

Mise à jour 2: Il y a maintenant une bonne solution par Franci Penov que semble assez bon, mais je n'ai pas essayé moi-même. Implique une certaine Win32, mais évite la lame de la création de l'extérieur de l'écran windows.

101voto

Franci Penov Points 45358

Il y a deux façons de cacher une fenêtre de la task switcher en API Win32:

  1. ajouter l' WS_EX_TOOLWINDOW étendue de style de fenêtre - 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 comme un contrôle flexible sur le style de la fenêtre Win32, donc une fenêtre avec WindowStyle=ToolWindow se termine avec la valeur par défaut WS_CAPTION et WS_SYSMENU styles, ce qui en fait une légende et un bouton de fermeture. D'autre part, vous pouvez supprimer ces deux styles en définissant WindowStyle=None, cependant que ne sera pas mis l' WS_EX_TOOLWINDOW style étendu, et la fenêtre ne sera pas masqué de la task switcher.

Pour avoir une fenêtre WPF avec WindowStyle=None que est également caché de la task switcher, on peut soit deux façons:

  • aller avec l'exemple de code ci-dessus et la fenêtre une fenêtre enfant d'une petite caché fenêtre de l'outil de
  • modifier le style de la fenêtre d'inclure également l' WS_EX_TOOLWINDOW style étendu.

Personnellement, je préfère la deuxième approche. Puis de nouveau, je fais quelques choses avancées comme l'extension de la vitre dans l'espace client et l'activation de WPF dessin dans la légende de toute façon, donc un peu de l'interopérabilité est pas un gros problème.

Voici un exemple de code pour le Win32 interop approche de la solution. Tout d'abord, le code XAML de la partie:

<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" >

Rien de trop de fantaisie ici, nous déclarons simplement une fenêtre avec WindowStyle=None et ShowInTaskbar=False. Nous avons également ajouter un gestionnaire pour l'événement Chargé où nous allons modifier l'étendue de la fenêtre de style. Nous ne pouvons pas faire le travail dans le constructeur, car il n'y a pas de poignée de fenêtre à ce moment encore. Le gestionnaire d'événement en 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 Win32 interop déclarations. J'ai supprimé tous les inutiles styles de la enums, juste pour garder l'exemple de code ici les petits. Aussi, malheureusement, l' SetWindowLongPtr point d'entrée n'est pas trouvé dans user32.dll sur Windows XP, donc le truc avec le routage de l'appel par le biais de l' SetWindowLong à la place.

    #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

43voto

Danny Beckett Points 6431

À l'intérieur de votre classe de formulaire, ajoutez ceci:

// Remove from Alt+Tab dialog
protected override CreateParams CreateParams
{
    get
    {
        var Params = base.CreateParams;
        Params.ExStyle |= 0x80;
        return Params;
    }
}

C'est aussi simple que cela; fonctionne à merveille!

21voto

chaiguy Points 7615

J'ai trouvé une solution, mais ce n'est pas assez. Jusqu'à présent c'est la seule chose que j'ai essayé et 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

Trouvé ici.

D'une manière plus générale, l'réutilisables solution serait sympa. Je suppose que vous pourriez créer un guichet unique " w " et les réutiliser pour toutes les fenêtres de votre application qui doivent être cachés par le Alt+Tab.

Mise à jour: Ok, donc ce que j'ai fait était de déplacer le code ci-dessus, diminuée de la this.Owner = w peu (et en déplaçant w.Hide() immédiatement après l' w.Show(), ce qui fonctionne très bien) dans ma demande du constructeur, la création d'un public static Window appelés OwnerWindow. Chaque fois que je veux une fenêtre d'exposer ce problème, j'ai simplement mis this.Owner = App.OwnerWindow. Fonctionne très bien, et ne concerne que la création d'un extra (et invisible) de la fenêtre. Vous pouvez même configurer this.Owner = null si vous voulez que la fenêtre de réapparaître dans le Alt+Tab boîte de dialogue.

Merci à Ivan Onuchin plus sur les forums MSDN pour la solution.

Mise à jour 2: Vous devez également configurer ShowInTaskBar=false sur w pour l'empêcher de clignoter brièvement dans la barre des tâches lorsque indiqué.

11voto

Andrey Points 71

Pourquoi est-elle si Complexe? Essayez ceci:

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

Idée tooked à partir d'ici:http://www.csharp411.com/hide-form-from-alttab/

10voto

Matt Hendricks Points 51

Voici ce que fait le truc, quel que soit le style de la fenêtre de votre essayez de cacher Alt-Tab.

Placez le code suivant 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 apportez votre formulaire un enfant d'un invisible de la fenêtre qui a le style correct et ShowInTaskbar paramètre afin de garder hors de l'Alt-Tab liste. Vous devez également définir votre propre formulaire de ShowInTaskbar valeur false à la propriété. Le meilleur de tous, il n'a tout simplement pas d'importance ce que le style de votre formulaire principal, et tous les réglages à réaliser le masquage est juste quelques lignes dans le code du constructeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X