快速业务通道

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

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
spatch()来处理。

但这里需要强调指出的是TControl自己并没有获得焦点Focus的能力。TControl的子类TWinControl才具有这样的能力。我凭什么这样讲?呵呵,还是打开BCB的帮助。很多朋友抱怨BCB的帮助实在不如VC的MSDN。毋庸讳言,的确差远了。而且这个帮助还经常有问题。但有总比没有好啊。

言归正传,在帮助的The TWinControl Branch 分支下,您可以看到关于TWinControl类的简介。指出TWinControl类是所有窗体类控件的基类。所谓窗体类控件指的是这样一类控件:

1. 可以在程序运行时取得焦点的控件。

2. 其他的控件可以显示数据,但只有窗体类控件才能和用户发生键盘交互。

3. 窗体类控件能够包含其他控件(容器)。

4. 包含其他控件的控件又称做父控件。只有窗体类控件才能够作为其他控件的父控件。

5. 窗体类控件拥有句柄。

除了能够接受焦点之外,TWinControl的一切都跟TControl没什么分别。这一点意味着TwinControl可以对许多的标准事件作出响应,Windows也必须为它分配一个句柄。并且与这个主题相关的最重要的是,这里提到是由BCB负责来对控件进行重画以及消息处理。这就是说,TwinControl封装了这一切。

似乎扯的太远了。但我要提出来的问题是TControl类的WndProc方法中处理了鼠标消息。但这个消息只有它的子类TwinControl才能够得到啊!?

这怎么可以呢... Borland是如何实现这一切的呢?这个问题实在很奥妙。为了看个究竟,再次深入VCL吧。

还是在control.pas中,TWinControl继承了TControl的WndProc方法。源码如下:

procedure TWinControl.WndProc(var Message: TMessage);
var
  Form: TCustomForm;
  KeyState: TKeyboardState;
  WheelMsg: TCMMouseWheel;
begin
  case Message.Msg of
   WM_SETFOCUS:
    begin
     Form := GetParentForm(Self);
     if (Form <> nil) and not Form.SetFocusedControl(Self) then Exit;
    end;
   WM_KILLFOCUS:
    if csFocusing in ControlState then Exit;
   WM_NCHITTEST:
    begin
     inherited WndProc(Message);
     if (Message.Result = HTTRANSPARENT) and (ControlAtPos(ScreenToClient(
      SmallPointToPoint(TWMNCHitTest(Message).Pos)), False) <> nil) then
      Message.Result := HTCLIENT;
     Exit;
    end;
   WM_MOUSEFIRST..WM_MOUSELAST:
    //下面这一句话指出,鼠标消息实际上转入IsControlMouseMsg方法来处理了。
    if IsControlMouseMsg(TWMMouse(Message)) then
    begin
     if Message.Result = 0 then
      DefWindowProc(Handle, Message.Msg, Message.wParam, Message.lParam);
     Exit;
    end;
   WM_KEYFIRST..WM_KEYLAST:
    if Dragging then Exit;
   WM_CANCELMODE:
    if (GetCapture = Handle) and (CaptureControl <> nil) and
     (CaptureControl.Parent = Self) then
     CaptureControl.Perform(WM_CANCELMODE, 0, 0);
  else
   with Mouse do
    if WheelPresent and (RegWheelMessage <> 0) and
     (Message.Msg = RegWheelMessage) then
    begin
     GetKeyboardState(KeyState);
     with WheelMsg do
     begin
      Msg := Message.Msg;
      ShiftState := KeyboardStateToShiftState(KeyState);
      WheelDelta := Message.WParam;
      Pos := TSmallPoint(Message.LParam);
     end;
     MouseWheelHandler(TMessage(WheelMsg));
     Exit;
    end;
  end;
  inherited WndProc(Message);
end;

鼠标消息是由IsControlMouseMs

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号