105

私は数年前から .NET 開発者をしていますが、これはまだ適切に行う方法がわからないことの 1 つです。Windows フォームと WPF の両方で、プロパティを介してタスク バーからウィンドウを非表示にするのは簡単ですが、私が知る限り、これはAlt+↹Tabダイアログから非表示になることを保証するものではありません (必ずしも影響を与えることさえありません)。+に非表示のウィンドウが表示されるを見たことがありますが、 +ダイアログに (表示されているかどうかに関係なく)ウィンドウが表示されないことを保証する最善の方法は何か疑問に思っています。Alt↹TabAlt↹Tab

更新:以下の投稿されたソリューションを参照してください。私自身の回答を解決策としてマークすることは許可されていませんが、これまでのところ、機能するのはこれだけです。

更新 2: Franci Penov による適切な解決策があり、かなり良さそうですが、自分で試したことはありません。いくつかの Win32 を含みますが、画面外のウィンドウの不自由な作成を回避します。

4

14 に答える 14

103

アップデート:

@donovan によると、現代の WPF は、設定 ShowInTaskbar="False"Visibility="Hidden"XAML でこれをネイティブにサポートしています。(私はまだこれをテストしていませんが、それでもコメントの可視性を上げることにしました)

元の答え:

Win32 API でタスク スイッチャーからウィンドウを非表示にする方法は 2 つあります。

  1. 拡張ウィンドウ スタイルを追加するには、WS_EX_TOOLWINDOWこれが正しいアプローチです。
  2. 別のウィンドウの子ウィンドウにします。

WindowStyle=ToolWindow残念ながら、 WPFは Win32 ほど柔軟なウィンドウ スタイルの制御をサポートしていませWS_CAPTIONWS_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=Noneandで宣言するだけ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 相互運用宣言。サンプル コードを小さく保つために、列挙型から不要なスタイルをすべて削除しました。また、残念ながら、SetWindowLongPtrWindows 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
于 2009-02-15T23:36:23.280 に答える
21

私は解決策を見つけましたが、それはきれいではありません。これまでのところ、実際に機能するのはこれだけです。

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

ここで見つけました。

より一般的で再利用可能なソリューションがあればいいのですが。単一のウィンドウ「w」を作成して、Alt+から非表示にする必要があるアプリ内のすべてのウィンドウに再利用できると思います↹Tab

更新:this.Owner = wわかりました。上記のコードからビットを差し引いたものをアプリケーションのコンストラクターに移動し(そしてw.Hide()直後に移動します。これは正常に機能します)、。というw.Show()パブリックスタティックを作成しました。ウィンドウにこの動作を表示させたいときはいつでも、を設定するだけです。うまく機能し、1つの余分な(そして見えない)ウィンドウを作成するだけです。+ダイアログにウィンドウを再表示するかどうかを設定することもできます。WindowOwnerWindowthis.Owner = App.OwnerWindowthis.Owner = nullAlt↹Tab

ソリューションを提供してくれたMSDNフォーラムのIvanOnuchinに感謝します。

更新2:表示されたときにタスクバーで短時間点滅しないように設定ShowInTaskBar=falseする必要もあります。w

于 2008-12-10T21:00:35.213 に答える
14

Alt+から非表示にしようとしているウィンドウのスタイルに関係なく、トリックは次のとおり↹Tabです。

フォームのコンストラクターに次を配置します。

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

ShowInTaskbar = false;

Form form1 = new Form ( );

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

Owner = form1;

基本的に、フォームを非表示ウィンドウの子にします。このウィンドウには、適切なスタイルと ShowInTaskbar 設定があり、Alt-Tab リストから除外されます。また、独自のフォームの ShowInTaskbar プロパティを false に設定する必要があります。何よりも、メイン フォームのスタイルは問題ではなく、非表示を実現するためのすべての調整は、コンストラクター コードの数行だけです。

于 2010-04-30T03:33:46.087 に答える
12

Why so complex? Try this:

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

Idea taken from here:http://www.csharp411.com/hide-form-from-alttab/

于 2010-04-23T11:35:27.963 に答える
3

なぜそんなに多くのコードを試すのですか? FormBorderStyleプロパティを に設定するだけFixedToolWindowです。それが役に立てば幸い。

于 2012-02-22T11:21:53.150 に答える
3

それを参照してください:( 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);
于 2010-05-11T13:09:37.537 に答える
2

メインフォームの可視性が自動的にtrueに変更されるたびにfalseに設定しようとしました:

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

それは完璧に動作します:)

于 2011-01-02T16:27:19.400 に答える
1

フォームをフチなしにしたい場合は、フォームのコンストラクターに次のステートメントを追加する必要があります。

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

また、派生したFormクラスに次のメソッドを追加する必要があります。

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

詳細

于 2012-09-27T18:50:13.920 に答える
1

XAML で 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>

編集:タスクバーではなく、Alt + Tabにまだ表示されていると思います。

于 2008-12-10T19:25:01.270 に答える
0

フォームを表示しないでください。不可視を使用します。

詳細はこちら: http://code.msdn.microsoft.com/TheNotifyIconExample

于 2008-12-29T16:32:36.940 に答える
-1

個人的には、何らかの方法でウィンドウにフックしないとこれは不可能であると知っている限り、それがどのように行われるのか、または可能かどうかさえわかりません。

必要に応じて、アプリケーション コンテキストを NotifyIcon (システム トレイ) アプリケーションとして開発すると、ALT + TAB に表示されずに実行できるようになります。ただし、フォームを開くと、そのフォームは引き続き標準の機能に従います。

必要に応じて、デフォルトで NotifyIcon のみであるアプリケーションの作成に関するブログ記事を掘り下げることができます。

于 2008-12-10T19:02:58.570 に答える