昨天我发现了一种键盘ShortCut在我预期时没有发射的情况。
具体情况是:我在MDI子项上按下了ShortCut键组合以获取ActionList的Action,而MDI表单上的侧栏则被聚焦。
我总是认为ShortCuts可以在全球范围内运作。在什么情况下他们不会开火?
答案 0 :(得分:25)
这是一个看似简单的问题,答案非常长。首先,我将处理一些基础知识,然后通过VCL代码遵循ShortCut,最终得出 - 我希望 - 一个令人满意的结论。
ShortCut表示导致操作的一个或多个键的特殊键盘组合。 Special 对于为特定组合键赋予意义的程序员来说意味着特殊。
在Delphi中,ShortCut的类型为TShortCut
,它被声明为Word
范围内的整数(0..65535)。 ShortCut通常由几个键构成,例如:
CTRL + K = scCtrl
+ Ord('K')
= 16384
+ 75
= 16459
可以将ShortCuts分配给Action的ShortCut
或SecondaryShortCuts
属性或MenuItem的ShortCut
属性,从而调用该Action OnExecute
按下ShortCut键盘组合时事件或MenuItem的OnClick
事件。
对于要处理的Action的ShortCut,需要启用Action,并将其添加到未挂起的ActionList或附加到已启用的MenuItem。同样,要处理MenuItem的ShortCut,需要将MenuItem添加到菜单中。
也可以从Application,Form或ApplicationEvents'来解释快捷方式。 OnShortCut
事件。在这些事件中,Msg
参数将键码保存在其CharCode
成员中,并且可能包含特殊键,例如 Shift , Ctrl 或 Alt 可以使用GetKeyState
提取:
procedure TForm1.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
if (Msg.CharCode = Ord('K')) and (GetKeyState(VK_CONTROL) < 0) then
begin
Caption := 'CTRL+K pressed';
Handled := True;
end;
end;
如果Handled
参数设置为True
,则会跳过对该密钥的任何后续处理。
VCL不会保留所有指定快捷方式的列表。 (怎么可能?)因此,所有键击可能是一个ShortCut。这正是VCL解释ShortCuts的方式:通过评估所有按下的键。
Peter Below通过VCL写了一篇关于A Key's Odyssey的优秀而全面的文章。简而言之,ShortCut如下:
TApplication.Run
选择发送到应用程序的每条Windows消息,TApplication.ProcessMessage
调用IsKeyMsg
,将消息(如果有WM_KEYDOWN
消息)传递到焦点控件的CN_KEYDOWN
消息处理程序。 TWinControl.CNKeyDown
检查该键是否为菜单键(我们将看到此菜单的定义超出了物理菜单):
TWinControl.IsMenuKey
首先检查密钥是否为控件中的ShortCut或其父 PopupMenu 之一,
TMenu.IsShortCut
1)遍历所有其(子)菜单项,并使用ShortCut调用已启用MenuItem的OnClick
事件处理程序,如果有的话,TCustomForm.IsShortCut
2)来检查密钥是否是控件所在的表单的快捷方式,
OnShortCut
事件,FActionLists
。 That was considered a bug并且从BDS2006开始,该字段被淘汰,ActionLists也可以由Form间接拥有。
TCustomActionList.IsShortCut
遍历其所有操作并调用已启用操作的HandleShortCut
,并在其ShortCut
或SecondaryShortCuts
属性中设置ShortCut,Application.IsShortCut
(通过CM_APPKEYDOWN
),
OnShortCut
事件,其中包括项目中所有ApplicationEvents组件的OnShortCut
个事件(如果已分配),IsShortCut
例程(参见 2)),但仅在启用MainForm时 < / em>的。例如。当活动表单是模式表单时,将禁用MainForm。这将触发MainForm的 OnShortCut
事件或将遍历所有直接或间接拥有的MainForm 的ActionLists (取决于上面提到的Delphi版本)。 / LI>
当它是:
OnShortCut
事件,但仅在启用MainForm时,OnShortCut
事件或任何ApplicationEvents组件。设置为:
时