Wann feuert ein ShortCut?

8

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?

    
NGLN 22.11.2014, 22:29
quelle

1 Antwort

14

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.

Was ist ein ShortCut?

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 .

Wie spezifiziert man einen ShortCut?

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 Formular oder von ApplicationEvents " 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 :

%Vor%

Wenn der Parameter Handled auf True gesetzt ist, wird jede nachfolgende Verarbeitung für den Schlüssel übersprungen.

Wie wird ein ShortCut eingefangen?

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.

Wie wird der ShortCut verarbeitet?

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)
    • auf
  • Falls nicht verarbeitet, wird überprüft, ob der Schlüssel ein ShortCut des Formulars ist, auf dem sich das Steuerelement befindet, indem TCustomForm.IsShortCut 2) ,
    • Das OnShortCut -Ereignis des Formulars heißt, falls zugewiesen,
    • Wenn es nicht verarbeitet wird, prüft es, ob der Schlüssel ein ShortCut innerhalb des Forms MainMenu (falls 1) ist, falls vorhanden,
    • Falls nicht verarbeitet, wird der Schlüssel an alle Aktionslisten gesendet, die dem Formular gehören (immer noch über das aktive Formular). Vor Version 10 von Delphi (BDS2006) müssen diese Aktionslisten direkt dem Formular gehören und in einem geschützten Bereich gespeichert werden (der bei Bedarf eine Intervention ermöglicht). Field 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,
  • Wenn nicht verarbeitet, Application.IsShortCut wird aufgerufen (via CM_APPKEYDOWN ),
    • Das OnShortCut -Ereignis der Anwendung wird ausgelöst, einschließlich OnShortCut -Ereignissen aller ApplicationEvents-Komponenten das Projekt, falls vorhanden,
    • Falls nicht verarbeitet, wird die Routine 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)
    • durchstreift.

Also, wann wird der ShortCut verarbeitet?

Wenn es ist:

  • Legen Sie für ein aktiviertes MenuItem in einem PopupMenu fest, das an das gerade fokussierte Steuerelement oder an eines seiner übergeordneten Elemente angehängt ist,
  • Legen Sie für ein aktiviertes MenuItem in einem MainMenu fest, das auf dem aktuell aktiven Formular oder dem MainForm angezeigt wird, aber nur wenn das MainForm aktiviert ist,
  • Legen Sie für eine aktivierte Aktion in einer nicht angehaltenen ActionList fest, die dem gerade aktiven Formular oder MainForm gehört, aber nur, wenn MainForm aktiviert ist,
  • Wird im OnShortCut -Ereignis des gerade aktiven Formulars oder der MainForm eingefangen, aber nur, wenn MainForm aktiviert ist,
  • Wird im OnShortCut -Ereignis des Applicaton oder einer beliebigen ApplicationEvents-Komponente erfasst.

Und wann wird der ShortCut nicht verarbeitet?

Wenn es eingestellt ist für:

  • Ein deaktiviertes MenuItem,
  • Ein MenuItem ohne Menü,
  • Ein MenuItem in einem MainMenu, das keinem Formular zugeordnet ist,
  • Ein MenuItem in einem PopupMenu, das an ein Geschwister angehängt ist,
  • Eine deaktivierte Aktion,
  • Eine Aktion ohne Aktionsliste,
  • Eine Aktion in einer Aktionsliste, die nicht dem derzeit aktiven Formular oder der MainForm gehört. Zum Beispiel: ein anderes Formular, ein DataModule, eine Anwendung, eine Versorgungseinheit, etc ...
  • Eine Aktion in einer Aktionsliste, die nicht direkt dem aktuell aktiven Formular oder der MainForm in Delphi-Versionen unterhalb von BDS2006 gehört.
NGLN 22.11.2014, 22:29
quelle

Tags und Links