Trapping Messages Sent to an Application

來源:互聯網
上載者:User

標籤:des   blog   http   io   os   ar   for   strong   sp   

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 doesn‘t seem to fire on all messages.

Is there a way to trap all messages sent to my application? 

There sure is. And the answer to this "problem"  is amazingly simple.

But before I go into 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 you can seen evidence of this by creating a new application saving it,

then running it (make 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 will only fire when there‘s something in the Application object‘s message queue.

These messages are 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 more familiar with handling windows messages

might think that a solution to the problem above

might be to override the WndProc method for the Application object.

Unfortunately, that‘s not possible because TApplication‘s WndProc method is not 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 WndProc (not that you‘d want either).

But that doesn‘t mean that 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 you to 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 is 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 like so:

type  TWindowHook = function(var Message : TMessage) : Boolean of object;

Since TWindowHook is a method pointer, you can define your own method as the hook function

as long as it follows the nomenclature defined for TWindowHook.

Notice that 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 will be passed back to the Application‘s WndProc and

message processing for that message will 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 default  if Message.Msg = WM_<SomethingOrOther> then begin    ...DoSomething...    Result := True;  end;end; 

Okay, now that we‘ve set up everything,

we need to make the application hook the messages.

This can be done in the main form‘s OnCreate method:

function TForm1.FormCreate(Sender : TObject);begin  HookMainWindow(AppHookFunc);end; 

I should mention that you need to clear the hook using,

you guessed it, UnHookMainWindow,

after you‘re done using it, and this can be done

in the OnDestroy for the main form:

function TForm1.FormDestroy(Sender : TObject);begin  UnHookMainWindow(AppHookFunc);end; 

Okay, disgustingly simple.

But I feel the best things in life are those that give maximum satisfaction

for the least amount of cost (please don‘t read ANYTHING into that <G>).

So, now you‘ve got the tools to create your own message "hooker" (sorry, had to do that at least once).

Until next time...

 

Trapping Messages Sent to an Application

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.