五种情况下会刷新控件状态(刷新控件状态才能刷新所有子FWinControls的显示):

在TWinControls.PaintControls中,对所有FWinControls只是重绘了边框,而没有整个重绘这些FWinControl子控件。那么什么时候才整个重绘全部FWinControls呢?这时候,就不是一个单纯的WM_PAINT来解决控件重绘的问题了,而是这个TWinControl.UpdateShowing函数:

procedure TWinControl.UpdateShowing;
var
ShowControl: Boolean;
I: Integer;
begin
ShowControl := (FVisible or (csDesigning in ComponentState) and
not (csNoDesignVisible in ControlStyle)) and
not (csReadingState in ControlState);
if ShowControl then
begin
if FHandle = then CreateHandle;
if FWinControls <> nil then
for I := to FWinControls.Count - do
TWinControl(FWinControls[I]).UpdateShowing;
end;
if FHandle <> then
if FShowing <> ShowControl then
begin
FShowing := ShowControl;
try
Perform(CM_SHOWINGCHANGED, , );
except
FShowing := not ShowControl;
raise;
end;
end;
end;

那么什么时候才会调用TWinControl.UpdateShowing;呢?回答是,就一种情况下:当控件状态改变的时候:

procedure TWinControl.UpdateControlState;
var
Control: TWinControl;
begin
Control := Self;
while Control.Parent <> nil do
begin
Control := Control.Parent;
if not Control.Showing then Exit;
end;
if (Control is TCustomForm) or (Control.FParentWindow <> 0) then UpdateShowing; // 必须有父窗口,才给显示。TCustomForm那已经是顶级窗口
end;

那么什么时候算控件状态改变?回答是,一共五种情况:从DFM读取数据时、新增加子控件时、重新创建当前控件的句柄时、设置父控件时、显示状态被改变时:

// 情况一:
procedure TWinControl.ReadState(Reader: TReader);
begin
DisableAlign;
try
inherited ReadState(Reader);
finally
EnableAlign;
end;
FixupTabList;
if FParent <> nil then Perform(CM_PARENTCTL3DCHANGED, , );
UpdateControlState;
end; // 情况二:
procedure TWinControl.InsertControl(AControl: TControl);
begin
AControl.ValidateContainer(Self);
Perform(CM_CONTROLLISTCHANGE, Integer(AControl), Integer(True));
Insert(AControl);
if not (csReading in AControl.ComponentState) then
begin
AControl.Perform(CM_PARENTCOLORCHANGED, , );
AControl.Perform(CM_PARENTFONTCHANGED, , );
AControl.Perform(CM_PARENTSHOWHINTCHANGED, , );
AControl.Perform(CM_PARENTBIDIMODECHANGED, , );
if AControl is TWinControl then
begin
AControl.Perform(CM_PARENTCTL3DCHANGED, , );
UpdateControlState;
end else
if HandleAllocated then AControl.Invalidate;
AlignControl(AControl);
end;
Perform(CM_CONTROLCHANGE, Integer(AControl), Integer(True));
end; // 情况三:
procedure TWinControl.CMRecreateWnd(var Message: TMessage);
var
WasFocused: Boolean;
begin
WasFocused := Focused;
DestroyHandle;
UpdateControlState;
if WasFocused and (FHandle <> ) then Windows.SetFocus(FHandle);
end; // 情况四:
procedure TWinControl.SetParentWindow(Value: HWnd);
begin
if (FParent = nil) and (FParentWindow <> Value) then
begin
if (FHandle <> ) and (FParentWindow <> ) and (Value <> ) then
begin
FParentWindow := Value;
Windows.SetParent(FHandle, Value);
if (Win32MajorVersion >= ) and (Win32Platform = VER_PLATFORM_WIN32_NT) then
Perform(WM_CHANGEUISTATE, MakeWParam(UIS_INITIALIZE, UISF_HIDEACCEL or UISF_HIDEFOCUS), );
end else
begin
DestroyHandle;
FParentWindow := Value;
end;
UpdateControlState;
end;
end; // 情况五:
procedure TWinControl.CMVisibleChanged(var Message: TMessage);
begin
if not FVisible and (Parent <> nil) then RemoveFocus(False);
if not (csDesigning in ComponentState) or
(csNoDesignVisible in ControlStyle) then UpdateControlState;
end;

但是还是有个问题,在TWinControl.UpdateShowing里执行了CM_SHOWINGCHANGED消息,也就是:

procedure TWinControl.CMShowingChanged(var Message: TMessage);
const
ShowFlags: array[Boolean] of Word = (
SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_HIDEWINDOW,
SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_SHOWWINDOW);
begin
SetWindowPos(FHandle, , , , , , ShowFlags[FShowing]);
end;

可是SetWindowPos会触发WM_PAINT消息吗?看MSDN没有这么说啊,那么显示所有WinControl子控件和调用它的WM_PAINT真正自绘,两者怎样才能联系起来呢?

