昨天我发现了一种情况,当我期望触发一个键盘快捷键时,它并没有被触发。
具体情况是:当我在MDI子窗口上按下ActionList的操作的快捷键组合时,MDI表单上的侧边栏处于焦点状态。
我一直以为快捷键可以全局使用。在什么情况下会或不会触发快捷键?
昨天我发现了一种情况,当我期望触发一个键盘快捷键时,它并没有被触发。
具体情况是:当我在MDI子窗口上按下ActionList的操作的快捷键组合时,MDI表单上的侧边栏处于焦点状态。
我一直以为快捷键可以全局使用。在什么情况下会或不会触发快捷键?
ShortCuts还可以从Application、Form或ApplicationEvents的OnShortCut
事件中解释。在这些事件中,Msg
参数将在其CharCode
成员中保存按键代码,并且可能使用GetKeyState
提取特殊键,如Shift、Ctrl或Alt:
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
,则键的任何后续处理都将被跳过。TApplication.Run
接收应用程序发送的每个Windows消息,TApplication.ProcessMessage
调用IsKeyMsg
,如果是WM_KEYDOWN
消息,则将消息传递给聚焦的控件的CN_KEYDOWN
消息处理程序。TWinControl.CNKeyDown
检查按键是否为菜单键(我们将看到这里的 菜单 定义超出了物理菜单):
TWinControl.IsMenuKey
首先检查键是否是控件或其父级菜单中的 PopupMenu 中的 ShortCut,
TMenu.IsShortCut
1) 遍历所有子菜单项并调用启用了 ShortCut 的 MenuItem 的 OnClick
事件处理程序,TCustomForm.IsShortCut
2),
OnShortCut
窗体事件,则会调用该事件,FActionLists
中(当需要时可以进行干预)。这被认为是一个错误,从 BDS2006 开始,该字段被删除,ActionLists 也可以间接地归属于窗体。
TCustomActionList.IsShortCut
遍历其所有 Actions 并使用其 ShortCut
或 SecondaryShortCuts
属性中设置的 ShortCut 调用启用了 Action 的 HandleShortCut
,Application.IsShortCut
(通过 CM_APPKEYDOWN
),
OnShortCut
应用事件,其中包括项目中的所有 ApplicationEvents 组件的 OnShortCut
事件(如果已分配),IsShortCut
程序(参见 2)),但 仅当 MainForm 已启用时。例如,当活动窗体为模态窗体时,MainForm 将被禁用。这将触发 MainForm 的 OnShortCut
事件 或遍历 Mainform 直接或间接拥有的ActionLists(取决于上述 Delphi 版本)。当它:
OnShortCut
事件中捕获,但仅当主窗体已启用时,OnShortCut
事件中捕获。当它被设置为:
TCustomForm.IsShortCut
,似乎即使例如FormChild
是在FormParent
中作为父级/嵌套的,但如果它不是由FormParent
拥有,那么如果它当前没有焦点,FormChild
中的快捷键也不会被处理? - Edwin Yip