目录

Windows消息使用流程

Windows消息注意事项

Dispatch消息使用流程

Dispatch消息注意事项:


上一节讲述了RTL消息,本节讲述下Windows消息。首先看下演示程序如下:

对于Windows的消息说明如下:

  1. Windows消息一定是绑定在一个含有窗体句柄的对象上,例如TForm、TButton等;
  2. 如果不使用Windows系统自带的SendMessage和PostMessage发送消息,通过Dispatch分发消息,此时也可以不绑定在窗体对象上,只要是对象就可以;
  3. Demo程序演示了三种方式,其中SendMessage和PostMessage发送消息是使用的Windows的原生API。发送的方式有特别约定;Dispatch使用的是Delphi系统给对象封装的消息分发函数,可以用在任何对象上。
  4. 对于Windows的消息,实际上可以理解为一种有索引号的函数调用,调用参数可以灵活,包括字符串、数字、记录体甚至对象,但需要按照指针方式传递参数;
  5. 对于Dispatch调用,也可以传递任何参数,无需指针方式调用;

Windows消息使用流程

一、首先引用Winapi.Messages消息单元

uses....Winapi.Windows,....;

二、定义一个消息ID,整型常数。对于用户自定义消息,该常数必须大于WM_USER。

constWinMessageID      = WM_USER + 1;   //WM_USER 在Winapi.Messages中定义

三、在对象上定义一个响应消息的方法:

private{ Private declarations }//Winapi.Messages 中的消息响应事件procedure OnWinMessage(var Message); message WinMessageID;  //定义一个消息ID对应的消息处理函数过程

四、实现消息响应方法对应的函数体:

procedure TForm_Message_VCL.OnWinMessage(var Message);
varPStudent : ^TStudent;
beginPStudent := Pointer( Winapi.Messages.TMessage(Message).WParam);Memo1.Lines.Add('Win消息处理记录消息 姓名: ' + PStudent.Name);Memo1.Lines.Add('Win消息处理记录消息 年龄: ' + PStudent.age.ToString);if PStudent.Sex thenMemo1.Lines.Add('Win消息处理记录消息 性别: 男')elseMemo1.Lines.Add('Win消息处理记录消息 性别: 女');//如果是SendMessage 可以不释放 PStudent 指针资源,因为SendMessage是同步执行的,发送消息函数应该自己销毁,当然这里销毁也是可以的//如果是PostMessage,此时应该销毁这个指针,因为PostMessage是不需要等待结果的,此时如果释放资源就会出现问题。Dispose(PStudent);end;

五、发送消息,可以使用SendMessage或者PostMessage,其区别在于SendMessage需要等待函数执行完成返回结果,而PostMessage无需等待消息结果。

procedure TForm_Message_VCL.Button_SendMessageWinClick(Sender: TObject);
varPStudent: ^TStudent; //记录指针
begin//申请指针资源New(PStudent);//构造消息体内容PStudent.Name := LabeledEdit_WinName.Text;PStudent.age  := SpinEdit_WinAge.Value;PStudent.Sex  :=CheckBox_WinSex.Checked;//按照 windows 的约定发送消息,必须包含句柄SendMessage(Self.Handle,WinMessageID,DWord(PStudent),0);//此处是否释放需要根据程序决定,总之上面已经申请了资源,一定要记得在合适的地方释放//Dispose(PStudent);
end;

Windows消息注意事项

必须使用SendMessage或者PostMessage,两个函数定义的格式(参见Windows文档)如下:

LRESULT SendMessage(
  [in] HWND   hWnd,
  [in] UINT   Msg,
  [in] WPARAM wParam,
  [in] LPARAM lParam
);

参数说明

hWnd:表示的是窗口对象的句柄,窗口对象必须存在;

Msg:消息ID,整型数。对应Demo中的 WinMessageID

wParam:就是需要发送的消息体指针

IParam:附加的额外消息体指针

