没有内容,不代表没有边框。比如设计期一个空的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控件的显示内容与显示边框是两回事的更多相关文章

  1. DotNetBar 控件设置空内容时显示内容

    可以通过修改所有关于Watermark时的设置.

  2. delphi 控件的名称怎么不显示了

    选择菜单 Tools--Environment在打开的对话框中选择 Designer 页,选 其中的 Options 选项勾选 Show component captions ,点击 OK即可

  3. WinForm控件TreeView 只部分节点显示 CheckBox

    WinForm控件TreeView 只部分节点显示  CheckBox 用过asp.net的应该知道,要在treeview中实现上述功能可以使用ShowCheckBox 属性指定那些节点显示check ...

  4. Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,相似图片浏览器

    MAC : XCode -> Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,类似图片浏览器 STEP1:将两个目录复制到project里面ImageBrowser ...

  5. delphi Components[i]清除所有edit控件中的内容

    (* 一般的清空combobox方法 combobox1.clear; ... combobox9.clear; *)   procedure TForm1.Button1Click(Sender: ...

  6. Delphi 控件大全

    delphi 控件大全(确实很全)   delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org Tb97 最有名的工具条(ToolBar ...

  7. delphi控件属性大全-详解-简介

    http://blog.csdn.net/u011096030/article/details/18716713 button 组件: CAPTION 属性 :用于在按钮上显示文本内容 Cancel ...

  8. delphi 控件大全(确实很全)

    delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org Tb97 最有名的工具条(ToolBar)控件库,仿Office97,如TDoC ...

  9. DELPHI控件属性事件说明

    常用DELPHI控件属性事件设置说明 常用DELPHI控件属性设置说明目录TForm Class TPanel组件 TToolBar Class TToolButton Class TTimer Cl ...

  10. delphi 控件查询

    //老古董,以前这些东西太多了,收藏的没过来,只好粘贴至此,当然不是本人整理的. delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org ...

随机推荐

  1. Swift 表视图动画教程: Drop-In Cards

    http://www.raywenderlich.com/76024/swift-table-view-animations-tutorial-drop-cards 标准 table view 是一个 ...

  2. 3 - SQL Server 2008 之 使用SQL语句删除约束条件

    基本语法为: ALTER TABLE 表名 DROP CONSTRAINT 约束名1,约束名2…… 如果删除一个约束,不需要逗号后的约束名,如果删除两个及两个以上的约束,必须以逗号隔开. 使用上一节中 ...

  3. [Redis] C#中使用redis

    C#中使用redis 首先打开Visual Studio建立一个简单的控制台应用程序,我这里暂时使用的VS2013的版本. 然后通过Nuget进行安装Redis常用组件ServiceStack.Red ...

  4. Node.js + Express + Mongodb 开发搭建个人网站(一)

    一.Node + Express环境搭建 0.去Node官网下载安装node,如果安装了 npm 和 node的话 那么就 安装 全局的 express,-g全局安装 npm install expr ...

  5. 表达式:使用API创建表达式树(3)

    一.DebugInfoExpression:发出或清除调试信息的序列点. 这允许调试器在调试时突出显示正确的源代码. static void Main(string[] args) { var asm ...

  6. (转)基于PHP的cURL快速入门

    1. 原文:基于PHP的cURL快速入门 英文原文:http://net.tutsplus.com/tutorial ... for-mastering-curl/ 原文作者:Burak Guzel ...

  7. SimpleDateFormat使用详解

    http://blog.csdn.net/gubaohua/article/details/575488 public class SimpleDateFormat extends DateForma ...

  8. django连接已有的数据库

    以连接postgresql为例: 1.安装psycopg2,下载地址:http://www.stickpeople.com/projects/python/win-psycopg/ 2.配置setti ...

  9. 怎样在官网上下载xcode7.2

    其实我觉得还是有必要就这个写一篇论文的  以证明自己真的是个菜鸟 首先进入苹果开发者官网 https://developer.apple.com/ 选择 resource 然后 点击加号  然后下载就 ...

  10. Asp与Asp.Net的区别

    今天在网上看到一位朋友问asp与asp.net的区别.编辑本人也是从asp转型到.net来的,几年了,几乎都忘记了asp的存在,也说不出它们之间的区别,因为感觉两者是根本就没有联系,非要说有联系,那就 ...