C # Скрытие приложения от панели задач - PullRequest
12 голосов
/ 23 ноября 2011

Я изо всех сил пытался скрыть другое приложение из панели задач от моего приложения.
Я использовал функцию 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, но случайно исчезали другие атрибуты и т. Д.
Просматривая сообщения, я также увидел, что он получал сообщения типа STYLE_CHANGED.

Любая помощь будет оценена,
Рене

Ответы [ 4 ]

4 голосов
/ 23 ноября 2011

Правила определения того, какие окна имеют кнопки на панели задач, описаны в MSDN .Рэймонд Чен дает следующие сводные данные этих правил:

Есть несколько основных правил, по которым окна переходят на панель задач.Вкратце:

  • Если установлен расширенный стиль WS_EX_APPWINDOW, то он будет отображаться (когда он виден).
  • Если окно является неиспользуемым окном верхнего уровня, то оно будет(когда он виден).
  • В противном случае он не отображается.

Тот факт, что вы пытаетесь изменить окно в другом приложении, сильно мешает вам.Вы удаляете расширенный стиль WS_EX_APPWINDOW.Этого недостаточно, потому что рассматриваемое окно будет неизвестным окном верхнего уровня (см. Пункт 2).Вы не можете изменить владельца окна после того, как оно было создано, и так как окно управляется другим процессом, вы в значительной степени застряли.

Единственный оставшийся вариант - удалить расширенный стиль WS_EX_APPWINDOW и заменить его.с WS_EX_TOOLWINDOW.Это действительно уберет окно с панели задач, но изменит внешний вид окна :

Окно предназначено для использования в качестве плавающей панели инструментов.Окно инструмента имеет строку заголовка, которая короче обычной строки заголовка, а заголовок окна рисуется с использованием меньшего шрифта.Окно инструментов не появляется на панели задач или в диалоговом окне, которое появляется, когда пользователь нажимает ALT + TAB.Если окно инструмента имеет системное меню, его значок не отображается в строке заголовка.Однако вы можете отобразить системное меню, щелкнув правой кнопкой мыши или введя ALT + SPACE.

3 голосов
/ 23 февраля 2012

Вот как я это делаю.

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)

Это удалит целевое окно с панели задач и вкладки alt.Это будет работать на любой ОС, начиная с WS2000, по крайней мере.

Теперь Дэвид Хеффернан указал на документацию MSDN, в которой говорится, что вы не можете этого сделать.Ну, я не знаю, почему это говорит, но это неточно.Вы можете сделать это и INFACT .NET Framework делает это, просто используйте .NET Reflector для проверки кода для свойства System.Windows.Forms.Form.Owner - он использует SetWindowLong для передачи прав собственности, так часто, как вы этого хотите!

И для большего количества свидетельств о неправильной документации MSDN, посмотрите не более чем документы для свойства Owner , там написано: «Окно верхнего уровня не может иметь владельца».это должно быть полной противоположностью этому, ТОЛЬКО окна верхнего уровня могут иметь владельца!

2 голосов
/ 23 ноября 2011
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-битный компьютер.

1 голос
/ 23 ноября 2011

См. Принятый ответ на этот ответ StackOverflow для получения более подробной информации о том, что вы пытаетесь сделать. Обратите особое внимание на предостережения о безопасности и многопоточности.

...