最近看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的关键原因之一(否则每个虚函数都需要三个参数还不烦死;或者每个发送方都组装一遍也很烦,这样代码就重复了)。统一走消息路线好像是很正确的理解。