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 ...
随机推荐
- Entity Framework CodeFirst------使用CodeFirst方式建立数据库连接(一)
本文分步演练介绍通过 Code First 开发建立新数据库.这个方案包括建立不存在的数据库(Code First 创建)或者空数据库(Code First 向它添加新表).借助 Code First ...
- 第七章----pwm蜂鸣器
Linux代码的重用: 在头文件中加载即可使用到原来所有的功能,还有动态方式就是一个驱动使用另一个驱动的资源. 对于像蜂鸣器这样的实验,它的内部文件有很多,所有要有很多的源代码以用于妥善管理. 有多个 ...
- poj 1821 Fence 单调队列优化dp
/* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...
- Less 关于css hack的写法
由于工作需要,最近一直在弄css转写less,遇到最多的问题就是 hack的写法,一些IE的hack,less不支持编译: 常见的不支持的hack如下: IE的滤镜写法 \9\0 IE8部分支持 ...
- linux意外关机,如何修复
意外关机后,提示an error occurred during the file system check. 解决方法,输入root密码 执行 fdisk -l 查看磁盘 (Repair files ...
- javascript中,你真的会用console吗?
使用console进行性能测试和计算代码运行时间 对于前端开发人员,在开发过程中经常需要监控某些表达式或变量的值,如果使用用debugger会显得过于笨重,最常用的方法是会将值输出到控制台上方便调试. ...
- C## 输出Hello world
首先新建一个项目 然后在文件D:\C##Obj\HelloWorld\HelloWorld\Program.cs using System; using System.Collections.Gene ...
- asp.net数据导出到excel表格,并设置表格样式
1.首先在项目中添加引用
- C#内存修改
先通过 System.Diagnostics.Process类获取想要编辑的进程 调用API [Flags] public enum ProcessAccessT ...
- Android 四大组件之service与Broadcast
Android 四大组件之一:service: Service有五个生命周期:onCreat,onStartCommand, onBind,onUnbind, onDestroy 主要有绑定和非绑定两 ...