11

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

问题在于我需要它的宽度灵活,为此我想到了将框架内的所有内容alClientTEdit5 像素边距转动,以便用户可以看到圆角。

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

我看到正确的唯一方法是仅使用TEditwithalClient和 5px 边距和 no TShape。相反,我可以TFrame用透明度制作圆角,这样在不同颜色或TImages.

但是我该怎么做呢?

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

这是目标:透明圆角

4

1 回答 1

16

要回答您的问题如何制作带圆角的框架,您可以尝试类似的方法,但您会对结果不满意,因为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应用了平滑模式):

在此处输入图像描述

可以说,将 GDI+ 用于如此微小的东西,但没有抗锯齿的纯 GDI 渲染使结果看起来很难看,这是一个很大的开销。下面是使用纯 GDI 渲染的同一个圆角矩形的示例:

在此处输入图像描述

于 2012-07-26T21:01:05.973 回答