Gestern habe ich eine Situation entdeckt, in der ein Tastatur-ShortCut nicht ausgelöst wurde, als ich es erwartet hatte.
Die spezifische Situation war: Ich drückte die ShortCut-Tastenkombination für eine Aktion einer ActionList auf einem MDI-Kind, während eine Seitenleiste auf dem MDI-Formular fokussiert wurde.
Ich hatte immer den Eindruck, dass ShortCuts global funktionieren würden. Unter welchen Umständen feuern oder schießen sie nicht?
Das ist eine täuschend einfache Frage mit einer überraschend langen Antwort. Zuerst werde ich mich mit einigen Grundlagen befassen und dann dem ShortCut durch den VCL Code folgen, um schließlich - ich hoffe - eine befriedigende Schlussfolgerung zu erhalten.
Ein ShortCut repräsentiert eine spezielle Tastaturkombination aus einer oder mehreren Tasten, die eine Operation verursachen. Spezial bedeutet speziell für den Programmierer, der der spezifischen Tastenkombination Bedeutung verleiht.
In Delphi hat ein ShortCut den Typ TShortCut
, der innerhalb des Bereichs Word
(0..65535) als ganze Zahl deklariert ist. Ein ShortCut besteht oft aus mehreren Schlüsseln, z. B .:
STRG + K = scCtrl
+ Ord('K')
= 16384
+ 75
= 16459
.
ShortCuts können der Eigenschaft ShortCut
oder SecondaryShortCuts
einer Aktion oder der ShortCut
-Eigenschaft eines MenuItems zugewiesen werden, wodurch das OnExecute
-Ereignis der Aktion oder das OnClick
-Ereignis des MenuItems aufgerufen wird, wenn die ShortCut-Tastaturkombination verwendet wird ist gedrückt.
Damit ShortCut einer Aktion verarbeitet werden kann, muss die Aktion aktiviert und einer nicht angehaltenen Aktionsliste hinzugefügt oder an ein aktiviertes Menüelement angehängt sein. Damit ShortCut eines MenuItems verarbeitet werden kann, muss das MenuItem einem Menü hinzugefügt werden.
ShortCuts können auch aus der Anwendung , a OnShortCut
event. Innerhalb dieser Ereignisse enthält der Parameter Msg
den Schlüsselcode in seinem CharCode
-Member und möglicherweise spezielle Schlüssel wie Shift , Strg oder Alt kann extrahiert werden mit GetKeyState
:
Wenn der Parameter Handled
auf True
gesetzt ist, wird jede nachfolgende Verarbeitung für den Schlüssel übersprungen.
Die VCL führt keine Liste aller angegebenen ShortCuts. (Wie könnte es?). Daher könnten alle Tastenanschläge möglicherweise ein ShortCut sein. Und genau so interpretiert die VCL ShortCuts: durch Auswertung jeder gedrückten Taste.
Peter Below schrieb einen ausgezeichneten und umfassenden Artikel, der sich mit A Key's Odyssey durch die VCL beschäftigt. Kurz gesagt, ein ShortCut wird wie folgt eingefangen:
TApplication.Run
nimmt jede Windows-Nachricht auf, die an die Anwendung gesendet wird, TApplication.ProcessMessage
ruft IsKeyMsg
auf, die die Nachricht - wenn eine Nachricht WM_KEYDOWN
- an den Nachrichtenhandler CN_KEYDOWN
des fokussierten Steuerelements weiterleitet. TWinControl.CNKeyDown
prüft, ob der Schlüssel ein Menütaste ist (die Definition dieses Menüs liegt außerhalb eines physischen Menüs):
TWinControl.IsMenuKey
prüft zuerst, ob der Schlüssel ein ShortCut innerhalb des Controls oder eines seiner PopupMenu TMenu.IsShortCut
1) durchquert all seine (Unter-) Menüeinträge und ruft den OnClick
-Ereignishandler des aktivierten MenuItems mit dem ShortCut (falls vorhanden) TCustomForm.IsShortCut
2) ,
OnShortCut
-Ereignis des Formulars heißt, falls zugewiesen, FActionLists
. Das wurde als Fehler angesehen und ab BDS2006 wurde das Feld eliminiert und die ActionLists konnten indirekt sein gehört auch dem Formular.
TCustomActionList.IsShortCut
durchläuft alle Aktionen und ruft HandleShortCut
der aktivierten Aktion auf wenn der ShortCut in seiner Eigenschaft ShortCut
oder SecondaryShortCuts
gesetzt ist, falls vorhanden, Application.IsShortCut
wird aufgerufen (via CM_APPKEYDOWN
),
OnShortCut
-Ereignis der Anwendung wird ausgelöst, einschließlich OnShortCut
-Ereignissen aller ApplicationEvents-Komponenten das Projekt, falls vorhanden, IsShortCut
der MainForm (siehe 2) aufgerufen, aber nur, wenn die MainForm aktiviert ist . Z.B. Wenn das aktive Formular ein modales Formular ist, wird das MainForm deaktiviert. Dadurch wird das OnShortCut
-Ereignis der MainForm ausgelöst oder es werden alle ActionLists der MainForm (abhängig von der Delphi-Version wie oben erwähnt) Wenn es ist:
OnShortCut
-Ereignis des gerade aktiven Formulars oder der MainForm eingefangen, aber nur, wenn MainForm aktiviert ist, OnShortCut
-Ereignis des Applicaton oder einer beliebigen ApplicationEvents-Komponente erfasst. Wenn es eingestellt ist für:
Tags und Links delphi keyboard-shortcuts vcl