测试效果图:
自定义的 MyShape 单元:
测试代码:
自定义的 MyShape 单元:
unit MyShape; interface uses Windows, Classes, Graphics, Controls; type TMyShapeType = (stRectangle, stSquare, stRoundRect, stRoundSquare, stEllipse, stCircle, stPolygon); TPoints = array of TPoint; TMyShape = class(TGraphicControl) {根据 TShape 改写} private FPen: TPen; FBrush: TBrush; FShape: TMyShapeType; FPonits: TPoints; procedure SetBrush(Value: TBrush); procedure SetPen(Value: TPen); procedure SetShape(Value: TMyShapeType); procedure SetPonits(const Value: TPoints); protected procedure Paint; override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published 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: TMyShapeType read FShape write SetShape default stRectangle; property ShowHint; 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 OnStartDock; property OnStartDrag; property Ponits: TPoints read FPonits write SetPonits; end; implementation { MyTShape } constructor TMyShape.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := ControlStyle + [csReplicatable]; Width := 65; Height := 65; FPen := TPen.Create; FPen.OnChange := StyleChanged; FBrush := TBrush.Create; FBrush.OnChange := StyleChanged; end; destructor TMyShape.Destroy; begin FPen.Free; FBrush.Free; inherited Destroy; end; procedure TMyShape.Paint; var X, Y, W, H, S: Integer; begin with Canvas do begin 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; 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); stPolygon: Polygon(FPonits); end; end; end; procedure TMyShape.StyleChanged(Sender: TObject); begin Invalidate; end; procedure TMyShape.SetBrush(Value: TBrush); begin FBrush.Assign(Value); end; procedure TMyShape.SetPen(Value: TPen); begin FPen.Assign(Value); end; procedure TMyShape.SetShape(Value: TMyShapeType); begin if FShape <> Value then begin FShape := Value; Invalidate; end; end; procedure TMyShape.SetPonits(const Value: TPoints); var i,x,y: Integer; begin FPonits := Value; for i := 0 to Length(Value) - 1 do begin x := Value[i].X; y := value[i].Y; if Left > x then Left := x; if Top > y then Top := y; if Width < x then Width := x; if Height < y then Height := y; end; Invalidate; end; end.
测试代码:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses MyShape; var shape: TMyShape; procedure TForm1.Button1Click(Sender: TObject); var pts: TPoints; i: Integer; begin Randomize; SetLength(pts, Random(4)+3); {随机测试: 最少是三角形、最多是七边形} for i := 0 to Length(pts) - 1 do begin pts[i].X := Random(ClientWidth); pts[i].Y := Random(ClientHeight); end; shape.Ponits := pts; end; procedure TForm1.FormCreate(Sender: TObject); var pts: TPoints; begin shape := TMyShape.Create(Self); SetLength(pts, 4); pts[0] := Point(ClientWidth div 2, 10); pts[1] := Point(ClientWidth - 10, ClientHeight div 2); pts[2] := Point(ClientWidth div 2, ClientHeight - 10); pts[3] := Point(10, ClientHeight div 2); shape.Ponits := pts; shape.Shape := stPolygon; shape.Parent := Self; end; procedure TForm1.FormDestroy(Sender: TObject); begin shape.Free; end; end.测试窗体:
object Form1: TForm1 Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 206 ClientWidth = 339 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate OnDestroy = FormDestroy PixelsPerInch = 96 TextHeight = 13 object Button1: TButton Left = 256 Top = 160 Width = 75 Height = 25 Caption = 'Button1' TabOrder = 0 OnClick = Button1Click end end