Delphi的KeyPreview如何运作?

Tim*_*Tim 9 delphi

一位同事和我本人正在就哪种方式减轻系统资源负担进行辩论.(注意:这不是我想要答案的问题.相反,标题和粗体下面的行是我寻求答案的问题.)

1. Using KeyPreview to get the keypresses on a form.
Run Code Online (Sandbox Code Playgroud)

要么

2. Using defining an OnMessage procedure and handling it there.
Run Code Online (Sandbox Code Playgroud)

乍一看似乎KeyPreview不会占用系统负担,因为定义OnMessage过程会导致我们的程序检查每条消息.我们不关心的注意消息会导致它被第一个if语句跳出.在最坏的情况下,我们会为每条消息执行if语句.

但我们想知道Delphi如何处理KeyPreview属性......我们想知道Delphi是否在内部定义了自己的OnMessage并查看消息然后触发与keypresses相关的事件.

如果是这种情况,那么两种方法都会大致相同吗?

ain*_*ain 7

正如其他人已经说过的那样 - 可能没有明显的区别.

我只想Peter Below在这个主题上指出一篇优秀的文章:A Key's Odyssey

本文介绍了在Delphi 2007中为Win32 VCL表单应用程序实现的关键消息处理.与Delphi 7相比,这个领域发生了一些变化,但这些都是我们在遇到它们时会突出的补充内容.自Delphi 1时代以来,大部分代码都基本保持不变,这是对设计稳健性的致敬.如果您匆忙或对所有细节不感兴趣,可以参考摘要中的大纲以获得精简概述.

  • +1 Aaaah,彼得下面.德尔福的Jon Skeet.我从他那里读了很多东西.他似乎已经消失了. (3认同)

NGL*_*GLN 6

KeyPreview功能:

检查当前活动表单的KeyPreview属性,以查找当前活动控件的KeyUp-,KeyDown-和KeyPress-事件处理程序.即:在任何控件中按键都会导致检查表单的KeyPreview属性.

如果该属性为True,则所讨论的事件处理程序将在其自身之前调用该表单的事件处理程序.如果表单的事件处理程序未将键值更改为0(或#0,具体取决于KeyPress或KeyDown/KeyUp),则活动控件的事件处理程序将重新收回,否则将视为事件被处理.

与Application.OnMessage相比:

因此,在表单的事件处理程序中将键值设置为0 /#0与设置Application.OnMessage的Handled参数同义.在这方面,几乎没有区别.但由于OnMessage在调度过程中很早就被调用,因此性能有理论上的提高,因为消息不会被进一步发送.当您将Handled设置为False时,根本没有任何区别,因为无论是否设置了KeyPreview属性,都会被检查.

剩下的主要区别是你必须将állForms的KeyPreview设置为True,并为所有表单中的每个表单实现和维护适当的事件处理程序.将此与仅具有Application.OnMessage的一个事件处理程序进行比较.那就是:假设您只需要为所有表单执行一个例程.