对于具体的消息体,可以任意定义,Demo中定义的是一个记录体:

typeTStudent = recordName : string;age  : Byte;Sex  : Boolean;end;

如果不使用Windows消息,而是使用Delphi系统提供的Dispatch机制,也可以实现消息分发。

Dispatch消息使用流程

一、 和Windows消息一样,首先引用Winapi.Messages消息单元

uses....Winapi.Windows,....;

二、定义一个消息ID,整型常数。对于用户自定义消息ID,一般不要大于50000,否则会引起编译错误。同时定义一个需要传递的消息结构

constDispatchMessageID = WM_USER + 2;   //Dispatch 消息type//Dispatch需要的消息结构,注意增加了一个id字段TStudent2 = recordid   : Word;    //消息IDName : string;age  : Byte;Sex  : Boolean;end;

三、在对象上(注意不一定是窗口对象,也就是说不一定需要有句柄)定义一个消息响应函数过程:

private{ Private declarations }//Winapi.Messages 中的消息响应事件procedure OnWinMessage(var Message); message WinMessageID;  //定义一个消息ID对应的消息处理函数过程procedure OnDispatchMessage(var Message); message DispatchMessageID;  //定义一个消息ID对应的消息处理函数过程

四、实现消息响应方法对应的函数体(请注意和Windows消息的实现体的区别):

procedure TForm_Message_VCL.OnDispatchMessage(var Message);
varStudent2 : TStudent2;
beginStudent2 := TStudent2(Message);Memo1.Lines.Add('Win2消息处理记录消息 姓名: ' + Student2.Name);Memo1.Lines.Add('Win消息处理记录消息 年龄: ' + Student2.age.ToString);if Student2.Sex thenMemo1.Lines.Add('Win消息处理记录消息 性别: 男')elseMemo1.Lines.Add('Win消息处理记录消息 性别: 女');
end;

五、发送消息,调用对象上的Dispatch函数(Delphi系统已经在每个对象上都实现了Dispatch)

procedure TForm_Message_VCL.Button_DispatchClick(Sender: TObject);
varStudent2 : TStudent2;
beginStudent2.id := DispatchMessageID;//构造消息体内容Student2.Name := LabeledEdit_WinName.Text;Student2.age  := SpinEdit_WinAge.Value;Student2.Sex  :=CheckBox_WinSex.Checked;//通过对象的Dispatch发送消息,实际上就是调用函数Self.Dispatch(Student2);
end;

Dispatch消息注意事项:

Dispatch传递参数不需要指针,但是消息体中增加了一个字段id,是一个Word型的整数。对于Dispatch的定义在Delphi中有如下说明:

Calls message-handling methods for the object, based on the contents of the Message parameter.

Call Dispatch to automatically pass messages to the appropriate message handler.

Dispatch determines whether a message is in the list of message handlers declared for the object. If the object does not handle the message, Dispatch then examines the message-handler list of the ancestor class, and continues checking ancestors until it either finds a specific handler or runs out of ancestors, in which case it calls DefaultHandler.

The only assumption Dispatch makes about the data in Message is that the first two bytes contain a message ID—that is, an integer that determines which message handler Dispatch calls. Although any kind of data can be passed to Dispatch, most TObject descendants expect a message record such as TMessage or a specific data structure type.

注意红色加粗这句,意思是消息体的前两个字节必须包含一个 message ID。这个就是我们TStudent2中的id字段。

下一节:【Delphi】中使用消息Messages(六)总结及源代码

