La mejor forma de ocultar una ventana a partir de la combinación de teclas Alt-Tab programa de conmutador?

StackOverflow https://stackoverflow.com/questions/357076

  •  21-08-2019
  •  | 
  •  

Pregunta

He sido .NET developer para varios años y esta sigue siendo una de esas cosas que no sé cómo hacerlo correctamente.Es fácil ocultar una ventana de la barra de tareas a través de una propiedad en tanto en Windows Forms y WPF, pero como lo que yo puedo decir, esto no garantiza (o necesariamente afectar incluso) que se oculta de la Alt+↹Ficha cuadro de diálogo.He visto invisible windows mostrará en Alt+↹Ficha, y me pregunto ¿cuál es la mejor manera de garantizar una ventana nunca aparecen (visible o no), en el Alt+↹Ficha cuadro de diálogo.

Actualización: Por favor vea mis publicado solución a continuación.No puedo marcar mis propias respuestas como la solución, pero hasta el momento es el único que funciona.

Actualización 2: Ahora hay una solución adecuada por Franci Penov que se ve muy bien, pero no lo he probado yo misma.Involucra a algunos de Win32, pero evita el cojo creación de apagado de pantalla de windows.

¿Fue útil?

Solución

Actualización:

De acuerdo con @donovan, de los tiempos modernos WPF admite esta forma nativa, a través de la creación ShowInTaskbar="False" y Visibility="Hidden" en el XAML.(Yo no he probado este, pero sin embargo decidió golpear el comentario de la visibilidad)

Original respuesta:

Hay dos maneras de ocultar una ventana desde el conmutador de tareas en la API de Win32:

  1. para agregar el WS_EX_TOOLWINDOW extendido estilo de ventana - que es el enfoque correcto.
  2. para hacer de él un niño de la ventana de una ventana a otra.

Por desgracia, WPF no compatibles con el control más flexible sobre la ventana de estilo como Win32, por lo que una ventana con WindowStyle=ToolWindow termina con el valor de WS_CAPTION y WS_SYSMENU estilos, lo que hace que tengan un título y un botón de cierre.Por otro lado, puede quitar estos dos estilos mediante el establecimiento de WindowStyle=None, sin embargo , no se establece la WS_EX_TOOLWINDOW estilo extendido y la ventana no se oculta desde el conmutador de tareas.

Tener una ventana WPF con WindowStyle=None que también se oculta desde el conmutador de tareas, se puede de dos formas:

  • vaya con el código de ejemplo anterior y hacer que la ventana de un niño de la ventana de una pequeña herramienta oculta de la ventana
  • modificar el estilo de ventana para incluir también a la WS_EX_TOOLWINDOW estilo extendido.

Yo personalmente prefiero el segundo enfoque.A continuación, de nuevo, hago un poco de material avanzado como la extensión de la de vidrio en el área de cliente y la habilitación de WPF dibujo en el título de todos modos, así que un poco de interoperabilidad no es un gran problema.

Aquí está el código de ejemplo para el Win32 interoperabilidad enfoque de solución.En primer lugar, el código XAML parte:

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

Nada demasiado elegante, aquí, acabamos de declarar una ventana con WindowStyle=None y ShowInTaskbar=False.También vamos a añadir un manejador para el evento Loaded, donde vamos a modificar la ventana extendida estilo.No podemos hacer que el trabajo en el constructor, ya que no hay identificador de ventana en ese punto todavía.El controlador de eventos en sí es muy 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);
    }

Y el Win32 interoperabilidad de las declaraciones.He quitado todos los estilos de las enumeraciones, sólo para mantener el código de ejemplo aquí pequeña.También, por desgracia, el SetWindowLongPtr punto de entrada no se encuentra en user32.dll en Windows XP, por lo tanto el truco con el enrutamiento de la llamada a través de la SetWindowLong en su lugar.

    #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

Otros consejos

Dentro de su clase de formulario, añadir lo siguiente:

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

Es tan fácil como eso; que funciona a las mil maravillas!

He encontrado una solución, pero no es bastante. Hasta ahora, este es el solamente cosa que he intentado que realmente funciona:

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

Encontrados que aquí .

Una solución más general, reutilizable sería bueno. Supongo que se podría crear una sola ventana 'w' y reutilizarla para todas las ventanas de su aplicación que necesitan ser escondido de la Alt + ↹Tab .

Actualización: Ok, así que lo que hice fue mover el código anterior, menos el this.Owner = w bits (y en movimiento w.Hide() inmediatamente después w.Show(), que funciona muy bien) en el constructor de mi solicitud, la creación de un public static Window llamados OwnerWindow. Siempre que quiero una ventana para exhibir este comportamiento, simplemente me puse this.Owner = App.OwnerWindow. Funciona muy bien, y sólo implica la creación de una ventana adicional (e invisible). Incluso puede configurar this.Owner = null si desea que la ventana vuelva a aparecer en el Alt + ↹Tab diálogo.

Gracias a Ivan Onuchin más en los foros de MSDN para la solución.

Actualización 2:. También debe establecer ShowInTaskBar=false en w para evitar que parpadear brevemente en la barra de tareas cuando se muestra

¿Por qué tan compleja? Prueba esto:

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

Idea tomada de aquí: http://www.csharp411.com/hide -forma-from-AltTab /

Esto es lo que hace el truco, sin importar el estilo de la ventana de su están tratando de esconderse de Alt + ↹Tab .

Coloque el siguiente en el constructor de la forma:

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

ShowInTaskbar = false;

Form form1 = new Form ( );

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

Owner = form1;

En esencia, usted hace su forma a un niño de una ventana invisible que tiene el estilo correcto y ShowInTaskbar configurar para mantener fuera de la lista de Alt-Tab. También debe establecer la propiedad ShowInTaskbar de su propia forma de falsa. Lo mejor de todo, simplemente no importa qué estilo tiene su forma principal, y todas ajustes para lograr la ocultación está a sólo unas pocas líneas en el código constructor.

¿Por qué tratar tanto los códigos? Sólo hay que establecer la propiedad a FormBorderStyle FixedToolWindow. Espero que ayuda.

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

En XAML conjunto 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>

Editar:. Eso todavía lo muestra en el Alt + Tab supongo, pero no en la barra de tareas

He intentado establecer la visibilidad de la principal forma de falsa cada vez que se cambia automáticamente en true:

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

Funciona perfectamente:)

No mostrar una forma. Utilice la invisibilidad.

Más aquí: http://code.msdn.microsoft.com/TheNotifyIconExample

Propiedades de Form1:
FormBorderStyle: Considerables
WindowState: minimizado
ShowInTaskbar: Falso

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 desea que la forma de ser sin fronteras, entonces es necesario agregar las siguientes declaraciones al constructor de la forma:

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

Y debe agregar el siguiente método a la clase de forma derivada:

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

más detalles

En lo personal por lo que yo se que esto no es posible sin enganchar en las ventanas de alguna manera, ni siquiera estoy seguro de cómo se llevaría a cabo o si es posible.

En función de sus necesidades, el desarrollo de su contexto de aplicación como una aplicación NotifyIcon (bandeja del sistema) le permitirá estar en ejecución sin mostrar en ALT + TAB. Sin embargo, si se abre un formulario, que forma seguirá mostrando la funcionalidad estándar.

puedo desenterrar mi artículo blog sobre la creación de una aplicación que es sólo una NotifyIcon por defecto si se desea.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top