1.什么是消息消息,就是指Windows发出的一个通知,消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。这个记录类型叫做T M s g,它在Windows单元中是这样声明的:type TMsg = packed recordhwnd: HWND; //窗口句柄message: UINT; //消息常量标识符,可以是Windows单元中预定义的常量,也可以是自己自定义的常量wParam: WPARAM; // 32位消息的特定附加信息,通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。lParam: LPARAM; // 32位消息的特定附加信息,通常是一个指向内存中数据的指针。由于WParam、LParam和Pointer都是32位的,因此,它们之间可以相互转换。time: DWORD; //消息创建时的时间pt: TPoint; //消息创建时的鼠标位置end;2.Windows的消息系统是如何工作的:Windows的消息系统是由3个部分组成的:A. 消息队列。Wi n d o w s能够为所有的应用程序维护一个消息队列。应用程序必须从消息队列中获取消息,然后分派给某个窗口。B. 消息循环。通过这个循环机制应用程序从消息队列中检索消息,再把它分派给适当的窗口,然后继续从消息队列中检索下一条消息,再分派给适当的窗口,依次进行。C. 窗口过程。每个窗口都有一个窗口过程来接收传递给窗口的消息,它的任务就是获取消息然后响应它。窗口过程是一个回调函数;处理了一个消息后,它通常要返回一个值给Wi n d o w s。注意:回调函数是程序中的一种函数,它是由Windows或外部模块调用的。一个消息从产生到被一个窗口响应,其中有5个步骤:1) 系统中发生了某个事件。2) Windows把这个事件翻译为消息,然后把它放到消息队列中。3) 应用程序从消息队列中接收到这个消息,把它存放在TMsg记录中。4) 应用程序把消息传递给一个适当的窗口的窗口过程。5) 窗口过程响应这个消息并进行处理。
3. Delphi的消息系统:消息循环己经封装到VCL的Forms单元,Delphi还把Windows的TMsg记录中的信息映射为TMessage记录:Type TMessage = recordMsg : Cardinal;case Integer of 0:(WParam: LongInt;LParam: LongInt;Result: LongInt);1:(WParamLo: Word;WParamHi: Word;LParamLo: Word;LParamHi: Word;ResultLo: Word;ResultHi: Word;end;除了通用的TMessage记录外,Delphi为每个Windows消息定义了一个特殊的消息记录,这样就不必从wParam域和lParam域中分解出有关信息4.消息处理:在一个标准的Windows应用程序中,消息是由窗口过程处理的。而在Delphi中,每个消息都有各自的过程。用于消息处理的过程必须满足下列3个条件:A 这个过程必须是一个对象中的方法。B 这个过程必须有一个var参数,变量的类型是TMessage或其他特殊的消息记录。C 声明这个过程时,必须使用message指示符,后面跟要处理的消息的常量值。下面是声明一个处理WM_PAINT消息的过程的代码:Procedure WMPaint(var msg: TMessage); message WM_PAINT;注意给用于消息处理的过程命名时采用这样的约定:过程名与消息的标识符一致,但不要全部大写,也不要有下划线。对Result域赋值:当处理某些Windows消息时,Windows希望返回一个值。TApplication的OnMessage事件:要处理Windows的消息,也可以利用TApplication的OnMessage事件。建立了响应OnMessage事件的处理过程后,只要从消息队列中检索到一个消息,就会触发OnMessage事件。。响应Application.OnMessage事件的处理过程必须是TMessageEvent类型
5.发送自己的消息:就像Windows发送消息给应用程序一样,也可以在窗口与控件之间发送消息。Delphi提供了几种在一个应用程序内部发送消息的方式:调用Perform()(这种方式不依赖于Windows API),以及调用SendMessage(),PostMessage()API函数。Perform():VCL的Perform()方法使用于所有的TControl的派生对象.Perform可以向任何一个窗口和控件发送消息,只要知道这个窗口和控件的实例.Perform需要传递三个参数:消息标识符,wParam和lParam:function TControl.Perform(Msg: Cardinal;wParam,lParam: LongInt): LongInt;调用了Perform消息之后,它要等到消息处理了之后才会返回.SendMessage()和PostMessage()方法:通过窗口句柄发送消息SendMessage()直接把消息发送给窗口,并且等到消息被处理之后返回PostMessage()只是把消息发送到消息队列,然后立即返回function SendMessage(hWnd:HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;function PostMessage(hWnd:HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): bool; stdcall;
6. 用户自定义消息:A. 在应用程序内部发送消息:一个应用程序要发送消息给自己是很容易的,只要调用Perform(),SendMessage()或PostMessage(),并且使消息常量的值为WM_USER + 100到$7FFF(这个范围是Windows为用户自定义消息保留的)。B 在应用程序之间发送消息:最好调用RegisterWindowMessage(),这个函数能够确保每个应用程序使用一致的消息编号。RegisterWindowMessage()需要传递一个以null结束的字符串,并返回一个范围从$C000到$FFFF的新的消息常量。这就意味着,在要发送消息的应用程序之间,每个应用程序都必须传递相同的字符串给RegisterWindowMessage()函数;而Windows也会返回相同的消息常量值。调用RegisterWindowMessage()的真正好处是,对于任何给定的字符串将返回一个在整个系统中都唯一的消息常量,这样,就可以放心地向所有的窗口广播消息。C 广播消息:TWinControl的派生对象可以调用Broadcast()来向它的子控件广播一个消息。当需要向一组组件发送相同的消息时,你要用得这种技术。
