没有内容,不代表没有边框。比如设计期一个空的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. Entity Framework CodeFirst------使用CodeFirst方式建立数据库连接(一)

    本文分步演练介绍通过 Code First 开发建立新数据库.这个方案包括建立不存在的数据库(Code First 创建)或者空数据库(Code First 向它添加新表).借助 Code First ...

  2. 第七章----pwm蜂鸣器

    Linux代码的重用: 在头文件中加载即可使用到原来所有的功能,还有动态方式就是一个驱动使用另一个驱动的资源. 对于像蜂鸣器这样的实验,它的内部文件有很多,所有要有很多的源代码以用于妥善管理. 有多个 ...

  3. poj 1821 Fence 单调队列优化dp

    /* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...

  4. Less 关于css hack的写法

    由于工作需要,最近一直在弄css转写less,遇到最多的问题就是 hack的写法,一些IE的hack,less不支持编译: 常见的不支持的hack如下: IE的滤镜写法 \9\0    IE8部分支持 ...

  5. linux意外关机,如何修复

    意外关机后,提示an error occurred during the file system check. 解决方法,输入root密码 执行 fdisk -l 查看磁盘 (Repair files ...

  6. javascript中,你真的会用console吗?

    使用console进行性能测试和计算代码运行时间 对于前端开发人员,在开发过程中经常需要监控某些表达式或变量的值,如果使用用debugger会显得过于笨重,最常用的方法是会将值输出到控制台上方便调试. ...

  7. C## 输出Hello world

    首先新建一个项目 然后在文件D:\C##Obj\HelloWorld\HelloWorld\Program.cs using System; using System.Collections.Gene ...

  8. asp.net数据导出到excel表格,并设置表格样式

    1.首先在项目中添加引用

  9. C#内存修改

    先通过 System.Diagnostics.Process类获取想要编辑的进程 调用API [Flags]                    public enum ProcessAccessT ...

  10. Android 四大组件之service与Broadcast

    Android 四大组件之一:service: Service有五个生命周期:onCreat,onStartCommand, onBind,onUnbind, onDestroy 主要有绑定和非绑定两 ...