12

アプリケーションのタスクバーから別のアプリケーションを非表示にするのに苦労しています。拡張スタイルを設定/削除するためにSetWindowLong関数
を使用しています。WS_EX_APPWINDOW

プロパティを個別に設定および削除するだけでなく、現在のを取得して、そのプロパティWindowLongに削除/追加することも、次のように試しました。

SetWindowLong(pMainWindow, GWL_EXSTYLE, GetWindowLong(pMainWindow) & WS_EX_APPWINDOW);

そして、そのようにそれを削除してみました:

SetWindowLong(pMainWindow, GWL_EXSTYLE, GetWindowLong(pMainWindow) & ~WS_EX_APPWINDOW);

また、最初にウィンドウを長くすることなく、これらの両方の方法を試しました。これが私のコード全体です:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    [DllImport("User32.dll")]
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    [DllImport("User32.dll")]
    public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    private const int SW_HIDE = 0x00;
    private const int SW_SHOW = 0x05;

    private const int WS_EX_APPWINDOW = 0x40000;
    private const int GWL_EXSTYLE = -0x14;

    private void HideWindowFromTaskbar(IntPtr pMainWindow)
    {
        SetWindowLong(pMainWindow, GWL_EXSTYLE, ~WS_EX_APPWINDOW);

        ShowWindow(pMainWindow, SW_HIDE);
        ShowWindow(pMainWindow, SW_SHOW);
    }

    private void ButtonHide_Click(object sender, RoutedEventArgs e)
    {
        HideWindowFromTaskbar(Process.GetProcessesByName("notepad")[0].MainWindowHandle);
    }
}

プロパティを見ると、Spy++の変更に気づきました。追加されるなど、さまざまな結果が得WS_EX_APPWINDOWられましたが、他の属性がランダムに消えるなどもありました。
メッセージを見ると、のようなメッセージがDIDで取得されていることもわかりましたSTYLE_CHANGED

4

4 に答える 4

4

タスク バーにボタンがあるウィンドウを決定するためのルールは、MSDNに記載されています。Raymond Chen は、これらのルールの概要を次のように示しています。

どのウィンドウがタスクバーに表示されるかについて、いくつかの基本的なルールがあります。要するに:

  • WS_EX_APPWINDOW 拡張スタイルが設定されている場合は、表示されます (表示されている場合)。
  • ウィンドウが最上位の所有されていないウィンドウである場合は、表示されます (表示されている場合)。
  • それ以外の場合は表示されません。

別のアプリでウィンドウを変更しようとしているという事実は、あなたをひどく妨げています. WS_EX_APPWINDOW拡張スタイルを削除しています。問題のウィンドウはトップレベルの所有されていないウィンドウになるため、これでは十分ではありません (箇条書き 2 を参照)。ウィンドウが作成されると、ウィンドウの所有者を変更することはできません。また、ウィンドウが別のプロセスによって制御されているため、ほとんどスタックしています。

残っている唯一のオプションは、WS_EX_APPWINDOW拡張スタイルを削除して に置き換えることWS_EX_TOOLWINDOWです。これにより、実際にウィンドウがタスクバーから外れますが、ウィンドウの外観が変わります。

このウィンドウは、フローティング ツールバーとして使用するためのものです。ツール ウィンドウには、通常のタイトル バーよりも短いタイトル バーがあり、ウィンドウ タイトルは小さいフォントを使用して描画されます。ツール ウィンドウは、タスクバーまたはユーザーが Alt + Tab キーを押したときに表示されるダイアログに表示されません。ツール ウィンドウにシステム メニューがある場合、そのアイコンはタイトル バーに表示されません。ただし、右クリックするか、ALT + SPACE を入力すると、システム メニューを表示できます。

于 2011-11-23T15:21:31.627 に答える
3

これが私がこれを行う方法です。

1. Create a window (hwndOwner) with WS_POPUP style and WS_EX_TOOLWINDOW
2. Call SetWindowLong(hwnd, GWL_HWNDPARENT, hwndOwner)
3. Call SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) |     ~WS_EX_APPWINDOW)

これにより、タスクバーと代替タブからターゲットウィンドウが削除されます。これは、少なくともWS2000以降のすべてのOSで機能します。

さて、David Heffernanは、これはできないと言っているMSDNドキュメントを指摘しました。まあ、なぜそれがそれを言うのか分かりませんが、それは不正確です。これを実行して、.NET Frameworkに影響を与えることができます。.NETReflectorを使用してSystem.Windows.Forms.Form.Ownerプロパティのコードを調べるだけです。SetWindowLongを使用して、必要に応じて所有権を譲渡します。

また、誤ったMSDNドキュメントの証拠については、Ownerプロパティのドキュメントを参照してください。「トップレベルウィンドウに所有者を含めることはできません」と表示されます。これとは正反対である必要があります。所有者を持つことができるのはトップレベルのウィンドウだけです。

于 2012-02-22T23:14:34.613 に答える
2
private const int SW_HIDE = 0x00;
private const int SW_SHOW = 0x05;
private const int WS_EX_APPWINDOW = 0x40000;
private const int GWL_EXSTYLE = -0x14;
private const int WS_EX_TOOLWINDOW = 0x0080;

  private static void HideAppinTaskBar()
  {
  var Handle = FindWindowByCaption(IntPtr.Zero, "Untitled - Notepad");
  ShowWindow(Handle, SW_HIDE);
  SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) |     WS_EX_TOOLWINDOW);
  ShowWindow(Handle, SW_SHOW);
  }

これは私にとってはうまくいきます-メモ帳でテストしました。WinXp 32 ビット マシン。

于 2011-11-23T14:32:59.190 に答える
0

これは、.NET 6.0のPInvoke.User32 nuget パッケージを使用してWinUI3で機能します。

アレックスの答えから適応。

private void HideAppFromTaskBar(MainWindow window)
{
    //Get the Window's HWND
    var windowNative = window.As<IWindowNative>();
    var windowHandle = windowNative.WindowHandle;

    User32.ShowWindow(windowHandle, User32.WindowShowStyle.SW_HIDE);
    var flags = (User32.SetWindowLongFlags)User32.GetWindowLong(windowHandle, User32.WindowLongIndexFlags.GWL_EXSTYLE);
    User32.SetWindowLong(windowHandle, User32.WindowLongIndexFlags.GWL_EXSTYLE, flags | User32.SetWindowLongFlags.WS_EX_TOOLWINDOW);
    User32.ShowWindow(windowHandle, User32.WindowShowStyle.SW_SHOW);
}
于 2021-12-19T23:48:54.000 に答える