Jak dodać ikonę do traya
HIHER
Są dwie rzeczy, które trzeba wziąć pod uwagę tworząc aplikację do tray'a. Pierwsza to ukrycie aplikacji przed Windows. Mimo, że aplikacje takie wyglądają i zachowują się jak zwykłe aplikacje Windows, nie można się na nie przełączyć przy użyciu Alt-Tab ani nie mają swojego przycisku na pasku zadań. Tym zajmiemy się najpierw.
Każde okno posiadające styl WS_EX_TOOLWINDOW ani nie ma przycisku na pasku zadań ani nie można się na nie przełączyć. Z początku może wydawać się właściwym ustawienie tego stylu przy użyciu CreateParams. Niestety nie zadziała to dla formy. Tu mała dygresja. Główna forma aplikacji nie jest oknem (w terminologii Windows) aplikacji. Obiekt aplikacji ma swoje własne okno - nie można go zobaczyć
ale ono tam jest. To jest właśnie to okno, do którego należy przypisać styl WS_EX_TOOLWINDOW. Gdzie więc należy wstawić kod? Oczywiście w źródle projektu. Po wybraniu View|Project Source należy skopiować poniższy kod:
program Project1;
uses
Forms, Unit1 in 'Unit1.pas' {Form1},
Windows;//To jest wymagane aby znana była stała WS_EX_TOOLWINDOW i pozostałe
{$R *.RES}
var
ExtendedStyle : Integer; //Deklaracja zmiennej do przyjęcia informacji o stylu okna
begin
Application.Initialize;
//Pobranie informacji o oknie aplikacji przy użyciu GetWindowLong
ExtendedStyle:=GetWindowLong(Application.Handle, GWL_EXSTYLE);
//Teraz ustawiamy styl rozszerzony przy użyciu operacji na bitach
//Przekształca to okno z okna-aplikacji do okna-narzędzia
SetWindowLong(Application.Handle,GWL_EXSTYLE,ExtendedStyle or WS_EX_TOOLWINDOW and
not WS_EX_APPWINDOW);
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
A teraz aby utworzyć właściwy efekt aplikacji w trayu będziemy potrzebowali przede wszystkim głównej formy aplikacji. Połóż na formie komponent TPopupMenu. Będzie to główny interfejs do naszej aplikacji. Popatrz na poniższy kod:
{ Poniższe umieszcza aplikację w trayu. Jest to główna forma aplikacji. Posiada ona menu popup używane do wyświetlenia formy i zamknięcia aplikacji. Używając modułu ShellApi w prosty sposób pokażemy ikonę aplikacji w trayu i spowodujemy aby reagowała na kliknięcia myszą }
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ShellAPI, ExtCtrls, Menus;
type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
ShowMainForm1: TMenuItem;
N1: TMenuItem;
ExitApplication1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure ShowMainForm1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ExitApplication1Click(Sender: TObject);
private
procedure WndProc(var Msg : TMessage); override;
public
IconNotifyData : TNotifyIconData;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
// Zostawiamy tylko przycisk zamykający okno
BorderIcons := [biSystemMenu];
// Teraz wypełniamy rekord IconNotifyData tak aby przyjmował
// komunikaty wysyłane do aplikacji i pokazywał dymki podpowiedzi.
with IconNotifyData do begin
hIcon:=Application.Icon.Handle;
uCallbackMessage:=WM_USER+1;
cbSize:=SizeOf(IconNotifyData);
Wnd:=Handle;
uID:=100;
uFlags:=NIF_MESSAGE+NIF_ICON+NIF_TIP;
end;
// Kopiujemy tytuł aplikacji jako ;dymek;
StrPCopy(IconNotifyData.szTip, Application.Title);
// Dodajemy ikonę do traya
Shell_NotifyIcon(NIM_ADD,@IconNotifyData);
end;
procedure TForm1.WndProc(var Msg : TMessage);
var
p : TPoint;
begin
if (Msg.Msg=WM_USER+1) and (Msg.lParam=WM_RBUTTONDOWN) then
begin
GetCursorPos(p);
PopupMenu1.Popup(p.x, p.y);
end; inherited;
end;
// To jedna z procedur obsługi elementów menu
procedure TForm1.ShowMainForm1Click(Sender: TObject);
begin
Form1.Show;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begn
Action := caNone;
Form1.Hide;
end;
procedure TForm1.ExitApplication1Click(Sender: TObject);
begin
Shell_NotifyIcon(NIM_DELETE, @IconNotifyData);
Application.ProcessMessages;
Application.Terminate;
end;
end.
Jak widać nie ma wiele do zrobienia. Ale ważne jest aby rozumieć co zrobiliśmy w metodzie Create i jakie znaczenie ma rekord IconNotifyData. Jest to rekord zdefiniowany w module ShellAPI, który przechowuje informację o ikonie w trayu. Zauważ flagi, których użyliśmy: NIF_MESSAGE + NIF_ICON + NIF_TIP. Oznaczają one kolejno: obsługę komunikatów dla aplikacji, pokazywanie ikony aplikacji i pokazywanie dymku z podpowiedzią.
Następna sprawa to nadpisanie procedury WndProc (skrót od WindowProcedure). Dostaje ona wszystkie komunikaty przesyłane do okna i zachowuje się jak centralna rozdzielnia komunikatów. Można przejąć obsługę komunikatu pisząc własną jego obsługę i wywołując odziedziczoną procedurę. Przy obsłudze komunikatu sprawdzamy czy jest to nasz własny (wm_User+1) zdefiniowany w zmiennej IconNotifyData oraz czy nastąpiło
kliknięcie prawym przyciskiem myszy. Pozostałe komunikaty przesyłamy bez zmian.[...]
Mi wyskakuje seria błędów! Połowę kodu zaznacza na czerwono!
nie wiem co się dzieje ale nie wyświetla mi popupmenu, reszta śmiga dobrze.
Delphi 2006 ma wbudowany komponent do tego (coś jak w Builderze), jak macie możliwość żeby go użyć to polecam, jest dużo wygodniejszy :)
Wszystko fajnie, tylko nie usuwa aplikacji z ALT+TAB, jak zrobic zeby usuwalo??
Shell_NotifyIcon(NIM_DELETE,@icon);
Witam wszystkich.
Powiedzcie mi jak mogę usunąć ikonkę z tray'a.
Dzięki..
TEN SAM ART :) <url> http://www.delphi.qs.pl/faq1.php3#12</url> :)
czesc jest taki kod
procedure TForm1.WndProc(var Msg : TMessage);
i mam pytanie gdzie go doda??
Nie chce pisać na temat tego ArtuMam zasadnicze pytanie jak dodać pogram do treja który nie zawiera Formy bo jak wiadomo program skompilowany bez bibliotek alboz samym WINDOWS zajmuje jakieś 16 Kb w Delphi 7
Żeby menu znikało po kliknięciu np. na pulpicie trzeba przed pokazaniem menu (w funkcji WndProc) wywołać funkcję SetForegroundWindow(Handle):
if (Msg.Msg=WM_USER+1)and(Msg.lParam=WM_RBUTTONDOWN) then
begin
SetForegroundWindow(Handle)
GetCursorPos(p);
......
Ten tekst widziałem już w wielu faqach (identyczny), ale niestety to rozwiązanie jest złe!
Popup nie znika jesli klikniemy na pulpit, a powinien.
no dobra, niby dziala ale teraz pisze ze file not found *.dcu .........
gdzie ja mam wstawci pierwsza czesc kodu??>
nie mam czegos takiego jak view|source code
mam wstawic do Unit1.pas??
wstawilem tylko 2 czesc, dziala ale nie wyswietla mojego popupmenu, jak zrobic zeby wyswietlało?
gdzie ja mam wstawci pierwsza czesc kodu??>
nie mam czegos takiego jak view|source code
mam wstawic do Unit1.pas??
wstawilem tylko 2 czesc, dziala ale nie wyswietla mojego popupmenu, jak zrobic zeby wyswietlało?
Ah tu był mój komentarz ale już go niema bo źle zrozumiałem intecje pop. autrów komentarzy :) czyli ten art był przeniesiony?
nie, to się raczej nadaje do FAQ :) A chyba nawet tam jest coś podobnego...
Ludzie, to sie nadaje do dzialu Gotowce, a nie tutaj!!!