Il y a deux façons de cacher une fenêtre de la task switcher en API Win32:
- ajouter l'
WS_EX_TOOLWINDOW
étendue de style de fenêtre - c'est la bonne approche.
- 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