Среда, 18.06.2025
Королевство Delphi
Главное меню
Статьи
Наш опрос
Как часто ви на этот сайт заходите?
Всего ответов: 159
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Система » Разное

Секреты иконки в системном трее. Часть 1

Наверняка многие, кто начинает программировать на Delphi нередко задавались такими вопросами как:

  1. А как можно поместить иконки приложения в системный трей Windows возле часов?
  2. Как скрыть главную форму приложения при запуске и показывать ее по команде всплывающего меню иконки приложения в системной трее, и как затем скрыть ее обратно?

Знакомо да? Что ж, сам я тоже когда-то был начинающим программистом, и потратил уйму времени и нервов за изучение и поиска решений для всех вышеизложенных вопросов. И именно сейчас я готов изложить Вам все свои знания по части работы с иконкой приложения в системной трее.

Статью я решил разделить на две части. Что содержит каждая из них догадаться не трудно - вопросов, о решении которых я расскажу тоже две. 

Итак, это часть 1: "Добавление иконки в системный трей".

В этой части мы научимся:

  • добавлять, изменять и удалять иконку.
  • отлавливать события мыши на иконке (наведение, клик, двойной клик и т.д.)
  • менять иконку во время работы приложения, а также текст всплывающей подсказки.

Начать статью я решил не с описания всевозможных компонентов для данной сферы программинга (которых полным полно в интернете), а с описания азов - WinAPI функций, предназначенных для работы с system tray. Хотя, "функции", как то больно громко получилось. На самом деле она всего одна:

function Shell_NotifyIcon ( dwMessage: Cardinal; lpData: PNotifyIconData ) : LongBool;
(я привожу Вам упрощенное представление функции сделанное лично мной, т.к. если взять описание функции из WinAPI SDK - понять его будет намного труднее)

подробнее о параметрах:
dwMessage:

  Параметр, а точнее команда, которая указывает этой функции что именно она должна делать. Может принимать следующие значения констант:
 NIM_ADD - добавляет иконку в трей
 NIM_DELETE - удаляет иконку из системного трея
 NIM_MODIFY - меняет (обновляет) иконку в системном трее.
    lpData:
  Сей параметр есть запись, которая содержит всю информацию об добавляемой, удаляемой или изменяемой иконке. Данная запись имеет вид:

_NOTIFYICONDATAA = record
   cbSize: DWORD;
   Wnd: HWND;
   uID: UINT;
   uFlags: UINT;
   uCallbackMessage: UINT;
   hIcon: HICON;
   szTip: array [0..63] of AnsiChar;
end;
(указатель PNotifyIconData является указателем именно на эту запись)

Давайте рассмотрим, какие именно данные содержит данная запись:
     cbSize: Размер данной записи;
     Wnd: Handle того окна, которое будет получать сообщения от иконки;
     uID: Идентификатор иконки;
     uFlags: Здесь содержатся константы, означающие, какие данные верны в записи:
         NIF_ICON - hIcon содержит верную информацию.
         NIF_MESSAGE - uCallbackMessage содержит верную информацию.
         NIF_TIP -szTip содержит верную информацию.
        (Подробнее об этом я расскажу ниже)
     uCallbackMessage: Назначенный Вами идентификатор сообщения, которое будет получать приложение от иконки.
     hIcon: Собственно Handle иконки (TIcon.Handle). 
     szTip: Текст всплывающей подсказки (не более 64 символов).

Мда, наверняка ничего не понятно, да? ..особенно новичкам. Ничего! Далее я приведу код небольшой программы, написанной лично мной. Весь код программы имеет очень богатые комментарии. С их помощью понять смысл каждого шага Вам будет нетрудно:)

Вот скриншот этой небольшой программки:

Ниже привожу листинг файла main.pas (файл основной и единственной формы приложения):
Внимание!: в тексте программы прошу не путать два понятия: "иконка" - это то, что собственно находится в системно трее, и "иконка (изображение)" - это то, что содержит то само изображение иконочки.

unit main;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ShellApi, StdCtrls, ExtCtrls, Menus;

type
 TForm1 = class(TForm)
 GroupBox1: TGroupBox;
 TI_Event: TLabel;
 GroupBox2: TGroupBox;
 TI_DC: TLabel;
 GroupBox3: TGroupBox;
 Icon: TImage;
 IconFile: TEdit;
 Browse: TButton;
 Exit: TButton;
 About: TButton;
 OpenDialog1: TOpenDialog;
 GroupBox4: TGroupBox;
 ToolTip: TEdit;
 SetToolTip: TButton;
 AboutGroupBox: TGroupBox;
 Desk: TLabel;
 Author: TLabel;
 Label3: TLabel;
 Label4: TLabel;
 email: TLabel;
 www: TLabel;
 procedure FormCreate(Sender: TObject);
 procedure FormClose(Sender: TObject; var Action: TCloseAction);
 procedure BrowseClick(Sender: TObject);
 procedure ExitClick(Sender: TObject);
 procedure SetToolTipClick(Sender: TObject);
 procedure wwwClick(Sender: TObject);
 procedure emailClick(Sender: TObject);
 procedure AboutClick(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 procedure IconCallBackMessage( var Mess : TMessage ); message WM_USER + 100;
 //Здесь мы объявлем процедуру, которая будет выполнятся каждый раз, когда
 //на иконке будет происходит какое-либо событие (клик мышки и т.п.)
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var nid : TNotifyIconData;
begin
 //Добавляем иконку в трей при старте программы:
 with nid do //Указываем параметры иконки, для чего используем структуру
 //TNotifyIconData.
 begin
 cbSize := SizeOf( TNotifyIconData ); //Размер все структуры
 Wnd := Form1.Handle; //Здесь мы указывает Handle нашей главной формы
 //которая будет получать сообщения от иконки.
 uID := 1; //Идентификатор иконки
 uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP; //Обозначаем то, что в
 //параметры входят:
 //Иконка, сообщение и текст
 //подсказки (хинта).
 uCallbackMessage := WM_USER + 100; //Здесь мы указываем, какое
 //сообщение должна высылать
 //иконочка нашей главной форме,
 //в тот момент, когда на ней
 //(иконке) происходят
 //какие-либо события
 hIcon := Application.Icon.Handle; //Указываем на Handle
 //иконки (изображения)
 //(в данной случае берем
 //иконку основной формы
 //приложения. Ниже Вы увидите
 //как можно ее изменить)
 StrPCopy(szTip, ToolTip.Text); //Указываем текст всплывающей
 //посдказки, который берем из
 //компонента ToolTip,
 //расположенного на главной
 //форме.
 end;
 Shell_NotifyIcon( NIM_ADD, @nid );
 //Собственно добавляем иконку в трей:)
 //Обратите внимание, что здесь мы исползуем константу
 //NIM_ADD (добавление иконки).
 IconFile.Text:=Application.ExeName;
 //Выводим на главной форме пусть к файлу, который содержит
 //иконку (изображение):)
 Icon.Picture.Icon:=Application.Icon;
 //Теперь выводим на главной форме изображение
 //иконки (изображения) в увеличенном виде
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var nid : TNotifyIconData;
begin
 with nid do
 begin
 cbSize := SizeOf( TNotifyIconData );
 Wnd := Form1.Handle;
 uID := 1;
 uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
 uCallbackMessage := WM_USER + 100;
 hIcon := Application.Icon.Handle;
 StrPCopy(szTip, ToolTip.Text);
 end;
 Shell_NotifyIcon( NIM_DELETE, @nid );
 //Удаляем иконку из трея. Параметры мы вводим для того,
 //чтобы функция точно знала, какую именно иконку надо удалять.
 //Обратите внимание, что здесь мы исползуем константу
 //NIM_DELETE (удаление иконки).
end;

procedure TForm1.IconCallBackMessage( var Mess : TMessage );
var Mouse: TMouse;
begin
 case Mess.lParam of
 //Здесь Вы можете обрабатывать все события, происходящие на иконке:)
 //На главнй форме я специально расположил две метки, в которых,
 //при возникновении какого-либо события будет писаться что именно произошло:)
 //Но, теперь во второй части во время некоторых событий будут происходит
 //реальные процессы.
 WM_LBUTTONDBLCLK : TI_DC.Caption := 'Двойной щелчок левой кнопкой' ;
 WM_LBUTTONDOWN : TI_Event.Caption:= 'Нажатие левой кнопки мыши' ;
 WM_LBUTTONUP : TI_Event.Caption:= 'Отжатие левой кнопки мыши' ;
 WM_MBUTTONDBLCLK : TI_DC.Caption := 'Двойной щелчок средней кнопкой мыши';
 WM_MBUTTONDOWN : TI_Event.Caption:= 'Нажатие средней кнопки мыши' ;
 WM_MBUTTONUP : TI_Event.Caption:= 'Отжатие средней кнопки мыши' ;
 WM_MOUSEMOVE : TI_Event.Caption:= 'Перемещение мыши' ;
 WM_MOUSEWHEEL : TI_Event.Caption:= 'Вращение колесика мыши' ;
 WM_RBUTTONDBLCLK : TI_DC.Caption := 'Двойной щелчок правой кнопкой' ;
 WM_RBUTTONDOWN : TI_Event.Caption:= 'Нажатие правой кнопки мыши' ;
 WM_RBUTTONUP : TI_Event.Caption:= 'Отжатие правой кнопки мыши' ;
 end;
end;

procedure TForm1.BrowseClick(Sender: TObject);
var I : TIcon;
 nid : TNotifyIconData;
begin
 //Здесь мы меням иконку приложения, для чего используем диалоговое окно
 //(для выбора файла, который содержит изображение иконки)
 //Итак, все потизоньку:
 if OpenDialog1.Execute then //Запуск диаголового окна
 begin
 I:=TIcon.Create; //Создаем объект I типа TIcon
 I.LoadFromFile(OpenDialog1.Filename); //Теперь загружаем в него изображение
 //из того файла, который был выбран в
 //окне диалогового окна
 //Далее делаем все тоже самое, что и раньше, создаем структуру типа
 //TNotifyIconData куда заносим все параметры иконки:)
 with nid do
 begin
 cbSize := SizeOf( TNotifyIconData );
 Wnd := Form1.Handle;
 uID := 1;
 uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
 uCallbackMessage := WM_USER + 100;
 hIcon := I.Handle;
 StrPCopy(szTip, ToolTip.Text);
 end;
 Shell_NotifyIcon( NIM_MODIFY , @nid );
 //А вот здесь мы заносим изменения в иконку, которая находится в системном
 //трее обратите внимание, что здесь мы исползуем константу NIM_MODIFY
 //(изменение иконки).
 Icon.Picture.Icon:=I;
 IconFile.Text:=OpenDialog1.FileName;
 I.Free;
 end;
end;

procedure TForm1.ExitClick(Sender: TObject);
begin
 //Закрываем приложение. 
 Close;
end;

procedure TForm1.SetToolTipClick(Sender: TObject);
var nid : TNotifyIconData;
begin
 //Здесь мы назначаем всплывающую посказу:)
 //Здесь все тоже самое, что и в предыдущей процедуре.
 //Только иконка (изображение) берется из компонента Icon,
 //который назодится на главной форме:)
 //А текст всплывающей посказки берем из
 //компонента ToolTip (который расположен на главной форме)
 with nid do
 begin
 cbSize := SizeOf( TNotifyIconData );
 Wnd := Form1.Handle;
 uID := 1;
 uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
 uCallbackMessage := WM_USER + 100;
 hIcon := Icon.Picture.Icon.Handle;
 StrPCopy(szTip, ToolTip.Text);
 end;
 Shell_NotifyIcon( NIM_MODIFY , @nid );
 //.. и снова меням иконку:)
end;

//Далее идут процедуры, относящие работе сведений о программе
//Тут нет ничего сложного :-)
procedure TForm1.wwwClick(Sender: TObject);
begin
 ShellExecute(Application.Handle,'open','http://delphi.hostmos.ru',nil,nil,0);
end;

procedure TForm1.emailClick(Sender: TObject);
begin
 ShellExecute(Application.Handle,'open','mailto:srustik@rambler.ru',nil,nil,0);
end;

procedure TForm1.AboutClick(Sender: TObject);
begin
 if Form1.Width=250 then
 begin
 Form1.Width:=430;
 About.Caption:='О Программе <<';
 end
 else begin
 Form1.Width:=250;
 About.Caption:='О Программе >>';
 end;
 AboutGroupBox.Visible:=not AboutGroupBox.Visible;
end;

end.
end.

Вот в принципе и все:) Надеюсь данная часть помогла Вам понять азы работы с системным треем:)

Автор: Рустик

Получить ссылку на материал

Категория: Разное | Добавил: Барон (15.12.2011)
Просмотров: 1742 | Теги: иконка, трей | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
ActiveX [10]
CORBA и COM [16]
Kol и MCK [23]
WinAPI [28]
Компоненты [27]
Работа с Bluetooth [4]
Железо [8]
Текст [18]
Разное [98]
Королевство Delphi © 2010-2025
Яндекс цитирования