Http://www.delphicorner.f9.co.uk/articles/apps7.htm
Trapping Messages Sent to an application
I wrote code for the OnMessage event handler of Application object
To trap all Windows messages sent to my application,
But it's doesn ' t seem to fire in all messages.
Is there a-to-trap all messages sent to my application?
There sure is. And the answer to this "problem" are amazingly simple.
But before I go to trapping messages at the application level,
I should probably discuss some mechanics.
Tapplication ' s "Hidden" window
It's not a commonly known fact that the default Application object creates a hidden window
When your application is started.
But can seen evidence of creating a new application saving it,
Then running it to sure you don ' t rename anything-
Just keep the main form as "Form1" and the "project as" Project1).
When you run the application, you'll notice that the caption bar for your main form says,
"Form1" while the icon displayed on the task bar says "Project1."
That icon represents the application ' s hidden window,
And it affects your program in many ways,
Especially when you ' re trying to handle messages sent to your application.
Delphi surfaces the OnMessage event for the Application object.
The OnMessage event handler is ' supposed ' to allow you trap every message sent to your application.
But there's a problem with this:
OnMessage would only fire when there's something in the Application object ' s message queue.
These messages is typically window management messages such as WM_PAINT
or messages sent to the application from Windows through PostMessage,
Broadcast or SystemMessage.
However, messages sent directly to a window using SendMessage
Bypass the Application object ' s message queue,
So OnMessage doesn ' t fire for those types of situations.
Some of you and familiar with handling Windows messages
Might think that a solution to the problem above
Might is to override the WndProc method for the Application object.
Unfortunately, that's not possible because Tapplication's WndProc method isn't only private,
It ' s also declared as a static method which means it's not overrideable.
So it's not only invisible, you can ' t create a tapplication subclass
To override the WndProc (not so you ' d want either).
But that doesn ' t mean so you can ' t get to the WndProc method using alternative means.
"Hooking" all Messages
Even though WndProc is all but closed to direct subclassing,
Tapplication does include a method called Hookmainwindow
That allows the insert your own message handler
At the top of WndProc to intercept messages sent to your application
Before they ' re handled by the Application object.
This was convenient for all developers, and solves the problem
of trapping any message sent to your application.
Hookmainwindow is declared under Tapplication as follows:
Procedure Hookmainwindow (Hook:twindowhook);
Notice that Hookmainwindow takes one parameter,
Hook of type Twindowhook.
Twindowhook is a method pointer type that ' s defined:
Type Twindowhook = function (var message:tmessage): Boolean of object;
Since Twindowhook is a method pointer, can define your own method as the hook function
As long as it follows the nomenclature defined for Twindowhook.
Notice The return value of the function is of type Boolean.
This is the equivalent of the "Handled" parameter of OnMessage.
If your function handles a particular message, you ' d return true.
This'll be passed back to the application ' s WndProc and
Message processing for that message would be terminated.
Otherwise, you ' d return False. Here's an example method:
function Tform1.apphookfunc (var message:tmessage): Boolean;begin Result: = False;//i Just do this by Defau Lt if message.msg = wm_<somethingorother> then BEGIN ... dosomething ... Result: = True; End
Okay, now that we've set up everything,
We need to make the application hook the messages.
This can is done in the main form ' s OnCreate method:
function tform1.formcreate (sender:tobject); begin
I should mention that need to clear the hook using,
You guessed it, Unhookmainwindow,
After you ' re-done using it, and this can is done
The OnDestroy for the main form:
function Tform1.formdestroy (sender:tobject); begin
Okay, disgustingly simple.
But I feel the best things on life is those that give maximum satisfaction
For the least amount of cost (please don ' t read anything to that <G>).
So, now you've got the tools to create your own a message "hooker" (sorry, had to do, least once).
Until Next time ...
Trapping Messages Sent to an application