Domanda

Sono stato uno sviluppatore .NET ormai da diversi anni e questo è ancora una di quelle cose che non so come fare correttamente. E 'facile nascondere una finestra dalla barra delle applicazioni tramite una proprietà in entrambi i Windows Form e WPF, ma per quanto ne so, questo non garantisce (o necessariamente anche influenzare) essendo nascosto dalla Alt + ↹Tab finestra di dialogo. Ho visto invisibile finestre mostrano in Alt + ↹Tab , e sto solo chiedendo qual è il modo migliore per garantire una finestra sarà non apparire (visibile o meno) nella Alt + ↹Tab finestra di dialogo.

Aggiornamento: Si prega di consultare la mia soluzione postato qui sotto. Non mi è permesso di segnare le mie risposte come la soluzione, ma finora è l'unico che funziona.

Aggiornamento 2: C'è ora una soluzione adeguata per Franci Penov che sembra piuttosto buono, ma non hanno provato io stesso. Comporta qualche Win32, ma evita la creazione zoppo delle finestre off-schermo.

È stato utile?

Soluzione

Aggiornamento:

Secondo @donovan, tempi moderni WPF supporta in modo nativo, attraverso l'impostazione ShowInTaskbar="False" e Visibility="Hidden" in XAML. (Non ho ancora testato questo, ma comunque deciso di sbattere il commento visibilità)

risposta originale:

Ci sono due modi di nascondere una finestra dalla task switcher in Win32 API:

  1. per aggiungere il WS_EX_TOOLWINDOW finestra stile esteso - che è il giusto approccio
  2. .
  3. per renderlo una finestra figlio di un'altra finestra.

Purtroppo, WPF non supporta il controllo flessibile sopra lo stile della finestra come Win32, quindi una finestra con WindowStyle=ToolWindow finisce con il default WS_CAPTION e WS_SYSMENU stili, che fa sì che per avere una didascalia e una stretta pulsante. D'altra parte, è possibile rimuovere questi due stili impostando WindowStyle=None, tuttavia, che non imposterà il ShowInTaskbar=False stile esteso e la finestra non verrà nascosto dalla task switcher.

Per avere una finestra WPF con SetWindowLongPtr che è anche nascosto dalla task switcher, si può uno dei due modi:

  • andare con il codice di esempio sopra e rendere la finestra di una finestra secondaria di una piccola finestra strumento nascosto
  • modificare lo stile di finestra per includere anche la SetWindowLong stile esteso.

Io personalmente preferisco il secondo approccio. Poi di nuovo, faccio alcune cose avanzate come estendere il vetro nell'area client e consentendo WPF disegno nella didascalia comunque, quindi un po 'di interoperabilità non è un grosso problema.

Ecco il codice di esempio per l'approccio soluzione di interoperabilità Win32. In primo luogo, la parte 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" >

Niente di stratosferico qui, dobbiamo solo dichiarare una finestra con <=> e <=>. Aggiungiamo anche un gestore per l'evento Loaded dove modificheremo la finestra stile esteso. Non possiamo fare che il lavoro nel costruttore, in quanto non c'è maniglia della finestra, a quel punto ancora. Il gestore di eventi in sé è molto semplice:

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

E le dichiarazioni di interoperabilità Win32. Ho rimosso tutti gli stili non necessari dal enumerazioni, solo per mantenere il codice di esempio qui di piccole dimensioni. Inoltre, purtroppo il <=> punto di ingresso non si trova in user32.dll su Windows XP, da qui il trucco con instradamento della chiamata attraverso il <=> invece.

    #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

Altri suggerimenti

All'interno della vostra classe form, aggiungere questo:

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

E 'facile come questo; funziona un fascino!

Ho trovato una soluzione, ma non è abbastanza. Finora questo è il solo cosa che ho provato che funziona davvero:

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

qui .

Una più generale, la soluzione riutilizzabile sarebbe bello. Suppongo che si possa creare una singola finestra 'w' e riutilizzarlo per tutte le finestre della tua app che hanno bisogno di essere nascosto dalla Alt + ↹Tab .

Aggiornamento: Ok, quindi quello che ho fatto è stato spostare il codice di cui sopra, meno il this.Owner = w bit (e in movimento w.Hide() subito dopo w.Show(), che funziona bene) nel costruttore della mia domanda, Creazione di una public static Window chiamato OwnerWindow. Ogni volta che voglio una finestra per esporre questo comportamento, ho semplicemente messo this.Owner = App.OwnerWindow. Funziona alla grande, e coinvolge solo la creazione di un extra (e invisibili) finestra. È anche possibile impostare this.Owner = null se si desidera che la finestra per riapparire nel Alt + ↹Tab finestra di dialogo.

Grazie a Ivan Onuchin corso sui forum MSDN per la soluzione.

Aggiornamento 2:. È inoltre necessario impostare ShowInTaskBar=false su w per evitare che a lampeggiare brevemente nella barra delle applicazioni quando mostrato

Perché così complessa? Prova questo:

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

Idea presa da qui: http://www.csharp411.com/hide -Form-da-AltTab /

Ecco cosa fa il trucco, indipendentemente dallo stile della finestra vostro stanno cercando di nascondere da Alt + ↹Tab .

Inserire il seguente nel costruttore del modulo:

// Keep this program out of the Alt-Tab menu

ShowInTaskbar = false;

Form form1 = new Form ( );

form1.FormBorderStyle = FormBorderStyle.FixedToolWindow;
form1.ShowInTaskbar = false;

Owner = form1;

In sostanza, si effettua la forma di un bambino di una finestra invisibile, che ha lo stile corretto e ShowInTaskbar impostazione per tenere fuori dalla lista Alt-Tab. È inoltre necessario impostare la proprietà ShowInTaskbar del proprio modulo su false. Meglio di tutti, semplicemente non importa quale stile il modulo principale ha, e tutto tweaking per realizzare il nascondiglio si trova a pochi righe nel codice del costruttore.

Perché cercando così tanto i codici? Basta impostare il FormBorderStyle proprietà FixedToolWindow. Speranza che aiuta.

vedere: (da 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);

In XAML impostato 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>

Modifica:. Che ancora lo mostra in Alt + Tab credo, non solo nella barra delle applicazioni

Ho provato a fissare la visibilità del modulo principale per falsa ogni volta che viene modificata automaticamente su true:

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

Funziona perfettamente:)

Non mostrare un modulo. Utilizzare invisibilità.

Maggiori informazioni qui: http://code.msdn.microsoft.com/TheNotifyIconExample

Proprietà Form1:
FormBorderStyle:
Sizable WindowState: minimizzato
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;
}>

se si desidera che il modulo per essere senza confini, allora avete bisogno di aggiungere le seguenti istruzioni al costruttore del form:

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

E è necessario aggiungere il seguente metodo alla classe forma derivata:

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

maggiori dettagli

Personalmente, per quanto so che questo non è possibile senza aggancio nelle finestre in qualche modo, non sono nemmeno sicuro di come che sarebbe stato fatto o se è possibile.

A seconda delle esigenze, sviluppare il vostro contesto di applicazione come un NotifyIcon (system tray) applicazione gli permetterà di essere in esecuzione senza mostrare in ALT + TAB. Tuttavia, se si apre un modulo, che forma sarà ancora seguire la funzionalità standard.

posso scavare il mio articolo di blog sulla creazione di un'applicazione che è solo una NotifyIcon per impostazione predefinita se si desidera.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top