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的 ...
随机推荐
- 标准C程序设计七---45
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- ajax操作提交整个表单内容
1 2 3 4 5 6 7 8 9 10 11 12 13 $.ajax({ cache: true, type: "POST ...
- 首次远程安装 GlassFish 后以远程 Web 方式访问其后台管理系统出现错误的解决方法(修订)
首次远程安装 GlassFish 服务后,如果以远程 Web 方式访问其后台管理系统,会提示 Secure Admin must be enabled to access the DAS remote ...
- TCP server和client
http://blog.csdn.net/hguisu/article/details/7445768/ 原文:http://www.cnblogs.com/dolphinX/p/3460545.ht ...
- Xcode文件名后的字母含义
Xcode文件名后的字母含义 在Xcode中,左侧的dock区域显示项目结构.很多时候,文件名后方会出现一个字母提示,如M.A之类的.这实际是一种提示符号.如果项目中使用SVN.Git等版本控制工 ...
- Visual Studio各版本下载链接
Visual Studio 2015 企业版 链接: https://pan.baidu.com/s/1NFGyIbm2RNsuwwEU-bYicQ 提取码: m961 Visual Studio 2 ...
- java正则表达式的知识
/** 用途:正则表达式 * 创建人:向家康 * 创建日期:2019年4月21日 下午9:59:08 */ //有了登录界面当然少不了正则表达式啦,这是做项目必备的知识点 //通过本博客的代码,想必即 ...
- JDK/Java SE官方文档汇总
JDK一般是指Java SE. 1.5:https://docs.oracle.com/javase/1.5.0/docs/ 6:https://docs.oracle.com/javase/6/do ...
- array_map常用技巧
array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组. 简单来说 “array_map” 会对数组中的每一项进行处理,并返回处理后的数据. 定 ...
- Android在其他线程中更新UI
public class TransferTools { private static final int MSG_START = 1001; private static final int MSG ...