-
21-08-2019 - |
题
我正在使用 Delpho 2006。场景:
在数据模块上我有一个 ActionList。其中一项操作有一个快捷键 Ctrl+F4,我想要一个辅助快捷键 Ctrl+W。我尝试了以下所有方法:
将 Ctrl+W 添加到 IDE 中的操作 SecondShortcut 列表中。
使用以下任一方法将其添加到 DataModuleCreate 过程中
ActFileCloseFile.SecondaryShortCuts.Add('Ctrl+W');
或者
ActFileCloseFile.SecondaryShortCuts.AddObject('Ctrl+W',
TObject(Menus.ShortCut(87, [ssCtrl])));
在将使用该方法的表单的 Create 或 FormShow 过程中使用这两种方法。
主要快捷方式始终有效,但次要快捷方式则无效。
当我将 ActionList 放在主窗体而不是数据模块上时,只需在 IDE 中添加 Ctrl+W 即可工作。我做错了什么?
解决方案
迄今为止发现的最好的解决方法是这样的:
在形式要处理SecondaryShortCut,这增加了OnShortCut事件:
procedure TMyForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
Handled := dmDataModule.ActionList1.IsShortCut(Msg);
end;
替代:
(这不是一个真正的解决方案,但是一种替代方法。)
把动作列表,其具有相同的动作,以该数据模块上的一个形式。在其执行和更新事件只转发事件数据模块动作。的形式在菜单上使用本地行动。
在这种情况下,它足以使用IDE W至添加按Ctrl +到SecondaryShortCuts属性。
显然,当在数据模块变更的行为,我不得不改变所有的本地操作了。
其他提示
不是一个真正的解决方案,但如果你从它的工作的MainForm内创建数据模块:
procedure TMainForm.FormCreate(Sender: TObject);
begin
FDataModule := TMyDataModule.Create(self);
TMyButton.Action := FDataModule.TheAction;
end;
procedure TMyDataModule.DataModuleCreate(Sender: TObject);
begin
TheAction.SecondaryShortCuts.Add('Ctrl+W');
end;
我认为快捷方式是由具有当前焦点的形式处理的。所以,如果你以另一种形式使用它们哟可能会得到同样的问题。
简短回答:操作快捷键不 自动地 跨表单和数据模块触发。
如果您按照问题中的说明进行操作,您会发现即使是主要快捷方式也不会触发。这是因为说明中遗漏了一个关键步骤。这将有助于解释为什么 OP 经历了第一次短路射击而不是二次射击。
如果您包括额外的步骤:
- 向表单添加菜单。
- 并将菜单项链接到操作。
然后主要快捷方式将能够触发该操作。这是因为 Action 组件将其设置推送到菜单项(包括 ShortCut
财产)。然而, TMenuItem
没有实现二级快捷方式的概念。这就是为什么一个有效而另一个无效的原因。
停下来考虑一个具有多种表单和数据模块的应用程序;以及行动捷径是否可以在所有这些方面都发挥作用的含义。很明显他们不应该能够 自动地 在没有明确代码允许的情况下触发。您不希望后台表单执行大量操作,因为其配置的快捷键恰好是在其他不相关工作的上下文中按下的。
这 文档 指出将操作列表放在数据模块上的好处。但似乎没有提供任何解释如何使用操作 有捷径 在数据模块上 正确地. 。当然,在预期的地方没有提到任何内容,即: 捷径 和 辅助快捷键. 。(我会很失望,但我对像样文档的期望被拖得很低。)
所以...
什么 应该 如何通过跨表单和数据模块的快捷方式获取操作?
我做了一些调查并找到了一些选择。与往常一样,评估与您想要实现的目标相关的权衡。
当您将操作列表拖放到(非主)表单上时,所有快捷方式都会按预期工作。这是最常见的场景,适用于本地操作和特定形式的操作。
当您将操作列表放在主窗体上时,所有这些快捷方式都可以从任何其他窗体触发。这对于应用程序范围内的快捷方式(例如打开其他表单)非常有用。
笔记: 对于首先测试快捷方式的位置有一个优先顺序。因此,如果活动表单在主表单上有匹配的快捷方式,则该快捷方式将在本地处理。可以理解的是,主要形式不会得到它。
- 当测试表单以查看它是否处理快捷方式时,所有 拥有的组件 也被检查。(这实际上就是上面前两个起作用的原因。)这意味着只需设置
Owner
您的数据模块的正确设置将允许其快捷方式应用于您选择的表单。
IE。代替:
Application.CreateForm(TDataModule1, DataModule1);
您可以使用以下内容:
DataModule1 := TDataModule1.Create(LocalForm);
然而,由于数据模块的每个实例只能有一个所有者:您必须创建多个实例才能让多个表单共享快捷方式。这是否是一个选择取决于您的具体情况。但是,您也可以使主窗体成为数据模块的所有者,这在某种程度上相当于上面的第二个选项。
- 提供最大控制的最终选项是OP自己的答案。IE。任何需要支持“外部快捷方式”的表单都可以使用以下代码处理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;
在动作过得去形式吞噬......如果你想要一个次要形式/帧/数据模块来处理行动......你必须首先从主禁用的ActionList ...
Form1.ActionList1.State:= asSuspended;
DataModule1.ActionList1.State:= asNormal;