Delphi: Systemweiter HotKey
Tutorial von Stefan Trost | Letztes Update am 21.06.2021 | Erstellt am 04.11.2013
In diesem Tutorial möchte ich zeigen, wie man für seine Delphi Anwendung einen systemweiten HotKey registrieren kann (für eine Lazarus-Lösung bitte unten in den Kommentar schauen). Das bedeutet, dass das Programm eine Nachricht über das Drücken einer bestimmten Tastenkombination bekommt, selbst wenn das Programm nicht den Fokus hat.
Eine typische Anwendung wäre ein Programm, das lediglich ein Icon im SysTray von Windows hat und das mit einer eindeutigen Tastenkombination (zum Beispiel STRG + ALT + X) hervorgeholt werden kann.
Normalerweise kann nur das Programm einen Tastendruck empfangen, wenn dieses aktuell den Fokus hat. Soll das Programm auch auf Ereignisse reagieren, wenn eigentlich gerade ein anderes Programm bedient wird, brauchen wir daher einen Workaround.
Diese kann zum Beispiel so aussehen, dass wir die Taste oder Tastenkombination als HotKey bei Windows registrieren. Wird diese Kombination dann gedrückt, weiß Windows Bescheid und schickt unserem Programm eine Nachricht darüber, dass die Taste gedrückt wurde.
Wie man sich denken kann erwächst eine Schwierigkeit daraus, dass wir eine eindeutige Tastenkombination benötigen. Versuchen wir eine Tastenkombination zu registrieren, die schon von einem anderen Programm verwendet wird, wird dies nicht funktionieren. Auch sollten wir keine Tasten oder Kombinationen belegen, die man in einem anderen Programm noch benötigt.
Schauen wir uns aber zunächst an, wie wir einen solchen HotKey registrieren können.
ID unseres Hot Keys
Zunächst benötigt jeder unserer HotKeys, die wir registrieren möchte eine eindeutige ID, um diesen auch später wieder zuerkennen. Wir deklarieren dazu eine beliebige Integer-Variable im "private"-Bereich unserer Unit:
private { Private declarations } HotKeyID: Integer; HotKeyIDFunctionA, HotKeyIDFunctionB: Integer; HotKeyIDPrintKey: Integer;
Für jeden HotKey, den wir registrieren möchten, brauchen wir eine eigene Variable. Wollen wir nur einen Hot Key anlegen, reicht die Variable "HotKeyID", bei mehreren sollten wir den Namen der Funktionalität oder der gedrückten Taste hinterlegen, damit wir nicht später durcheinander kommen.
Hot Key registrieren
Als nächstes kümmern wir uns darum, dass unsere Hot Keys beim Starten des Programms bei Windows registriert werden. Den Code dazu schreiben wir in das OnCreate unserer Form.
Die Registrierung läuft immer gleich ab. Zunächst lassen wir mit der Funktion GlobalAddAtom von Windows eine eindeutige ID generieren, die wir dann in unserer HotKeyID-Variable speichern (denn die brauchen wir später wieder). Statt die Funktion GlobalAddAtom zu benutzen, könnten wir genauso einen beliebigen Integer-Wert wie "1" oder "2" benutzen. Das sollten wir aber lieber bleiben lassen, da es durchaus sein kann, dass diese Werte schon von anderen Programmen verwendet werden.
Nachdem wir unsere eindeutige ID von Windows bekommen haben, benutzen wir die Funktion RegisterHotKey, um unseren HotKey zu registrieren. Wir übergeben dazu das Handle unseres Programms (damit weiß Windows an wen beim Drücken der Tastenkombination zu senden ist), die ID und anschließend die Tastenkombination, die wir registrieren möchten.
procedure TForm1.FormCreate(Sender: TObject); const VK_A = $41; begin // HotKey STRG + F1 HotKeyID := GlobalAddAtom('HotKey1'); RegisterHotKey(Handle, HotKeyID, MOD_CONTROL, VK_F1); // HotKey ALT + SHIFT + A HotKeyIDFunctionA := GlobalAddAtom('HotKey2'); RegisterHotKey(Handle, HotKeyIDFunctionA, MOD_ALT + MOD_SHIFT, VK_A); // HotKey Windows-Taste + A HotKeyIDFunctionB := GlobalAddAtom('HotKey3'); RegisterHotKey(Handle, HotKeyIDFunctionA, MOD_WIN, VK_A); // HotKey Druck Taste HotKeyIDPrintKey := GlobalAddAtom('HotKey4'); RegisterHotKey(Handle, HotKeyIDPrintKey, 0, VK_SNAPSHOT); end;
Die Tastenkombination wird in 2 Parametern übergeben. Mit dem ersten Parameter lassen sich die Tasten ALT, STRG, SHIFT oder die Windows-Taste registrieren. Diese Tasten können mit den Konstanten MOD_ALT, MOD_CONTROL, MOD_SHIFT und MOD_WIN angegeben werden, die die Werte 1, 2, 4 und 8 haben. Sollen mehrere dieser Tasten gleichzeitig gedrückt werden, addiert man entsprechend die Werte. Also zum Beispiel MOD_ALT + MOD_CONTROL (1+2) für das gleichzeitige Drücken von ALT und STRG (ALT + SHIFT + A im Beispiel). Übergibt man eine 0, zählt nur der zweite Parameter als HotKey (Druck-Taste im Beispiel).
Der zweite Parameter ist der virtuelle Key Code der weiteren Taste. Also zum Beispiel VK_SNAPSHOT für die Druck-Taste, VK_F1 für F1 oder $41 für den Buchstaben A.
Die Funktion RegisterHotKey gibt false zurück, wenn die Registrierung fehlgeschlagen ist. Bei Bedarf kann man das noch an dieser Stelle abfangen.
Hot Key Registrierung löschen
Wird unser Programm geschlossen, sollten wir dafür sorgen, dass unsere registrierten HotKeys auch wieder aus dem System gelöscht werden.
procedure TForm1.FormDestroy(Sender: TObject); begin UnRegisterHotKey(Handle, HotKeyID); GlobalDeleteAtom(HotKeyID); UnRegisterHotKey(Handle, HotKeyIDFunctionA); GlobalDeleteAtom(HotKeyIDFunctionA); UnRegisterHotKey(Handle, HotKeyIDFunctionB); GlobalDeleteAtom(HotKeyIDFunctionB); UnRegisterHotKey(Handle, HotKeyIDPrintKey); GlobalDeleteAtom(HotKeyIDPrintKey); end;
Dazu rufen wir die Funktionen UnRegisterHotKey und GlobalDeleteAtom auf und übergeben entsprechend das Programm-Handle und all unsere IDs die wir zu Anfang registriert haben.
Im Programm auf HotKey reagieren
Zuletzt kommen wir zu dem wichtigsten Teil. Bislang haben wir unseren Hot Keys eindeutige IDs gegeben und sie registriert, jedoch reagiert unser Programm bisher noch nicht darauf.
Um auf einen registrierten HotKey reagieren zu können, müssen wir die Windows Message empfangen, die uns Windows an unserer Anwendung schickt, wenn eine entsprechend registrierte Tastenkombination gedrückt wurde.
Dazu deklarieren wir im private Bereich unserer Unit die Funktion WMHotKey:
private { Private declarations } procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
Der Code dieser Funktion könnte dann so aussehen:
procedure TForm1.WMHotKey(var Msg: TWMHotKey); begin if Msg.HotKey = HotKeyID then ShowMessage('STRG + F1'); if Msg.HotKey = HotKeyIDFunctionA then ShowMessage('ALT + SHIFT + A'); if Msg.HotKey = HotKeyIDFunctionB then ShowMessage('WIN + A'); if Msg.HotKey = HotKeyIDPrintKey then ShowMessage('PRINT KEY'); end;
In Msg.HotKey steht die ID des HotKeys, der die Funktion aufgerufen hat. Das heißt, wir müssen nur noch abfragen, welche unserer IDs in Msg.HotKey steht und können dann entsprechend darauf reagieren.
In diesem Beispiel geben wir nur mit ShowMessage() eine Nachricht aus, aber es wäre natürlich auch einen Aufruf jeder anderen Funktion oder eines anderen Programmcodes möglich.
Über den Autor
Software von Stefan Trost finden Sie auf sttmedia.de. Benötigen Sie eine individuelle Software nach Ihren eigenen Wünschen? Schreiben Sie uns: sttmedia.de/kontakt
Profil anzeigen
Ähnliche Themen
Tastenkombination um Dateien zu drucken
Tutorial | 0 Kommentare
Tastenkombination um eine Reihe von Dateien zu kopieren
Tutorial | 0 Kommentare
Delphi: Globale Behandlung von Fehlermeldungen (Exceptions)
Tutorial | 0 Kommentare
Delphi/Lazarus: Link zu einer Website in einer Anwendung setzen
Tutorial | 0 Kommentare
Delphi/Lazarus: 3 Wege um eine Zahl auf X Nachkommastellen zu runden
Tutorial | 0 Kommentare
Delphi: Mehrzeilige Caption für TLabel (zur Laufzeit und Design Zeit)
Tutorial | 1 Kommentar
Delphi/Lazarus: Kommandozeilen Parameter Tutorial Teil 1: Senden
Tutorial | 0 Kommentare
Wichtiger Hinweis
Bitte beachten Sie: Die Beiträge auf askingbox.de sind Beiträge von Nutzern und sollen keine professionelle Beratung ersetzen. Sie werden nicht von Unabhängigen geprüft und spiegeln nicht zwingend die Meinung von askingbox.de wieder. Mehr erfahren.
Jetzt mitmachen
Stellen Sie Ihre eigene Frage oder schreiben Sie Ihren eigenen Artikel auf askingbox.de. So gehts.
Wer dieses Tutorial mit Lazarus umsetzen möchte, wird auf die Fehlermeldung stoßen, dass TWMHotKey nicht definiert ist:
Um es dennoch zum laufen zu bekommen, müssen wir TWMHotKey
durch TMessage ersetzen:
TMessage enthält nicht die Eigenschaft "HotKey", stattdessen nehmen wir "wParam":
Nicht vergessen: Die Unit Windows muss zur USES Section hinzugefügt werden.
So funktioniert es auch mit Lazarus unter Windows einen systemweiten Hotkey zu registrieren.
16.08.2014 um 09:22
Und wenn als 2te Taste "<" oder "." verwendet werden möchte, wie stelle ich dann die VK_ ein?
21.06.2021 um 14:14
Nicht jedes Zeichen ist auch als VK_-Konstante definiert.
Du kannst aber ord() verwenden, um auf die Codes zu kommen:
Wenn du die Werte so ermittelt hast, kannst du die Konstanten natürlich auch gleich selber definieren um die Konstanten dann zu verwenden:
Analog ist dies natürlich auch für andere Tasten möglich.
Darüber hinaus kannst du dir in Lazarus auch die Unit LCLType ansehen, darin siehst du um Zeile 400 bis 500 herum alle vordefinierten Konstanten, die du verwenden kannst ohne sie selbst zu definieren.
21.06.2021 um 16:03