// 9个显示函数
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); virtual; // 虚函数,important 根据父控件
// 手法:固定不变的模式,或者简单调用,或者简单设置标志位,就不是虚函数。
procedure Show; // 设置自己和所有祖先的visible标识
procedure Hide; // 简单设置visible标识,与祖先无关
procedure Refresh; // 简单调用Repaint虚函数,但Refresh本身不是虚函数。一般应该使用它,因为可以获得更多的无关性。
procedure SendToBack;
procedure BringToFront; // 图形控件也要用此能力啊,所以在TControl就已经定义了

// 这三个函数,被TWinControl覆盖。即使使用,也是被inherited使用。
// 而图形控件都没有覆盖着三个函数,因此会经常用到它们。摆明了就是给图形控件用的。
// fixme 有空试试把它们都放到图形控件里去
procedure Repaint; virtual; // 虚函数,取得父控件的DC,重画父控件的所有子控件。被TWinControl覆盖。
procedure Invalidate; virtual; // 虚函数,调用非虚函数类函数InvalideControl,把自己需要重画的部分算清楚。被TWinControl覆盖。
{ 递归调用Parent的update,否则什么都不做。意思是,自己更新了,那么父控件也要更新。}
procedure Update; virtual; // 虚函数,通知父控件自己更新了。而父控件的Update是可以被改写的,这样就达到了目的。被TWinControl覆盖。

{
看一下VCL的源码,就不难发现了。
Paint是TCustomForm的Protected方法,实际就是调用OnPaint事件。
Invalidate是TWinControl的方法,主要是发送一个CM_INVALIDATE消息,对控件的值作有效性判断。
Update(其实)也是TWinControl的方法,是通过调用Win32API函数重画窗口。
Repaint是TControl的虚方法,在TWinControl中override,程序只有2行,就是(1)Invalidate;(2)Update
Refresh是TControl的方法,程序只有1句:Repaint.
所以ReFresh和RePaint对于TWinControl的子类来说是等价的(除非又重载过),但是应该说Refresh是更规范的用法。
至于Invalidate的Update一般是没有单独使用的必要的。
}

function TControl.GetDeviceContext(var WindowHandle: HWnd): HDC;
begin
if Parent = nil then
raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);
Result := Parent.GetDeviceContext(WindowHandle);
SetViewportOrgEx(Result, Left, Top, nil);
IntersectClipRect(Result, , , Width, Height);
end; procedure TControl.InvalidateControl(IsVisible, IsOpaque: Boolean);
var
Rect: TRect; function BackgroundClipped: Boolean;
var
R: TRect;
List: TList;
I: Integer;
C: TControl;
begin
Result := True;
List := FParent.FControls;
I := List.IndexOf(Self);
while I > do
begin
Dec(I);
C := List[I];
with C do
if C.Visible and (csOpaque in ControlStyle) then
begin
IntersectRect(R, Rect, BoundsRect);
if EqualRect(R, Rect) then Exit;
end;
end;
Result := False;
end; begin
if (IsVisible or (csDesigning in ComponentState) and
not (csNoDesignVisible in ControlStyle)) and (Parent <> nil) and
Parent.HandleAllocated then
begin
Rect := BoundsRect;
InvalidateRect(Parent.Handle, @Rect, not (IsOpaque or
(csOpaque in Parent.ControlStyle) or BackgroundClipped));
end;
end; procedure TControl.Invalidate;
begin
InvalidateControl(Visible, csOpaque in ControlStyle);
end; procedure TControl.Hide;
begin
Visible := False;
end; procedure TControl.Show;
begin
if Parent <> nil then Parent.ShowControl(Self);
if not (csDesigning in ComponentState) or
(csNoDesignVisible in ControlStyle) then Visible := True;
end; procedure TControl.Update;
begin
if Parent <> nil then Parent.Update; // 图形控件没法刷新自己,让父控件去刷新
end; procedure TControl.Refresh;
begin
Repaint;
end; procedure TControl.Repaint;
var
DC: HDC;
begin
if (Visible or (csDesigning in ComponentState) and
not (csNoDesignVisible in ControlStyle)) and (Parent <> nil) and
Parent.HandleAllocated then
if csOpaque in ControlStyle then
begin
DC := GetDC(Parent.Handle);
try
IntersectClipRect(DC, Left, Top, Left + Width, Top + Height);
Parent.PaintControls(DC, Self);
finally
ReleaseDC(Parent.Handle, DC);
end;
end else
begin
Invalidate;
Update;
end;
end;

PaintControls的意思是,重绘所有图形子控件

--------------------------------------------------------------------------------

例子1:可以看到Image1.的绘制过程

image1.Refresh;

例子2:

Image1.Hide;

例子3:

