自定义CM消息的原因

最近看VCL源码,有个问题,经常需要发送CM_消息去调用某个函数,我就不明白,为什么要这样。直接调用函数名称不是挺好吗,尤其是调用虚函数的话,一样很灵活。

比如:
procedure TWinControl.SetBorderWidth(Value: TBorderWidth);
begin
  if FBorderWidth <> Value then
  begin
    FBorderWidth := Value;
    Perform(CM_BORDERCHANGED, 0, 0); // 这里直接调用函数名称不好吗?
  end;
end;

procedure TWinControl.CMBorderChanged(var Message: TMessage);
begin
  inherited;
  if HandleAllocated then
  begin
    SetWindowPos(Handle, 0, 0,0,0,0, SWP_NOACTIVATE or
    SWP_NOZORDER or SWP_NOMOVE or SWP_NOSIZE or SWP_FRAMECHANGED);
    if Visible then
      Invalidate;
  end;
end;

而且发消息还有个缺点,更依赖于系统,如果系统正忙怎么办?而虚函数只和语言自己有关系,不是更稳妥可靠吗?为什么要自定义消息呢?还把VCL框架搞的更复杂了。真的不懂,请各位指教,谢谢。

----------------------------------------------------------------

Perform是直接调用WindowProc函数,同步调用没有系统忙不忙之说.相当于SendMessage.
不发消息直接调用函数倒也行,不过系统的消息处理总是要处理的.不如就统一走消息这条路了.

都说的在理。不过为啥要统一走消息啊,自定义消息累不累啊,而且我看有些地方也是调用虚函数的,也不在少数。不过Borland有意搞这个自定义消息,应该还是别有用意?兄台能不能挖空心思再想想啊。

另外,我有空把它全部改成虚函数试试,看看编出来的程序还会正确执行不?这不失为一次对OO深刻理解的尝试。

参考:
http://bbs.csdn.net/topics/390888872

另外消息函数实际是动态函数,如果子类派生层次比较多的话比虚函数在内存上是要节省一些的.而用法和虚函数又差不多

消息可以跨进程,虚函数能吗

----------------------------------------------------------------

最主要的参数的简洁,Perform会把三个参数重新组织成一个消息。CM消息还能做WndProc做响应和覆盖,虚函数不行,只能单独写。根据传来的三个参数来构建一个消息,这也许是使用CM的关键原因之一(否则每个虚函数都需要三个参数还不烦死;或者每个发送方都组装一遍也很烦,这样代码就重复了)。统一走消息路线好像是很正确的理解。

时间: 2024-10-25 14:30:46

自定义CM消息的原因的相关文章

自定义网络消息

#define MSG_HEAD_LEN 4 //消息头部结构 typedef struct tagMsg { //消息类型 u16 type; //消息体长度 u16 length; }TMsg; void receive(SOCKET s) { char buffer[1024*28]; //CServMsg cMsg; u16 wRecvLen = 0 ; u16 wMsgLen = 0; u16 wRet = 0; while (TRUE) { if(wRecvLen < MSG_HEA

FMX有两种消息处理的实现方式,一种是用TMessageManager来实现自定义的消息,另外一种象TEdit中的实现,直接声明消息方法

看FMX代码,发现有两种消息处理的实现方式,一种是用TMessageManager来实现自定义的消息,另外一种象TEdit中的实现,直接声明消息方法. 早前,看过文章说TMessageManager的用法,可用到的时候,又找不到,只好自己动手. 我的应用场景是这样: 当前的Frame弹出一个对话框Frame,当操作对话框的时候,想让当前的Frame跟着应响,让用户看到操作的结果,如下图,点大中小字体,后面的题目的字体会跟着变化: 参考fmx的代码,试着用消息机制实现了: 1.声明消息类: typ

WIN7/8系统下程序接收不到WM_COPYDATA 消息的原因和解决

