在Delphi Mdi应用程序的父窗口中使用KeyDown事件

时间:2008-10-22 09:46:20

标签: delphi mdi keypress

如果Key窗口具有焦点,如何让KeyDown事件在Delphi(2007)MDI Applications Parent窗口中工作?

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

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

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

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

您可以使用本地(不需要全局)keyboard hook。您还可以从signle表单基类派生所有MDI子表单,并在那里实现一次。你会发现这个设计也可以用来解决其他问题。

修改

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

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

答案 2 :(得分:2)

  

如果Key窗口具有焦点,如何让KeyDown事件在Delphi(2007)MDI Applications Parent窗口中工作?

作为一个更通用的解决方案(对于除了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;

答案 3 :(得分:1)

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

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