Delphi体系内部的4种消息传递办法(Send,Post,Perform,Dispatch)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Delphi体系内部的4种消息传递办法(Send,Post,Perform,Dispatch)相关的知识,希望对你有一定的参考价值。

一、什么是消息?

消息是windows对应用程序发送的有关‘发生了某种事件’的通知。例如点击鼠标,调整窗口大小或键盘上按下一个键,都会引起windows发送一条消息到应用程序中去,去通知应用程序发生了什么。

 

Windows以record的形式发送消息给应用程序。记录中包括事件的类型以及附加的特定信息。Windows发送给应用程序的记录类型是TMsg,定义在windows.pas单元中,定义如下

 

[delphi] view plain copy
 
  1. { Message structure }  
  2.  PMsg = ^TMsg;  
  3.  tagMSG = packed record  
  4.    hwnd: HWND;  
  5.    message: UINT;  
  6.    wParam: WPARAM;  
  7.    lParam: LPARAM;  
  8.    time: DWORD;  
  9.    pt: TPoint;  
  10.  end;  
  11.  {$EXTERNALSYM tagMSG}  
  12.  TMsg = tagMSG;  
  13.   MSG= tagMSG;  
  14.   {$EXTERNALSYM MSG}  

 

 

消息字段记录说明:

Hwnd:32位windows句柄,指向消息要发往的窗口,这个窗口可以是几乎所有的屏幕对象,因为window对大多数可是对象都维护了一个窗口句柄。

Message:代表某种消息的常量值,这些常量可以是在windows.pas中预定义的标准windows消息,也可以是用户自定义的消息。

Wparam:这个字段常常包含和消息关联的常量值,也可以包含一个窗口句柄或者消息关联的某个窗口或控件的ID值。

Lparam:这个字段经常容纳一个对内存数据的索引或指针,由于wparam和lparam都是32位大小,我们可以进行强制类型转换。

WM开头的通常是指WindowsMessage.

 

二、常用windows消息:

wm_active:窗口被激活

wm_char按下某个键发送wm_keydown和wm_keyup消息

wm_close窗口将要关闭

wm_keydown用户正在按下键盘上的一个键

wm_keyup:用户已经释放按下的键

wm_lbuttondown用户按下鼠标左键

wm_mousemove用户正在移动鼠标

wm_paint必须重绘窗口区域

wm_timer发生了一个计时器事件

wm_quit:发送终止程序请求

 

三、windows消息系统的工作方式

三个部分:消息队列、消息循环、窗口过程。

消息队列:Windows为每个应用程序维护一个消息队列,windows应用程序必须从这个队列中取得消息,并且把得到的消息分派到合适的窗口。

消息循环:windows程序从应用程序队列中取得一条消息,分派到适合的窗口中,然后再取得下一条消息,再分发到适合的窗口中,如此循环。这种消息机制就是消息循环。

窗口过程:应用程序中的每个窗口都有一个窗口过程,它接受消息循环中传入的每条消息,。窗口过程的任务是接受各个窗口消息并且对此做相应的回应。窗口过程是所谓的回调函数,在处理完毕一条消息之后,窗口过程通常要给windows一个返回值。

 

四、发送自己的消息:

我们需要在应用程序窗口和控件之间发送消息。Delphi提供了以下几种方法:

Perform()方法:VCL为所有的TContol派生类提供了perform()方法,可以发送消息给任何已知对象实例的对象或控件对象。Perform有三个参数:消息,对应的lparam和wparam。如下:

 

[delphi] view plain copy
 
  1. function Tcontrol.perform(Msg :cardinal;wparam,lparam:longint):longint;  

 

要发送一条消息给一个窗体或控件,使用下面的格式:

 

[delphi] view plain copy
 
  1. Retval:=controlname.perform(messageid,lparam,wparam);  

 

Perform是同步调用的,因此直到消息被处理完毕,才能得到返回值。Perform()方法把它的参数组合成一个TMessage记录,然后调用该对象的Dispatch方法去发送这条消息,绕开了windowsAPI消息系统。

Sendmessage()和postmessage()API函数:

Sendmessage和perform()类似,是同步调用的。消息直接发往目的窗口,该消息被处理完毕才返回;postmessage是异步调用的,发送消息给windows队列,然后立即返回。

 

通知消息:窗口的子控件发生事件,如果需要通知父窗口,就发送此消息。只发生在windows标准控件中如button、 listbox 、combox和通用控件如tree view、 list view等。

http://blog.csdn.net/sushengmiyan/article/details/7454919

以上是关于Delphi体系内部的4种消息传递办法(Send,Post,Perform,Dispatch)的主要内容,如果未能解决你的问题,请参考以下文章

使用websocket.send时如何知道消息何时到达?

如何使用 Mail::send() 获取 Mandrill 消息 ID - Laravel 4

终于懂了:Delphi消息的Result完全是生造出来的,不是Windows消息自带的(Delphi对Windows编程体系的改造越大,学习收获就越大)

Delphi中消息传递过程的现有过程类型?

delphi 数组作为参数传递

请大家解释一下Delphi的回调函数