Додавання іконки в SystemTray засобами Visual Basic (исходники), Різне, Програмування, статті

Ця стаття є самодостатньою, тобто в ній дана вичерпна інформація щодо створення іконки в SystemTray за допомогою VB. Однак при цьому вона є компіляцією загальнодоступних джерел, тобто заслуга автора полягає лише в зборі цієї інформації в одному місці і поясненнях.


Основи створення іконки викладені в FAQ Льва Серебрякова. Використовується приклад на VB від Alexander Shherbakov. Опис функцій і констант з книги Daniel Applemana і API.TXT. Питання пов’язані з редактором ресурсів не розглядаються.


Єдина функція для роботи з іконкою Shell_NotifyIcon. Її опис на VB виглядає так:


Declare Function Shell_NotifyIcon Lib “shell32.dll” Alias “Shell_NotifyIconA” _
(ByVal dwMessage As dwMess, lpData As NOTIFYICONDATA) As Long
Повертає нуль у разі помилки
Тип dwMess описується так:
Public Enum dwMess
NIM_ADD = & H0 “Додавання іконки
NIM_DELETE = & H2 “Видалення іконки
NIM_MODIFY = & H1 “Зміна параметрів іконки
End Enum
Мінлива dwMessage повинна мати одне з цих значень.
Тип NOTIFYICONDATA має наступну структуру:
Type NOTIFYICONDATA
cbSize As Long “Розмір змінної типу NOTIFYICONDATA
hwnd As Long “Покажчик вікна створює іконку
uID As Long “Покажчик на іконку в межах програми
uFlags As uF “Маска для наступних параметрів
uCallbackMessage As CallMess “Повертане подія
hIcon As Long “Покажчик на зображення для іконки
szTip As String * 64 “Спливаючий над іконкою текст
End Type


Де тип uF має вигляд:

Public Enum uF
NIF_MESSAGE = & H1 “Значення має uCallbackMessage NIF_ICON = & H2 “Значення має hIcon NIF_TIP = & H4 “Значення має szTip
End Enum

Ці константи можна застосовувати в будь-яких поєднаннях, для визначення який з параметрів має значення.
 
Тип CallMess:

Public Enum CallMess
WM_MOUSEMOVE = &H200
WM_LBUTTONDOWN = &H201
WM_LBUTTONUP = &H202
WM_LBUTTONDBLCLK = &H203
WM_RBUTTONDOWN = &H204
WM_RBUTTONUP = &H205
WM_RBUTTONDBLCLK = &H206
WM_MBUTTONDOWN = &H207
WM_MBUTTONUP = &H208
WM_MBUTTONDBLCLK = &H209
WM_SETFOCUS = &H7
WM_KEYDOWN = &H100
WM_KEYFIRST = &H100
WM_KEYLAST = &H108
WM_KEYUP = &H101
End Enum

Ці константи позначають, яка подія повертається зухвалій формі. Буквально, все, що відбуватиметься з іконкою, викликатиме у форми одне з перерахованих подій. Ясно, що найчастіше подія самої іконки це MouseMove, але для форми воно буде виглядати як подія заданий змінною uCallbackMessage. Як же дізнатися, що насправді сталося з іконою? Це можна дізнатися через змінні X і Y подій MouseMove, MouseDown і MouseUp викликає форми. При цьому Y, якщо подія сталася з іконкою, а не формою, завжди буде дорівнює нулю, а X несе інформацію про подію з іконкою.
 
Про параметрі X слід сказати окремо. Дійсно, він передає інформацію про події з іконкою, однак ці значення залежать від масштабного коефіцієнта системного шрифту, але не безпосередньо, а через параметр властивості TwipsPerPixelX об’єкта Screen. Тобто для однієї і тієї ж системи, при різних величинах системного шрифту, значення будуть різними. Початковими значеннями подій є наступні:


MouseMove ? 512
LeftButtonDown ? 513
LeftButtonUp – 514
LeftButtonDblClick – 515
RightButtonDown – 516
RightButtonUp ? 517
RightButtonDblClick – 518
 
Для того щоб дізнатися діючі в даній системі значення їх слід помножити на Screen.TwipsPerPixelX


Як же дізнатися, що подія сталася з іконкою, а не з формою? Просто, за значенням Y, рівному нулю. Але є й інший спосіб, якщо використовується двокнопочні миша то параметр Button в подіях MouseDown і MouseUp форми, буде приймати значення 1 і 2, і при uCallbackMessage одно WM_MBUTTONDOWN = & H207 або WM_MBUTTONUP = & H208 Button дорівнює 4, якщо подія з іконкою. Само собою зрозуміло, що повертаються X значення слідують одне за одним, як і події (Down-> Up-> DbClick), тому неможливо на одну кнопку миші призначити дві події, наприклад, Click і DbClick. Події не пов’язані з мишею не несуть практично ні якої інформації, і звичайно не використовуються, слід також відзначити, що кількість констант uCallbackMessage набагато більше і тут наведена лише невелика частина.


З описаного видно, що з іконкою можна зробити одну з таких дій: додати, модифікувати і видалити, при цьому, модифікуючи можна замінити повертається подія, картинку (покажчик при цьому залишиться тим же) і спливаючу напис (ToolTips).


Наступний момент, який потрібно висвітлити це отримання hIcon (покажчика на картинку). Передбачається, що іконка буде знаходиться в виконуваному файлі або в DLL з ресурсами, але ні в якому разі не валяється у вигляді ICO файлу. Якщо іконка запакована в DLL, то нам знадобляться дві функції:

