Подтвердить что ты не робот

С# Скрытие приложения из панели задач

Я пытаюсь скрыть другое приложение из панели задач из своего приложения.
Я использовал функцию 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.

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

4b9b3361

Ответ 1

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

Существуют некоторые основные правила, по которым окна входят в панель задач. В Короче говоря:

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

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

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

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

Ответ 2

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

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, посмотрите не дальше, чем документы для свойства Владелец, в нем говорится: "Окно верхнего уровня не может иметь владельца". это должна быть полная противоположность этому, ТОЛЬКО окна верхнего уровня могут иметь владельца!

Ответ 3

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 бит.

Ответ 4

Для получения более подробной информации о том, что вы пытаетесь сделать, см. принятый ответ на fooobar.com/info/434768/.... Обратите внимание, в частности, на предостережения о безопасности и потоках.