1. Подготовительная часть
Для начала объявим модуль и новый тип, которые необходимы для нашей работы:
uses ShellAPI;
type
TDUMMYUNIONNAME = record
case Integer of
0: (uTimeout: UINT);
1: (uVersion: UINT);
end;
TNotifyIconDataNew = record
cbSize: DWORD;
Wnd: HWND;
uID: UINT;
uFlags: UINT;
uCallbackMessage: UINT;
hIcon: HICON;
szTip: array[0..127] of Char;
dwState: DWORD;
dwStateMask: DWORD;
szInfo: array[0..255] of Char;
DUMMYUNIONNAME: TDUMMYUNIONNAME;
szInfoTitle: array[0..63] of Char;
dwInfoFlags: DWORD;
end;
При наведении мыши на иконку в области уведомлений на панели задач будет появляться
всплывающая подсказка. Замечено, что в операционных системах данная подсказка
некорректно работает, при условии, что если длина текста составляет более 63
символа. Ниже дана функция "вырезания" текста IconTreeHint .
function IconTreeHint(s: string): string;
begin
if Length(s)>63 then
s:=Copy(s, 1, 60)+'...';
Result:=s;
end;
где:
s – текст всплывающей подсказки.
2. Создание иконки на панели задач
procedure IconTreeCreate(Form: TForm; Icon: TIcon; ID: integer; Hint: string);
var NID: TNotifyIconDataNew;
begin
Hint:=IconTreeHint(Hint);
with NID do
begin
cbSize:=SizeOf(NID);
Wnd:=Form.Handle;
uID:=ID;
uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP;
uCallBackMessage:=WM_USER;
hIcon:=Icon.Handle;
StrPCopy(szTip, Hint);
end;
Shell_NotifyIcon(NIM_ADD, @NID);
end;
где:
Form – форма приложения;
Icon – иконка в виде рисунка (она отображается на панели задач);
ID – идентификационный номер иконки;
Hint – текст в виде всплывающей подсказки.
Например,
IconTreeCreate(Form1, Application.Icon, 2,
'Иконка на панели задач') .
3. Изменение иконки
procedure IconTreeChange(Form: TForm; Icon: TIcon; ID: integer; Hint: string);
var NID: TNotifyIconDataNew;
begin
Hint:=IconTreeHint(Hint);
with NID do
begin
cbSize:=SizeOf(NID);
Wnd:=Form.Handle;
uID:=ID;
uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP;
uCallBackMessage:=WM_USER;
hIcon:=Icon.Handle;
StrPCopy(szTip, Hint);
end;
Shell_NotifyIcon(NIM_MODIFY, @NID);
end;
где:
Form – форма приложения;
Icon – иконка в виде рисунка (она отображается на панели задач);
ID – идентификационный номер иконки;
Hint – текст в виде всплывающей подсказки.
Например,
IconTreeChange(Form1, Application.Icon, 2,
'Изменение всплывающей подсказки на панели задач') .
4. Сообщение программы на панели задач
procedure IconTreeMessage(Form: TForm; Icon: TIcon; ID: integer; ImagePicture: DWORD; Caption, Text: string);
var NID: TNotifyIconDataNew;
begin
Caption:=IconTreeHint(Caption);
with NID do
begin
cbSize:=SizeOf(NID);
Wnd:=Form.Handle;
uID:=ID;
uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP or $10;
uCallBackMessage:=WM_USER;
hIcon:=Icon.Handle;
StrPCopy(szInfo, Text);
StrPCopy(szInfoTitle, Caption);
dwInfoFlags:=ImagePicture;
end;
Shell_NotifyIcon(NIM_ADD, @NID);
Shell_NotifyIcon(NIM_MODIFY, @NID);
end;
где:
Form – форма приложения;
Icon – иконка в виде рисунка (она отображается на панели задач);
ID – идентификационный номер иконки;
ImagePicture – номер значка сообщения, значения которых даны ниже:
0 – нет иконки,
1 – информация,
2 – внимание,
3 – ошибка,
4 – значок программы,
5 и более – другие значки;
Caption – заголовок сообщения;
Text – текст сообщения.
Например,
IconTreeMessage(Form1, Application.Icon, 2, 3,
'Сообщение', 'Образец сообщения') .
5. Наведение мыши на иконку
В типе TForm1 создать процедуру WMICON , которая будет
выполняться при манипуляциях мыши на иконках:
type
TForm1 = class(TForm)
Label1: TLabel;
procedure WMICON(var msg: TMessage); message WM_USER;
private
{ Private declarations }
public
{ Public declarations }
end;
...
procedure TForm1.WMICON(var msg: TMessage);
begin
Label1.Caption:=Format('ID = %d, Signal = %d', [msg.WParam, msg.LParam]);
end;
...
где:
msg – переменная типа TMessage , следующие
свойства которых необходимы для обработки:
msg.WParam – идентификационный номер иконки,
msg.LParam – числовой код, основные значения которых даны ниже:
WM_MOUSEMOVE – наведена мышь на иконку,
WM_LBUTTONDOWN – нажата левая кнопка мыши на иконке,
WM_LBUTTONDBLCLK – двойной щелчок левой кнопки мыши на иконке,
WM_RBUTTONDOWN – нажата правая кнопка мыши на иконке,
WM_RBUTTONDBLCLK – двойной щелчок правой кнопки мыши на иконке,
1028 – щелчок правой кнопки мыши по всплывающему сообщению программы,
1029 – щелчок левой кнопки мыши по всплывающему сообщению программы.
6. Удаление иконки
procedure IconTreeDestroy(Form: TForm; ID: integer);
var NID: TNotifyIconDataNew;
begin
with NID do
begin
cbSize:=SizeOf(NID);
Wnd:=Form.Handle;
uID:=ID;
end;
Shell_NotifyIcon(NIM_DELETE, @NID);
end;
где:
Form – форма приложения;
ID – идентификационный номер иконки.
Например,
IconTreeDestroy(Form1, 2) .
7. Программа
Рассмотрим программу, позволяющую делать любые операции с иконками на панели задач.
На пустую форму добавим 5 кнопок (желательно столбиком) типа TButton ,
пустую картинку TImage и контекстное меню TPopupMenu .
Примечание. Для работы программы необходимо наличие
файла-иконки *.ico. В событии FormCreate указан файл
'1.ico'. При отсутствии данной иконки программа
может некорректно работать.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Menus;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Image1: TImage;
PopupMenu1: TPopupMenu;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure WMICON(var msg: TMessage); message WM_USER;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses ShellAPI;
type
TDUMMYUNIONNAME = record
case Integer of
0: (uTimeout: UINT);
1: (uVersion: UINT);
end;
TNotifyIconDataNew = record
cbSize: DWORD;
Wnd: HWND;
uID: UINT;
uFlags: UINT;
uCallbackMessage: UINT;
hIcon: HICON;
szTip: array[0..127] of Char;
dwState: DWORD;
dwStateMask: DWORD;
szInfo: array[0..255] of Char;
DUMMYUNIONNAME: TDUMMYUNIONNAME;
szInfoTitle: array[0..63] of Char;
dwInfoFlags: DWORD;
end;
TIconTree = class
private
NID: TNotifyIconDataNew;
public
constructor Create(Form: TForm; Icon: TIcon; ID: integer; Hint: string);
destructor Destroy; override;
procedure Change(Hint: string); overload;
procedure Change(Icon: TIcon); overload;
procedure Change(Icon: TIcon; Hint: string); overload;
procedure Message(ImagePicture: DWORD; Caption, Text: string);
end;
var IconTree1, IconTree2: TIconTree;
procedure TForm1.Button1Click(Sender: TObject);
begin
IconTree1:=TIconTree.Create(Form1, Application.Icon, 1, 'Иконка приложения');
IconTree2:=TIconTree.Create(Form1, Image1.Picture.Icon, 5, 'Иконка файла *.ico');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
IconTree1.Change(Image1.Picture.Icon, 'Обмен иконок (ID = 1)');
IconTree2.Change(Application.Icon, 'Обмен иконок (ID = 5)');
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
IconTree1.Message(2, 'Сообщение',
'Образец сообщения. Можно щелкнуть по нему правой кнопкой мыши...');
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Hide;
IconTree2.Message(1, 'Окно невидимо!',
'Для отображения окна кликните ДВОЙНЫМ щелчком мыши на значок. '+
'Левая и правая кнопка мыши не имеет значения!');
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
IconTree1.Free;
IconTree2.Free;
Close;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: byte;
Items: array[0..3] of TMenuItem;
begin
Button1.Caption:='Создать иконки';
Button2.Caption:='Обменять иконки';
Button3.Caption:='Сообщение';
Button4.Caption:='Скрыть окно';
Button5.Caption:='Закрыть программу';
for i:=1 to 5 do
TButton(FindComponent('Button'+IntToStr(i))).Width:=125;
Image1.Picture.LoadFromFile('E:\1.ico');
Items[0]:=TMenuItem.Create(PopupMenu1);
Items[0].Caption:='Скрыть окно';
Items[0].OnClick:=Button4Click;
PopupMenu1.Items.Add(Items[0]);
Items[1]:=TMenuItem.Create(PopupMenu1);
Items[1].Caption:='Отобразить окно';
Items[1].OnClick:=N2Click;
PopupMenu1.Items.Add(Items[1]);
Items[2]:=TMenuItem.Create(PopupMenu1);
Items[2].Caption:='-';
PopupMenu1.Items.Add(Items[2]);
Items[3]:=TMenuItem.Create(PopupMenu1);
Items[3].Caption:='Закрыть программу';
Items[3].OnClick:=Button5Click;
PopupMenu1.Items.Add(Items[3]);
end;
procedure TForm1.N2Click(Sender: TObject);
begin
Show;
end;
procedure TForm1.WMICON(var msg: TMessage);
var P: TPoint;
begin
if (msg.WParam=1) and (msg.LParam=1028) then
MessageBox(0, 'Вы щелкнули правой кнопкой мыши по всплывающему сообщению',
'Окно', MB_OK);
if (msg.WParam=5) and ((msg.LParam=WM_LBUTTONDBLCLK) or
(msg.LParam=WM_RBUTTONDBLCLK)) then
Show;
if (msg.WParam=5) and (msg.LParam=WM_RBUTTONDOWN) then
begin
GetCursorPos(P);
PopupMenu1.Popup(P.X, P.Y);
end;
end;
{ TIconTree }
function IconTreeHint(s: string): string;
begin
if Length(s)>63 then
s:=Copy(s, 1, 60)+'...';
Result:=s;
end;
procedure TIconTree.Change(Hint: string);
begin
Hint:=IconTreeHint(Hint);
with NID do
begin
StrPCopy(szInfo, '');
StrPCopy(szInfoTitle, '');
StrPCopy(szTip, Hint);
end;
Shell_NotifyIcon(NIM_ADD, @NID);
Shell_NotifyIcon(NIM_MODIFY, @NID);
end;
procedure TIconTree.Change(Icon: TIcon);
begin
NID.hIcon:=Icon.Handle;
Shell_NotifyIcon(NIM_ADD, @NID);
Shell_NotifyIcon(NIM_MODIFY, @NID);
end;
procedure TIconTree.Change(Icon: TIcon; Hint: string);
begin
Change(Icon);
Change(Hint);
end;
constructor TIconTree.Create(Form: TForm; Icon: TIcon; ID: integer;
Hint: string);
begin
Hint:=IconTreeHint(Hint);
with NID do
begin
cbSize:=SizeOf(NID);
Wnd:=Form.Handle;
uID:=ID;
uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP or $10;
uCallBackMessage:=WM_USER;
hIcon:=Icon.Handle;
StrPCopy(szTip, Hint);
end;
Shell_NotifyIcon(NIM_ADD, @NID);
end;
destructor TIconTree.Destroy;
begin
Shell_NotifyIcon(NIM_DELETE, @NID);
inherited;
end;
procedure TIconTree.Message(ImagePicture: DWORD; Caption, Text: string);
begin
Caption:=IconTreeHint(Caption);
with NID do
begin
StrPCopy(szInfo, Text);
StrPCopy(szInfoTitle, Caption);
dwInfoFlags:=ImagePicture;
end;
Shell_NotifyIcon(NIM_ADD, @NID);
Shell_NotifyIcon(NIM_MODIFY, @NID);
end;
end.
Запустим программу. На панели задач имеются различные стандартные иконки системных,
пользовательских и прочих программ:
В этой программе рекомендуется нажимать кнопки по порядку. Нажмем на первую кнопку
'Создать иконки'. На панели задач появятся наши 2
иконки, при наведении мыши на которых появляются всплывающие подсказки:
После нажатия на вторую кнопку 'Обменять иконки'
произойдет обмен иконок:
После нажатия на третью кнопку 'Сообщение' на
панели задач появится сообщение (уведомление). По ней можно щелкнуть правой кнопкой
мыши:
После нажатия на четвертую кнопку 'Скрыть окно'
окно скроется и появится другое всплывающее сообщение:
Обратите внимание, что каждая иконка имеет свой идентификационный номер
ID , а процедура WMICON реагирует на различные манипуляции
мыши с такими иконками. Параметр msg.WParam служит для определения
какой иконки, с которой указатель мыши выполнил операцию (msg.WParam
эквивалентно ID ).
При нажатии правой кнопки мыши на иконку с ID = 5 появляется
контекстное меню:
При выборе пункта меню 'Отобразить окно' окно
появится, а контекстное меню исчезнет.
После нажатия на пятую (последнюю) кнопку 'Закрыть
программу' иконки с панели задач удаляются, а программа закрывается.
|