码迷,mamicode.com
首页 > Windows程序 > 详细

Delphi控件的显示内容与显示边框是两回事

时间:2015-08-26 19:42:02      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

没有内容,不代表没有边框。比如设计期一个空的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 := 0;
    if First <> nil then
    begin
      I := FControls.IndexOf(First);
      if I < 0 then I := 0;
    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, 0, 0, Width, Height); // API,新建一个完全的区域
          // 原本图形控件不能接受Windows消息的,现在也接受了。注意传递了父控件的DC
          Perform(WM_PAINT, DC, 0);     // 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 := 0 to FWinControls.Count - 1 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 - 1, Top - 1, Left + Width, Top + Height), FrameBrush); // API 画矩形边框
          DeleteObject(FrameBrush); // API
          FrameBrush := CreateSolidBrush(ColorToRGB(clBtnHighlight));
          FrameRect(DC, Rect(Left, Top, Left + Width + 1, Top + Height + 1), FrameBrush); // 画两条线
          DeleteObject(FrameBrush); // API
        end;
end;

留个爪,以后再详细研究~

Delphi控件的显示内容与显示边框是两回事

标签:

原文地址:http://www.cnblogs.com/findumars/p/4761148.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!