Question

Je suis un développeur .NET depuis plusieurs années et cela est encore une de ces choses que je ne sais pas comment faire correctement. Il est facile de cacher une fenêtre dans la barre des tâches via une propriété dans les deux Windows Forms et WPF, mais pour autant que je peux dire, cela ne garantit pas (ni même nécessairement affecter) étant cachée de la Alt + ↹Tab dialogue. Je l'ai vu invisible fenêtres apparaissent dans Alt + ↹Tab , et je me demande quelle est la meilleure façon de garantir une fenêtre seront jamais apparaissent (visible ou non) dans la section Alt + ↹Tab dialogue.

Mise à jour: S'il vous plaît voir ma solution affichée ci-dessous. Je ne suis pas autorisé à marquer mes propres réponses que la solution, mais jusqu'à présent, il est le seul qui fonctionne.

Mise à jour 2: Il y a maintenant une solution appropriée par Franci Penov qui semble assez bon, mais ne l'ont pas essayé moi-même. Win32 certains Implique, mais évite la création lame de fenêtres hors écran.

Était-ce utile?

La solution

Mise à jour:

Selon @donovan, les temps modernes WPF supporte nativement, à travers l'établissement Et dans ShowInTaskbar="False" le XAML Visibility="Hidden". (Je ne l'ai pas encore testé, mais néanmoins décidé de remonter la visibilité commentaire)

Réponse originale:

Il y a deux façons de cacher une fenêtre du Gestionnaire de tâches dans l'API Win32:

  1. pour ajouter le style de fenêtre étendu WS_EX_TOOLWINDOW - c'est la bonne approche
  2. .
  3. pour en faire une fenêtre enfant d'une autre fenêtre.

Malheureusement, WPF ne supporte pas le contrôle aussi flexible sur le style de fenêtre Win32, donc une fenêtre avec WindowStyle=ToolWindow se retrouve avec la valeur par défaut et WS_CAPTION styles WS_SYSMENU, ce qui l'amène à avoir une légende et un proche bouton. D'autre part, vous pouvez supprimer ces deux styles en mettant WindowStyle=None, mais qui ne sera pas définir le style étendu et la ShowInTaskbar=False fenêtre ne sera pas caché du sélecteur de tâche.

Pour avoir une fenêtre WPF avec qui est également SetWindowLongPtr caché dans le Gestionnaire de tâches, on peut soit de deux façons:

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

Personnellement, je préfère la deuxième approche. Là encore, je fais des choses avancées comme l'extension du verre dans la zone client et permettant WPF dessin dans la légende de toute façon, donc un peu de Interop est pas un gros problème.

Voici l'exemple de code pour la solution approche Interop Win32. Tout d'abord, la partie 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" >

Rien d'extraordinaire ici, nous déclarons juste une fenêtre avec et <=> <=>. Nous ajoutons également un gestionnaire à l'événement Loaded où nous allons modifier le style de fenêtre étendu. Nous ne pouvons pas faire ce travail dans le constructeur, car il n'y a pas de poignée de fenêtre à ce moment-là encore. Le gestionnaire d'événement 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 Interop Win32. J'ai supprimé tous les styles inutiles des énumérations, juste pour garder l'exemple de code ici peu. De plus, malheureusement, le point d'entrée ne se trouve pas <=> dans user32.dll sous Windows XP, d'où le truc avec l'acheminement de l'appel par 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

Autres conseils

Dans votre classe de formulaire, ajoutez ceci:

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

Il est aussi simple que cela; fonctionne un charme!

Je l'ai trouvé une solution, mais ce n'est pas assez. Jusqu'à présent, c'est le que que j'ai essayé 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é .

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

Mise à jour: Ok, donc ce que je faisais était de déplacer le code ci-dessus, moins le bit this.Owner = w (et immédiatement après le déplacement w.Hide() w.Show(), qui fonctionne très bien) dans le constructeur de ma demande, la création d'un Window public static appelé OwnerWindow. Chaque fois que je veux une fenêtre pour exposer ce comportement, je simplement mis this.Owner = App.OwnerWindow. Fonctionne très bien, et implique que la création d'une fenêtre supplémentaire (et invisible). Vous pouvez même définir si vous voulez this.Owner = null la fenêtre réapparaisse dans la Alt + ↹Tab dialogue.

Merci à Ivan Onuchin sur le forum MSDN pour la solution.

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

Pourquoi si complexe? Essayez ceci:

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

Idée prise d'ici: http://www.csharp411.com/hide -forme-de-alttab /

Voici ce qui fait le tour, quel que soit le style de la fenêtre de votre essaient de cacher Alt + ↹Tab .

Placez le 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 faites votre formulaire un enfant d'une fenêtre invisible qui a le style correct et la mise en ShowInTaskbar garder hors de la liste Alt-Tab. Vous devez également définir la propriété ShowInTaskbar de votre propre formulaire à false. Mieux encore, il n'a tout simplement pas d'importance ce que le style de votre formulaire principal a, et tout peaufinage pour accomplir la cachette est juste quelques lignes dans le code constructeur.

Pourquoi essayer tant les codes? Il suffit de définir la propriété à FormBorderStyle FixedToolWindow. Espérons que cela aide.

voir: (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éfini 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:. Qu'il montre encore Alt + Tab je suppose, mais pas dans la barre des tâches

J'ai essayé le réglage de la principale forme de la visibilité à false chaque fois qu'il change automatiquement sur true:

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

Il fonctionne parfaitement:)

Ne pas afficher un formulaire. Utilisez l'invisibilité.

Plus d'informations ici: http://code.msdn.microsoft.com/TheNotifyIconExample

Propriétés Form1:
FormBorderStyle: Sizable
WindowState: Minimisation
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 la forme soit sans marge, vous devez ajouter les déclarations suivantes au constructeur du formulaire:

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

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

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 sais que ce n'est pas possible sans accrochage dans les fenêtres d'une certaine façon, je ne suis même pas sûr de savoir comment cela sera fait ou s'il est possible.

En fonction de vos besoins, le développement de votre contexte d'application comme une application NotifyIcon (barre d'état système) permettra d'être en cours d'exécution sans montrer ALT + TAB. Toutefois, si vous ouvrez un formulaire, ce formulaire sera toujours suivre la fonctionnalité standard.

Je peux déterrer mon article de blog sur la création d'une application qui est seulement une NotifyIcon par défaut si vous voulez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top