Um mit Icons in der
TNA (TNA = Taskbar Notification Area)[meta]Icon neben Uhr, unten rechts[/meta] zu arbeiten benötigen wir die
Shell_NotifyIcon Funktion welche in der Unit
ShellAPI.pas importiert wird. Also nicht vergessen diese Unit in die Uses-Klausel aufzunehmen.
Die Funktion Shell_NotifyIcon erwartet zwei Paramter:
- Message:
Mit diesem Parameter legen wir fest was genau wir mit dem Aufruf von Shell_NotifyIcon bezwecken möchten. Mögliche Werte wären:
- NIM_ADD: Legt fest, das wir ein Icon in die TNA hinzuzufügen möchten.
- NIM_DELETE: Legt fest, dass wir ein Icon aus der TNA entfernen möchten.
- NIM_MODIFY: Legt fest, dass wir ein Icon und deren Eigenschaften ändern möhcten.
Es gibt noch zwei weitere Werte (NIM_SETFOCUS & NIM_SETVERSION) diese werden aber in unserem Beispiel nicht benötigt.
- Data:
Eine Pointer auf die TNOTIFYICONDATA-Struktur (Record). Diese Struktur enthält Informationen die benötigt werden um ein Icon in die TNA hinzuzufügen, zu ändern oder zu löschen.
Da es sich bei Shell_NotifyIcon um eine Funktion handelt bekommen wir natürlich auch ein Ergebnis zurück. Die Funktion liefert True wenn alles geklappt hat und False bei einem Fehler zurück.
Aufbau von TNOTIFYICONDATA:
- cbSize: Gibt die Größe der Struktur an
- Wnd: Das Fensterhandle welches die Message empfangen soll
- uID: Ein Wert um mehrere Icons von einander zu unterscheiden
- uFlags: Verschiede Flags die festlegen hinter welcher Variable gültige Werte angegeben sind:
- NIF_MESSAGE: uCallbackMessage hat einen gültigen Wert (erst dann ist es möglich Messages zu empfangen)
- NIF_ICON: hIcon verweisst auf ein gültiges Icon-Handel
- NIF_TIP: szTip ist gesetzt (erst dann ist der Tooltip zu sehen)
- uCallbackMessage: Message-Identifier
- hIcon: Handel auf ein Icon
- szTip: Tooltip (max 64 Zeichen)
Hier nur ein Beispiel wie man ein Icon in die TNA hinzufügt. Erstmal müssen wir die Unit ShellAPI einbinden:
Delphi-Quelltext
Dann brauchen wir eine Variable vom Typ TNOTIFYICONDATA. Diese definieren wir in der Private-Sektion der Form:
Delphi-Quelltext
1: 2:
| private fIconData: TNOTIFYICONDATA; |
Im OnCreate-Event der Form wird das Icon in die TNA hinzugefügt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure TForm1.FormCreate(Sender: TObject); begin with fIconData do begin cbSize := SizeOf (TNOTIFYICONDATA); Wnd := Handle; uID := 1; uFlags := NIF_ICON + NIF_TIP; hIcon := LoadIcon (0, IDI_INFORMATION); szTip := 'Tooltip'; end;
If not Shell_NotifyIcon (NIM_ADD, @fIconData) then ; end; |
Um das Icon zu entfernen muss statt NIM_ADD die Konstante NIM_DELETE benutzt werden (in unserem Beispiel wird das Icon im OnDestroy-Event der Form entfernt):
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TForm1.FormDestroy(Sender: TObject); begin if not Shell_NotifyIcon (NIM_DELETE, @fIconData) then ; end; |
Möchten wir zum Beispiel das Icon und/oder den Tooltip ändern müssen wir wie folgt vorgehen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.Button1Click(Sender: TObject); begin with fIconData do begin hIcon := LoadIcon (0, IDI_WARNING); szTip := 'Neuer Tooltip'; end;
if not Shell_NotifyIcon (NIM_MODIFY, @fIconData) then ; end; |
So, jetzt wissen wir bereits wie man Icons, hinzufügt, ändert und löscht. Aber es fehlt natürlich noch etwas. Wir müssen auf verschiedene Aktionen, die mit dem Icon vom User durchgeführt werden können, reagieren können. Windows verschickt bei jeder Aktion (klicken, doppelklick, etc) eine Message die wir dann auswerten müssen. Als erstes definieren wir eine neue Message-Konstante:
Delphi-Quelltext
1: 2:
| const cWM_MYTRAYICONCALLBACK = WM_USER + 1000; |
Dann müssen wir eine Procedure definieren die die Messages empfängt. Dazu definieren wir in der Private-Sektion der Form die Procedure:
Delphi-Quelltext
1: 2:
| Private procedure TaskTrayWndProc (var Msg: TMessage); message cWM_MYTRAYICONCALLBACK; |
Die Implementation dieser Procedure könnte wie folgt aussehen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.TaskTrayWndProc (var Msg: TMessage); begin case Msg.LParam of WM_LBUTTONDOWN: MessageDlg ('Linke Maustaste gedrückt!', mtInformation, [mbOK], 0); WM_RBUTTONDOWN: MessageDlg ('Rechte Maustaste gedrückt!', mtInformation, [mbOK], 0); end; end; |
Damit Windows jetzt auch weiß welche Message es verschicken muss müssen wir dies beim erstellen des Icons angeben. Deshalb ist folgende Änderung in dem OnCreate-Event notwendig:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| with IconData do begin cbSize := SizeOf (TNOTIFYICONDATA); Wnd := Handle; uID := 1; uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP; hIcon := LoadIcon (0, IDI_INFORMATION); szTip := 'Tooltip'; uCallBackMessage := cWM_MYTRAYICONCALLBACK; end; |
Sollte, aus welchen Gründen auch immer, der Explorer von Windows abstürzten und sich anschl. neu starten so sendet der Explorer die Windows Message
TaskbarCreated an alle Top-Level-Fenster damit diese dann, falls vorhanden, ihr Icon wieder in die TAN hinzufügen können. Ein Beispiel von
Martin1966 findest du
hier.
Solltest du an einer fertigen Komponente interessiert sein die all die hier genanten Funktionen (und noch viele weitere) schon fertig verpackt unterstützt so kann ich dir die
CoolTrayIcon Komponente von Troels Jakobsen empfehlen.