LCL Key Handling/ja
│
English (en) │
日本語 (ja) │
português (pt) │
キーを押し下げた (KeyDown)
widgetsetがキーを押されたことを受け取ると、次のようにふるまいます。 "ネイティブ"なwidgetにキーを処理させる前に、CN_KEYDOWNやCN_SYSKEYDOWNをLCLに送ります。(CN_SYSKEYDOWNはaltキーが押されたときに発生します。) これは、DoKeyDownBeforeInterfaceが次のようなフローでコールします。
- Application.NotifyKeyDownBeforeHandlerがコールされます。 (ハンドラの前に呼び出されます。)
- keypreviewがある親フォームを取得し、そのDoKeyDownBeforeInterfaceメソッドを呼び出します。
- 関連づけられているdragobjectにキーを処理させます。
- KeyDownBeforeInterfaceをコールします。 (もし、コントロールがcsNoStdEventsをControlStyleに持っていない場合):
- KeyDownをコールします。
- OnKeyDown ハンドラがあればコールします。
- KeyDownをコールします。
もし、キーが処理されなければ(すなわち、Message.Result=0)、widgetにキーを処理させます。もしwidgetが有意義なことをすることがなければ、LCLにLM_KEYDOWN/LM_SYSKEYDOWNメッセージを送ります。これは、DoRemainingKeyDownを次のようなフローでコールします。
- if a popupmenu is assigned, check it for shortcuts (whether it is popped up or not)
- get parent form, let it handle possible shortcut (TCustomForm.IsShortcut):
- if form has OnShortcut event assigned, call it
- if form has Menu assigned, check it for shortcuts:
- iterate through all menu items for this menu, check shortcuts, ".Click" the item
- set the menu's ShortcutHandled property to false in the menu item's OnClick handler, if you did not handle the shortcut and want to let the key processing continue
- check the action lists for shortcuts, .Execute matching actions
- let the application handle a shortcut (Application.IsShortcut):
- if application has OnShortcut assigned, call it
- if there is a modal form active, let it handle a shortcut (see above, TCustomForm.IsShortcut)
- else if there is a focused form (Screen.ActiveCustomForm), let it handle a shortcut
- else if there is a main form (Application.MainForm), let it handle a shortcut
- if there is a Parent, iteratively call Parent.ChildKey to handle key message
- use it to handle key shortcuts in a certain "area", for example a panel
- TWinControl will call it's Parent's ChildKey; that's the "iteratively"
- call ControlKeyDown, which in TWinControl, calls Application.ControlKeyDown:
- handle tab navigation for controls
- if your custom control does something special with tab, override and inhibit, for example TCustomMemo
- call KeyDownAfterInterface; TWinControl does nothing here
- let Application call KeyDownAfter handlers
Note that result (returning 1 or 0 in Message.Result) matters sometimes: windows for example will only send a WM_CHAR message for a key when a WM_KEYDOWN message that key has returned 0.
キーを押している, キャラクタが送られている(KeyPress)
The widgetset can either send CN_CHAR message, or call the IntfUtf8KeyPress method. CN_CHAR does not support UTF-8 characters, so that is why a IntfUtf8KeyPress exists. CN_CHAR handling consists of:
- if widgetset (interface) does not send utf8 key presses, then call IntfUtf8KeyPress
- call DoKeyPress:
- get parent form, and if it has KeyPreview call it's DoKeyPress
- call KeyPress (if control does not have csNoStdEvents in ControlStyle):
- call OnKeyPress handler if any
IntfUtf8KeyPress (DoUtf8KeyPress) handling consists of:
- get parent form, and if it has KeyPreview call it's DoUtf8KeyPress
- call Utf8KeyPress (if control does not have csNoStdEvents in ControlStyle):
- call OnUtf8KeyPress handler if any
When unhandled, that is, Message.Result = 0, it lets the widget handle the key, and if the widget has not done anything useful, then send a LM_CHAR/LM_SYSCHAR message to the LCL, which calls SendDialogChar consisting of:
- get parent form and if found call it's .DialogChar:
- TWinControl broadcasts DialogChar to all it's children
- use it to implement accelerator shortcuts for controls "near" (on the same form) as the focused control
- example: TCustomLabel uses it to Focus the assigned .FocusControl when alt+accelerator is pressed
- TWinControl broadcasts DialogChar to all it's children
押されているキーを離した(KeyUp)
Releasing a key is very much, in the order of events happening, alike pressing a key, but some functions are missing. Again the widgetset will send a CN_KEYUP/CN_SYSKEYUP to the LCL before letting the widget handle the key, which will call DoKeyUpBeforeInterface consisting of:
- get parent form, if it has keypreview, call it's DoKeyUpBeforeInterface
- let the associated dragobject handle the key
- call KeyUpBeforeInterface (if control does not have csNoStdEvents in ControlStyle):
- call KeyUp:
- call OnKeyUp handler if any
- call KeyUp:
When unhandled, that is, Message.Result = 0, it lets the widget handle the key, and if the widget has not done anything useful, then send a LM_KEYUP/LM_SYSKEYUP message to the LCL, which calls DoRemainingKeyUp consisting of:
- call ControlKeyUp, which in TWinControl, calls Application.ControlKeyDown:
- handle Enter and Escape keys for forms
- if your custom control does something special with enter and escape, override and inhibit
- call KeyUpAfterInterface; TWinControl does nothing here