Розміщення значка додатка в system tray - статті

Часто програмістові доводиться стикатися із завданням написання додатка, що працює у фоновому режимі і не потребує місці на панелі завдань. Якщо ви подивіться на правий нижній кут робочого столу Windows, то напевно знайдете там додатки, для яких ця проблема вирішена: годинник, перемикач розкладок клавіатури, регулятор гучності і т. П. Ясно, що, як би ви не збільшували і не зменшували форми свого додатки, потрапити туди звичайним шляхом не вдасться. Спосіб для цього надає Shell API.

Ті картинки, які знаходяться на System Tray - це дійсно просто картинки, а не укладені вікна. Вони управляються і розташовуються панеллю System Tray. Вона ж бере на себе ще дві функції: показ підказки для кожного із значків і оповіщення додатки, який створив значок, про всі переміщення миші над ним.

Весь API System Tray складається з 1 (однієї) функції:

Параметр dwMessage визначає одну з операцій: NIM_ADD означає додавання значка в область, NIM_DELETE - видалення, NIM_MODIFY - зміна.

Хід операції залежить від того, які поля структури TNotifyiconData будуть заповнені. Обов'язковою для заповнення є поле cbsize - там міститься розмір структури. Поле wnd повинно містити дескриптор вікна, яке буде сповіщена про події, пов'язаних із позначкою. Ідентифікатор повідомлення Windows, яке ви хочете отримувати від системи про переміщення миші над позначкою, запишіть в полі uCallbackMessage. Якщо ви хочете, щоб при цих переміщеннях над вашим значком показувалася підказка, то задайте її текст в поле szTip. В поле UID задається номер значка - кожне застосування може помістити на System Tray скільки завгодно значків. Подальші операції ви будете робити, ставлячи це номер. Дескриптор розміщується значка повинен бути заданий в полі hIcon. Тут ви можете задати значок, пов'язаний з вашим додатком, або завантажити свій - з ресурсів.

Примітка. Змінити головний значок програми можна в діалоговому вікні Project / Options на сторінці Application. Він буде доступний через властивість Application.Icon. Тут же можна відредагувати і рядок для підказки - властивість Application.Title.

Нарешті, в поле uFlags ви повинні повідомити системі, що саме ви від неї хочете, або, іншими словами, які з полів hicon, uCaiibackMessage і szTip ви насправді заповнили. У цьому полі передбачена комбінація трьох прапорів: NIF_ICON, NIF_MESSAGE і NIF_TIP. Ви можете заповнити, скажімо, поле szTip, але якщо ви при цьому не встановили прапор NIF_TIP, створений вами значок не матиме рядка з підказкою.

Два наведених нижче методу ілюструють сказане. Перший з них створює значок на System Tray, а другий - знищує його.

Примітка: нe забувайте знищувати створені вами значки на System Tray. Це не робиться автоматично навіть при закритті програми. Значок буде видалений тільки після перезавантаження системи. Зовнішній вигляд значка, поміщеного нами на System Tray, нічим не відрізняється від значків інших додатків.

Повідомлення, що задається в поле uCallbackMessage, по суті справи є єдиною ниточкою, що зв'язує вас із позначкою після його створення. Воно об'єднує в собі кілька повідомлень. Коли до вас прийшло таке повідомлення (у прикладі, розглянутому вище, воно має ідентифікатор WM_MYTRAYNOTIFY), поля в переданій в обробник структурі типу TMessage розподілені так. Параметр wParam містить номер значка (той самий, що задавався в полі uID при його створенні), а параметр LParam - ідентифікатор повідомлення від миші, на кшталт WM_MOUSEMOVE, WM_LBUTTONDOWN і т. П. На жаль, інша інформація з цих повідомлень втрачається. Координати миші в момент події доведеться дізнатися, викликавши функцію API GetCursorPos:

Зверніть увагу, що при показі спливаючого меню недостатньо просто викликати метод Popup. При цьому потрібно винести головну форму додатку на передній план, в іншому випадку вона не отримає повідомлень від меню.

Тепер вирішимо ще два завдання. По-перше, як зробити, щоб додаток мінімізувався нема на Панель завдань (TaskBar), а на System Tray? І більш того - як відразу запустити його в мінімізованому вигляді, а показувати головну форму тільки після настання певної події (приходу пошти, настанню певного часу і т. П.).

Відповідь на перше запитання очевидна. Якщо мінімізувати не тільки вікно головної форми додатка (Application.MainForm.Handle), але і вікно програми (Application.Handle), то додаток повністю зникне "з екранів радарів". У цей самий момент потрібно створити значок на панелі System Tray. У його спливаючому меню повинен бути пункт, при виборі якого обидва вікна відновлюються, а значок видаляється.

Щоб додаток запустилось відразу в мінімізованому вигляді і без головної форми, слід до вищесказаного додати установку властивості Application.showMainForm в значення False. Тут виникає одна складність - якщо головна форма створювалася в невидимому стані, її компоненти будуть також створені невидимими. Тому при першому її показі встановимо їх властивість visible в значення True. Щоб не повторювати це двічі, встановимо прапор - глобальну змінну shownonce: