delphi的消息处理不是好理解的,我在学习时有种云里雾里的感觉,网上的资料太微观化,不利于初学者在脑子里建立起大的框架。没有这个大框架学习微观处理知识时就不知为什么要这么处理。经过一段时间的摸索,自己有了一些了解,这些也是刚学习时对我困惑最严重的,今天写出来供参考,也许理解的不全面或不对,还肯请过来人指点,不胜感激!
1.delphi消息处理独特之处:
delphi处理消息有自己的独特之处。常规的窗口(非delphi)在注册时,指定了一个静态函数作为回调函数(资料:windows 的回调函数使用静态函数: 在类中, static 型的成员函数,由于是类所拥有的,而不是具体对象所有的 ,这一点对于 windows 的回调机制非常有用。因为对于回调函数而言, windows 不会借助任何对象去调用它,也就不会传递 this 指针,那么对于一般成员函数作为回调函数的后果,就是堆栈中有一个随机的变量会成为 this 指针,这当然会引发程序的崩溃。而 static 函数,由于是整个类的,屏蔽了 this 指针。因此,如果成员函数作为回调函数,就应该用 static 去修饰它。)。
    而delphi要用自己的方式去处理消息,因此在窗体类的构造函数中(twincontrol.create), 利用一种技巧把窗体的静态回调函数替换成了twincontrol的成员方法,从此消息处理进入到了delphi的轨道。这种技巧就是:先把一个符合windows回调函数要求的静态函数InitWndProc注册到窗体结构中,当初次回调InitWndProc时(CreateWindowEx创建窗体实例时候系统将发送一个WM_CREATE消息给窗口,处理这个消息的是InitWndProc。),InitWndProc将自己替换为作为处理消息的twincontrol的成员方法,从此,windows回调到的就是twincontrol的成员方法mainwndproc,delphi的消息处理从这里开始,而InitWndProc 就不再被调用了。(delphi利用汇编代码把成员方法变成了符合windows要求的静态函数形式,其实就是隐藏了代表对象的参数self),
2.窗体中控件事件消息的处理:
比如单击窗体中的button控件,系统会响应LbuttonUP事件,通过上述的技巧,系统调用到了Twincontrol.mainwndproc,但它并没有处理这个消息WM_LBUTTONUP,按类的继承关系一直上朔,最终消息由windows处理,windows把该消息转换为wm_command发给button的父窗体,在该父窗体的类继承关系中找到处理wm_command的方法,并把wm_command转换成Cn_command消息发送给button,同样根据类继承关系中找到处理cn_command的方法,如果有响应代码就执行。由此可知,窗体中的控件发生的事件必须通过消息,由它的父窗体知道。因为父窗体管理着这些控件,所以这些控件的状态必须随时通知父窗体。