Delphi как скрыть окно из панели задач

Блог GunSmoker-а

. when altering one’s mind becomes as easy as programming a computer, what does it mean to be human.

10 августа 2010 г.

Не будьте беспомощны: скрытие/показ кнопок окон в панели задач

Этот пост — добавление к моему посту 90% кода в интернете — говно.

На примере вопроса «Как скрыть окно из Панели задач» я покажу, как вы можете использовать свои голову и руки, чтобы успешно (и самостоятельно) решить эту проблему. Да это бредовый пост, но меня уже просто взбесило, что никто и не чешется что-то делать, когда им тыкаешь в подробное описание.

Когда начинающий задаёт такой вопрос на форуме, он обычно получает три вида ответов:

  • (60%) RTFM (aka «читать факи»).
  • (39%) Код. Причём в 90% случаев код взят по принципу «бери этот код, он у меня работает, я гарантирую это!».
  • (1%) Ссылку на MSDN или аналогичное описание.

Я не буду разбирать подход, основанный на чтении FAQ или задании вопроса на форумах, ибо, как мы узнали в предыдущий раз, такой подход ведёт к говно-коду (в частности — решений из 90-х). Положим, мы хотим самостоятельно найти решение какой-то простой проблемы, в данном случае — показ/скрытие кнопки на Панели задач. Как мы будем действовать?

Шаг 1 — найти официальную документацию

Для этого мы используем поисковик (я предпочитаю Google, чего и вам советую). Формулируем ключевые слова для своей проблемы. К примеру, в нашем случае это будет «taskbar buttons» (не знаете английский?) или что-то такое. Далее, вы делаете поиск документации. В некоторых случаях вы можете сузить область поиска, указав сайт, на котором лежит документация. Если вы ищете что-то о Delphi, то ограничивайте поиск сайтом docwiki.embarcadero.com, если по продуктам Microsoft — то msdn.microsoft.com, если ещё что-то — то используйте соответствующие поправки.

Все ссылки вида social.msdn.microsoft.com — это типа форумов. Отметаем сразу.

Итак, что мы получили? Ссылка 1 — это guideline-ы для Панели задач. Тоже весьма полезное чтиво, но сейчас интересует не это. Пропускаем.

Ссылка 2 — рассказ о Панели задач в рамках раздела «Расширение Панели задач». Во, похоже на то, что нам надо. Пробегая раздел глазами, встречаем подразделы «Managing Taskbar Buttons» и «Modifying the Contents of the Taskbar». Оно? Оно.

Читайте также:  Клавиатура мышь джойстик трекбол сенсорная панель

Шаг 2 — чтение и анализ документации

The Shell creates a button on the taskbar whenever an application creates a window that isn’t owned. To ensure that the window button is placed on the taskbar, create an unowned window with the WS_EX_APPWINDOW extended style. To prevent the window button from being placed on the taskbar, create the unowned window with the WS_EX_TOOLWINDOW extended style. As an alternative, you can create a hidden window and make this hidden window the owner of your visible window.

The Shell will remove a window’s button from the taskbar only if the window’s style supports visible taskbar buttons. If you want to dynamically change a window’s style to one that doesn’t support visible taskbar buttons, you must hide the window first (by calling ShowWindow with SW_HIDE), change the window style, and then show the window.

The window button typically contains the application icon and title. However, if the application does not contain a system menu, the window button is created without the icon.

If you want your application to get the user’s attention when the window is not active, use the FlashWindow function to let the user know that a message is waiting. This function flashes the window button. Once the user clicks the window button to activate the window, your application can display the message.

Modifying the Contents of the Taskbar

Version 4.71 and later of Shell32.dll adds the capability to modify the contents of the taskbar. From an application, you can now add, remove, and activate taskbar buttons. Activating the item does not activate the window; it shows the item as pressed on the taskbar.

The taskbar modification capabilities are implemented in a Component Object Model (COM) object (CLSID_TaskbarList) that exposes the ITaskbarList interface (IID_ITaskbarList). You must call the ITaskbarList::HrInit method to initialize the object. You can then use the methods of the ITaskbarList interface to modify the contents of the taskbar.

Шаг 3 — написание или поиск заголовочников

Окей, если вы взяли первый подход, то все заголовочники у нас уже есть — это модуль Windows. Если вы взяли второй подход, то. то вам нужно их ещё найти. В частности, нам нужно определение интерфейса ITaskbarList.

Читайте также:  Все обозначения приборной панели ваз 2114

Где искать заголовочники:

  1. В Delphi. Да, иногда бывает. Запускайте поиск «ITaskbarList» в «*.pas» файлах в папке Delphi.
  2. В JWAPI. Аналогично, но поиск по папке JWAPI.
  3. В интернете. Надо понимать, что качество этих заголовочников может быть. не очень.
  4. В Platform SDK. Окей, владельцам новых Delphi повезло — в их состав входят более-менее свежие заголовочники. В этом случае делаем поиск «ITaskbarList» в «*.h» файлах в папке Delphi. Всем остальным? Качать и ставить Platform SDK или MSDN.