五种情况下会刷新控件状态(刷新所有子FWinControls的显示)——从DFM读取数据时、新增加子控件时、重新创建当前控件的句柄时、设置父控件时、显示状态被改变时的更多相关文章

  1. Oracle redo 日志损坏的几种情况下的恢复

    Oracle redo 日志损坏的几种情况下的恢复 第一:损坏的redo为非正在使用的redo log 1.归档模式,不是当前正在日志损坏,数据库打开模式. 模拟损坏:SQL> select * ...

  2. css3动画贝塞尔曲线cubic-bezier,css3动画的五种情况

    当大家开始做css3动画的时候,了解贝塞尔曲线就成了不可或缺的.“贝赛尔曲线”是由法国数学家Pierre Bézier所发明,由此为计算机矢量图形学奠定了基础.它的主要意义在于无论是直线或曲线都能在数 ...

  3. Java实现PV操作 | 读者与写者(在三种情况下进行讨论)

    注 :本文应结合[天勤笔记]进行学习. 1.读者优先 设置rmutex信号量来对readcount变量进行互斥访问.mutex信号量对写者与读者进行同步. static syn rmutex=new ...

  4. create-react-app:reject和不reject(使用react-app-rewired)这2种情况下的antd组件按需引入配置

    create-react-app:eject和不eject(使用react-app-rewired)这2种情况下的antd组件按需引入配置: 不eject(使用react-app-rewired)配置 ...

  5. hdu 5060 五种情况求圆柱体与球体交

    http://acm.hdu.edu.cn/showproblem.php?pid=5060 官方题解http://bestcoder.hdu.edu.cn/给复杂了 实际上用圆柱体与球体体积差的积分 ...

  6. 怎么设置tomcat在get请求的中文也不乱码?两种情况下配置

    我们都知道,get请求和post请求的一个比较显著区别就是,在使用post请求的时候,中文不会乱码,但是在使用get请求的时候,如果url后面带有中文就会乱码了.那么这个怎么解决呢? 前提:配置项目的 ...

  7. virtualBox中有线和无线两种情况下centos虚拟机和本地机互ping的方案

    之前写微信点餐系统的时候,刚开始是无线连接,然后每次进去虚拟机ip和本地ip都会改变,所以每次都需要配置一下nginx,还有本地的路径.之后换有线连接,就研究了一下桥接模式有线情况下虚拟机静态ip设置 ...

  8. EasyUI Datagrid 分页的情况下实现点击表头的小三角图标对数据库中所有数据重新排序

    说明一下: 当点击 datagrid 表头某一列的小三角图标时,easyui 本身是有排序的,但是在当我们对 datagrid 进行了分页的情况下,点击排序只是对当前页的数据进行排序,而需求需要我对数 ...

  9. 小明同学喜欢体育锻炼,他常常去操场上跑步。跑道是一个圆形,在本题中,我们认为跑道是一个半径为R的圆形,设圆心的坐标原点(0,0)。小明跑步的起点坐标为(R,0),他沿着圆形跑道跑步,而且一直沿着一个方向跑步。回到家后,他查看了自己的计步器,计步器显示他跑步的总路程为L。小明想知道自己结束跑步时的坐标,但是他忘记自己是沿着顺时针方向还是逆时针方向跑的了。他想知道在这两种情况下的答案分别是多少。

    include "stdafx.h" #include<iostream> #include<vector> #include<string> ...

随机推荐

  1. JMS和消息驱动Bean(MDB)

    一.说明 本示例使用的ActiveMQ作为消息中间件,服务器为Glassfish,使用JMS发送消息,在MDB接收到消息之后做打印输出. 二.ActiveMQ安装配置 1.安装console war包 ...

  2. A_全然背包

    /* copyright: Grant Yuan algorithm: 全然背包 time : 2014.7.18 __________________________________________ ...

  3. [概率dp] ZOJ 3822 Domination

    题意: 给N×M的棋盘.每天随机找一个没放过棋子的格子放一个棋子 问使得每一个每列都有棋子的天数期望 思路: dp[i][j][k] 代表放了i个棋子占了j行k列 到达目标状态的期望 然后从 dp[n ...

  4. Java--CyclicBarrier使用简介

    CyclicBarrier介绍 (一)一 个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时 ...

  5. 【通信框架】Apache的开源通信框架thrift概述

    在阅读的过程中有不论什么问题.欢迎一起交流 邮箱:1494713801@qq.com    QQ:1494713801 一.作用 Thrift("Scalable Cross-Languag ...

  6. Android layoutInflate.inflate 方法具体解释,removeView()错误解决

    错误: The specified child already has a parent. You must call removeView(). 解答: 这个错误非常直白,就是你viewGroup. ...

  7. 【linux】具体芯片MACHINE_START处理

    欢迎转载,转载时需保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http:// ...

  8. Java基础07 包

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经写了一些Java程序.之前的每个Java程序都被保存为一个文件,比如Tes ...

  9. VC Office2007界面对话框实现

    我们知道VS2008SP1之后,MFC就多了一个功能包,可以快速的建立一个ribbon的界面,视觉样式可以在office 2007蓝.黑等颜色之间切换,这对于单文档/多文档做界面非常方便,而且也蛮好看 ...

  10. 1941. Scary Martian Word

    1941. Scary Martian Word 这道题 一个长度为3的字符串视为 一个 火星文 字母(ASCII 33-122) ,给出一个火星人认为恐怖的单词(由火星字母组成) 然后 给你一篇文章 ...