Delphi - TShape控件解析

技术交流,DH讲解.

这个控件在Additional选项卡,位于ExtCtrls.pas中.
使用的样子:
image
这个控件应该就是一个图形控件,所以它应该直接从TGraphicControl继承下来,然后重载Paint方法就可以了,因为也没有其他好做的了.
我们看看源码吧.

type
  //这个控件可以设置形状
  TShapeType = (stRectangle, stSquare, stRoundRect, stRoundSquare,
    stEllipse, stCircle);

  TShape = class(TGraphicControl)
  private
    //笔(画边框) 和 笔刷(填背景)
    FPen: TPen;
    FBrush: TBrush;
    //什么形状
    FShape: TShapeType;
    //属性的方法,设置属性后,调用Invalidate刷新
    procedure SetBrush(Value: TBrush);
    procedure SetPen(Value: TPen);
    procedure SetShape(Value: TShapeType);
  protected
    //关键是这个
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    //这个其实就是Invalidate
    procedure StyleChanged(Sender: TObject);
    property Align;
    property Anchors;
    property Brush: TBrush read FBrush write SetBrush;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Constraints;
    property ParentShowHint;
    property Pen: TPen read FPen write SetPen;
    property Shape: TShapeType read FShape write SetShape default stRectangle;
    property ShowHint;
    property Touch;
    property Visible;
    property OnContextPopup;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
    property OnGesture;
    property OnStartDock;
    property OnStartDrag;
  end;
我们看看设置属性的代码:
procedure TShape.SetBrush(Value: TBrush);
begin
  FBrush.Assign(Value);
end;

procedure TShape.SetPen(Value: TPen);
begin
  FPen.Assign(Value);
end;

procedure TShape.SetShape(Value: TShapeType);
begin
  if FShape <> Value then
  begin
    FShape := Value;
    Invalidate;
  end;
end;
前面2个为什么没有Invalidate?是不是觉得我在忽悠你?嘿嘿,不慌,我们看看Create里面干了什么事?
constructor TShape.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];//这个属性什么用,看我转的上一篇文章ControlStyle的意义吧
  Width := 65;
  Height := 65;
  FPen := TPen.Create;
  FPen.OnChange := StyleChanged;
  FBrush := TBrush.Create;
  FBrush.OnChange := StyleChanged;
end;

destructor TShape.Destroy;
begin
  FPen.Free;
  FBrush.Free;
  inherited Destroy;
end;
看见了设置了Pen和Brush的OnChange事件为StyleChanged,也就是Pen或者Brush有改变就执行StyleChanged方法:
procedure TShape.StyleChanged(Sender: TObject);
begin
  Invalidate;
end;
我之前说了Invalidate是刷新,也就是调用Paint方法,那么我们看看Paint:
procedure TShape.Paint;
var
  X, Y, W, H, S: Integer;
begin
  with Canvas do
  begin
    //设置画布的属性 和TShape一致
    Pen := FPen;
    Brush := FBrush;
    //确定画图区域,起始位置要注意笔的线宽的一半
    X := Pen.Width div 2;
    Y := X;
    W := Width - Pen.Width + 1;
    H := Height - Pen.Width + 1;
    if Pen.Width = 0 then
    begin
      Dec(W);
      Dec(H);
    end;
    if W < H then S := W else S := H;
    //正方形 圆角正方形 和 圆都需要设置长宽一样
    if FShape in [stSquare, stRoundSquare, stCircle] then
    begin
      Inc(X, (W - S) div 2);
      Inc(Y, (H - S) div 2);
      W := S;
      H := S;
    end;
    //最后一步根据 形状 调用不同的Canvas方法画图形
    case FShape of
      stRectangle, stSquare:
        Rectangle(X, Y, X + W, Y + H);
      stRoundRect, stRoundSquare:
        RoundRect(X, Y, X + W, Y + H, S div 4, S div 4);
      stCircle, stEllipse:
        Ellipse(X, Y, X + W, Y + H);
    end;
  end;
end;
很简单吧,这个控件的确很简单,我们看源代码的时候,一步一步来就好了,关键思路要清晰.
我是DH.

转载于:https://www.cnblogs.com/huangjacky/archive/2010/03/03/1677037.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值