Ein Icon in der Taskbar (Infobereich) anzeigen und bei Klick ein Popup-Menü anzeigen

In Windows gibt es rechts unten in der Taskbar den sogenannten System Tray oder Infobereich. Dort kann man ein Icon erstellen und dem Benutzer über Klick ein Menü anbieten, wie man es von diversen Programmen kennt die hauptsächlich im Hintergrund laufen (z.B. Virenscanner, usw.).

In Delphi ist dies auch relativ einfach möglich. Hier die dazu nötigen Schritte:

  • Erstelle eine neue VCL Formularanwendung und füge ein Popup-Menü hinzu
  • Füge ShellApi zu den uses-Bibliotheken hinzu und erstelle eine Konstante WM_TASKBAREVENT
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, Buttons, ComCtrls, Menus, ShellApi;

const
  WM_TASKABAREVENT = WM_USER + 1;
  • Erstelle die Events FormCreate und FormDestroy und füge folgenden Code ein:
procedure TForm1.FormCreate(Sender: TObject);
var
    NotifyIconData: TNotifyIconData;
begin

    Fillchar(NotifyIconData, Sizeof(NotifyIconData), 0);
    NotifyIconData.cbSize := Sizeof(NotifyIconData);
    NotifyIconData.Wnd := Handle;
    NotifyIconData.uFlags := NIF_MESSAGE
      or NIF_ICON
      or NIF_TIP;
    NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
    NotifyIconData.hIcon := Application.Icon.Handle;
    NotifyIconData.szTip := 'Mein Programm';
    Shell_NotifyIcon(NIM_ADD, @NotifyIconData);
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
    NotifyIconData: TNotifyIconData;
begin
    Fillchar(NotifyIconData, Sizeof(NotifyIconData), 0);
    NotifyIconData.cbSize := Sizeof(NotifyIconData);
    NotifyIconData.Wnd := self.Handle;
    NotifyIconData.uFlags := NIF_MESSAGE
      or NIF_ICON
      or NIF_TIP;
    NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
    NotifyIconData.hIcon := Application.Icon.Handle;
    NotifyIconData.szTip := 'Punkt';
    Shell_NotifyIcon(NIM_DELETE, @NotifyIconData);

end;
  • Deklariere eine private Prozedur TaskbarEvent und erstelle sie mit folgenden Code:
  private
    { Private-Deklarationen }
    procedure TaskbarEvent(var Msg: TMessage);
    Message WM_TASKABAREVENT;
procedure TForm1.TaskbarEvent(var Msg: TMessage);
var
    Point: TPoint;
begin
    case Msg.LParam of
        WM_LBUTTONDBLCLK:
            begin
                SetForegroundWindow(Handle);
                Form1.Show;
            end;
        WM_LBUTTONUP:
            begin
                SetForegroundWindow(Handle);
                GetCursorPos(Point);
                PopupMenu1.Popup(Point.x, Point.y);
            end;
    end;
end;

Wenn ihr das Projekt ausführt, sollte im Infobereich ein kleines Delphi-Icon erscheinen. Mit klick darauf erscheint das Popup-Menü. Jetzt könnt ihr die Form mit Form1.Hide verschwinden lassen, und über Doppel-Klick auf das Tray-Icon wird sie wieder angezeigt.

Ihr könnt das Icon ändern indem ihr unter Projekt -> Optionen -> Anwendung ein anders Symbol einstellt.

Hier nochmal der vollständige Code:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, Buttons, ComCtrls, Menus, ShellApi;

const
  WM_TASKABAREVENT = WM_USER + 1;
type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    est11: TMenuItem;
    est21: TMenuItem;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure TaskbarEvent(var Msg: TMessage);
    Message WM_TASKABAREVENT;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    form1.Hide;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
    NotifyIconData: TNotifyIconData;
begin

    Fillchar(NotifyIconData, Sizeof(NotifyIconData), 0);
    NotifyIconData.cbSize := Sizeof(NotifyIconData);
    NotifyIconData.Wnd := Handle;
    NotifyIconData.uFlags := NIF_MESSAGE
      or NIF_ICON
      or NIF_TIP;
    NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
    NotifyIconData.hIcon := Application.Icon.Handle;
    NotifyIconData.szTip := 'Mein Programm';
    Shell_NotifyIcon(NIM_ADD, @NotifyIconData);
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
    NotifyIconData: TNotifyIconData;
begin
    Fillchar(NotifyIconData, Sizeof(NotifyIconData), 0);
    NotifyIconData.cbSize := Sizeof(NotifyIconData);
    NotifyIconData.Wnd := self.Handle;
    NotifyIconData.uFlags := NIF_MESSAGE
      or NIF_ICON
      or NIF_TIP;
    NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
    NotifyIconData.hIcon := Application.Icon.Handle;
    NotifyIconData.szTip := 'Punkt';
    Shell_NotifyIcon(NIM_DELETE, @NotifyIconData);

end;

procedure TForm1.TaskbarEvent(var Msg: TMessage);
var
    Point: TPoint;
begin
    case Msg.LParam of
        WM_LBUTTONDBLCLK:
            begin
                SetForegroundWindow(Handle);
                Form1.Show;
            end;
        WM_LBUTTONUP:
            begin
                SetForegroundWindow(Handle);
                GetCursorPos(Point);
                PopupMenu1.Popup(Point.x, Point.y);
            end;
    end;
end;
end.