手工找出来,对比一下,有助于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,并在可变参数里记下句柄

TWinControl与TControl的覆盖函数(TWinControl对TControl的10个消息覆盖函数,17个覆盖函数,私有虚函数仍可多态)的更多相关文章

  1. 私有虚函数的特点(C++和Java的机制还有所不同)

    多态性与将实现多态的函数的访问限定符没有任何关系,private 函数仍然可以实现多态,它的指针仍然位于vtbl中,只不过该函数的多态一般只能在基类的内部由其他非虚函数调用该函数的时候反映出来,访问限 ...

  2. 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数

    1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...

  3. 虚函数重载(overwrite) 继承覆盖问题

    引言 类接口需要添加默认参数,以适应不同情况调用, 但是clang-tidy 不允许在接口上设置默认参数,ps: 可能担心继承类里接口重新设置新默认参数而导致误用的情况 #include <st ...

  4. C++ 系列:虚函数

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  5. C++之虚函数和多态

    干货较多-需要自己深思理解: C++支持两种多态性: 1.编译时多态性(静态绑定-早绑定) 在程序编译阶段即可以确定下来的多态性 通过使用 重载机制(重载函数)实现 (模板)http://blog.c ...

  6. C++之虚函数的作用和使用方法

    在同一类中是不能定义两个名字相同.参数个数和类型都相同的函数的,否则就是“重复定义”.但是在类的继承层次结构中,在不同的层次中可以出现名字相同.参数个数和类型都相同而功能不同的函数.例如在例12.1( ...

  7. C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现

    tfref 前言 C++对象的内存布局 只有数据成员的对象 没有虚函数的对象 拥有仅一个虚函数的对象 拥有多个虚函数的对象 单继承且本身不存在虚函数的继承类的内存布局 本身不存在虚函数(不严谨)但存在 ...

  8. C++ Pirmer : 第十五章 : 面向对象程序设计之基类和派生的定义、类型转换与继承与虚函数

    基类和派生类的定义以及虚函数 基类Quote的定义: classs Quote { public: Quote() = default; Quote(cosnt std::string& bo ...

  9. C++纯虚函数

    本文较为深入的分析了C++中虚函数与纯虚函数的用法,对于学习和掌握面向对象程序设计来说是至关重要的.具体内容如下: 首先,面向对象程序设计(object-oriented programming)的核 ...

随机推荐

  1. net core 实战之 redis 负载均衡和"高可用"实现

    net core 实战之 redis 负载均衡和"高可用"实现 1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的& ...

  2. Javascript null和undefined

    Javascript的数据类型包括数字.字符串.布尔值.null.undefined和对象.其中null和undefined是两种特殊的原始类型,很容易混淆.今天就来剖析一下null和undefine ...

  3. 阿里云服务器mysql修改编码问题

    最近在学习struts+spring+hibernate,强烈推荐新手一本书:陈天河<轻量级web应用开发>,这本书是我见过的国内最好的书,初学者可以买本读读. 不说这个了,来说说我的问题 ...

  4. 细究UTF-8,GB2312及ISO-8859-1区别

    各个国家和地区所制定的不同 ANSI 编码标准中,都只规定了各自语言所需的“字符”.比如:汉字标准(GB2312)中没有规定韩国语字符怎样存储.这些 ANSI 编码标准所规定的内容包含两层含义:1. ...

  5. C#和asp.net执行外部EXE程序

    这两天研究下.Net的执行外部EXE程序问题,就是在一个程序里通过按钮或其他操作运行起来另外一个程序,需要传入参数,如用户名.密码之类(实际上很类似单点登录,不过要简单的多的多):总结如下: 1.CS ...

  6. 学习Linux第三天

    1.常用的命令: reset 清屏 leave +hhmm 建立离开提醒 sudo apt-get yum 安装yum程序 sudo su 切换root身份 see test.c 可以直接查看文件,神 ...

  7. 关于Python中的yield

    关于Python中的yield   在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,f ...

  8. 高效SQL语句(SQL Server)

    以下的SQL语句以Northwind为例 1.不要再where子句中"="的左侧使用函数和表达式,因为系统无法应用函数或表达式中的索引 SELECT * FROM Customer ...

  9. 一个有趣的Ajax Hack示范

    今天在梦之光芒的BLOG上看见了一个Ajax Hack示范,其实跨站发现很容易,但是要做到大危害还是很难,偷偷COOKIE什么的只针对用户而已,XSS WORM的那种利用才是可怕的. 来看看他的一段V ...

  10. (转) C++ static、const和static const 以及它们的初始化

    const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间. static表示的是静态的.类的静态成员函数.静态成员变量是和类相关的,而不是和类的 ...