Delphi控件的显示内容与显示边框是两回事
没有内容,不代表没有边框。比如设计期一个空的TImage仍是有边框的。
if (csOpaque in image1.ControlStyle) then ShowMessage('不透明')
else ShowMessage('透明') // image1没有内容的时候,就是透明;有内容的时候,就是不透明
再比如:
procedure TWinControl.PaintControls(DC: HDC; First: TControl);
var
I, Count, SaveIndex: Integer;
FrameBrush: HBRUSH;
begin
// 这个DC其实是父Win控件的句柄
// 一共有2处调用此函数。分别是TControl.Repaint和TWinControl.PaintHandler,分别用来重绘图形控件和Win控件(后者包括了图形子控件,也正因为这个才需要执行这个函数)
if DockSite and UseDockManager and (DockManager <> nil) then
DockManager.PaintSite(DC);
// 重画所有子控件(图形和句柄控件)
// FControls和FWinControls在TControl.SetParent里调用TWinControl.Insert里增加元素
if FControls <> nil then // 专指图形控件,不包含windows控件
begin
I := ;
if First <> nil then
begin
I := FControls.IndexOf(First);
if I < then I := ;
end;
Count := FControls.Count;
while I < Count do
begin
with TControl(FControls[I]) do
if (Visible or (csDesigning in ComponentState) and not (csNoDesignVisible in ControlStyle)) and
RectVisible(DC, Rect(Left, Top, Left + Width, Top + Height)) then // API
begin
if csPaintCopy in Self.ControlState then Include(FControlState, csPaintCopy);
SaveIndex := SaveDC(DC); // API,重画前,保存父控件的DC
MoveWindowOrg(DC, Left, Top); // 调用2个API
IntersectClipRect(DC, , , Width, Height); // API,新建一个完全的区域
// 原本图形控件不能接受Windows消息的,现在也接受了。注意传递了父控件的DC
Perform(WM_PAINT, DC, ); // important7,图形控件已经把WM_PAINT消息内容已经填好,就等程序员填写Paint函数加上真正要执行的内容。
RestoreDC(DC, SaveIndex); // API,恢复父控件的DC
Exclude(FControlState, csPaintCopy); // 画完之后,去除标记
end;
Inc(I);
end;
end;
// 除此以外,还要给Windows子控件额外画边框(因为实体已经画好了)(注意不是给自己画边框)
if FWinControls <> nil then // 专指windows控件,不包含图形控件
for I := to FWinControls.Count - do
with TWinControl(FWinControls[I]) do
if FCtl3D and (csFramed in ControlStyle) and
(Visible or (csDesigning in ComponentState) and not (csNoDesignVisible in ControlStyle)) then
begin
// fixme 可以试试屏蔽这里的语句,看看效果
FrameBrush := CreateSolidBrush(ColorToRGB(clBtnShadow)); // API
FrameRect(DC, Rect(Left - , Top - , Left + Width, Top + Height), FrameBrush); // API 画矩形边框
DeleteObject(FrameBrush); // API
FrameBrush := CreateSolidBrush(ColorToRGB(clBtnHighlight));
FrameRect(DC, Rect(Left, Top, Left + Width + , Top + Height + ), FrameBrush); // 画两条线
DeleteObject(FrameBrush); // API
end;
end;
又看到一个函数:
procedure TWinControl.WMWindowPosChanged(var Message: TWMWindowPosChanged);
var
Framed, Moved, Sized: Boolean;
begin
// 三明治手法,这里使边框失效
// 判断是否有边框,是否移动了,是否改变了尺寸
Framed := FCtl3D and (csFramed in ControlStyle) and (Parent <> nil) and (Message.WindowPos^.flags and SWP_NOREDRAW = );
Moved := (Message.WindowPos^.flags and SWP_NOMOVE = ) and IsWindowVisible(FHandle); // API
Sized := (Message.WindowPos^.flags and SWP_NOSIZE = ) and IsWindowVisible(FHandle);
// 如果有边框,并且已经移动或者改变了尺寸,那么使边框无效
if Framed and (Moved or Sized) then InvalidateFrame; // 类函数 fixme 这不是重复了吗?
// 仅仅调整边框不够,更主要是调整控件自己的位置
if not (csDestroyingHandle in ControlState) then UpdateBounds; // 类函数,使用API调整控件在屏幕上的位置 inherited; // super 三明治手法,调用程序员潜在的消息函数,并重新计算最大化最小化的限制和坞里的尺寸 // fixme 根据消息的内容,再次使边框无效(如果有显示或隐藏标记的话)
if Framed and ((Moved or Sized) or (Message.WindowPos^.flags and (SWP_SHOWWINDOW or SWP_HIDEWINDOW) <> )) then
InvalidateFrame; // 类函数,简单调用API
end;
procedure TWinControl.InvalidateFrame;
var
R: TRect;
begin
R := BoundsRect; // 类属性,调用方法,简单计算
InflateRect(R, , ); // API
InvalidateRect(Parent.FHandle, @R, True); // API
end;
留个爪,以后再详细研究~
Delphi控件的显示内容与显示边框是两回事的更多相关文章
- DotNetBar 控件设置空内容时显示内容
可以通过修改所有关于Watermark时的设置.
- delphi 控件的名称怎么不显示了
选择菜单 Tools--Environment在打开的对话框中选择 Designer 页,选 其中的 Options 选项勾选 Show component captions ,点击 OK即可
- WinForm控件TreeView 只部分节点显示 CheckBox
WinForm控件TreeView 只部分节点显示 CheckBox 用过asp.net的应该知道,要在treeview中实现上述功能可以使用ShowCheckBox 属性指定那些节点显示check ...
- Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,相似图片浏览器
MAC : XCode -> Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,类似图片浏览器 STEP1:将两个目录复制到project里面ImageBrowser ...
- delphi Components[i]清除所有edit控件中的内容
(* 一般的清空combobox方法 combobox1.clear; ... combobox9.clear; *) procedure TForm1.Button1Click(Sender: ...
- Delphi 控件大全
delphi 控件大全(确实很全) delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org Tb97 最有名的工具条(ToolBar ...
- delphi控件属性大全-详解-简介
http://blog.csdn.net/u011096030/article/details/18716713 button 组件: CAPTION 属性 :用于在按钮上显示文本内容 Cancel ...
- 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 ...
随机推荐
- 字符串 赋值 以及gets
我们知道字符串用字符数组或用指针实现,但是在赋值的时候产生了不少疑惑 使用方法一: char a[ ]={"I LOVE YOU!"}; 但是以下这样就是错的: char a[20 ...
- CentOS 6.3 源码安装LAMP(Linux+Apache+Mysql+Php)环境
一.简介 什么是LAMP LAMP是一种Web网络应用和开发环境,是Linux, Apache, MySQL, Php/Perl的缩写,每一个字母代表了一个组件,每个组件就其本身而>言都是在它所 ...
- css 权威指南笔记(二)元素
替换元素 用来替换元素内容的部分并非有文档内容直接表示. img input 非替换元素 其内容由用户代理(通常是一个浏览器)在元素本身生成的框中显示. 块级元素 块级元素生成一个 元素框,(默认)会 ...
- fedora虚拟机中的vsftp服务配置
最近在学习unix,但在使用ftp链接虚拟机时总是总是各种报错,查了很多资料,试了很多方法,都有一定的问题,最后也算是久病成医,这里给其他跟我一样小白提供一个比较好的解决方案希望能有所帮助. Fedo ...
- eclipse下将普通的java工程转换成web工程
开发过程中需要对普通的java工程转换成动态的web工程,网络上查询了资料很简单的几步操作就可以搞定,操作步骤如下: 编辑.project 修改以下配置 <nature>org.eclip ...
- JAVA学习笔记--二
一.抽象类: 访问修饰符 abstract class 类名{ } 抽象类和普通类的区别: 1. 抽象类不能被实例化 2. 抽象类一般含有抽象方法 抽象方法:在抽象类中只有方法签名(方法声明),没有方 ...
- ORACLE 中ROWNUM用法总结!(转)
对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=),并非说用>,>=,=,be ...
- 从XML文件中获取格式化的文本信息
在FMW的运维过程中,时常需要将中间传输的XML信息转换为excel格式化的问题提交给关联系统人员,现总结三种格式化问题提供方式 一.使用Excel转换 因为从系统中取到的xml文档为中间信息文档,需 ...
- helloServlet
创建第一个web程序 用myeclipse创建一个web项目,继而创建一个servlet 自动帮助你创建了一个web.xml文件 <servlet>....<servlet>指 ...
- c#抽象工厂模式
抽象工厂模式向客户端提供一个接口,使得客户端在不必指定具体类型的情况下,创建多个产品族中的对象.本文采取的仍然是接着以前的那个快餐店的例子. 现在,快餐店经常良好,逐渐发展壮大,为了适合不同地方人的饮 ...