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

 

 Copyright © 2000 PTiK. Wszystkie prawa zastrze┐one.
 Kopiowanie tekst≤w w ca│o╢ci lub we fragmentach bez zgody redakcji i autor≤w zabronione.