Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];

Вниз

Как засунуть в трэй иконку API-программы?   Найти похожие ветки 

 
MENfromUSA   (2004-07-25 13:47) [0]

Прога пишеться на чистом API. Подскажите как засунуть иконку из таскбара в трэй...


 
Красный молоток   (2004-07-25 13:57) [1]

Для того чтобы создать иконку на SystemTray имеется всего лишь одна функция из модуля ShellAPI –

function Shell_NotifyIcon(dwMessage: Cardinal; lpData: PNOTIFYICONDATAA): LongBool;

PNOTIFYICONDATAA – указатель на структуру _NOTIFYICONDATAA
Поля _NOTIFYICONDATAA имеют следующий смысл:
cbSize - размер структуры, должен, быть SizeOf(TNotifyIconDataA).
hWnd - дескриптор окна, которое будет получать события мыши над иконкой.
uID - уникальный идентификатор иконки. Идентификатор должен быть уникален в пределах окна - обработчика, передаваемого в hWnd.
uFlags - битовое поле, определяющее какое из следующих полей несет действительную информацию. Может быть одним из следующих значений: NIF_ICON,
NIF_MESSAGE, NIF_TIP или их OR-комбинацией.
uCallbackMessage - сообщение, передаваемое окну-обработчику при событиях мыши. Возможна также OR-комбинация сообщений.
hIcon - дескриптор иконки, помещаемой на SystemTray.
szTip - текст для Hint"а, если szTip[0] = #0, то Hint"а не будет.

Получается, для того чтобы создать иконку на SystemTray необходимо вызвать функцию Shell_NotifyIcon() с параметрами NIM_ADD и указателем на переменную типа _NOTIFYICONDATAA с заполненными полями cbSize, hWnd, uId, uFlags и uCallbackMessage. szTip можно оставить пустым, в таком случае его не будет.

Получаем: функция создания иконки на SystemTray:

function TaskBarAddIcon(hWindow: THandle; ID: Cardinal;
Icon : hIcon; WMessage: Cardinal; Tip: String): Boolean;
var
NID: _NOTIFYICONDATAA;
begin
with NID do
 begin
  cbSize := SizeOf(_NOTIFYICONDATAA);
  Wnd := hWindow;
  uID := ID;
  uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
  uCallbackMessage := WMessage;
  hIcon := Icon;
   if Length(Tip)>63 then SetLength(Tip, 63);
  StrPCopy(szTip, Tip);
 end;
Result := Shell_NotifyIcon(NIM_ADD, @NID);
end;

Перед выходом из программы надо удалить иконку. Для того чтобы это сделать, надо вызвать функцию Shell_NotifyIcon() с параметрами NIM_DELETE и указателем на переменную типа _NOTIFYICONDATAA с заполненными полями cbSize, hWnd, uId.

Соответственно процедура удаления иконки с SystemTray:

procedure DestroyIcon(hWindow: THandle; ID: Cardinal);
var
NID: _NOTIFYICONDATAA;
begin
with NID do begin
 cbSize := SizeOf(_NOTIFYICONDATAA);
 Wnd := hWindow;
 uID := ID;
end;
Shell_NotifyIcon(NIM_DELETE, @NID);
end;


 
VMcL ©   (2004-07-25 14:02) [2]

>>MENfromUSA  (25.07.04 13:47)

Смотреть раздел "Интересное о себе":
http://www.delphimaster.ru/cgi-bin/anketa.pl?id=997775670


 
MENfromUSA   (2004-07-25 14:02) [3]

Написал что-то такое... Навожу крысу на иконку - и она исчезает :) какие предложения?


 
MENfromUSA   (2004-07-25 14:11) [4]


> Смотреть раздел "Интересное о себе":

Посмотрел :) Да, очень интересно...

Моя проблема в том, как "удержать" иконку в трее, что нужно обрабатывать в ответ на действие с иконкой (типа там доблэклик, клик, наведение и т.п.???) Иконка вылетает и все... Может обрабатывать Shell_NotifyIcon(NIM_MODIFY, @NID)??? Это нужно делать во всех действиях с иконкой или нет?


 
Polevi ©   (2004-07-25 14:12) [5]

не туда засунул


 
VMcL ©   (2004-07-25 14:32) [6]

>>MENfromUSA  (25.07.04 14:02) [3]

>Написал что-то такое... Навожу крысу на иконку - и она исчезает :) какие предложения?

Это очень плохо. Надеюсь, ты это уже исправил.


 
Piter ©   (2004-07-25 17:18) [7]

Для работы с SysTray"ем (область где часики) в WinApi есть всего лишь одна функция - Shell_NotifyIcon. С помощью нее можно добавлять свои иконки в SysTray, модифицировать их и удалять.
Вот ее описание:

function Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL; stdcall;

Ее заголовок, а также определение типов TNotifyIconData, PNotifyIconData находится в юните shellapi.pas, который надо подключить для использования данной функции:
uses
ShellAPI;


Первый параметр dwMessage указывает, что вы хотите сделать: добавить иконку, удалить или модифицировать существующую.
Соответственно, может принимать такие значения:

NIM_ADD
NIM_DELETE
NIM_MODIFY

Следующий параметр lpData - это указатель на запись TNotifyIconData, которая описана так:
TNotifyIconData = record
   cbSize: DWORD;
   Wnd: HWND;
   uID: UINT;
   uFlags: UINT;
   uCallbackMessage: UINT;
   hIcon: HICON;
   szTip: array [0..63] of AnsiChar;
end;

cbSize - размер этой самой структуры TNotifyIconData. Легко вычисляется с помощью sizeof

Wnd - номер окна, которое будет принимать сообщения от иконки

uID - уникальный номер иконки в вашем приложении

uFlags - флаги, показывающие какие поля TNotifyIconData должны быть обработаны системой

uCallbackMessage - если в uFlags установлено NIF_MESSAGE, то uCallbackMessage указывает номер сообщения, которое будет послано окну под номером Wnd

hIcon - если в uFlags установлено NIF_ICON, то hIcon показывает номер иконки, которая будет будет отображаться в SysTray"е

szTip - если в uFlags установлено NIF_TIP, то szTip задает всплывающий текст, который отображается при наведении курсора мышки на иконку

Ну вот собственно и все, что нужно знать для того, чтобы "запуздырить" свою иконку в SysTray.
В программе где-то имеет смысл объявить глобальную переменную, например NID типа TNotifyIconData.
var NID: TNotifyIconData;
Глобально - потому что эта переменная понадобится, чтобы удалять иконку и модифицировать ее.
Осталось рассмотреть конкретную реализацию.

procedure TForm1.Button1Click(Sender: TObject);
begin
 NID.uID :=0;
 NID.Wnd := Handle;
 NID.uCallbackMessage :=WM_USER;
 NID.hIcon := LoadIcon(HINSTANCE,"ICON1");
 NID.szTip := "Моя иконка";
 NID.uFlags :=NIF_ICON or NIF_MESSAGE or NIF_TIP;
 NID.cbSize :=sizeof(NID);
 Shell_NotifyIcon(NIM_ADD,@NID);
end;


NID.uID :=0;
уникальный номер иконки в приложении. Если у вас несколько иконок в одном приложении, то это позволит вам их различать. У нас иконка одна, так что ставим что угодно. Например, ноль.

NID.Wnd := Handle;
Выбираем окно, которое будет обрабатывать сообщение от иконки. В моем тестовом приложении только одна форма, одно окно, его и выбираю.
Выбираемое окно должно иметь процедуру обработки сообщения.

NID.uCallbackMessage :=WM_USER;
Выбираем номер сообщения, которое будет послано нашему окну, как только с иконкой произведут какие-либо действия.
Для наших личных сообщений Microsoft рекомендует использовать номера от WM_USER до 0x7FFF. Выбираем WM_USER

NID.hIcon := LoadIcon(HINSTANCE,"ICON1");
Тут загружаем изображение, иконку, которая будет отображена в SysTtay. По этому пункту почему-то возникает много вопросов, типа "а как загрузить-то?".
Это, наверное, тема для очередного вопроса в FAQ, но кратко расскажу как можно. Запускаете "Tools->ImageEditor" и создаете новый "Resource File" или открываете существующий (только не главный ресурсный файл вашего приложения, типа project1.res).
Рисуете иконку под именем ICON1, сохраняете ресурсный файл под именем icon.res, кладете файл в каталог с программой.
В модуле формы, где используется LoadIcon, после {$R *.dfm} пишете {$R icon.RES}, после чего Delphi включит ресурсы вашего icon1.res в создаваемый exe файл. В том числе включит иконку ICON1.
После чего эту иконку можно загрузить как показано выше.

NID.szTip := "Моя иконка";
Просто задаете текст всплывающей подсказки. Так как объявлено:
szTip: array [0..63] of AnsiChar;
то соответственно, подсказка не должна быть длиннее 64 символов.

NID.uFlags :=NIF_ICON or NIF_MESSAGE or NIF_TIP;
задаются флаги, которые показывают, какие поля TNotifyIconData должны учитываться системой. Мы заполнили и hIcon, и uCallbackMessage, и szTip. Соответственно, пусть они все будут учитываться.

