This Might Be Useful

Установка иконки приложения в system tray

Поговорим о сожительстве трея (SysTray, где часики и всякие иконки у Вас в Windows-е живут) и Delphi. А именно - как засунуть иконку в трей своими руками и не запачкаться.

Зачем помещать иконку в трей? Очевидно, таким образом TaskBar меньше засоряется и программы работающие в background меньше мозолят глаза оставаясь по прежнему лёгко-доступными. К сожалению, в дистрибутивах Delphi нет компоненты, позволяющей легко и не принудительно помещать иконки в трей (возможно будет, так как компонента TrayIcon есть в C# Builder). По этой причине предлагаю не искать по всему интернету готовое решение, а сделать всё самому. На самом деле всё просто.

Нам понадобится системная функция Shell_NotifyIcon. Чтобы иметь к ней доступ необходимо подключить библиотеку ShellAPI (uses ShellAPI;). Синтаксис Shell_NotifyIcon:

DELPHI:
  1. Shell_NotifyIcon(dwMessage: integer; pnid: PNOTIFYICONDATA): boolean;

dwMessage указывает на осуществляемую операцию и может принимать значения NIM_ADD - добавить иконку, NIM_DELETE - удалить существующую иконку и NIM_MODIFY - изменить. Результат функции опредеяется успешностью проведённой операции. pnid - это структура с описанием создаваемой иконки.

Чтобы создать нашу первую иконку напишем следующий код в разделе interface:

DELPHI:
  1. Const WM_ICONTRAY = WM_USER + 1;
  2. // Это сообщение будет передаваться от иконки в программу
  3.  
  4. Type TForm1 = class(TForm)
  5.   private
  6.     { Private declarations }
  7.     TrayIconData: TNotifyIconData;
  8.   public
  9.     { Public declarations }
  10.   end;

Теперь добавим PopupMenu в наш проект и создадим обработчики OnCreate и OnDestroy для нашей формы. Ниже приведён код OnCreate, создающий во время запуска нашего проекта необходимую иконку:

DELPHI:
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   with TrayIconData do
  4.   begin
  5.     cbSize := SizeOf(TrayIconData);
  6.     // Размер используемой структуры
  7.     Wnd := Handle;
  8.     // Дескриптор окна, получающего сообщения
  9.     uID := 0;
  10.     // Идентификатор иконки для программы,
  11.     // используется для работы с несколькими иконками
  12.     uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
  13.     // Иконка передаёт сообщения в программу, имеет изображение и подсказку
  14.     uCallbackMessage := WM_ICONTRAY;
  15.     // Иконка передаёт сообщение WM_ICONTRAY
  16.     hIcon := Application.Icon.Handle;
  17.     // Дескриптор изображения для иконки
  18.     StrPCopy(szTip, Application.Title);
  19.     // szTip содержит подсказку
  20.   end;
  21.   Shell_NotifyIcon(NIM_ADD, @TrayIconData);
  22.   // Создаём иконку в трее
  23. end;

Вроде больше нечего дополнить. Если необходимо создать дополнительные иконки, то необходимо для каждой их них назначать уникальное значение uID. При закрытии программы следует убрать созданную иконку из трея:

DELPHI:
  1. procedure TForm1.FormDestroy(Sender: TObject);
  2. begin
  3.   Shell_NotifyIcon(NIM_DELETE, @TrayIconData);
  4. end;

В функции мы передаём @TrayIconData, а не TrayIconData, так как функции требуют тип PNotifyIconData - указатель на структуру. Чтобы обрабатывать передаваемое в программу сообщение от иконки необходимо написать функцию обработки сообщения WM_ICONTRAY. Для этого в описание TForm1 добавим строку

DELPHI:
  1. procedure TrayMessage(var Msg: TMessage); message WM_ICONTRAY;

и напишем соответствующую процедуру:

DELPHI:
  1. procedure TForm1.TrayMessage(var Msg: TMessage);
  2. begin
  3.   case Msg.lParam of
  4.     WM_LBUTTONUP:
  5.       // Произошло нажатие на левую кнопку,
  6.       // прячем или показываем главное окно программы
  7.       begin
  8.         if Form1.Visible then
  9.           Form1.Hide
  10.         else
  11.           Form1.Show
  12.       end;
  13.     WM_RBUTTONUP:
  14.       // Произошло нажатие на правую кнопку
  15.       begin
  16.         SetForegroundWindow(Handle);
  17.         PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
  18.         // Показываем всплывающее меню (помните, мы его создали в самом начале)
  19.         PostMessage(Handle, WM_NULL, 0, 0);
  20.         // В Windows есть баг, поэтому чтобы не было проблем с менюшкой
  21.         // Microsoft рекомендует делать такой вызов
  22.       end;
  23.   end;
  24. end;

Вот и всё, иконка готова. Что можно добавить? Например, таймер, чтобы сделать анимированную иконку, можно разукрасить менюшку. Вобщем фантазия ни чем не ограничена :)

· Запуск приложения и ожидание его завершения
· Убираем всплывающие jobs и notifications в KDE 4.2
· Оптимизация Windows XP
· Установка оптимального размера файла подкачки и правильное его размещение
· Подключение NFS-раздела в Windows Vista

- Коментировать
- Trackback

5 Responses to “Установка иконки приложения в system tray”


  1. Aux Says:

    Кхм, а почему не указано оригинальное авторство? Это новый прикол такой?

  2. Filosoff Says:

    статья была написана тобой для Erased.info, который принадлежит мне. и я счел возможным продублировать статью тут в таком виде, в каком мне было удобно. кроме того, авторство тут относится разве что к связующим фразам между кодом.

  3. Beavis Says:

    Спасибо, чайнику помогло. Все просто и ясно даже мне

  4. mr ToNik Says:

    2 Filosoff:

    Авторское право ещё никто не отменял. Даже если вы и владеете имущественными правами на данную статью.

  5. Grey Says:

    супер, большое спасибо

Leave a Reply

code