zoukankan      html  css  js  c++  java
  • TWinControl与TControl的覆盖函数(TWinControl对TControl的10个消息覆盖函数,17个覆盖函数,私有虚函数仍可多态)

    手工找出来,对比一下,有助于VCL框架的理解。
    --------------------------------------------------------------------------------------------

    才注意到,所有消息处理函数都是私有的,为什么呢?
    问题:其子类会继承它们吗?回答:不能直接继承它们,但不影响子类通过inherite调用,程序员也不能在子类或者外部直接调用它们。详细可以Google一下“虚函数 私有函数”,虽然出来的结果是C++的,而且这里是动态函数,但道理是相同的。
    关于私有虚函数的特点,这是我参考别人帖子以后总结的(C++和Java的机制还有所不同,Delphi与C++一致):
    http://www.cnblogs.com/findumars/p/4164736.html

    TWinControl对TControl的消息覆盖函数,共10个,其中2个WM消息,8个CM消息:

    procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED; // 间接调用DefaultHandler 先调整位置,后调整大小
    procedure WMContextMenu(var Message: TWMContextMenu); message WM_CONTEXTMENU; // 判断是否落在图形控件的区间里,子控件没处理,才轮到自己处理
    procedure CMVisibleChanged(var Message: TMessage); message CM_VISIBLECHANGED; procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED; procedure CMDesignHitTest(var Message: TCMDesignHitTest); message CM_DESIGNHITTEST; procedure CMSysFontChanged(var Message: TMessage); message CM_SYSFONTCHANGED; procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED; procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED; procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED; procedure CMFloat(var Message: TCMFloat); message CM_FLOAT;

    TControl对父类的覆盖函数(都是很琐碎的一些基本功能,不需要深刻理解,不过最好笑的是图形控件也有WndProc函数,主要处理鼠标与键盘消息),共12个,分为3类:

    // 其中3个是对TObject类函数的覆盖:
    constructor Create(AOwner: TComponent); override; // 加入组件,指定WndProc指针,控件属性
    destructor Destroy; override; // 把属性Parent赋值nil
    procedure DefaultHandler(var Message); override; // 只处理三个处理文字的消息,不再继续传递消息了。TComponent根本没有覆盖它
    // 其中2个是对TPersistent类函数的覆盖:
    procedure AssignTo(Dest: TPersistent); override; // 根据Action设置五项属性
    procedure DefineProperties(Filer: TFiler); override; // 函数内容监督
    // 其中7个是对TComponent类函数的覆盖:
    procedure ReadState(Reader: TReader); override; // 发送5个组件消息
    procedure SetParentComponent(Value: TComponent); override; // 设置父组件
    procedure SetName(const Value: TComponentName); override; // 先判断是否允许设置名字
    procedure Loaded; override; // 主要处理新增的Action
    procedure Notification(AComponent: TComponent; Operation: TOperation); override; // 在删除组建的时候,去掉右键菜单和和Action
    function GetParentComponent: TComponent; override; // 直接返回的就是父控件(就是TWinControl),而TComponent的同名方法直接返回Nil指针
    function HasParent: Boolean; override; // 简单判断父控件是否为空

    TWinControl对父类的覆盖函数,共25个,分为三类:

    // 其中6个是对TControl函数的进一步覆盖(源自TObject或者TPersistent或者TComponent函数),属于增强型函数:
    constructor Create(AOwner: TComponent); override; // 调用MakeObjectInstance 创建TBrush 创建边条(用不用另说)
    destructor Destroy; override; // 先挨个通知子控件,然后移除和销毁所有子控件,最后还归还FObjectInstance的空间
    procedure DefaultHandler(var Message); override; // Delphi与生俱来的功能,处理少部分消息(右键菜单,通知消息,传递消息给CallWindowProc API,根据消息找控件RM_GetObjectInstance),最后传递给Windows处理消息
    procedure ReadState(Reader: TReader); override; // 读入数据后,全部重整(调整对齐和Tab顺序,重新显示)
    procedure AssignTo(Dest: TPersistent); override; // 增加Action的HelpContext(在前面的基础上)
    procedure DefineProperties(Filer: TFiler); override; // 重新对齐
    // 其中2个是直接对TComponent类函数的覆盖(TControl没有相应的类函数),而TComponent提供的是空函数体:
    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; // 如果当前控件的子控件的父控件是root,那么执行函数Proc(子控件)
    procedure SetChildOrder(Child: TComponent; Order: Integer); override; // 设置Z顺序(不管这个子控件是图形控件还是TWin控件)

    其中最重要的当属对TControl类的覆盖,共17个:

    // 消息与事件
    procedure WndProc(var Message: TMessage); override; // 虚函数,处理少部分消息(设置焦点,转发鼠标消息给图形控件),如果找不到,则调用父类同名函数
    procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
    function GetActionLinkClass: TControlActionLinkClass; override; // 简单函数,取得类之类
    
    // 客户区
    function GetClientOrigin: TPoint; override; // 简单调用API
    function GetClientRect: TRect; override;    // 简单调用API
    procedure SetZOrder(TopMost: Boolean); override; // 调用API
    
    // 改变大小
    procedure AdjustSize; override; // 调用API
    function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override; // 标识如何重定义尺寸
    function CanResize(var NewWidth, NewHeight: Integer): Boolean; override;
    procedure ConstrainedResize(var MinWidth, MinHeight, MaxWidth, MaxHeight: Integer); override;
    procedure ChangeScale(M, D: Integer); override;
    
    // 其中最重要的是对显示函数的处理:
    procedure Repaint; override;    // 简单调用虚函数Invalidate和虚函数update,即重画后立即生效。但图形控件没有改写这个函数(它要求父控件重画自己)。对比:它自己就可以声明自己无效并重画,不需要依赖父控件。
    procedure Invalidate; override; // 简单发送CM_INVALIDATE消息,先通知所有父控件,看它们有没有需要处理这件事情的,然后再重画自己。这就叫做组件之间的互动。对比:它本身的无效区域不需要计算,全部区域即可。
    procedure Update; override;     // 简单调用API UpdateWindow(如果有句柄)。对比:它不再需要一路向上通知父控件,直接更新自己即可。
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override; // 调用API设置窗口位置(很正常,图像控件不能靠API来设置)
    function PaletteChanged(Foreground: Boolean): Boolean; override;
    function GetDeviceContext(var WindowHandle: HWnd): HDC; override; // super 调用API,取得DC,并在可变参数里记下句柄
  • 相关阅读:
    iOS 自定义UITabBarController的tabBar
    iOS 设置导航栏之二(设置导航栏的颜色、文字的颜色、左边按钮的文字及颜色)
    iOS 设置导航栏的颜色和导航栏上文字的颜色
    iOS 修改UITextField的placeholder属性的字体颜色(修改UITextField占位符字体的颜色)
    iOS TPKeyboardAvoiding自动识别键盘的高度
    iOS 获取快递物流信息(GCD异步加载)
    iOS 图片循环滚动(切片效果)
    iOS block在两个页面间的简单传值
    swift
    iOS 10 之后权限设置
  • 原文地址:https://www.cnblogs.com/findumars/p/4153769.html
Copyright © 2011-2022 走看看