• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Windows消息机制和Delphi的事件驱动机制

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

http://blog.163.com/muhx1981@126/blog/static/81459489200610305170213/

    一直以来都弄不清楚Delphi的事件驱动机制,今天看Delphi源代码,似乎有些明白了。
    问题:用鼠标单击按钮,为什么能执行我写的代码?
    环境:创建一个工程并保存,窗体上放置一个Button,在Button上双击鼠标左键,在Button1Click中写入一行代码,保存,所有控件的名字都保持默认的命名。
    现象:
      1.在Unit1.dfm中有一行语句
          OnClick = Button1Click
      2.TButton类中有published限制的属性
          property OnClick;
        从声明方式可知是继承而来的属性。
      3.TButton的父类和祖先类TButtonControl, TWinControl中没有关于OnClick的信息。
      4.TWinControl的父类TControl中有Published限制的属性
          property OnClick: TNotifyEvent read FOnClick write FOnClick stored IsOnClickStored;
      5.TNotifyEvent = procedure(Sender: TObject) of Object;
        这是一个方法指针的定义。
      6.跟踪FOnClick,发现只有在下面过程中使用到FOnClick:
          procedure TControl.Click;
          begin
            { Call OnClick if assigned and not equal to associated action's OnExecute.
              If associated action's OnExecute assigned then call it, otherwise, call
              OnClick. }
            if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
              FOnClick(Self)
            else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
              ActionLink.Execute(Self)
            else if Assigned(FOnClick) then
              FOnClick(Self);
          end;
        这段代码有一条注释。
      7.跟踪过程Click,发现只存在以下过程:
          procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
          begin
            inherited;
            if csCaptureMouse in ControlStyle then MouseCapture := False;
            if csClicked in ControlState then
            begin
              Exclude(FControlState, csClicked);
              if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
            end;
            DoMouseUp(Message, mbLeft);
          end;
        即,当鼠标左键送开并且满足一定条件时,执行Click过程。
        需要注意的是当执行Click过程之后依然需要执行DoMouseUp过程。
      8.找到这个过程的定义处,发现类接口中如下定义:
          procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
        而消息常量:
          {$EXTERNALSYM WM_LBUTTONUP}
          WM_LBUTTONUP = $0202;
          
    至此,已经和Wondows消息机制联系起来了。
    
    结论:控件的事件实际上是响应Windows消息的过程。事件用方法指针实现,当将过程赋值给方法指针,而Wondows发出了对应的消息,则通过事件(方法指针)指向的实际过程来使得对应的消息得到响应。 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
TWebBrowser组件在DELPHI中POST数据和取得网页源文件发布时间:2022-07-18
下一篇:
Delphi的颜色转换发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap