Delphi控件的透明与不透明(要挨个解释一下原因),对InvalidateControl的关键理解
procedure TForm1.Button3Click(Sender: TObject);
begin
if (csOpaque in ControlStyle) then ShowMessage('不透明')
else ShowMessage('透明') // Form透明
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if (csOpaque in Panel1.ControlStyle) then ShowMessage('不透明') // Panel不透明
else ShowMessage('透明')
end;
if (csOpaque in Button1.ControlStyle) then ShowMessage('不透明')
else ShowMessage('透明') // Button透明
if (csOpaque in label1.ControlStyle) then ShowMessage('不透明') // Label不透明
else ShowMessage('透明')
if (csOpaque in image1.ControlStyle) then ShowMessage('不透明')
else ShowMessage('透明') // image1没有内容的时候,就是透明;有内容的时候,就是不透明
if (csOpaque in bitbtn1.ControlStyle) then ShowMessage('不透明')
else ShowMessage('透明') // bitbtn1有没有内容都是透明
http://bbs.2ccc.com/topic.asp?topicid=461248
---------------------------------------------------------------
对InvalidateControl的关键理解:
1.它是TControl的非虚函数,虽然它可以被TWinControl调用,但是根据VCL的其它代码,充分证明它实际上只能被图形子控件所使用:
procedure TWinControl.RemoveControl(AControl: TControl);
begin
Perform(CM_CONTROLCHANGE, Integer(AControl), Integer(False)); // 通知父控件
if AControl is TWinControl then
with TWinControl(AControl) do
begin
RemoveFocus(True); // 类函数
DestroyHandle; // important5 销毁它和它所有的子控件
end
else
if HandleAllocated then
AControl.InvalidateControl(AControl.Visible, False); // important5 让图形控件消失使用这种手法
Remove(AControl); // 类函数
Perform(CM_CONTROLLISTCHANGE, Integer(AControl), Integer(False)); // 通知父控件
Realign;
end; procedure TControl.DoDock(NewDockSite: TWinControl; var ARect: TRect);
begin
{ Erase TControls before UpdateboundsRect modifies position }
if not (Self is TWinControl) then InvalidateControl(Visible, False);
if Parent <> NewDockSite then
UpdateBoundsRect(ARect) // 类函数
else
BoundsRect := ARect; // 类属性
if (NewDockSite = nil) or (NewDockSite = NullDockSite) then Parent := nil;
end;
2. 它的实际内容:
procedure TControl.InvalidateControl(IsVisible, IsOpaque: Boolean);
var
bParentOpaque: Boolean;
bChlipped: Boolean;
Rect: TRect;
begin
if (IsVisible or (csDesigning in ComponentState) and not (csNoDesignVisible in ControlStyle))
and (Parent <> nil) and Parent.HandleAllocated then
begin
Rect := BoundsRect; // 类函数,简单计算(根据控件的长宽高)标签的坐标以及尺寸
bParentOpaque := csOpaque in Parent.ControlStyle; // Form默认透明(csOpaque不在风格里)。但是父控件不一定是Form,不要思维僵化在这里。
bChlipped:=BackgroundClipped;
// 实验说明后两个一般情况下都是False
// 第三个参数为False,则保持背景不变。Not作用符以后,有三者条件之一成立即可,就会保持背景不变。
// IsOpaque表示TControl自己不透明,完全遮住了父控件相应的区域,当然不用重绘背景
// bParentOpaque表示父控件自己就是不透明的,现有的背景已经足够(不需要更新父父控件的背景),那么无论TControl子控件怎么办自绘,都不需要更新背景。
// bChlipped 重合了
// 反过来说,自己透明(而且有可能是从不透明变成透明),这时当然要重绘背景。因为原来那部分背景根本就没有绘制。
// 父控件透明,也可以从不透明变成透明,这时也要背景重绘。fixme 如果父控件一直是透明的呢,那么每次绘制都要求父父控件背景重绘,因为父父控件的状态也有可能在改变。
// fixme 有空仔细研究背景消息 才能深刻理解
InvalidateRect(Parent.Handle, @Rect, not (IsOpaque or bParentOpaque or bChlipped)); // API
end;
end;
关键在于最后一个参数,三个条件之一成立,结果就是false,就不需要重绘背景了。这三个条件分别是:
1. 自身不透明(比如自身是Panel,或者自身是默认状态的标签),那么在自己的区域坐标内,自己可以随意重绘,而整个父控件的大背景不用变化。这个最容易理解。
2. 父控件不透明(比如父控件是Panel),那么父控件的背景不用看别的控件脸色,子控件在上面无论怎么自绘,也不需要改变父控件的背景。这个也能理解。
3. 兄弟控件的矩形区域与自己完全相同(也就是当前控件的区域坐标,与另一个z轴比它低、且不透明的兄弟控件的区域坐标完全一致,此时bChipped=true,此时当前控件的背景色要看这个兄弟控件的颜色即可,与父控件的颜色完全无关了)。这个也好理解,当前控件怎么自绘,都不影响和不需要父控件的背景。
但是,如果透明标签放在Form上,那么IsOpaque=false, bParentOpaque=false, bChipped=false,那么此时就会重绘整个句柄的区域,而不仅仅是指定的部分。
If the bErase parameter is TRUE for any part of the update region, the background is erased in the entire region, not just in the specified part.
Delphi控件的透明与不透明(要挨个解释一下原因),对InvalidateControl的关键理解的更多相关文章
- Delphi 控件大全
delphi 控件大全(确实很全) delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org Tb97 最有名的工具条(ToolBar ...
- delphi 控件大全(确实很全)
delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org Tb97 最有名的工具条(ToolBar)控件库,仿Office97,如TDoC ...
- DELPHI控件属性事件说明
常用DELPHI控件属性事件设置说明 常用DELPHI控件属性设置说明目录TForm Class TPanel组件 TToolBar Class TToolButton Class TTimer Cl ...
- delphi 控件查询
//老古董,以前这些东西太多了,收藏的没过来,只好粘贴至此,当然不是本人整理的. delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org ...
- delphi控件属性大全-详解-简介
http://blog.csdn.net/u011096030/article/details/18716713 button 组件: CAPTION 属性 :用于在按钮上显示文本内容 Cancel ...
- 对Delphi控件作用的新理解(控件本身的源代码就是一个很强的工业级源码)
最近几天,对Delphi控件的含义有了一个新的理解.其实它不仅仅是给程序员提供功能的一个表层调用,控件本身的源代码就是一个很强的工业级源码.而且它的Main例子,往往就已经是半成品.而别的语言里没有那 ...
- Ehlib(Delphi控件) v9.2.024 D7-XE10.2 免费绿色特别版
下载地址:https://www.jb51.net/softs/579413.html#downintro2 EHLib是一个DELPHI 下的非常棒的第三方Grid控件,比DELPHI自带的强大许多 ...
- delphi 控件集
delphi 控件集: 1)RAIZE 控件包 :http://www.raize.com/devtools/rzcomps/ 被收购 Raize Components has been ac ...
- Delphi控件-复合控件【转】
复合控件复合控件是Delphi控件中非常重要的一种控件,复合控件就是将两个或两个以上的控件重新组合成一个新的控件.例如TspinEdit.TlabeledEdit.TDBNavigator等就是复合控 ...
随机推荐
- Google技术专家的建议:各种SdkVersion如何选择?
原文链接: https://medium.com/google-developers/picking-your-compilesdkversion-minsdkversion-targetsdkver ...
- Java NIO 学习笔记
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3344148.html ...
- 各大浏览器CSS Hack收集
各大浏览器CSS Hack收集 >>>>>>>>>>>>>>>>>>>>> ...
- PHP 解决未定义变量报错
在PHP中 有时候会出现 Notice: Undefined index: sid in D:\Apache Group\Apache2\htdocs\php_mobile\mobile\chao\s ...
- 关于一些Android冷知识
1. 在Android4.0以后,EditText就由以前的输入框变成了一条划线的输入方式,如需要变为老版本的,只需在layout里面引入代码: android:background="@a ...
- angularjs 将带标签的内容解析后返回
参考地址:http://okashii.lofter.com/post/1cba87e8_29e0fab 引入angular-sanitize.js文件 注入ngSanitize 页面数据绑定 ng- ...
- poj1828
poj1828 [问题的描述]是这样的:程序猿的近亲 猴子(......)最近在进行王位争夺站. 题中使用二维坐标轴上的点(x,y)来代表猴子所占有的位置, 每只猴子占有一个坐标点.并且一个坐标点上面 ...
- 提供他人class文件
1.考虑的问题,提供的文件是否依赖于其他jar包. 例如:解析html简历时,依赖于Jsoup包.
- C#操作数据库,将其查查出来的记录条数显示在winform窗体中的方法之一
//1.数据库链接的基本操作(略) //2.创建对象函数(关键部分) sqlConn.Open(); //初始化定义记录条数 ; object obj = sqlComm.ExecuteScalar( ...
- git 教程 git.oschina.net
官方说明:http://git.oschina.net/oschina/git-osc/wikis/%E5%B8%AE%E5%8A%A9#ssh-keys 安装完成后,在开始菜单里找到"Gi ...