1

如何让 KeyDown 事件在 Delphi (2007) MDI 应用程序父窗口中工作,即使子窗口具有焦点?

我想实现一个在 MDI 应用程序中显示帮助屏幕的快捷键 (F1),我已将 KeyDown 过程添加到 MDI 父窗口并在父窗口和子窗口中启用了 KeyPreview,但它不能作为预期的。

如果我在父母 KeyDown 代码中设置一个断点,我可以看到它永远不会执行,即使它没有打开子窗口。但是,如果我将相同的代码添加到子窗口中,它就可以正常工作。

有没有办法让父窗口接收按键,即使子窗口有焦点,因为将代码添加到 25+ 窗体接缝有点浪费?

4

4 回答 4

5

这周我遇到了完全相同的问题!我通过在主窗体上的 ActionManager 中创建一个动作来修复它。此操作打开帮助文件并将 F1 键设置为快捷方式。它也适用于所有 MDI 子屏幕。

于 2008-10-22T12:32:36.663 回答
2

您可以使用本地(不需要全局)键盘挂钩。您还可以从一个单一表单基类派生所有 MDI 子表单并在那里实现一次。你会发现这种设计对于其他问题也很方便。

编辑

应用程序范围的热键/快捷方式也可以通过 TApplication.OnShortCut 事件来实现。见http://delphi.about.com/od/adptips2004/a/bltip0904_3.htm

F1 已经是触发 TApplication.OnHelp 的标准帮助快捷方式。所以也许你想使用 OnHelp 事件?如果您使用 HelpFile、HelpContext、HelpType 和 HelpKeyword 属性,您甚至可能根本不需要实现任何代码。

于 2008-10-22T09:54:34.470 回答
2

如何让 KeyDown 事件在 Delphi (2007) MDI 应用程序父窗口中工作,即使子窗口具有焦点?

作为更通用的解决方案(对于 F1 以外的应用程序寻求帮助),我使用与此类似的代码来捕获主窗体中的 keydown 事件。无论如何,这都会获取所有密钥,即使 MDI 子项处于活动状态也是如此。在此示例中,我正在做与您尝试做的相反的事情(我希望消息由我的子表单而不是主表单处理),但是在父表单中捕获键的概念是相同的)。

Application.OnMessage := AppMessage;

procedure TMainForm.Appmessage(var Msg: TMsg; var Handled: Boolean);
var
  message: TWMKey;
begin
  If (msg.message = WM_KEYDOWN) and
     ( LoWord(msg.wparam) = VK_TAB ) and
     (GetKeyState( VK_CONTROL ) < 0 ) and
     Assigned( ActiveMDIChild ) then
  Begin
    Move( msg.message, message.msg, 3*sizeof(Cardinal));
    message.result := 0;
    Handled := ActiveMDIChild.IsShortcut( message );
  End;
end;
于 2008-10-22T14:32:05.363 回答
1

F1 帮助处理内置在 Delphi 中,因此您所要做的就是正确处理帮助消息。这可能与为应用程序设置帮助文件属性一样少。您可以使用表单的帮助设置特定页面???特性。

基本上,只需使用提供的帮助系统并忘记 keydown。这就是德尔福——你不必努力工作。

于 2008-10-22T10:45:27.880 回答