我想基于TFrame
和TLMDShapeControl
(用于绘制圆角背景)和TEdit
控件(也可以是TComboBox
或一个TDBEdit
等等。
之后,我将使用“添加到调色板”命令将其转换为可重用的组件控件。
问题在于我需要宽度灵活,因此我有想法将框架alClient
和TEdit
内的所有内容都设置为5像素边距,这样用户就可以看到圆角角落。
这很糟糕,因为我不能使用Align
并将组件设置在另一个的顶部。现在我每次必须使用它时都要复制和粘贴组件! : - (((
我看到正确的事情的唯一方法是仅使用TEdit
alClient
和5px边距而不使用TShape
。相反,我可以使TFrame
成为具有透明度的圆角,因此不会看到不同颜色的丑陋或TImages
。
但我该怎么做?
有没有人有任何代码示例?
答案 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
)。
以下属性对其使用很重要:
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渲染的相同圆角矩形的示例: