一位同事和我本人正在就哪种方式减轻系统资源负担进行辩论。 (注意:这不是我想要答案的问题。相反,标题和下面粗线是我寻求答案的问题。)
1. Using KeyPreview to get the keypresses on a form.
或
2. Using defining an OnMessage procedure and handling it there.
乍一看,似乎KeyPreview不会占用系统负担,因为定义OnMessage过程会导致我们的程序检查每条消息。我们不关心的注意消息会导致它跳出第一个if声明。在最坏的情况下,我们会为每条消息执行if语句。
但我们想知道Delphi如何处理KeyPreview属性......我们想知道Delphi是否在内部定义了自己的OnMessage并查看消息然后触发与按键相关的事件。
如果是这种情况,那么两种方法都会大致相同吗?
答案 0 :(得分:7)
正如其他人已经说过的那样 - 可能没有明显的区别。
我只是想通过Peter Below
就该主题指出一篇优秀的文章:A Key's Odyssey
本文介绍了关键信息 处理在Delphi中实现 2007 for Win32 VCL表单应用程序。 这个领域发生了一些变化 与Delphi 7相比,但这些都是 主要是我要强调的补充 当我们到达他们。大部分代码 从那以后基本没有幸存 德尔福1的时代,致敬 设计的稳健性。如果你 匆忙或不感兴趣 你可以参考的所有细节 简要概述为简明 概述
答案 1 :(得分:6)
检查当前活动表单的KeyPreview属性,以查找当前活动控件的KeyUp-,KeyDown-和KeyPress-事件处理程序。即:在任何控件中按键都会导致检查表单的KeyPreview属性。
如果该属性为True,则所讨论的事件处理程序会在其自身之前调用该表单的事件处理程序。如果表单的事件处理程序没有将键值更改为0(或#0,具体取决于KeyPress或KeyDown / KeyUp),则活动控件的事件处理程序将重新收回,否则将认为该事件已处理。
因此,在表单的事件处理程序中将键值设置为0 /#0与设置Application.OnMessage的Handled参数同义。在这方面,几乎没有区别。但由于OnMessage在调度过程中很早就被调用,因此性能中存在理论增益,因为消息不会被进一步调度。当您将Handled设置为False时,根本没有任何区别,因为无论是否设置了KeyPreview属性,都会被检查。
剩下的主要区别在于你必须将állForms的KeyPreview设置为True,并为所有表单中的每个表单实现和维护适当的事件处理程序。将此与仅具有Application.OnMessage的一个事件处理程序进行比较。那就是:假设您只能为所有表单执行一个例程。
答案 2 :(得分:4)
最好的答案是衡量它。很可能没有人会在系统上放置任何明显的“负担”,如果你在专门寻找它时没有注意到它,那么你的用户也不会。因此,如果您需要在将来的某个时间回到该代码,请更容易理解。
答案 3 :(得分:4)
这里的底线是你无法快速生成输入以使计算机发出通知。如果您以比通常更高的数百甚至数千的速率生成输入消息,那么计算机就不会有麻烦。
您无法衡量处理OnMessage
中的内容与使用KeyPreview
之间的区别。
因此决定使用哪种方法最为方便。如果您需要在应用程序范围内进行处理,并且您没有所有表单的公共基类,则使用OnMessage
。如果您想要不同表单的不同行为,则需要使用KeyPreview
。
我个人强烈建议重构,以便项目中的所有表单都来自一个公共基础(TForm
的子类)。这可以让您更灵活。例如,通过这种方式,您可以使用KeyPreview
机制为应用程序中的所有表单应用干预点。
至于如何实施KeyPreview
,输入消息会在KeyDown
中的KeyPress
,TControl
等重定向。要了解更多信息,请阅读源代码。