更新:
@donovanによると、現代のWPFは設定ShowInTaskbar="False"
とVisibility="Hidden"
XAMLでこれをネイティブにサポートしています
。(私はまだこれをテストしていませんが、それでもコメントの可視性を上げることにしました)
元の答え:
Win32 APIのタスクスイッチャーからウィンドウを非表示にする方法は2つあります。
WS_EX_TOOLWINDOW
拡張ウィンドウスタイルを追加する-それは正しいアプローチです。
- 別のウィンドウの子ウィンドウにする。
残念ながら、WPFはウィンドウスタイルの柔軟な制御をWin32ほどサポートしていないため、ウィンドウWindowStyle=ToolWindow
のデフォルトWS_CAPTION
とWS_SYSMENU
スタイルが表示され、キャプションと閉じるボタンが表示されます。一方、これらの2つのスタイルはを設定することで削除できますがWindowStyle=None
、WS_EX_TOOLWINDOW
拡張スタイルは設定されず、ウィンドウはタスクスイッチャーから非表示になりません。
これを含むWPFウィンドウWindowStyle=None
もタスクスイッチャーから非表示にするには、次の2つの方法のいずれかを実行できます。
- 上記のサンプルコードを使用して、ウィンドウを小さな非表示のツールウィンドウの子ウィンドウにします。
- ウィンドウスタイルを変更して、
WS_EX_TOOLWINDOW
拡張スタイルも含める。
私は個人的に2番目のアプローチを好みます。次に、クライアント領域でグラスを拡張したり、キャプションでWPF描画を有効にしたりするなど、いくつかの高度な処理を実行します。したがって、相互運用の少しは大きな問題ではありません。
以下は、Win32相互運用ソリューションアプローチのサンプルコードです。まず、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" >
ここでは空想的なことは何もありません。WindowStyle=None
そして、とでウィンドウを宣言するだけShowInTaskbar=False
です。また、Loadedイベントにハンドラーを追加して、拡張ウィンドウスタイルを変更します。その時点ではウィンドウハンドルがまだないため、コンストラクターでそれを行うことはできません。イベントハンドラ自体は非常に単純です。
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);
}
そして、Win32相互運用宣言。ここではサンプルコードを小さく保つために、列挙型からすべての不要なスタイルを削除しました。また、残念ながら、SetWindowLongPtr
エントリポイントはWindows XPのuser32.dllにはありません。そのため、SetWindowLong
代わりにコールをルーティングするトリックが必要です。
#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