NID.cbSize :=sizeof(NID);
просто задается размер TNotifyIconData. Эта строчка всегда будет именно такой.

Shell_NotifyIcon(NIM_ADD,@NID);
собственно говоря, вызывается функция Shell_NotifyIcon с нужными параметрами (так как должен передаваться указатель на структуру, а не сама TNotifyIconData, то поэтому @NID, а не просто NID). Можно анализировать значение, возвращаемое функцией. True в случае успешного добавления иконки и False в случае неуспеха.

Созданную иконку можно удалить. Например, это следует делать при завершении приложения:

procedure TForm1.FormDestroy(Sender: TObject);
begin
 Shell_NotifyIcon(NIM_DELETE,@NID);
end;


Если вы хотите модифицировать текст всплывающей подсказки или отобразить другую иконку вместо прежней, то просто перезаполните нужное поле NID и вызывайте:

Shell_NotifyIcon(NIM_MODIFY,@NID);

Но это не все, иконку мы добавили, но ведь нужно как-то обрабатывать события, такие, например, как клик мышкой по иконке.
Именно для этого окно (на которое указывает параметр Wnd), которое будет получать события от иконки, должно иметь обработчик сообщений. Мы определили сообщение как WM_USER. Соответственно, добавим к нашей форме нужную процедуру:

procedure IconMessage (var Msg: TMessage); message wm_USER;

Теперь, при действиях с иконкой, соответствующие сообщения будут посылаться окну Wnd, что приведет к вызову нашей процедуры IconMessage и передаче ей структуры TMessage, полностью определяющей возникшее событие.
По параметру lParam можно судить о произошедшем действии, например:

WM_LBUTTONDOWN - клик левой кнопкой мышки по иконке
WM_RBUTTONDOWN - клик правой


 
Piter ©   (2004-07-25 17:19) [8]

WM_MOUSEMOVE - движение курсора мышки над иконкой

и так далее. Подробнее можно посмотреть во встроенной справке Windows SDK (файл WIN32S.HLP) в разделе "Mouse Input Messages".

В соответствии со сказанным реализуем нашу процедуру.
Например, мы хотим, чтобы при клике левой кнопкой по иконке выводился бокс с сообщением, а по клику правой кнопки хотим вывести существующее PopUp меню:

procedure TForm1.IconMessage(var Msg: TMessage);
var
 Pt: TPoint;
begin
case Msg.lParam of
 WM_LBUTTONDOWN : showmessage("По иконке кликнули левой кнопкой мыши!");
 WM_RBUTTONDOWN :
   begin
     GetCursorPos (Pt);
     PopupMenu1.Popup (Pt.x, Pt.y);
   end;
end;

end;


Ну и совсем напоследок хочу предупредить, что иконка автоматически удаляется как только окно Wnd, указанное в TNotifyIconData, удаляется из системы. При это возникает стандартный глюк, выражающийся в том, что иконка хоть и удалена, но она "висит" в SysTray, пока не получит сообщения, например, пока к ней не подведут мышку.
При этом удаление окна может произойти не только при закрытии приложения, а, например, при смене BorderStyle у формы, так как при этом окно уничтожается и создается заново, но с другими параметрами стиля.


 
parovoZZ ©   (2004-07-25 20:18) [9]

Добавить иконку в трей:

function AddTrayIcon (Window : THandle): Boolean;
begin
  TrayIcon.cbSize := SizeOf (TrayIcon);
  TrayIcon.Wnd := Window;
  TrayIcon.uID := 100;
  TrayIcon.uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
  TrayIcon.uCallbackMessage := WM_MYTRAYMSG;
  TrayIcon.hIcon := LoadIcon (hInstance, "MYHEARTS");
  TrayIcon.szTip := "Подсказка";
  TrayEnabled := Shell_NotifyIcon (NIM_ADD, @TrayIcon);
  Result := TrayEnabled;

end;

Убрать её оттуда:

procedure DeleteTrayIcon;
begin
 If TrayEnabled then Shell_NotifyIcon (NIM_DELETE,@TrayIcon);
end;



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.035 c
14-1093105357
Черный прапор
2004-08-21 20:22
2004.09.12
Сталкивались ли вы с переводом ресурсов (локализацией)


6-1088876071
alexa
2004-07-03 21:34
2004.09.12
Сокеты


6-1089282292
sapsi
2004-07-08 14:24
2004.09.12
Определение количества подключений на сервере сокетов


3-1092375802
REP
2004-08-13 09:43
2004.09.12
Не удается записать в TBlobField произвольный файл


1-1093573791
Ozone
2004-08-27 06:29
2004.09.12
MDI приложение





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский