[解決済み] Alt-Tabのプログラムスイッチャーからウィンドウを隠す最良の方法?
質問
私は数年前から.NETの開発者ですが、これはいまだに正しい方法を知らないことの一つです。Windows Forms と WPF の両方で、プロパティを通じてタスクバーからウィンドウを隠すことは簡単ですが、私が知る限り、これは、ウィンドウが Alt + ↹タブ のダイアログを表示します。見たところ 不可視 で表示されるウィンドウを Alt + ↹タブ を保証する最善の方法は何でしょうか? 決して に表示されないことを保証する最善の方法は何でしょうか? Alt + ↹タブ ダイアログを表示します。
更新しました。 以下に私の投稿した解決策をご覧ください。私は自分自身の答えを解決策としてマークすることを許可されていませんが、今のところ、それは動作する唯一のものです。
更新2です。 Franci Penovによる適切なソリューションがあり、それはかなり良さそうですが、自分では試していません。いくつかの Win32 を含みますが、オフスクリーン ウィンドウのお粗末な作成は回避できます。
どのように解決するのですか?
更新しました。
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 interop 宣言。ここのサンプルコードを小さくするために、列挙型から不要なスタイルをすべて削除しています。また、残念ながら
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
関連
-
[解決済み】XAMLにSystem.Stringを埋め込む
-
[解決済み] msiexec を使用せずにコマンドラインから MSI ファイルをアンインストールする
-
[解決済み] WCF エラーの解決。このサービスのメタデータパブリッシングは現在無効になっています。
-
[解決済み] C++/CLIにおけるキャレット('^')の意味は?
-
[解決済み] EF Coreのadd-migrationのビルドに失敗しました。
-
[解決済み] ファイルまたはアセンブリ 'System.Data.SQLite' をロードできませんでした。
-
[解決済み] Microsoft.NETFrameworkとMicrosoft.NETFramework64の違いは何ですか?
-
[解決済み] LINQ: フィルタリング基準で SingleOrDefault と FirstOrDefault() を使用する場合
-
[解決済み] CryptographicException「キーセットが存在しない」、ただしWCF経由に限る
-
[解決済み】WPFとイニシャルフォーカス
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] CLSID {XXXX} を持つコンポーネントの COM クラスファクトリの取得は、次のエラーにより失敗しました: 80040154。
-
[解決済み] msiexec を使用せずにコマンドラインから MSI ファイルをアンインストールする
-
[解決済み] Marginのプロパティ順
-
[解決済み] ネットワークの位置からアセンブリをロードすることはできません
-
[解決済み] 実際のサービスはデータを返すのに、なぜWebServiceはnullを返すのですか?
-
[解決済み] .NETにおけるstructとclassの違いは何ですか?
-
[解決済み] MemoryStreamから文字列を取得する方法は?
-
[解決済み] Visual Studioの「Any CPU」ターゲットはどういう意味ですか?
-
[解決済み] プライベートメソッドのユニットテストはどのように行うのですか?
-
[解決済み】マジックナンバーとは何ですか、なぜ悪いのですか?[クローズド]