TGraphicControl和TCustomControl自绘过程的理论解释
TGraphicControl = class(TControl) // 这个类实在是简单,因为所有事情都已经委托给它的父Win控件了,只要管自己即可
private
FCanvas: TCanvas; // 私有内部画板,不用程序员申请就有了
// 注意区别,其实图形控件没有画自己一说(但仍然接受WM_PAINT消息),直接响应消息并绘画即可。
// 其父类已经在VCL体系中搭好了框架绘制当前图形控件,它会调用Paint函数执行程序员的画图动作。
// Graphic控件自绘过程:
// 0. Windows发消息给其父Win控件
// 1. 如果父控件是WinControl,那么流程是:WMPaint, PaintHandler, PaintWindow, PaintWindows,其中最后一个函数PaintWindows会绘制所有图形子控件
// 2. PaintWindows 给所有图形子控件执行 Perform(WM_PAINT, DC, 0) 消息,其中DC是父控件的句柄
// 3. Graphic控件会通过WMPaint函数响应WM_PAINT消息,程序员不必改动这个函数,
// 4. WMPaint函数调用虚函数Paint,程序员改写Paint可被准确应用上而不必对整个VCL框架有任何改动,甚至不用理解这件事情,只需填写Paint函数即可
// 5. 如果父控件是CustomControl,那么会再多绕一道弯:先执行CustomControl的WMPaint,目的是加上自绘状态,再调用WinControl的WMPaint
// 总结:整个过程特简单,就是父控件发来WM_Paint消息,对应的WMPaint函数已经写好,程序员自己填上Paint函数的内容即可
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
protected
procedure Paint; virtual; // 虚函数,空函数。注意一定是要虚函数才符合面向对象的精神,才能正确被调用。
property Canvas: TCanvas read FCanvas;
public
constructor Create(AOwner: TComponent); override; // 简单创建Canvas并连接当前图形控件
destructor Destroy; override; // 销毁内部画板和自己,取消自己的焦点 fixme 图形控件也可以有焦点?
end;
--------------------------------------------------------------------------------------------------
TCustomControl = class(TWinControl) // 这个类的主要框架都在TWinControl里搭好了框架,所以才会出现最简单的三明治风格
private
FCanvas: TCanvas; // 私有内部画板,不用程序员申请就有了
// Custom控件自绘过程:
// 0. Windows发消息给CustomControl控件自己(也是Win控件,具有句柄)
// 1. 响应绘制自己控件的源头,还是从CustomControl控件的WMPaint函数开始
// 2. 三明治风格,加上csCustomPaint自绘风格后,调用父类同名WMPaint函数,这样可以把自己和所有子控件都管起来(有现成的VCL框架代码在其父类中准备好了)
// 3. 父类同名函数根据四种不同情况:双缓冲,DC句柄,子控件数量,自绘标记,分别作出不同的判断后进行绘制
// 4. 先绘制自己,再绘制所有子图形控件(如果有的话)
// 5. 绘制自己的时候,父类的管理函数(一般是PaintHandler)会调用本类的PaintWindow覆盖函数(虚函数)
// PaintWindow又会调用Paint函数,程序员通过改写Paint函数的内容,达到在框架内被自动调用的目的
// 6. 图形子控件的绘制过程是通过父控件给它发送WM_PAINT消息,其中包含了父控件的DC句柄,然后委托给图形子控件自己进行绘制
// 总结1:Custom控件的整个绘制过程道理与Graphic控件非常类似,只是少绕一些弯子(不必通过父控件来重绘)
// WMPaint直接调用本类的Paint函数,而程序员通过改写Paint函数的内容,达到在框架内被自动调用的目的
// 总结2:与直接继承自TWinControl的控件有所区别,后者直接覆盖PaintWindow函数,而不必响应WM_PAINT消息就可以达到被调用的目的了:http://www.cnblogs.com/findumars/p/3931703.html
procedure WMPaint(var Message: TWMPaint); message WM_PAINT; // 加Custom风格后重绘,调用TWinControl.WMPaint函数,因为要重画所有子控件
protected
// 此函数只被PaintHandler调用,后者又会被WMPaint WMPrintClient调用
procedure PaintWindow(DC: HDC); override; // 虚函数,在VCL体系中搭好了框架画自己,它会调用Paint;函数执行程序员的画图动作。
procedure Paint; virtual; // 虚函数,空函数。等待程序员填写画板的真正内容。框架已经由PaintWindow搭好了。
property Canvas: TCanvas read FCanvas;
public
constructor Create(AOwner: TComponent); override; // 创建并设置内部画板
destructor Destroy; override; // 销毁内部画板和自己
end;
TGraphicControl和TCustomControl自绘过程的理论解释的更多相关文章
- 《Android内核剖析》读书笔记 第13章 View工作原理【View重绘过程】
计算视图大小的过程(Measure) 视图大小,准确的来说应该是指视图的布局大小:我们在layout.xml中为每个UI控件设置的layout_width/layout_height两个属性被用来设置 ...
- [Android FrameWork 6.0源码学习] View的重绘过程
View绘制的三部曲, 测量,布局,绘画今天我们分析测量过程 view的测量是从ViewRootImpl发起的,View需要重绘,都是发送请求给ViewRootImpl,然后他组织重绘在重绘的过程中 ...
- IP地址,子网掩码、默认网关,DNS理论解释
在网上发现的这篇文章写的非常好,有理论有示例. (一) 问题解析 001. 问: IP地址,子网掩码,默认网关,DNS服务器,有什么区别呀?我知道没有IP地址就不能上网,我也知道没设DNS就不 ...
- Linux 启动过程的详细解释
对于无论什么系统, 但无法打开电源这么简单的事, 很多事情将在几秒钟内几秒钟或几十本短时间内发生, 了解这一过程将是完整的引导解决问题的任何或提高开机速度的前提. 下一个, 我们会专门寻找Linux程 ...
- VxWorks启动过程的详细解释(上)
vxworks有三个图像: VxWorks Image有三种类型的文件 Loadable Images:由Boot-ROM引导通过网口或串口下载到RAM ROM-based Images(压缩/没有压 ...
- java继承子类实例化过程(细节解释)
1 package face_08; 2 class Fu{ 3 Fu(){ 4 super(); 5 show(); 6 return; 7 } 8 void show() { 9 System.o ...
- ANDROID定义自己的看法——onMeasure,MeasureSpec源代码 过程 思考具体解释
一个简短的引论: 在他们的定义view什么时候,其实很easy,只需要知道3: 1.測量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGrou ...
- 机器学习-LDA主题模型笔记
LDA常见的应用方向: 信息提取和搜索(语义分析):文档分类/聚类.文章摘要.社区挖掘:基于内容的图像聚类.目标识别(以及其他计算机视觉应用):生物信息数据的应用; 对于朴素贝叶斯模型来说,可以胜任许 ...
- 浏览器渲染详细过程:重绘、重排和 composite 只是冰山一角
https://juejin.im/entry/590801780ce46300617c89b8 渲染 这张很经典的图许多人都看过,其中的概念大家应该都很熟悉,也就是这么几个步骤:js修改dom结构或 ...
随机推荐
- JAVA 学习笔记 - 基础语法 2
---恢复内容开始--- 1.数组的申明和应用 数据类型 数组名称[] = null; //在堆栈中申明变量名称 数组名称 = new 数据类型[10]; // ...
- [转]最值得拥有的免费Bootstrap后台管理模板
在PHP开发项目中,后台管理因为面向群体相对比较固定,大部分以实现业务逻辑和功能.使用Bootstrap后台模板可以让后端开发很轻松的就展现给客户一个响应式的后台,节约前端开发的时间.下面PHP程序员 ...
- Redis系列(十)--集群cluster
在之前学习了Master-Slave.Sentinel模式,但是在某些情况下还是无法满足系统对QPS等要求,这时候就需要Cluster,Redis3.0支持了cluster 一.为什么使用Cluste ...
- php中 如何找到session 的保存位置
[前言] 刚刚想测试FQ操作,需要删除session,这里记录分享下 [主体] (1)想要查看session保存的目录,需要先找到 php.ini配置文件 (2)在php.ini文件中查找 sessi ...
- ThinkPHP---thinkphp框架介绍
目录: (1)简述: (2)下载: (3)文件结构: (4)部署: (5)细节问题: 主体: (1)简述 ThinkPHP诞生于2006年初,最初叫FSC.于2007年元旦更名为PHP,同时官网上线. ...
- BZOJ 1176: [Balkan2007]Mokia KDtree
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin), ...
- Python orm基础
ORM 对象映射关系程序. 通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sq ...
- cgroup代码浅析(1)
前置:这里使用的linux版本是4.8,x86体系. cgroup_init_early(); 聊这个函数就需要先了解cgroup. cgroup概念 这个函数就是初始化cgroup所需要的参数的.c ...
- 洛谷——P3389 【模板】高斯消元法
P3389 [模板]高斯消元法 以下内容都可省略,直接转大佬博客%%% 高斯消元总结 只会背板子的蒟蒻,高斯消元是什么,不知道诶,看到大佬们都会了这个水题,蒟蒻只好也来切一切 高斯消元最大用途就是解多 ...
- JDBC—简单的数据交互
东西传值.交互 ps:里面的时间为手动添加.如果需要更改为系统日期,那就把里面 加了 // 的语句去掉 ,然后再加 包驱动. 新建一个1.jsp 用来当做用户输入东西的界面 再新建 第二个页面 ...