虚函数的特点就是执行的时候会下降到子类去执行同名覆盖函数 good
var
t: TBitBtn;
begin
t:=TBitBtn.Create(nil);
t.Name:='BitBtn100';
t.parent :=Self; // 这里下断点
end;
一路跟踪就会发现到TWinControl.UpdateShowing函数,它发现当前控件尚未有句柄,因此会调用CreateHandle,然后就有了这些虚函数的系列旅程,会执行子类覆盖函数:
TBitBtn.CreateHandle; // 在TWinControl.UpdateShowing里调用CreateHandle的时候,会下降到这里来
TButton.CreateWnd; // 在TWinControl.CreateHandle里调用CreateWnd的时候,会下降到这里来
TBitBtn.CreateParams // 在TWinControl.CreateWnd里调用CreateParams的时候,会下降到这里来
但是子类通常不会放弃父类已经提供的功能,全都是在父类函数执行前或者执行后的结果上增加一小部分特性,形成三明治风格。
干脆,我们看看TBitBtn增加些什么东西:
procedure TBitBtn.CreateHandle; var
State: TButtonState;
begin
if Enabled then // 增加按钮的状态
State := bsUp
else
State := bsDisabled;
inherited CreateHandle; // 三明治风格
TButtonGlyph(FGlyph).CreateButtonGlyph(State); // 增加按钮的图像
end; procedure TButton.CreateWnd;
begin
inherited CreateWnd;
FActive := FDefault; // 增加判断是否处于激活状态
end; procedure TBitBtn.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do Style := Style or BS_OWNERDRAW; // 增加自绘状态
end;
可以手动执行跟踪一遍,加深印象~
虚函数的特点就是执行的时候会下降到子类去执行同名覆盖函数 good的更多相关文章
- C# -- 等待异步操作执行完成的方式 C# -- 使用委托 delegate 执行异步操作 JavaScript -- 原型:prototype的使用 DBHelper类连接数据库 MVC View中获取action、controller、area名称、参数
C# -- 等待异步操作执行完成的方式 C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] ...
- TWinControl的刷新过程(5个非虚函数,4个覆盖函数,1个消息函数,默认没有双缓冲,注意区分是TCustomControl还是Windows原生封装控件,执行流程不一样)
前提条件:要明白在TWinControl有以下四个函数的存在,注意都是虚函数: procedure Invalidate; override;procedure Update; override;pr ...
- TWinControl与TControl的覆盖函数(TWinControl对TControl的10个消息覆盖函数,17个覆盖函数,私有虚函数仍可多态)
手工找出来,对比一下,有助于VCL框架的理解.----------------------------------------------------------------------------- ...
- 无法执行 FunctionImport“entitys.xx”,因为未将它映射到存储函数。EF
EF突然报了一个这样的错误: 无法执行 FunctionImport"entitys.xx",因为未将它映射到存储函数.EF 其中xx是存储过程: 可能是因为我在.edmx文件中& ...
- 异步控制---实现函数asyncAll,在执行完传入数组中func1,func2,func3异步函数后,输出“end”
实现函数asyncAll,在执行完传入数组中func1,func2,func3异步函数后,输出"end" function func1(callback) { setTimeout ...
- CAD调试时抛出“正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码”异常的解决方法
这些天重装了电脑Win10系统,安装了CAD2012和VS2012,准备进行软件开发.在调试程序的时候,CAD没有进入界面就抛出 “正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain ...
- 正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样...
出错提示: 正尝试在 OS 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 原因分析: .NET2.0中增加了42种非常强大的调试助手 ...
- 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码
来自:http://www.cnblogs.com/lcxu2/archive/2011/01/16/2004016.html 正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain 或 ...
- 正尝试在 OS 载入程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内执行托管代码,这样做会导致应用程序挂起。
出错提示: 正尝试在 OS 载入程序锁内执行托管代码. 不要尝试在 DllMain 或映像初始化函数内执行托管代码,这样做会导致应用程序挂起. 原因分析: .NET2.0中添加了42种非常强大的调试助 ...
随机推荐
- 9.Hierarchy Editor
Hierarchy Editor(层次编辑器) 用于定义3D图层的结构,向Ventuz渲染引擎发出“命令”,并指定命令的发生顺序.通常,每个层次节点都会导致对GPU的一个或多个调用,例如设置材质或渲染 ...
- centos7安装mysql和mysql-connector-c++
最近为了搭建自己的开发环境,又一次在centos7上面开始安装mysql和c++的访问环境,特此记录一下搭建过程,方便以后查阅 一.安装mysql centos7 默认安装了mariaDB,导致不能安 ...
- 接口测试(一)--soapui实践
一.接口的概念 接口是指系统模块与模块或系统与系统之间进行交互,一般用的多的是HTTP协议的接口.webService协议的接口,还有RPC的接口. RPC:Remote Procedure Call ...
- 11、scala函数式编程
1.将函数赋值给变量 2.匿名函数 3.高阶函数 4.高阶函数的类型推断 5.Scala的常用高级函数 6.闭包 7.SAM转换 8.Currying函数 9.return 1.将函数赋值给变量 Sc ...
- 【技术累积】【点】【java】【26】@Value默认值
@Value 该注解可以把配置文件中的值赋给属性 @Value("${shit.config}") private String shit; 要在xml文件中设置扫描包+place ...
- ABP生成错误:必须添加对程序集“netstandard”的引用
当前使用ABP版本为:4.6.0 升级vs2017到15.4版本,升级framework到4.7版本 如果Core版本请升级到net core 2
- js的三种对象
JS中,可以将对象分为“内部对象”.“宿主对象”和“自定义对象”三种. 1,内部对象 js中的内部对象包括Array.Boolean.Date.Function.Global.Math.Number. ...
- 为什么Java中的密码优先使用 char[] 而不是String?
可以看下壁虎的回答:https://www.zhihu.com/question/36734157 String是常量(即创建之后就无法更改),会保存到常量池中,如果有其他进程可以dump这个进程的内 ...
- Python学习【第4篇】:Python之文件操作
文件操作 读取一行 f=open("D:\\1.txt",'rb') print f.readline() f.close() 将文件内容保存在一个list with open(& ...
- chrome本地测试cookie时无效的原因
https://blog.csdn.net/lyj787505955/article/details/38079079 应该是chrome的原因, 同一网页放在tomcat后,通过localhost方 ...