一、什么是消息?

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

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

  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。如下:

  1. function Tcontrol.perform(Msg :cardinal;wparam,lparam:longint):longint;

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

  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)的更多相关文章

  1. 分布式系统ID的几种生成办法

    前言 一般单机或者单数据库的项目可能规模比较小,适应的场景也比较有限,平台的访问量和业务量都较小,业务ID的生成方式比较原始但是够用,它并没有给这样的系统带来问题和瓶颈,所以这种情况下我们并没有对此给 ...

  2. Unity多单位战斗寻路问题的一种解决办法

    Unity多单位战斗寻路问题的一种解决办法 Unity提供了NavMesh 导航组件   NavMesh是在实践中通用性最好的一种导航方式,但是Unity的实现并没有完全提供一个开放自由的API. 主 ...

  3. 64位Ubuntu运行32位程序时报文件不存在(No such file or Directory)的一种解决办法

    尝试在64位Ubuntu下面运行32位程序时, 一直说 文件不存在(No such file or directory), 我只想说++. 你tm说个文件格式不正确不就好了? 非得说个文件不存在! 真 ...

  4. 解决蓝屏代吗0x0000007B的几种常见办法

        解决蓝屏代吗0x0000007B的几种常见办法 0x0000007B 蓝屏代码的分析 ◆错误分析:Windows在启动过程中无法访问系统分区或启动卷. 网络上经过收集,主要有四种可能.第一是新 ...

  5. (转)eclipse安装ADT插件重启后不显示Android SDK Manager和Android Virtual Device Manager图标的一种解决办法

    文章来源:http://blog.csdn.net/zcyhappy1314/article/details/8307534 下面说的这种情况是在正确安装ADT插件的前提下,重启eclipse后,工具 ...

  6. Delphi反汇编内部字符串处理函数/过程不完全列表

    Delphi反汇编内部字符串处理函数/过程不完全列表 名称 参数 返回值 作用 等价形式 / 备注   _PStrCat EAX :目标字符串 EDX :源字符串 EAX 连接两个 Pascal 字符 ...

  7. [转]Delphi调用cmd的两种方法

    delphi调用cmd的两种方法vars:string;begins:='cmd.exe /c '+edit1.Text+' >c:\1.txt';winexec(pchar(s),sw_hid ...

  8. Delphi反汇编内部字符串处理函数不完全列表

    Delphi反汇编内部字符串处理函数/过程不完全列表 名称 参数 返回值 作用 等价形式 / 备注 _PStrCat EAX :目标字符串 EDX :源字符串 EAX 连接两个 Pascal 字符串 ...

  9. 百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法

    原文:百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法 公司的网站改版要求在一个页面显示百度地图.上面要同时显示很多标注点,标注点当然要有提示信息嘛,提 ...

随机推荐

  1. jquery 动态增加的html元素,初始化设置在id或class上的事件无效

    一般情况,我们会在页面初始化完成后对class定义一些全局事件,举个栗子: $(document).ready(function(){ $(".class").on("m ...

  2. CMD获取当前目录的绝对路径

    @echo offecho 当前盘符:%~d0echo 当前盘符和路径:%~dp0echo 当前批处理全路径:%~f0echo 当前盘符和路径的短文件名格式:%~sdp0echo 当前CMD默认目录: ...

  3. 工程脚本插件方案 - c集成Python基础篇(VC++嵌入Python)

    序: 为什么要集成脚本,怎么在工程中集成Python脚本. 在做比较大型的工程时,一般都会分核心层和业务层.核心层要求实现高效和稳定的基础功能,并提供调用接口供业务层调用的一种标准的框架划分.在实际中 ...

  4. Android dp和sp的用法汇总

    1 > dp 是跟像素密度无关的单位,也就是说在相同尺寸.但不同的分辨率的手机上,用dp标识的东西,显示的大小是一样的. sp是用于标识字体的,它不仅跟屏幕尺寸有关,还跟设置的系统字体大小有关. ...

  5. Error Unable to start the Genymotion virtual device.解决

    The Genymotion virtual device could not obtain an IP address.For an unknown reason.VirtualBox DHCP h ...

  6. c++ 复制构造函数和赋值函数

    c++ 自动提供了下面这些成员函数 1默认构造函数 2.复制构造函数 3.赋值操作符 4.默认析构函数 5.地址操作符 赋值构造函数copy construtor 用于将一个对象复制到新创建的对象中, ...

  7. Objective中的协议(Protocol)

    Objective中的协议(Protocol) 作用: 专门用来声明一大堆方法. (不能声明属性,也不能实现方法,只能用来写方法的声明). 只要某个类遵守了这个协议.就相当于拥有这个协议中的所有的方法 ...

  8. Linux下批量转换文件编码

    find -iname "*.java" -exec enca {} + |grep -v ASCI |grep -v -i utf |awk -F':' '{print $1}' ...

  9. D.6661 - Equal Sum Sets

    Equal Sum Sets Let us consider sets of positive integers less than or equal to n. Note that all elem ...

  10. poj 1363 Rails in PopPush City &&【求堆栈中合法出栈顺序次数】

    问题如下: 问题 B: Rails 时间限制: Sec 内存限制: MB 提交: 解决: [提交][状态][讨论版] 题目描述 There is a famous railway station in ...