Alt-Tabプログラムスイッチャーからウィンドウを非表示にする最良の方法は?


101

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

更新:以下の投稿された解決策を参照してください。私は自分の答えを解決策としてマークすることは許可されていませんが、これまでのところ、これが機能する唯一のものです。

更新2:かなり見栄えが良いが、自分で試したことがない、Franci Penovによる適切な解決策があります。一部のWin32を含みますが、画面外のウィンドウの不完全な作成を回避します。


13
システムトレイアプリはその良い例です
TravisO

3
フルスクリーンの半透明の黒いウィンドウを使用して、アプリがUACダイアログのようなモーダルインターフェイスを表示しているときに「減光」効果を提供するので、それを行う理由があります。これはインタラクティブなウィンドウではないので、Alt-Tabダイアログに表示しても意味がありません。
devios1 2008

8
アプリが独自のモーダルダイアログを表示する場合は、デスクトップ全体を淡色表示しないことをお勧めします。デスクトップを暗くすると、OSレベルの操作が提案されます。ほとんどの人は、それが安全なデスクトップではないことを理解できるほど高度な知識を持っていなかったでしょう。
Franci Penov、2009

3
「プロパティを使用してタスクバーからウィンドウを非表示にするのは簡単です」。このプロパティはShowInTaskbarです(レコードのみ)。
greenoldman 2010

問題は、タスクバーからではなく、Alt-Tabからウィンドウを隠すことです。
Alexandru Dicu

回答:


93

更新:

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

元の答え:

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

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

残念ながら、WPFはウィンドウスタイルの柔軟な制御をWin32ほどサポートしていないため、ウィンドウWindowStyle=ToolWindowのデフォルトWS_CAPTIONWS_SYSMENUスタイルが表示され、キャプションと閉じるボタンが表示されます。一方、これらの2つのスタイルはを設定することで削除できますがWindowStyle=NoneWS_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

2
これを確認していませんが、何を話しているのかわかっているようです。:)もう一度やり直す必要がある場合は、このことを覚えておきますが、他の解決策はうまく機能しているため(そして、この本を閉じてからしばらく経っています)、いじったり何かを壊したりしたくありません。ありがとう!
devios1 2009

1
完璧に動作します!ありがとう!
Anthony Brien、2010

私にとってはうまくいきます。しかし、私はこのようにdllをインポートする必要がありません:P
J4N

8
@ J4N-P / Invokeのビットに時々問題はありません:-)
Franci Penov

1
これはWPFでは機能しませんでした。しかし、遊んでみたところ、XAMLでShowInTaskbar = "False"とVisibility = "Hidden"を設定する方がはるかに簡単な解決策であることがわかりました。特別なピンボークは必要ありません。
ドノバン、2015

40

フォームクラス内に次を追加します。

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

        return Params;
    }
}

それはそれと同じくらい簡単です。魅力的です!


3
これが機能するためには、ShowInTaskbarをfalseに設定する必要もあります。
Nick Spreitzer 2013

20

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

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

更新: [OK]を私がやったことは上記のコードを移動し、マイナスだったのでthis.Owner = w(と移動ビットw.Hide()た直後w.Show()のpublic static作成し、自分のアプリケーションのコンストラクタに罰金を働く、)Windowと呼ばれるがOwnerWindow。ウィンドウがこの動作を示すようにしたいときはいつでも、単にを設定しthis.Owner = App.OwnerWindowます。うまく機能し、1つの追加(および非表示)ウィンドウを作成するだけです。+ ダイアログにthis.Owner = nullウィンドウを再表示するかどうかを設定することもできます。Alt↹Tab

ソリューションのMSDNフォーラムでIvan Onuchinに感謝します。

アップデート2:あなたはまた、設定すべきShowInTaskBar=falsew示されたときにタスクバーに簡単に点滅するのを防止します。


その問題に対するWin32相互運用ソリューションもあります。
Franci Penov、2009

興味深いことに、私はこのアプローチを行っていますが、隠しウィンドウ(メインアプリウィンドウを所有者として使用)を避け、Alt-Tabに表示されません...
Dave

1
デュアルモニター構成では、2番目の画面も負の座標を持つ可能性があると思います。
トーマスウェラー14

@ThomasW。あなたはおそらく正しいです。のようなオフセットを使用する-100000ことはおそらくより良いでしょう。
devios1 14

これは本当にこの問題の悪いハックです。
Alexandru Dicu

10

なぜそんなに複雑なのですか?これを試して:

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

ここから抜粋したアイデア:http : //www.csharp411.com/hide-form-from-alttab/


私のために働く。貢献してくれてありがとう!
MiBol

ただし、ToolWindowを最大化または最小化することはできません。ToolWindowが常に望ましいオプションであるとは限りません。
Alexandru Dicu

10

これは、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;

基本的に、Alt-Tabリストに含まれないように、正しいスタイルとShowInTaskbar設定を持つフォームを非表示ウィンドウの子にします。また、独自のフォームのShowInTaskbarプロパティをfalseに設定する必要があります。何よりも、メインフォームのスタイルは問題ではなく、非表示にするための微調整は、コンストラクターコードのほんの数行です。


待って...これはC#、C、C ++のどれですか??? 私は本当にCファミリーの
n00b

3

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


2

ご覧ください:(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);

「ハンドル」はvar handle = new WindowInteropHelper(this).Handle;によって取得できることをここに追加します。
Alexandru Dicu

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に表示されます。


ええ、それが問題です。ShowInTaskbarは、予想どおりAlt + Tabダイアログに影響しません。
devios1 2008

1

メインフォームが自動的にtrueに変更されるたびに、メインフォームの可視性をfalseに設定してみました。

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

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


2
最も簡単な解決策であるだけでなく、私にとっても非常にうまく機能しました。
Daniel McQuiston、2012年

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;
    }
}

詳細



0

Form1プロパティ:
FormBorderStyle:Sizable
WindowState:最小化された
ShowInTaskbar:False

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;
}>

-1

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

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

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



おかげで、私はすでにNotifyIconsに精通しています。問題は、開いている(非インタラクティブ、または最上位の)ウィンドウをAlt + Tabから非表示にすることです。興味深いことに、VistaサイドバーがAlt + Tabに表示されないことに気付いたので、それを行うにはいくつかの方法があるはずです。
devios1 2008

(赤ひげが投稿されたように)ウィンドウのタイプを変更せずにさまざまな部分を見て、これを行う方法がわかりません。
ミッチェルセラーズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.