在WIN7/win8,如果发送消息的程序用户权限低于和接收消息的程序,则消 息无法传递.发送程序必须等于或者等于接收程序的权限.如发送与接收 是同一个用户,或者发送是管理员帐户,接收是是普通用户,这样就可以 成功. 以下内容摘自: http://blog.csdn.net/tian_jinping/article/details/12950077 正如我们前文所说,等级的划分,是为了防止以下犯上.所以,有了用户 界面特权隔离,一个运行在较低特权等级的应用程序的行为就受到了诸多 限制,它不可以:

Laravel 5.5 FormRequest 自定义错误消息

Laravel 5.5 FormRequest 自定义错误消息 使用FormRequest进行表单验证,就不用让验证逻辑和控制器里面的逻辑都混在一起.但在使用的时候呢,发现json错误返回的数据,与我们想要的有点差距.下面我给个例子:(不喜勿喷) 在用ajax进行提交时,如果验证错了,那么他会返回 如果是权限错了,他会返回 但我想要的是 那怎么办呢,其实很简单 我们只需要在 App\Exceptions\Handler 里面重写两个函数就可以了 添加上这两个函数,然后里面怎么定义,就看你了 记得

Kafka 自定义指定消息partition策略规则及DefaultPartitioner源码分析

Kafka 自定义指定消息partition策略规则及DefaultPartitioner源码分析 一.概述 kafka默认使用DefaultPartitioner类作为默认的partition策略规则,具体默认设置是在ProducerConfig类中(如下图) 二.DefaultPartitioner.class 源码分析 1.类关系图 2.源码分析 public class DefaultPartitioner implements Partitioner { //缓存map key->to

SpringMVC自定义配置消息转换器踩坑总结

问题描述 最近在开发时候碰到一个问题,springmvc页面向后台传数据的时候,通常我是这样处理的,在前台把数据打成一个json,在后台接口中使用@requestbody定义一个对象来接收,但是这次数据传不过去,报400的错误,原因也很容易想到,该对象有一个属性也是一个对象,属性对象是用抽象类定义的,他有几个具体实现,具体实现中的字段都是不一样的,springmvc是不会自动识别并注入你使用的是哪一个实现类的.所以无法传过来. 传递对象如下: @Data public class Activit

Android中实现自定义XMPP消息包收发

在Android平台实现XMPP即时通讯主要是使用asmack这个包,asmack是XMPP协议的实现.但是asmack只能帮助我们实现一些基本消息包的收发,如果需要实现特定的自定义消息包收发需要我们自己处理. 一.asmack消息的发送和接收 发送Message消息: 发送一个message结的消息,可以使用sendMessage()发送消息,这个方法有两个重载方法,一种类型的参数是String类型,另一种则是传入Message对象.String类型的方法传入的字符串即为要发送的消息:传入me

【Java TCP/IP Socket】构建和解析自定义协议消息(含代码)

在传输消息时,用Java内置的方法和工具确实很用,如:对象序列化,RMI远程调用等.但有时候,针对要传输的特定类型的数据,实现自己的方法可能更简单.容易或有效.下面给出一个实现了自定义构建和解析协议消息的Demo(书上例子). 该例子是一个简单的投票协议.这里,一个客户端向服务器发送一个请求消息,消息中包含了一个候选人的ID,范围在0~1000.程序支持两种请求:一种是查询请求,即向服务器询问候选人当前获得的投票总数,服务器发回一个响应消息,包含了原来的候选人ID和该候选人当前获得的选票总数:另

Android开发实践:自定义带消息循环(Looper)的工作线程

上一篇文章提到了Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也提供了封装有消息循环(Looper)的HandlerThread类,这种线程,可以绑定Handler()对象,并通过Handler的sendMessage()函数向线程发送消息,通过handleMessage()函数,处理线程接收到的消息.这么说比较抽象,那么,本文就利用基础的Java类库,实现一个带消息循环(Looper)的线程,以帮助初学者理解这样一个Looper到底是怎么工作的. 1