TControl,TWinControl和TGraphicControl的显示函数
-------------------------- 显示隐藏刷新 --------------------------
TControl = class(TComponent)
procedure Show; 调用 Parent.ShowControl(Self);
procedure Refresh; 简单调用虚拟函数 Repaint,自己不直接起作用。名叫Refresh的函数就这里一个,别无分号。
procedure Repaint; virtual; 不透明则GetDC且重画控件,透明就简单Invalidate并Update,复杂。在TWinControl里被覆盖了,因此就算被调用也是对TGraphicControl起作用而已。
procedure Invalidate; virtual; 调用InvalidateControl类函数,后者调用InvalidateRect API函数
procedure Update; virtual; 调用 Parenet.Update,它的Parent是TWinControl,所以这句就是一个呼叫转移作用,并不直接起作用。
procedure WndProc(var Message: TMessage); virtual; 处理完消息一般会Exit,否则只能Dispatch(Message);
function Perform(Msg: Cardinal; WParam: WPARAM; LParam: LPARAM): LRESULT; overload; 根据参数构建TMessage,并调用WindowProc(Message);最后取得返回值
procedure DefaultHandler(var Message); override; 只处理WM_SETTEXT消息,并且不继续传递
TWinControl = class(TControl)
procedure TWinControl.CMInvalidate(var Message: TMessage);
procedure WMPaint(var Message: TWMPaint); message WM_PAINT; 双缓冲则调用 PaintHandler,否则调用BeginPaint,复杂
procedure Repaint; override; 直接调用 Invalidate; Update; 特简单。自定义控件的时候,总要写这句标识无效且立即重画。注意,这里Invalidate也是类函数,不是API
procedure Update; override; 有句柄就立即UpdateWindow(WindowHandle); 这里的UpdateWindow可是真正的API,亮真家伙了,才能真正重画,不再转移呼叫了。
procedure PaintControls(DC: HDC; First: TControl); 重画WinControl所包含的所有子控件(TLabel等) FControls FWinControls ,发送 Perform(WM_PAINT, DC, 0);
procedure PaintHandler(var Message: TWMPaint); 调用BeginPaint或者PaintWindow或者重画FControls 复杂
procedure PaintWindow(DC: HDC); virtual; 构建并发送 WM_PAINT到DefaultHandler里,所以一般得覆盖,否则不起作用(无法调用程序员的Paint代码),但是仍然可以画出默认的程序界面。而且在TCustomControl里也确实被重载了。
procedure WndProc(var Message: TMessage); override;
procedure DefaultHandler(var Message); override; 处理了少部分消息。自己有句柄的话,会调用CallWindowProc(FDefWndProc),否则inherited DefaultHandler(Message);
TGraphicControl = class(TControl)
private
FCanvas: TCanvas; 可以画图了
procedure WMPaint(var Message: TWMPaint); message WM_PAINT; 简单调用 Paint;
protected
procedure Paint; virtual; 空函数,等待重写。比如TLabel的重画,就依赖于 procedure TCustomLabel.Paint; (它的上级TWinControl给它发WM_PAINT后调用它的Paint)。具体过程如下:TLabel的Create函数根据OS版本预先指定FDrawTextProc函数指针(也是指向自定义的类函数)。它的上级TWinControl收到WM_PAINT消息后,会给所有子控件发送WM_PAINT消息(具体过程查看TWinControl.PaintControls函数),此时TLabel会收到一个WM_PAINT消息,执行WMPaint函数,WMPaint会调用Paint虚函数,因此TLabel会调用自己的Paint函数,Paint函数会调用DoDrawText函数,DoDrawText根据不同情况判断Autosize和BiDi等属性做出相应处理后,最后调用FDrawTextProc函数,最后它会调用API函数Windows.DrawTextW,完成绘制。值得注意的是,这个API所用DC是借用父控件的DC。
property Canvas: TCanvas read FCanvas;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TCustomControl = class(TWinControl)
private
FCanvas: TCanvas; 可以自绘了
procedure WMPaint(var Message: TWMPaint); message WM_PAINT; 简单调用 inherited
protected
procedure Paint; virtual; 空函数,等待重写
procedure PaintWindow(DC: HDC); override; 简单调用 Paint;
property Canvas: TCanvas read FCanvas;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
要搞清楚 TWinControl 和 TCustomControl 的区别,就要搞清楚TCustomControl为什么要覆盖 WMPaint。为什么有的控件从TWinControl继承,有的从TCustomControl继承?主要区别在于后者可以自绘,前者不需要。
-------------------------- 从TGraphicControl和TCustomControl开始,自动创建和包含Canvas实体 --------------------------
constructor TGraphicControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
end;
constructor TCustomControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
end;
TControl,TWinControl和TGraphicControl的显示函数的更多相关文章
- TWinControl与TControl的覆盖函数(TWinControl对TControl的10个消息覆盖函数,17个覆盖函数,私有虚函数仍可多态)
手工找出来,对比一下,有助于VCL框架的理解.----------------------------------------------------------------------------- ...
- TControl的显示函数(5个非虚函数,4个虚函数)和三个例子的执行过程(包括SetParent的例子)
// 9个显示函数 procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); virtual; // 虚函数,important 根据父控 ...
- 如何让vim自动显示函数声明-使用 echofunc.vim插件
echofunc.vim可以显示函数的declaration, 默认的是针对c/c++, 对于php, 只要 启用了 ctags都可以, 因为echofunc是从tags file中获取数据的... ...
- EmWin 文本显示函数
函数模型----------------------------------- 1:void GUI_DispChar(U16 c): 在当前窗口的当前文本位置处,使用当前字体显示单个字符. c ...
- 如何在gvim中安装autoproto自动显示函数原型
cankao: http://www.vim.org/scripts/script.php?script_id=1553 注意, 在gvim中执行的命令, :foo和:!foo 的区别, 跟vim一样 ...
- ue-edit设置显示函数列表
UltraEdit的函数列表竟然不显示函数,那这功能要它何用,应该如何才能让函数显示出来呢? 公司编程基本上都在UltraEdit中进行,俺刚来公司还不熟悉,今天装了个UltraEdit,可是看着别人 ...
- sublime text 格式化html css 与显示函数列表
sublime 格式化html css 1.ctrl + shift + p 2.输入install package,选择install package 3.输入:HTML-CSS-JS Pretti ...
- LCD浮点数显示函数的探讨
LCD浮点数显示函数的探讨 原创 2017年12月19日 单片机开放附赠的学习资料里面很少见到显示浮点数的函数,显示浮点数的操作也相当烦坠! 一般转换显示法 拿STM32单片机资源,我们选取ADC采样 ...
- matlab中的输出显示函数
matlab中的输出显示函数 在matlab中使用的显示函数有disp.sprintf.fprintf比较常用.下面来介绍一下他们的用法. 1.disp()函数: disp(x)主要是用来输出变量x的 ...
随机推荐
- HDU 6206 Apple
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6206 判断给定一点是否在三角形外接圆内. 给定三角形三个顶点的坐标,如何求三角形的外心的坐标呢? 知乎 ...
- 搭建vue-cli时候报错处理
最近在使用vue-cli搭建目录时出现 “webpack-dev-server不是内部或外部命令,也不是可运行的程序 或批处理文件”情况 在网上查了不少资料和解决方法后,结合自己的情况应该是环境变量的 ...
- 安装Vmware增强工具
主机: Win7 虚拟机: VMware8.0+Debian6 目标: 离线安装软件包和VMware Tools 在虚拟机上安装完debian6后 1.在vmware的菜单中选择Vm->inst ...
- iOS真机测试,为Provisioning添加设备
------------添加设备到provisioning------------- 1,登陆https://developer.apple.com/devcenter/ios/index.actio ...
- Go -- etcd详解(转)
CoreOS是一个基于Docker的轻量级容器化Linux发行版,专为大型数据中心而设计,旨在通过轻量的系统架构和灵活的应用程序部署能力简化数据中心的维护成本和复杂度.CoreOS作为Docker生态 ...
- vue doubleclick 鼠标双击事件
Vue-dblclick事件(此外事件还有mouseover,mouseout,click,mousdown...): v-on:dblclick="函数" v-on:click/ ...
- DICOM医学图像处理:Orthanc Plugin SDK实现WADO服务
背景: Orthanc是博主发现的一个很完美的DICOM和HTTP服务端开源软件,前几篇分别介绍了Orthanc的基本使用.Orthanc从0.8.0版本之后给出了Plugin SDK,通过该SDK可 ...
- 微型企业如何使用odoo
作者 jeffery Q913547235 保留所有权利 Odoo可以帮助微型企业提升运营效率,做到电子化,信息化. 管理仓库进销存,建立收货单.交货单,并基于收货.交货情况确认应收款和应付款 ...
- viewState详解
作者:Infinities Loop 概述 ViewState是一个被误解很深的动物了.我希望通过此文章来澄清人们对 ViewState的一些错误认识.为了达到这个目的,我决定从头到尾详细的描述一下整 ...
- SDUT 1068-Number Steps(数学:直线)
Number Steps Time Limit: 1000ms Memory limit: 10000K 有疑问?点这里^_^ 题目描写叙述 Starting from point (0,0) ...