var
Image2 : TImage;
begin
Image2 := TImage.Create(self);
Image2.Left := 100;
Image2.Top := 50;
Image2.Picture.LoadFromFile('c:\pic.jpg');
Image2.Parent := Form1;
end;

TControl的显示函数(5个非虚函数,4个虚函数)和三个例子的执行过程(包括SetParent的例子)的更多相关文章

  1. C++ - 虚基类、虚函数与纯虚函数

    虚基类       在说明其作用前先看一段代码 class A{public:    int iValue;}; class B:public A{public:    void bPrintf(){ ...

  2. 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针

      您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...

  3. 阻塞、非阻塞的概念和select函数的阻塞功能

    其它文档: http://www.cnitblog.com/zouzheng/archive/2010/11/25/71711.html (1)阻塞block     所谓阻塞方式block,顾名思义 ...

  4. [C++基础]C++中静态成员函数如何访问非静态成员

    #include <iostream> /* 静态成员函数只能访问静态数据成员.静态成员函数和类以外的函数和数据,不能访问非静态数据成员,但静态成员函数或静态数据成员可由任意访问许可的函数 ...

  5. C++函数中那些不可以被声明为虚函数的函数

    转自C++函数中那些不可以被声明为虚函数的函数 常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函 ...

  6. C++静态成员函数不能调用非静态成员变量

    其实我们从直观上可以很好的理解静态成员函数不能调用非静态成员变量这句话因为无论是静态成员函数还是静态成员变量,它们 都是在类的范畴之类的,及在类的整个生存周期里始终只能存在一份.然而非静态成员变量和非 ...

  7. 在Word2010文档中显示域代码而非域值

    当Word2010文档中含有域内容时,默认情况下显示域值,这样可以使插入的域内容清晰明了.用户可以根据需要选择显示域代码或显示域值,操作步骤如下所述: 步骤/方法 第1步,打开Word2010文档窗口 ...

  8. C++ virtual函数重写,在继承的时候没有在函数前写virtual关键字也依然是虚函数吗?

    比如: class Base { Base() {}; ~Base() {}; virtual void Init(); }; class Derived:public Base { virtual ...

  9. Docker-machine创建虚机时停在虚机启动的提示上,并且创建的虚机显示Ip Not found

    Docker-machine创建虚机时停在虚机启动的提示上,并且创建的虚机用docker-machine ls 列出来的时候显示Ip Not found, 是什么原因那? [答案] 看这个帖子: ht ...

随机推荐

  1. c++ 文件写样例

    #include <iostream> #include <sstream> #include <fstream>> using namespace std; ...

  2. C# 二进制替换第一弹 byte 数组替换

    在做通讯相关的数据操作时常常须要用到 byte[]   byte 数组替换操作.比方协义转换相关的 如今提供了几种替换的方法 /// <summary> /// 二进制数据 操作 /// ...

  3. Java基础知识强化之集合框架笔记39:Set集合之HashSet存储字符串并遍历

    1. HashSet类的概述: (1)不保证set的迭代顺序 (2)特别是它不保证该顺序恒久不变 HashSet底层数据结构是哈希表,哈希表依赖于哈希值存储,通过哈希值来确定元素的位置,  而保证元素 ...

  4. Android Activity横竖屏转换的生命周期

    新创建一个Activity,用来此次测试. 先贴代码 package com.hugo.apj.activitylifetest; import android.support.v7.app.AppC ...

  5. 一款js、css压缩工具yuicompressor

    //压缩JS java -jar yuicompressor-.jar --type js --charset utf- -v src.js > packed.js //压缩CSS java - ...

  6. Weex 学习教程

    一.环境搭建 1.安装Node,官网下载(http://nodejs.org/) 2.查看npm安装版本,终端输入:npm -v版本不能低于2.15.1 3.安装weex-toolkit,终端输入:n ...

  7. C#语法糖之开篇

    本人虽然大学不是学的计算机但是对于IT行业的热爱,依然决然进军IT行业了,自从踏进这个行业到现在也已经3年多了,从去年开发通过网上 了解博客园后深深的爱上这儿了,这里有很多牛人,通过拜读他们的代码,让 ...

  8. 查询可用的Nuget服务地址

    解决访问Nuget源失败问题 查询IP址址 nslookup nuget.org 如失败,通过google 的dns服务器查询 nslookup nuget.org 8.8.8.8 将得到的Ip地址加 ...

  9. Android性能优化之ViewStub

    http://www.cnblogs.com/lwbqqyumidi/p/4047108.html ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View.虽然Andro ...

  10. SQL server抽疯后修改sa密码无法成功的处理办法

    今天上班打开电脑,发现尼玛所有项目启动后都报错,原因是说数据库sa的验证错误,无法进行数据库链接等等东西,简单地说---SQL server抽疯了!!!:( 昨天还好好的.而且没有修改过东西.为啥会出 ...