|
Ikona na tacy systemowej w Delphi
Uwaga jeśli w tekscie wystąpi np.
Jakiś tekst (->)
(->) inny tekst
oznacza to, że te linie znajdują się w jednym we4rsie, tylko ze względy
na szerokość magazynu musiały zostać podzielone...
Teoria
Taca systemowa (inaczej Windows Tray) to niewielki prostokątny obszar w
prawym dolnym rogu ekranu (znajduje się tam zegar systemowy i kilka ikonek - głośniczek
i coś jeszcze). W tym artykule opiszę jak umieścić tam ikonę własnego
programu, jak sprawić aby program nie miał szufladki na pasku zadań i jak obsługiwać
komunikaty od ikonki. Wszystko będę popierał kodem w Delphi 5.0, ale będzie
chodziło też na wcześniejszych wersjach i po pewnych poprawkach w C++
Builderze.
Program (czyt. jego szkielet), który przy okazji powstanie to Podręcznik
programisty, czyli zestaw okien (mojego autorstwa) pomagający w tworzeniu
programów.
Czarna robota
A więc tworzymy nowy projekt aplikacji i zapisujemy go jako pp.dpr
(najlepiej w specjalnie do tego utworzonym katalogu pp). Zapisujemy także
unit1.pas .
Najpierw należy sprawić, aby w czasie uruchamiania aplikacji nie pojawiało
się jej główne okno i żeby nie pojawiała się szufladka na pasku zadań. W
tym miejscu namawiam do nietestowania naszej aplikacji, zanim ją dokończymi,
gdyż mniej doświadczeni będą mieli problemy z zamknięciem niewidocznej
aplikacji.
Aby okno się nie pojawiło należy umieścić następującą linię w kodzie
pliku pp.dpr (między wywołaniami funkcji Initialize i CreateForm):
Application.ShowMainForm:=false;
To powinno załatwić sprawę. Jednak we wczesniejszych wersjach należy umieścić
zamiast jednej linii cały kod:
w sekcji var:
StylOkna : Integer;
między Initialize i CreateForm:
StylOkna:=GetWindowLong(Application.Handle,GWL_EXSTYLE);
SetWindowLong(Application.Handle,GWL_EXSTYLE, (->)
(->)StylOkna or WS_EX_TOOLWINDOW and not WS_EXE_APPWINDOW);
Musimy wywołać te funkcje ponieważ w Delphi główna forma aplikacji nie
jest właściwym oknem aplikacji. To okno jest wykorzystywane przez obiekt
Application i my nie mamy do niego dostępu. Nie widzimy go również, gdyż ma
szerokość i wysokość równą 0.
Gdy pojawianie okna mamy już z głowy przystępujemy do umieszczenia ikonki
w Tray'u. Zrobimy to oczywiście w konstruktorze formy. Przedtem jednak
zmieniamy nazwę Form1 na MainForm (tak dla jaj). Klikamy dwukrotnie na formie i
jesteśmy w środku zdarzenia FormCreate.
Do umieszczenia ikonki będzie nam potrzebna funkcja API o nazwie
Shell_NotifyIcon z modułu ShellApi (należy go dodać w sekcji uses). Ikona
jaka umiescimy na tacy będzie zarazrem ikona aplikacji (Możesz ją w tym
momencie zmienić na dowolną).
Na potrzeby tej funkcji deklarujemy sobie też zmienna globalną typu
TNotifyIconData:
IkonaNaTacy : TNotifyIconData;
Ma ona następującą strukturę:
TNotifyIconData = record
cbSize : DWORD;
- to rozmiar tego rekordu = sizeof(TNotifyIconData)
Wnd : HWND;
- to uchwyt okna, do którego będzie kierowany komunikat ikony
uID : UINT;
- to identyfikator ikony w przypadku, gdy aplikacji ma wiecej ikon na tacy
uFlags : UINT;
- flagi określające, które z nastepnych pól będą wypełnione, może być
kombinacją flag NIF_ADD,
NIF_MESSAGE, NIF_TIP
uCallbackMessage : UINT;
- identyfikator komunikatu ikony
hIcon : HICON;
- uchwyt do obrazka ikony
szTip : array[0..63] of AnsiChar; - podpowiedź
wysuwająca sie gdy myszka wejdzie w obszar ikony
end;
Musimy również zadeklarować stałą globalną, która będzie
identyfikatorem komunikatu wysyłanego przez naszą ikonę (gdy użytkownik na
nią kliknie).
const WM_IKONANATACY = WM_USER + 1;
Teraz możemy przystąpić do oprogramowania zdarzenia FormCreate. Umieszczmy
tam następujący kod:
with IkonaNaTacy do
begin
cbSize:=sizeof(TNotifyIconData);
Wnd:=Handle;
uId:=0;
uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP;
uCallBackMessage:=WM_IKONANATACY;
szTip:='Podręcznik programisty';
hIcon:=Application.Icon.Handle;
end;
Shell_NotifyIcon(NIM_ADD,@IkonaNaTacy);
Wyjaśnienia wymaga jeszcze funkcja Shell_NotifyIconData. Jako pierwszy
parametr przyjmuje ona stałą, która mówi co chcemy zrobić. Jesli jest to
NIM_ADD to chcemy wstawić ikonę, której dane wskazuje drugi parametr. Jeśli
jest to NIM_DELETE to usuwamy ikonkę (podając jako drugi parametr wskaźnik na
jakiś obiekt TNotifyIconData). Możemy też użyć flagi NIM_MODIFY aby zmienic
jakąś cechę już umieszczonej ikony.
Mamy więc umieszczoną ikonę na tacy. Teraz należy zadbać, aby była
usunięta, gdy aplikacja się zakończy. Robimy to w destruktorze formy
FormDestroy:
Shell_NotifyIcon(NIM_DELETE,@IkonaNaTacy);
Wszystko jest cacy! Ale chwileczkę - co nam da ikona na tacy, gdy nie mamy z
nią żadnego kontaktu. Oczywiście kontakt taki musimy utowrzyć. Załóżmy,
ze chcemy, aby gdy użytkownik podwójnie kliknie lewym przyciskiem myszy
pojawiała się MainForm, a gdy naciśnie prawy przycisk myszy aby wyskakiwało
menu kontekstowe. Do tego celu posłuży nam identyfikator komunikatu
WM_IKONANATACY. Tworzymy nową metodę klasy MainForm o prototypie:
procedure KOMUNIKAT_IKONANATACY(var Message : TMessage); (->)
(->)message WM_IKONANATACY;
i definicji:
procedure TMainForm.KOMUNIKAT_IKONANATACY (->)
(->)(var Message : TMessage);
var
Punkt : TPoint;
begin
case Message.LParam of
WM_LBUTTONDBLCLK:
MainForm.Show;
WM_RBUTTONDOWN:
begin
GetCursorPos(Punkt);
//pobiera współrzędne kursora myszy
MenuPodreczne.Popup(Punkt.x,Punkt.y);
//powoduje wyskoczenie menu
end;
end;
end;
Aby wszystko działało należy jeszcze położyć na formie komponent
TPopupMenu i nadac mu nazwę MenuPodreczne i dodac do niego własne pozycje.
Post Scriptum
Programy umieszczające się na tacy mogą być bardzo przydatne. Ja
wykorzystuję właściwie tylko dwa programy mające na tacy swoje ikonki -
jednym z nich jest skaner antywirusowy, a drugim mój własny - Podręcznik
programisty.
Mr Bin
delfisajt@poczta.onet.pl
www.polbox.com/t/tplsoft
|