Иконку в трей помещают с помощью Shell_NotifyIconW. Интересено посмотреть на этот процесс с другой точки зрения.
Цитата с сайта delphi.mastak.ru:
Shell_NotifyIconW просто ищет окно с классом "Shell_TrayWnd" и посылает в него сообщение WM_COPYDATA. в качестве данных выступает простая структура TNIDMessage.
возвращаясь к топику: если создать свое окно с классом "Shell_TrayWnd" и обрабатывать входящие сообщения WM_COPYDATA, то можно написать полный аналог system tray! ...
(с) paul_shmakov
...чем и займемся.
В первую очередь немаловажное замечание: сообщение посылается только одному окну, то есть наше приложение должно грузится первым. Разные там explorer'ы и другие подобные будут мешать.
procedure TFORM1.WMCOPYDATA(var Msg: Tmessage);
var
pcd: PCopyDataStruct;
NID: PNotifyIconData;
begin
pcd := PCOPYDATASTRUCT(msg.lParam);
if pcd^.dwData = 1 thenbegin
NID := pointer(integer(pcd.lpData) + 8);
case integer(pointer(integer(pcd.lpData) + 4)^) of
NIM_ADD: Msg.Result := NewTrayIcon(NID); // добавить иконку
NIM_DELETE: Msg.Result := DeleteTrayIcon(NID); // удалить иконку
NIM_MODIFY: Msg.Result := ModifyTrayIcon(NID);
// изменить иконку (или подсказку)end;
exit;
end;
end;
Обратите внимание на Msg.Result. Желательно чтобы NewTrayIcon,
DeleteTrayIcon, ModifyTrayIcon возвращали Integer(True) или Integer(False) в
зависимости от помещения/удаления иконки. Некоторые приложения не проверяют
этот результат, но если начнут проверять - то причины "глючного" поведения
иконки того же AVP Monitor можно искать долго и безуспешно.
Шаг третий:
Поймали, и че с ним теперь делать?
А мы имеем очень интересную структуру -
NID.cbSize - размер записи, в принципе не интересен;
NID.Wnd - хендл окна (владельца иконки);
NID.uID - идентификатор иконки (если их в приложении несколько), для данной
задачи нужен для отсылки обратного сообщения;
NID.uFlags - определяет, какие поля используются в сообщении. Параметр может
быть любой комбинацией из флагов (0 - uCallbackMessage, 2 - hIcon, 4 - czTip);
NID.uCallbackMessage - номер сообщения, которое посылается окну,
определяемому полем NID.Wnd (владельцу). lParam отсылаемого сообщения дожен
равняться NID.uID, а wParam сообщение от мыши. Пример:
PostMessage(NID.Wnd, NID.uCallBack, NID.uID, MOUSE_EVENT)
где MOUSE_EVENT может принимать значения WM_LBUTTONDOWN, WM_LBUTTONUP,
WM_LBUTTONDBLCLK и подобные для других кнопок мыши.
NID.hIcon - хендл иконки, которую собственно и предполагается отображать;
NID.szTip - строка, оканчивающаяся нулевым символом, содержит подсказку,
которая должна выводится при наведении курсора на иконку.
В случаях ошибки нужно информировать приложения про
необходимость поместить иконки обратно. Для этого послужат такие действия:
procedure TForm1.FormCreate(Sender: TObject);
var
WM_TASKBARCREATED: UINT;
begin
WM_TASKBARCREATED := RegisterWindowMessage('TaskbarCreated');
PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
end;
ВНИМАНИЕ!!! Следуйте данным инструкциям только в том случае, если Вы ясно понимаете смысл действий!!!
Повторюсь: Shell_NotifyIconW сообщение посылает только одному окну. Поэтому чтобы увидеть результаты работы демопроекта, загружать его надо без или вместо explorer'а.
Первый вариант (для Win9x): Пример: файл %windir%\system.ini изменить следующим образом:
Найти строчку:
shell=explorer.exe
Заменить на (предполагается что демопроект находится в C:\Demotray\ ) :
Shell своими руками - System Tray: создание аналога системной шкалы трея с помощью Delphi.
Комментарии и вопросы
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.