Declare Function LoadLibrary Lib “kernel32” Alias “LoadLibraryA” (ByVal _
lpLibFileName As String) As Long

Повертає hInstance бібліотеки з ім’ям lpLibFileName. Досить вказати тільки ім’я файлу з розширенням, без шляху. Повертає нуль у разі помилки

Declare Function LoadIconA Lib “user32” (ByVal hInstance As Long, ByVal _
lpIconName As String) As Long

Повертає hIcon для іконки зазначеної параметром lpIconName в бібліотеці. Цей параметр може бути String або Long, залежно від даного вами найменування в Res файлі, відповідно треба змінити декларацію. Можна передати і число як рядок, для цього перед числом ставиться знак #, а все це береться в лапки. Слід зауважити, що використання строкового параметра не бажано із за значно більшого розміру займаної пам’яті і відповідно, більшого часу на передачу параметра. Функція повертає нуль у випадку помилки


Знадобиться також функція:

Declare Function FreeLibrary Lib “kernel32” (ByVal hLibModule As Long) As Long

Вивантажувати бібліотеки з пам’яті. Параметр hLibModule це hInstanse, що повертається LoadLibrary. Повертає нуль у разі помилки. Обов’язково треба не забути вивантажити з пам’яті бібліотеку, для звільнення пам’яті. Вивантаження можна зробити відразу ж після додавання іконки в SystemTray.

Declare Function GetModuleHandle Lib “kernel32” Alias “GetModuleHandleA” _
(ByVal lpModuleName As String) As Long

Повертає hInstanse нашого застосування. Як lpModuleName передається ім’я EXE файлу з розширенням. Слід бути уважним, тому що ім’я процесу в TaskMenager не завжди відповідає імені процесу для Windows. Я використовую для визначення імені DLLView, можна скористатися, вбудованим в VB System Information. Функція повертає дійсне значення тільки при роботі скомпільованого додатки, а в режимі налагодження повертає нуль, адже реального процесу при налагодженні не існує. Властивість hInstanse об’єкта App завжди повертає дійсне значення, проте при налагодженні із за відсутності процесу LoadIcon повертає 0, і створюється “порожня” іконка, тим не менш придатна для налагодження (реагує на всі події).


Отримане hInstanse передаємо LoadIconA, як lpIconName вказуємо номер або ім’я іконки в Res файлі, як і у випадку з DLL. Вивантажувати в цьому випадку нічого не треба.


Створення іконки можна проілюструвати наступним прикладом. Вважається, що іконка з номером 101 знаходиться у файлі Project1.exe. Зрозуміло, що поки ми його не скомпілювали, її там немає (та й самого файлу немає). Форма додатка називається Form1.

Dim NID As NOTIFYICONDATA
Sub AddIcon()
Dim IDLib As Long “Покажчик на бібліотеку Dim IDIcon As Long “Покажчик на іконку Const IDMyIcon = 101 “Ідентифікатор іконки всередині програми Dim AddResult As Long “Результат додавання іконки
IDLib = GetModuleHandle (“Project1.exe”) “Отримуємо hInstanse IDIcon = LoadIcon (IDLib, “# 101”) “Отримуємо hIcon
“Заповнюємо структуру NID типу NOTIFYICONDATA
NID.cbSize = Len (NID) “Розмір структури NID.hwnd = Form1.hWnd “Покажчик на форму NID.uID = IDMyIcon “Ідентифікатор іконки NID.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP “Зазначаємо, що чинними є поля “UCallBackMessage, hIcon і szTip. NID.uCallbackMessage = WM_LBUTTONDOWN “Зазначаємо, що подією повертається у форму “Є MouseDown з параметром Button = 2 NID.hIcon = IDIcon “Покажчик на іконку у файлі NID.szTip = Left $ (“MyIcon”, 63) & Chr (0) “Передаємо спливаючу фразу” MyIcon “, при цьому обрізаємо “Її до 63 символів і додаємо 64-й символ з кодом нуль AddResult = Shell_NotifyIcon (NIM_ADD, NID) “Викликаємо функцію, через параметр dwMessage вказуємо, “Що слід додати іконку, і передаємо заповнений NID
End Sub

Видалення створеної іконки можна зробити так:

Sub DeleteIcon()
Dim DeletResult As Long DeleteResult = Shell_NotifyIcon (NIM_DELETE, NID) “Викликаємо функцію, через dwMessage вказуємо, “Що слід видалити іконку, при цьому, раз мінлива NID описана на рівні модуля, не слід “Заповнювати її заново
End Sub

Розмір структури достатньо вказувати один раз, так як за час життя змінної він змінитися не може, і в даному виді становить 88 байт. Навіть при зміні спливаючій рядки її довжина (рядки) не буде більше 64 байт.


Для модифікації іконки треба викликати Shell_NotifyIcon з параметром dwMessage рівним NIM_MODIFY і NID із внесеними змінами, при цьому параметр uFlags буде вказувати, які з параметрів змінені.


У формі Form1 для обробки, наприклад, DbClick лівою кнопкою миші по іконці можна застосувати наступний код:

Private Sub Form_MouseDown(Button As Integer, Shift As Integer _ X As Single, Y As Single) “Подія MouseDown відбувається не тому,  “Що користувач натиснув на кнопку миші над іконкою, а через те,  “Що параметр uCallbackMessage має значення WM_LBUTTONDOWN
If Y = 0 Then “Y = 0 якщо подія з іконкою
Select Case X Case 515 * Screen.TwipsPerPixelX “Значення X при LeftDblClick “Код, що виконується в разі LeftDblClick
End Select
End If
End Sub

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*