Наверняка многие, кто начинает программировать на Delphi нередко задавались
такими вопросами как:
- А как можно поместить иконки приложения в системный трей Windows возле часов?
- Как скрыть главную форму приложения при запуске и показывать ее по команде
всплывающего меню иконки приложения в системной трее, и как затем скрыть ее
обратно?
Знакомо да? Что ж, сам я тоже когда-то был начинающим
программистом, и потратил уйму времени и нервов за изучение и поиска решений для
всех вышеизложенных вопросов. И именно сейчас я готов изложить Вам все свои
знания по части работы с иконкой приложения в системной трее.
Статью я решил разделить на две части. Что содержит каждая из
них догадаться не трудно - вопросов, о решении которых я расскажу тоже две.
Итак, это часть 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.
Вот в принципе и все:) Надеюсь данная часть помогла Вам понять азы работы с
системным треем:)
Автор: Рустик
|