快速业务通道

深入VCL理解BCB的消息机制2

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30

重载TControl的WndProc方法

还是先谈谈VCL的继承策略。VCL中的继承链的顶部是TObject基类。一切的VCL组件和对象都继承自TObject。

打开BCB帮助查看TControl的继承关系:

TObject->TPersistent->TComponent->TControl

呵呵,原来TControl是从TPersistent类的子类TComponent类继承而来的。TPersistent抽象基类具有使用流stream来存取类的属性的能力。

TComponent类则是所有VCL组件的父类。

这就是所有的VCL组件包括您的自定义组件可以使用dfm文件存取属性的原因『当然要是TPersistent的子类,我想您很少需要直接从TObject类来派生您的自定义组件吧』。

TControl类的重要性并不亚于它的父类们。在BCB的继承关系中,TControl类的是所有VCL可视化组件的父类。实际上就是控件的意思吧。所谓可视化是指您可以在运行期间看到和操纵的控件。这类控件所具有的一些基本属性和方法都在TControl类中进行定义。

TControl的实现在\Borland\CBuilder5\Source\Vcl\control.pas中可以找到。『可能会有朋友问你怎么知道在那里?使用BCB提供的Search -> Find in files很容易找到。或者使用第三方插件的grep功能。』

好了,进入VCL的源码吧。说到这里免不了要抱怨一下Borland。哎,为什么要用pascal实现这一切.....:-(

TControl继承但并没有重写TObject的Dispatch()方法。反而提供了一个新的方法就是xycleo提到的WndProc()。一起来看看Borland的工程师们是怎么写的吧。

procedure TControl.WndProc(var Message: TMessage);
var
  Form: TCustomForm;
begin
//由拥有control的窗体来处理设计期间的消息
  if (csDesigning in ComponentState) then
  begin
   Form := GetParentForm(Self);
   if (Form <> nil) and (Form.Designer <> nil) and
    Form.Designer.IsDesignMsg(Self, Message) then Exit;
  end
//如果需要,键盘消息交由拥有control的窗体来处理
  else if (Message.Msg >= WM_KEYFIRST) and (Message.Msg <= WM_KEYLAST) then
  begin
   Form := GetParentForm(Self);
   if (Form <> nil) and Form.WantChildKey(Self, Message) then Exit;
  end
//处理鼠标消息
  else if (Message.Msg >= WM_MOUSEFIRST) and (Message.Msg <= WM_MOUSELAST) then
  begin
   if not (csDoubleClicks in ControlStyle) then
    case Message.Msg of
     WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK, WM_MBUTTONDBLCLK:
      Dec(Message.Msg, WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
    end;
   case Message.Msg of
    WM_MOUSEMOVE: Application.HintMouseMessage(Self, Message);
    WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
     begin
      if FDragMode = dmAutomatic then
      begin
       BeginAutoDrag;
       Exit;
      end;
      Include(FControlState, csLButtonDown);
     end;
    WM_LBUTTONUP:
     Exclude(FControlState, csLButtonDown);
   end;
  end
// 下面一行有点特别。如果您仔细的话会看到这个消息是CM_VISIBLECHANGED.
// 而不是我们熟悉的WM_开头的标准Windows消息.
// 尽管Borland没有在它的帮助中提到有这一类的CM消息存在。但很显然这是BCB的
// 自定义消息。呵呵,如果您对此有兴趣可以在VCL源码中查找相关的内容。一定会有不小的收获。
  else if Message.Msg = CM_VISIBLECHANGED then
   with Message do
    SendDockNotification(Msg, WParam, LParam);
// 最后调用dispatch方法。
  Dispatch(Message);
end;

看完这段代码,你会发现TControl类实际上只处理了鼠标消息,没有处理的消息最后都转入Di

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号