【Delphi】中使用消息Messages(五)Windows消息相关推荐

  1. DELPHI 中 Window 消息大全使用详解

    Window 消息大全使用详解 导读: Delphi是Borland公司的一种面向对象的可视化软件开发工具. Delphi集中了Visual C++和Visual Basic两者的优点:容易上手.功能 ...

  2. 在Delphi中获取和修改文件的时间

    Delphi中提供了很完备的Windows API函数的调用接口,可以方便的进行高级Windows编程.利用Delphi中的FindFirst函数可以得到一个文件的属性记录,该记录中的FindData ...

  3. 【Delphi】中使用消息Messages(七)Android 系统消息

    前面6节介绍了Delphi中消息机制的基本原理,并通过一个演示程序进行实际演示.本节开始,我讲介绍Delphi开发Android系统时需要使用的一些特殊消息.以下所说系统,泛指Android系统. 一 ...

  4. 【Delphi】中使用消息Messages(八)Android 系统消息感知

    目录 一.实现android广播消息事件绑定 二.在onReceive中实现接收系统广播消息处理: 三.注册(订阅)系统状态变化消息广播: 四.控件整体定义: 在上一节我提出了两个问题: App中主动 ...

  5. Delphi中对消息的处理

    Delphi中对消息的处理 刘文彦  张  翔  摘   要:本文对覆盖消息和自定义消息的处理方法进行讨论,总结出两类消息处理的步骤, 并通过例程加以实现. 关键词:Delphi; 消息; 通 ...

  6. Delphi中的消息截获

    Windows是一个基于消息驱动的系统,因此,在很多时候,我们需要截获一些消息然后自己进行处理.而VCL系统又有一些特定的消息.下面对我所了解的delphi环境中截获消息进行一些总结.       就 ...

  7. 在WPF中处理Windows消息

    在Winform中 处理Windows消息通过重写WndProc方法 在WPF中 使用的是System.Windows. Sytem.Windows.Controls等名字空间,没有WndProc函数 ...

  8. C#中如何截取Windows消息来触发自定义事件

    原文 C#中如何截取Windows消息来触发自定义事件 在c#windows开发中,我们常常会遇到拦截windows消息,来触发某个特定任务的问题. 由于目前使用c#的开发人员非常多,而且大多数c#程 ...

  9. wince 中Windows消息的十六进制表述

    windows mobile编程,无论使用eVC还是.net CF,都脱不开windows消息机制这个框架.在日常的程序编写过程中,windows消息也是很常用的,windows消息常用的api函数也 ...

最新文章

  1. redhat 复制文件夹及子文件夹_python文件夹怎么操作呢??(建议详读)
  2. python 导入库:from scipy.misc import imread出错问题
  3. UVA 307 Sticks
  4. 【面试招聘】社招如何拿到心仪公司的offer
  5. linux计划任务执行日志,linux中centos制定计划任务执行命令并且输出日志
  6. 基于ABP落地领域驱动设计-04.领域服务和应用服务的最佳实践和原则
  7. imagettftext php7,mac php7 imagettftext
  8. android双联动列表,Android Fragment实现列表和内容联动
  9. 支付宝APP支付(基于Java实现支付宝APP支付)
  10. 实践案例丨GaussDB网络重传/丢包问题定位总结
  11. 25-[jQuery]-ajax
  12. css实现w3cschool广告轮播图
  13. IBM DB2百度云下载
  14. eml文件可以转换为html,eml格式转换成word eml文件转换word
  15. 通过jenkins+gitlab构建CI/CD流水线
  16. [补集转化 有序化去重] Ural 1212 Battleship
  17. 原生64位卸载工具Revo Uninstaller Pro V2.5.7
  18. 香港保险和内地保险的利与弊,有什么区别?
  19. Java中grabImage_JavaCV实现将视频以帧方式抽取
  20. 数据赋能,助力新零售数字化突围

热门文章

  1. memcpy函数优化及DMA对比
  2. 轮盘赌算法-Roulette
  3. 嵌入式 IIC(I2C)协议
  4. 一篇文章说完Flutter页面路由导航及传参
  5. 设计模式(10)——策略模式
  6. java有函数吗_java有函数吗?
  7. C语言绘制象棋棋盘/残局
  8. VS+OpenCV+VC超详细的配置教程
  9. PHP 无限极分类下拉列表实现
  10. 求解TSP问题神器——elkai(简单好用)