简短回答:操作快捷方式不会跨表单和数据模块自动触发。
如果您按照问题中的说明进行操作,您会发现即使是主要的捷径也不会着火。这是因为说明中遗漏了一个关键步骤。这将有助于解释为什么 OP 经历了主要的捷径射击而不是次要的捷径。
如果您包括额外的步骤:
然后主快捷方式将能够触发该动作。这是因为 Action 组件将其设置推送到菜单项(包括ShortCut
属性)。但是,TMenuItem
没有实现二级快捷方式的概念。这就是为什么一个有效而另一个无效的原因。
暂停考虑具有许多表单和数据模块的应用程序;以及动作捷径是否会在所有这些方面触发的含义。很明显,如果没有明确的代码允许,它们不应该能够自动触发。您不希望后台表单做很多事情,因为它配置的快捷键恰好在其他不相关工作的上下文中被按下。
该文档指出了将操作列表放在数据模块上的好处。但似乎没有提供任何解释如何正确地在数据模块上使用带有快捷方式的操作。当然,在预期的地方没有提到任何内容,即:ShortCut和SecondaryShortcuts。(我会很失望,但我对体面文档的期望被拖得很低。)
所以...
应该怎么做才能使用跨表单和数据模块的快捷方式执行操作?
我做了一些调查,发现了一些选择。与往常一样,评估相对于您要实现的目标的权衡。
注意:对于首先测试捷径的位置有一个优先顺序。因此,如果活动表单在主表单上有一个与主表单匹配的快捷方式,则该快捷方式将在本地处理。可以理解,主要形式不会得到它。
- 当测试表单以查看它是否处理快捷方式时,还会检查所有拥有的组件。(这实际上就是上述前两个有效的原因。)这意味着只需
Owner
适当地设置数据模块的 ,就可以将其快捷方式应用于您选择的表单。
即代替:
Application.CreateForm(TDataModule1, DataModule1);
您可以使用以下内容:
DataModule1 := TDataModule1.Create(LocalForm);
但是,由于数据模块的每个实例只能有一个所有者:您必须创建多个实例才能让多个表单共享快捷方式。这是否是一种选择取决于您的情况。但是,您也可以将主窗体设置为数据模块的所有者,这在某种程度上等同于上面的第二个选项。
- 提供最多控制的最后一个选项是 OP 自己的答案。即任何需要支持“外部快捷方式”的表单都可以使用以下代码处理 OnShortCut 事件:
从代码示例中可以看出,您可以根据您选择的优先级委托给不同位置的多个操作列表。
procedure TMyForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
Handled := DataModule1.ActionList3.IsShortCut(Msg);
Handled := Handled or DataModule2.ActionList1.IsShortCut(Msg);
Handled := Handled or DataModule1.ActionList1.IsShortCut(Msg);
end;