Autor Beitrag
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: Fr 07.03.03 14:09 
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:
ausblenden Delphi-Quelltext
1:
2:
uses
  ShellAPI;

Dann brauchen wir eine Variable vom Typ TNOTIFYICONDATA. Diese definieren wir in der Private-Sektion der Form:
ausblenden Delphi-Quelltext
1:
2:
private
  fIconData: TNOTIFYICONDATA;

Im OnCreate-Event der Form wird das Icon in die TNA hinzugefügt:
ausblenden 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
  // NotifyIconData-Struktur mit Werten füllen
  with fIconData do
    begin
      cbSize := SizeOf (TNOTIFYICONDATA);
      Wnd := Handle;
      uID := 1;
      uFlags := NIF_ICON + NIF_TIP;
      hIcon := LoadIcon (0, IDI_INFORMATION);
      szTip := 'Tooltip';
    end;

  // Icon in die TNA hinzufügen
  If not Shell_NotifyIcon (NIM_ADD, @fIconData) then
    { Fehler! };
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):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.FormDestroy(Sender: TObject);
begin
  // Icon aus der TNA entfernen
  if not Shell_NotifyIcon (NIM_DELETE, @fIconData) then
    { Fehler! };
end;

Möchten wir zum Beispiel das Icon und/oder den Tooltip ändern müssen wir wie folgt vorgehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.Button1Click(Sender: TObject);
begin
  // Erst die Änderungen in der NotifyIconData-Struktur vornehmen
  with fIconData do
    begin
      hIcon := LoadIcon (0, IDI_WARNING);
      szTip := 'Neuer Tooltip';
    end;

  // Dann die Änderungen in der TNA durchführen lassen
  if not Shell_NotifyIcon (NIM_MODIFY, @fIconData) then
    { Fehler! };
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:
ausblenden 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:
ausblenden Delphi-Quelltext
1:
2:
Private
  procedure TaskTrayWndProc (var Msg: TMessage); message cWM_MYTRAYICONCALLBACK;

Die Implementation dieser Procedure könnte wie folgt aussehen:
ausblenden 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:
ausblenden 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 user profile iconMartin1966 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.