辅助快捷方式不会触发

时间:2009-05-12 06:16:15

标签: delphi shortcuts taction tactionlist

我正在使用Delpho 2006.场景:

在数据模块上,我有一个ActionList。其中一个动作有一个快捷键Ctrl + F4,我希望有一个辅助快捷键Ctrl + W.我尝试了以下所有方法:

将Ctrl + W添加到IDE中的操作SecondaryShortcut列表。

使用

在DataModuleCreate过程中添加它
ActFileCloseFile.SecondaryShortCuts.Add('Ctrl+W');

ActFileCloseFile.SecondaryShortCuts.AddObject('Ctrl+W',
  TObject(Menus.ShortCut(87, [ssCtrl])));

在将要使用它的表单的Create或FormShow过程中使用这两种方法。

主要快捷方式始终有效,但不是辅助快捷方式。

当我将ActionList放在主窗体而不是数据模块上时,只需在IDE中添加Ctrl + W即可。我做错了什么?

4 个答案:

答案 0 :(得分:3)

到目前为止找到的最优雅的解决方案是:

在您要处理SecondaryShortCut的表单上,将其添加到OnShortCut事件中:

procedure TMyForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Handled := dmDataModule.ActionList1.IsShortCut(Msg);
end;

替代方案:

(这不是一个真正的解决方案,而是一种解决方法。)

在表单上放置一个操作列表,该列表与数据模块上的操作具有相同的操作。在其执行和更新事件中,它仅将事件转发到数据模块操作。表单上的菜单使用本地操作。

在这种情况下,只需使用IDE将Ctrl + W添加到SecondaryShortCuts属性即可。

显然,当数据模块上的操作发生变化时,我也必须更改所有本地操作。

答案 1 :(得分:1)

不是一个真正的解决方案,但是如果你在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;

我认为快捷方式是由具有当前焦点的表单处理的。所以如果你以另一种形式使用它们,你可能会遇到同样的问题。

答案 2 :(得分:1)

简答:操作捷径不会在表单和数据模块中自动触发。

如果你按照问题中的说明进行操作,你会发现即使是主要的捷径也不会发生火灾。这是因为说明中遗漏了一个关键步骤。这将有助于解释为什么OP经历了主要的快捷射击,而不是次要射击。

如果您包含额外的步骤:

  • 在表单中添加一个菜单。
  • 并将菜单项链接到操作。

然后主要的快捷方式将能够解雇该动作。这是因为Action组件将其设置推送到菜单项(包括ShortCut属性)。但是,TMenuItem没有实施二级捷径的概念。这就是为什么一个有效而不是另一个。


暂停考虑具有多种表单和数据模块的应用程序;如果行动捷径可以解决所有这些问题,那么这意味着什么。显而易见的是,如果没有明确的代码允许,它们就不应该自动开火。你不希望背景形式做一堆事情,因为它配置的快捷键恰好在其他不相关的工作环境中被按下。

documentation指出了将动作列表放在数据模块上的好处。但似乎没有提供任何解释如何在数据模块上正确使用快捷方式 。当然,在预期的地方没有提到任何内容,即:ShortCutSecondaryShortcuts。 (我感到失望,但我对体面文档的期望被拖得很低。)

因此...

应该做什么才能在表单和数据模块中使用快捷方式进行操作?

我做了一些调查,发现了一些选择。与往常一样,评估相对于您想要实现的目标的权衡。

  • 当您在(非主要)表单上删除操作列表时,所有快捷方式都按预期工作。这是最常见的方案,适用于操作是本地操作和特定于表单的情况。

  • 当您在主表单上删除操作列表时,所有这些快捷方式都可以从任何其他表单中触发。这对于应用程序范围的快捷方式非常有用,例如打开其他表单。

注意:首先测试快捷方式的优先顺序。因此,如果活动表单在主表单上有一个快捷方式匹配,则快捷方式将在本地处理。主要形式可以理解为没有得到它。

  • 当测试表单以查看它是否处理快捷方式时,还会检查所有拥有的组件。 (这实际上是前两个工作的原因。)这意味着只需简单地设置数据模块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;

答案 3 :(得分:0)

表单会吞下这个动作......如果你想要一个辅助表单/框架/数据模块来处理动作......你必须先从主要部分禁用动作列表......

Form1.ActionList1.State:= asSuspended;

DataModule1.ActionList1.State:= asNormal;