Понятно, что в первых трёх случаях у вас на руках будут Delphi файлы. В последнем — только C-шные исходники. Поэтому.

Шаг 3а — конвертация заголовочников

В файле ShObjIdl.h вы найдёте такие строки:
Переводя это на Delphi, получаем (не знаете C?):
Обратите внимание на safecall. Я уже много раз про него рассказывал.

Шаг 4 — вызов кода

Итак, если вы решили пойти способом модификации условий, то вы можете:

  • Сбросить WS_EX_APPWINDOW
  • Установить WS_EX_TOOLWINDOW
  • Установить окну владельца в терминах системы (можно невидимого)

Все пункты обычно выполняются перегрузкой CreateParams. Иногда — вызовом Get/SetWindowLong(Ptr). Если вы посмотрите на FAQ или на форумы, то увидите, как этот принцип реализуется в коде.

Если вы пошли способом ручного управления, то вы создаёте ITaskbarList, инициализируете его (вызовом HrInit) и вызываете метод DeleteTab для своего окна. Достаточно прозрачно.

Шаг 5 — адаптация к Delphi

Ну и нужно учесть специфику Delphi.

Пункт 1 — это запутанное управление окнами в старых Delphi, где кнопка окна на Панели задач на самом деле не была кнопкой от окна! Это была кнопка от невидимого окна Application. Это же кривое поведение может быть доступно и в новых Delphi с MainFormOnTaskbar равным False. Иными словами, вам нужно знать, какой режим активен в вашем приложении, и чем Application.Handle отличается от Form1.Handle.

Пункт 2 — ну, это опционально, но вы можете использовать CreateComObject вместо ручного вызова CoCreateInstance:

Пункт 3 — Delphi часто автоматически выполняет за вас вызов CoInitialize(Ex), но когда она это не делает, многие просто не знают, что это нужно делать.

Шаг 6 — готовое решение

Например (вариант для MainFormOnTaskbar = True):
Вы можете использовать и другой подход. Я не хочу и не буду расписывать все варианты решения — просто используйте свою голову.

Заключение

Как видите, это простая задачка на 15 минут максимум. Однако, чтобы сделать это, мне понадобилось:

  • Хорошее знание Delphi:
    • Я знал про CreateParams (если вы выбрали путь со сменой условий).
    • Я знал про пересоздание окон, поэтому повесил код с ITaskbarList на CreateWnd, а не на (более простой, но неверный вариант) FormCreate.
    • Я знал про CreateComObject (хотя моё знание COM очень поверхностно, поэтому я могу где-то наврать).
    • Я знал про Application.Handle <> Form1.Handle и MainFormOnTaskbar.
    • Я знал про safecall в Delphi и обработку ошибок в COM.
  • Знание C, чтобы переводить заголовочники.
  • Знание WinAPI (Get/SetWindowLong, если вы взяли этот путь).
  • Знание работы с битовой логикой (смена битовых флагов в CreateParams или SetWindowLong).
  • Знание COM, чтобы успешно работать с интерфейсами и делать их перевод.
  • Знание английского, чтобы читать документацию и выполнять поиск.
  • Знание мест, где можно получить информацию (сайт MSDN, Wiki Embarcadero).
  • Знание доступных решений (в нашем случае — JWAPI).
Читайте также:  Как в автокаде добавить панель инструментов сверху

Это хорошая задачка, которая показывает как могут действовать ваши скиллы вместе. По сути, этот пост стал также хорошей иллюстрацией к предыдущему посту. Иллюстрацией в том плане, что он показывает, что вам недостаточно прочитать книжку по Delphi, чтобы стать программистом.

Кажется сложным? Ну, возьмите тогда компонент 😉

Источник

Delphi как скрыть окно из панели задач

«Maxthon» wrote in message news:2557001@news.rsdn.ru.
> Использую RxTrayIcon, То есть в трее отображается иконка программы. Как сделать так, чтобы программа не была видна на панели задач, а только в трее?

Если нужно убирать только при минимизации, тогда так:

От: Maxthon
Дата: 25.06.07 05:56
Оценка:

Здравствуйте, wellwell, Вы писали:

W>в DPR файле:
W>

Почему-то не работает. Добавляю эту строку в dpr-файл, а от этого ничего не меняется. Также не работает self.hide, если прописывать его в onCreate. В чем может быть проблема?

От: wellwell https://www.softperfect.com
Дата: 25.06.07 05:59
Оценка:

«Maxthon» wrote in message news:2557242@news.rsdn.ru.
> Почему-то не работает. Добавляю эту строку в dpr-файл, а от этого ничего не меняется. Также не работает self.hide, если прописывать его в onCreate. В чем может быть проблема?

Покажи куда в DPR добавляешь.

От: Maxthon
Дата: 25.06.07 05:59
Оценка:

Разобрался, но это не совсем то, что мне хотелось. Так форма не видна совсем, то есть ее нет не только на панели задач, но и на экране. А мне нужно, чтобы она присутствовала на экране и в трее, но не в панели задач. Так, например, умеет делать Winamp.

Источник

Оцените статью
Авто Город