理解Windows消息(在Delphi中)-

理解Windows消息(在Delphi中)- -

1.什么是消息

2.Windows的消息系统是如何工作的

3. Delphi的消息系统

4.消息处理

5.发送自己的消息

6. 用户自定义消息


1.什么是消息
消息,就是指Windows发出的一个通知,消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。例如,
对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。这个记录类型叫做T M s g,它
在Windows单元中是这样声明的:
type TMsg = packed record
hwnd: 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 = record
Msg : 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()来向它的子控件广播一个消息。当需要向一组组件发
送相同的消息时,你要用得这种技术。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值