我正在使用 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;

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top