A colleague and myself were debating over which way was less of a burden on the system resources. (Note: this is not the question I want an answer to. Rather the title and t
The best answer would be, measure it. Most likely neither one is going to place any noticeable "burden" on the system, and if you don't notice it when you're specifically looking for it, then your users won't either. So just go with whichever one's easier to understand in case you need to come back to that code sometime in the future.
The bottom line here is that you can't generate input quick enough to make the computer even notice. The computer would not be troubled if you produced input messages at rates hundreds or even thousands greater than you typically do.
You won't be able to measure the difference between handling something in OnMessage
and using KeyPreview
.
So the decision as to which to use comes down to which is most convenient. If you need handling to happen at an application wide level, and you don't have a common base class for all your forms, then you use OnMessage
. If you want different behaviour for different forms then you need to use KeyPreview
.
Personally I strongly recommend refactoring so that all forms in your projects derive from a common base (a subclass of TForm
). This allows you much more flexibility. Done this way you can, for example, use the KeyPreview
mechanism to apply intervention points for all forms in your applications.
As for how KeyPreview
is implemented, the input messages get redirected in KeyDown
, KeyPress
etc. in TControl
. To learn more read the source code.
As others have already said - there is probably no noticeable difference.
I just wanted to point out an exellent article by Peter Below
on that topic: A Key's Odyssey
This article describes the key message processing as implemented in Delphi 2007 for Win32 VCL forms applications. A few things have changed in this area compared with Delphi 7, but these are mostly additions that I will highlight when we get to them. Most of this code has survived basically unchanged since the times of Delphi 1, a tribute to the robustness of the design. If you are in a hurry or not interested in all the details you can refer to the outline in the summary for a condensed overview.
The KeyPreview property of the current active form is checked for the KeyUp-, KeyDown- and KeyPress- event handlers of the current active control. I.e.: a key press in any control results in the check of the form's KeyPreview property.
If that property is True, the event handler in question invokes the event handler of the form prior to that of itself. If the form's event handler does not change the key value to 0 (or #0, depending on KeyPress or KeyDown/KeyUp), then the active control's event handler takes back over, otherwise the event is considered handled.
So setting the key value to 0/#0 in a form's event handler is synonymous to setting the Handled parameter of Application.OnMessage. In this, there is virtually no difference. But since OnMessage is called very early in the dispatching process, there is a theoretical gain in performance because the message is not being dispatched any further. When you leave Handled to False, there is no difference at all, because the KeyPreview property is always checked, whether it is set or not.
The main difference that is left is that you have to set the KeyPreview of áll Forms to True, ánd implement and maintain for each of all forms the appropriate event handlers. Compare this to having just one event handler for Application.OnMessage. That is: assuming you could do with just one routine for all of your forms.