如何制作圆角框架?

时间:2012-07-26 18:08:42

标签: delphi user-interface frame delphi-2006

我想基于TFrameTLMDShapeControl(用于绘制圆角背景)和TEdit控件(也可以是TComboBox或一个TDBEdit等等。 之后,我将使用“添加到调色板”命令将其转换为可重用的组件控件。

问题在于我需要宽度灵活,因此我有想法将框架alClientTEdit内的所有内容都设置为5像素边距,这样用户就可以看到圆角角落。

这很糟糕,因为我不能使用Align并将组件设置在另一个的顶部。现在我每次必须使用它时都要复制和粘贴组件! : - (((

我看到正确的事情的唯一方法是仅使用TEdit alClient和5px边距而不使用TShape。相反,我可以使TFrame成为具有透明度的圆角,因此不会看到不同颜色的丑陋或TImages

但我该怎么做?

有没有人有任何代码示例?

this is the goal: transparent rounded corners

1 个答案:

答案 0 :(得分:14)

要回答你的问题如何制作带圆角的框架你可以尝试这样的东西,但是你会对结果不满意,因为这里使用的CreateRoundRectRgn没有抗锯齿。

type
  TFrame1 = class(TFrame)
    Edit1: TEdit;
    Button1: TButton;
  protected
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
  end;

implementation

procedure TFrame1.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
  Region: HRGN;
begin
  inherited;
  Region := CreateRoundRectRgn(0, 0, ClientWidth, ClientHeight, 30, 30);
  SetWindowRgn(Handle, Region, True);
end;

<强> 更新

由于GDI没有任何支持弧形渲染抗锯齿的功能,我在这里发布了一个使用GDI +的圆形矩形形状(只是一个纯填充的圆形矩形)的示例(为此你需要GDI +包装器from here)。

以下属性对其使用很重要:

  • 颜色 - 是形状填充颜色(可以增强笔颜色,渐变等)。
  • 半径 - 是用于绘制圆角的圆的​​半径(以像素为单位)
  • AlphaValue - 是渲染的圆角矩形的不透明度值(仅为了好玩: - )

unit RoundShape;

interface

uses
  SysUtils, Classes, Controls, Graphics, GdiPlus;

type
  TCustomRoundShape = class(TGraphicControl)
  private
    FRadius: Integer;
    FAlphaValue: Integer;
    procedure SetRadius(Value: Integer);
    procedure SetAlphaValue(Value: Integer);
  protected
    procedure Paint; override;
    property Radius: Integer read FRadius write SetRadius default 10;
    property AlphaValue: Integer read FAlphaValue write SetAlphaValue default 255;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TRoundShape = class(TCustomRoundShape)
  public
    property Canvas;
  published
    property Align;
    property AlphaValue;
    property Anchors;
    property Color;
    property Constraints;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Font;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property Radius;
    property ShowHint;
    property Visible;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;

procedure Register;

implementation

{ TCustomRoundShape }

constructor TCustomRoundShape.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Width := 213;
  Height := 104;
  FRadius := 10;
  FAlphaValue := 255;
end;

procedure TCustomRoundShape.SetRadius(Value: Integer);
begin
  if FRadius <> Value then
  begin
    FRadius := Value;
    Invalidate;
  end;
end;

procedure TCustomRoundShape.SetAlphaValue(Value: Integer);
begin
  if FAlphaValue <> Value then
  begin
    FAlphaValue := Value;
    Invalidate;
  end;
end;

procedure TCustomRoundShape.Paint;
var
  GPPen: TGPPen;
  GPColor: TGPColor;
  GPGraphics: IGPGraphics;
  GPSolidBrush: IGPSolidBrush;
  GPGraphicsPath: IGPGraphicsPath;
begin
  GPGraphicsPath := TGPGraphicsPath.Create;
  GPGraphicsPath.Reset;
  GPGraphicsPath.AddArc(0, 0, FRadius, FRadius, 180, 90);
  GPGraphicsPath.AddArc(ClientWidth - FRadius - 1, 0, FRadius, FRadius, 270, 90);
  GPGraphicsPath.AddArc(ClientWidth - FRadius - 1, ClientHeight - FRadius - 1,
    FRadius, FRadius, 0, 90);
  GPGraphicsPath.AddArc(0, ClientHeight - FRadius - 1, FRadius, FRadius, 90, 90);
  GPGraphicsPath.CloseFigure;

  GPColor.InitializeFromColorRef(ColorToRGB(Color));
  GPColor.Alpha := FAlphaValue;
  GPPen := TGPPen.Create(GPColor);
  GPSolidBrush := TGPSolidBrush.Create(GPColor);

  GPGraphics := TGPGraphics.Create(Canvas.Handle);
  GPGraphics.SmoothingMode := SmoothingModeAntiAlias;
  GPGraphics.FillPath(GPSolidBrush, GPGraphicsPath);
  GPGraphics.DrawPath(GPPen, GPGraphicsPath);
end;

procedure Register;
begin
  RegisterComponents('Stack Overflow', [TRoundShape]);
end;

end.

结果(应用了SmoothingModeAntiAlias平滑模式):

enter image description here

可以说,使用GDI +进行这么小的事情是一个很大的开销,但纯粹的GDI渲染而没有抗锯齿,结果看起来很丑陋。以下是使用纯GDI渲染的相同圆角矩形的示例:

enter image description here