简单介绍一下VCL消息传递
VCL除了封装了WINDOWS消息外,还有自己自定义的一些消息。WINDOWS的消息以WM_ 开头,可以参考Delphi Help里带的WINDOWS SDK 或MSDN, 在Messages.pas文件中也可以看得到. VCL的一些内部消息,一般是以CM_ CN_ CB_ 等开头的,在Controls.pas文件中也可以看得到,具体的使用可以查看Delphi方面的资料。
下面,我就VCL的内部消息做一个简单介绍。
Delphi 中每一个VCL构件都有一内在的消息处理机制,基本原理就是构件类接收到某些消息并把它们发送给适当的处理方法, 如果没有特定的处理方 法,则调用缺省的消息处理句柄。处理消息的几个方法有:
mainwndproc 是定义在Twincontrol 类中的一个静态方法, 不能被重载(Override)。 它不直接处理消息, 而是交由wndproc 方法处理, 并为wndproc 方法提供一个异常处理。Mainwndproc 方 法 声 明 如 下:
procedure MainWndProc(var Message: TMessage);
Wndproc 是在Tcontrol 类中定义的一个虚拟方法, 由它调用dispatch 方法来进行消息的分配, wndproc 方 法 声 明 如 下:
procedure WndProc(var Message: TMessage); virtual;
dispatch 方法是在Tobject 根类中定义的, 其声明如下:
procedure Tobject.dispatch(var Message);
传递给dispatch 的消息参数必须是一个记录 类型, 且这个记录中第一个入点必须是一个cardinal 类型的域(field), 它包含了要分配的消息的消息号码, 如Tmessage 类型(具体定义参见Delphi), 而Dispatch 方法会根据消息号码调用构件的最后代类中处理此消息的句 柄方法. 如果此构件和它的祖先类中都没有对应此消息的处理句柄,Dispatch 方法便会调 用Defaulthandler 方法.Defaulthandler 方法是定义于Tobject 中的虚拟方法, 其声明如下:
procedure Defaulthandler(var Message);virtual;
Tobject 类中的Defaulthandler 方法只是实现简单的返回而不对消息进行任何的处理. 我们可以通过对此虚拟方法的重载, 在子类中实现对消息的缺省处理. 对于VCL中的构件 而言, 其Defaulthandler 方法会启动 windows API 函 数Defwindowproc 对消息进行处理.
以上篇的TMyEdit为例.
TMyEdit=class(TEdit)
private
…
protected
////重写消息事件 消息的声明
procedure CMExit(var Message: TCMExit); message CM_EXIT;?
public
…
endl
消息的声明如上,消息处理方法必须是一个过程, 方法后面必须有一个Message. 在后面加消息定义,不需要用override 命令来显式指明重载, 且一般声明在构件的protected 或private 区.
当然你可以写自己的消息,一般从WM_User 加一个常数作为你的消息.你可以通过SendMessage 和 PostMessage 触发你的消息. VCL的所有事件都是通过消息来触发的, 由此,你也可以增加自己构件事件. 顺便说一下SendMessage 和 PostMessage的区别: 前一个是有返回, 后一个是不需要返回的. 如果你对构件的某个改变是依赖于某个消息的所触发的处理完成的结果,你就必须用SendMessage . SendMessage的声明如下
function SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
第一个参数是构件句柄, 第二就是消息常量, 后面的是一些其他参数信息, 鼠标,键盘等等.在这里我们不另外定义自定义消息了, 就用CM_EXIT 试举一例:
SendMessage(MyEdit.hanle, CM_EXIT,0,0 ) ;
这样就可以触发CMExit 也就是控件的焦点退出OnExit事件.
关于VCL消息就说这麽多了,我自己也没有搞得太明白,不太说得清楚.? Windows API就不说了, 很多资料可以查, MSDN很全, 我也只知道几个常用的.
?