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
|