-------------------------- 显示隐藏刷新 --------------------------

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的显示函数的更多相关文章

  1. TWinControl与TControl的覆盖函数(TWinControl对TControl的10个消息覆盖函数,17个覆盖函数,私有虚函数仍可多态)

    手工找出来,对比一下,有助于VCL框架的理解.----------------------------------------------------------------------------- ...

  2. TControl的显示函数(5个非虚函数,4个虚函数)和三个例子的执行过程(包括SetParent的例子)

    // 9个显示函数 procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); virtual; // 虚函数,important 根据父控 ...

  3. 如何让vim自动显示函数声明-使用 echofunc.vim插件

    echofunc.vim可以显示函数的declaration, 默认的是针对c/c++, 对于php, 只要 启用了 ctags都可以, 因为echofunc是从tags file中获取数据的... ...

  4. EmWin 文本显示函数

    函数模型----------------------------------- 1:void GUI_DispChar(U16 c):  在当前窗口的当前文本位置处,使用当前字体显示单个字符.  c ...

  5. 如何在gvim中安装autoproto自动显示函数原型

    cankao: http://www.vim.org/scripts/script.php?script_id=1553 注意, 在gvim中执行的命令, :foo和:!foo 的区别, 跟vim一样 ...

  6. ue-edit设置显示函数列表

    UltraEdit的函数列表竟然不显示函数,那这功能要它何用,应该如何才能让函数显示出来呢? 公司编程基本上都在UltraEdit中进行,俺刚来公司还不熟悉,今天装了个UltraEdit,可是看着别人 ...

  7. sublime text 格式化html css 与显示函数列表

    sublime 格式化html css 1.ctrl + shift + p 2.输入install package,选择install package 3.输入:HTML-CSS-JS Pretti ...

  8. LCD浮点数显示函数的探讨

    LCD浮点数显示函数的探讨 原创 2017年12月19日 单片机开放附赠的学习资料里面很少见到显示浮点数的函数,显示浮点数的操作也相当烦坠! 一般转换显示法 拿STM32单片机资源,我们选取ADC采样 ...

  9. matlab中的输出显示函数

    matlab中的输出显示函数 在matlab中使用的显示函数有disp.sprintf.fprintf比较常用.下面来介绍一下他们的用法. 1.disp()函数: disp(x)主要是用来输出变量x的 ...

随机推荐

  1. 22深入理解C指针之---通过指针传递函数

    一.通过指针传递函数与通过指针传递数据的本质是一样的,区别就是此时的数据是函数指针(函数的开始的地址) 1.定义:通过函数指针将函数传入函数:通过函数返回函数指针实现函数返回函数的目标 2.特征: 1 ...

  2. 开发使用mysql的一些必备知识点整理(一)初阶

    简介 主要知识点包括:能够与mysql建立连接,创建数据库.表,分别从图形界面与脚本界面两个方面讲解 相关的知识点包括:E-R关系模型,数据库的3范式,mysql中数据字段的类型,字段约束 数据库的操 ...

  3. Codeforces 934 A.Compatible Pair

    http://codeforces.com/contest/934 A. A Compatible Pair   time limit per test 1 second memory limit p ...

  4. Jmeter(四十九)_常用的性能测试监听器

    概述 jmeter中提供了很多性能数据的监听器,我们通过监听器可以来分析性能瓶颈 本文以500线程的阶梯加压测试结果来描述图表. 常用监听器 1:Transactions per Second 监听动 ...

  5. 洛谷——P2983 [USACO10FEB]购买巧克力Chocolate Buying

    P2983 [USACO10FEB]购买巧克力Chocolate Buying 题目描述 Bessie and the herd love chocolate so Farmer John is bu ...

  6. boost::function和boost::bind 介绍

    一. boost::function介绍 原文:http://www.cnblogs.com/sld666666/archive/2010/12/16/1907591.html 本片文章主要介绍boo ...

  7. HTTP状态码之200和304

    HTTP状态码之200和304   HTTP状态码(HTTP Status Code)是一种表示网页服务器响应状态的三位数字编码.通过这些数字,可以简化状态的表达.状态码有几十种,其中首位数字为1-5 ...

  8. RabbitMQ 消费端限流、TTL、死信队列

    目录 消费端限流 1. 为什么要对消费端限流 2.限流的 api 讲解 3.如何对消费端进行限流 TTL 1.消息的 TTL 2.队列的 TTL 死信队列 实现死信队列步骤 总结 消费端限流 1. 为 ...

  9. 1.搭建maven,eclipse创建maven项目

    1.下载maven包,下载地址为:http://maven.apache.org/download.cgi 2.解压zip包 3.eclipse 引入maven: window-Preferences ...

  10. Ubuntu 16.04下使用Wine安装Windows版的微信(不太完美)

    说明: 真的不太完美,别试了:除了需要安装额外的输入法之后,无法上传图片和间接性的BUG出现等等问题. 建议安装网页版的微信:http://www.cnblogs.com/EasonJim/p/711 ...