五种情况下会刷新控件状态(刷新控件状态才能刷新所有子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. quartz群调查调度机制和源代码分析

    pageId=85056282#quartz集群调度机制调研及源代码分析-quartz2.2.1集群调度机制调研及源代码分析" style="color:rgb(59,115,17 ...

  2. 距离变换DT

    距离变换:计算区域中的每个点与最接近的区域外的点之间距离,把二值图象变换为灰度图象. 对于目标中一个点,距离变换的定义为改点与目标边界最近的距离. 目标点离边界约近则值越小,转换的点越暗:越远,值越大 ...

  3. python pyfits

    原链接:http://blog.sina.com.cn/s/blog_a046022d0101a48h.html,全文复制以备出错.   导入pyfits模块:import pyfits        ...

  4. 【译】在Asp.Net中操作PDF – iTextSharp-列表

    原文 [译]在Asp.Net中操作PDF – iTextSharp-列表 在前文中,我们已经知道了如何利用iTextSharp创建PDF文档,设置字体样式和风格.本文开始讲述iTextSharp中的有 ...

  5. 高级特性(6)- 高级Swing

    6.1 列表 6.1.1 JList构件 6.1.2 列表模式 6.1.3 插入和移除值 6.1.4 值的绘制6.2 表格 6.2.1 简单表格 6.2.2 表格模型 6.2.3 对行和列的操作 6. ...

  6. matlab三维画图

    matlab三维画图主要有三个命令:plot3命令.mesh命令和surf命令. plot3 plot3是三维画图的基本函数,绘制的是最为主要的3D曲线图,最主要的调用格式是: plot3(X,Y,Z ...

  7. 设置HTTP代理

    Maven通过<<UserHome>>/.m2/settings.xml(如果没有该文件,复制<<MavenHome>>/conf/settings.x ...

  8. 双击GridView查看详情

    效果如下: protected void gvEquData_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowTy ...

  9. Swift - 使用UISearchController实现带搜索栏的表格

    我原来写过一篇文章“Swift - 带结果列表的搜索条(UISearchDisplayController)的用法”,当时是使用UISearchDisplayController来实现带有搜索功能的列 ...

  10. Python的字符串格式化符号

    1.字符串格式化符号含义 %c:格式化字符及其ASCII码 %s:格式化字符串 %d:格式化整数 %o:格式化无符号八进制数 %x:格式化无符号十六进制数 %X:格式化无符号十六进制数(大写) %f: ...