如何使TFrame与圆角? [英] How to make TFrame with rounded corners?
问题描述
我想使用 TFrame
与 TLMDShapeControl
(用于绘制圆角背景)和 TEdit
控件(也可以是 TComboBox
或 TDBEdit
等等)。
之后,我将使用添加到调色板命令将其转换为可重用组件控件。
I want to make a component based on a TFrame
with TLMDShapeControl
(for drawing round corner background) and a TEdit
control (that can be also a TComboBox
or a TDBEdit
and so on).
After that I will use the "Add to Palette" command to turn it into a Reusable Component Control.
我需要它的宽度为灵活的,因此我有想法将框架内的所有内容转换为5像素边框,因此可以将框架内的所有内容转到框架 alClient
和 TEdit
用户可以看到圆角。
The problem in that I need it to be width flexible and for that I had the idea of turn everything inside the Frame alClient
and the TEdit
with 5 pixel margin so the user can see the rounded corners.
这是可怕的,因为我不能使用对齐
并将组件放在另一个的顶端。现在我必须复制和粘贴组件,每次我必须使用它! : - (((
It was terrible because I can't use Align
and set components one in the top of another. Now I have to copy and paste the components on every time I have to use it! :-(((
我看到正确的东西的唯一方法是仅使用 TEdit
与 alClient
和5px margin,没有 TShape
,而是可以使 TFrame
透明度为圆角,所以它不会看起来丑陋的不同颜色或 TImages
。
The only way I see the right thing is to use only the TEdit
with alClient
and 5px margin and no TShape
. Instead I could make the TFrame
to be rounded corner with transparency, so it won't look ugly on of different colors or TImages
.
但是我该怎么做?
有没有人有任何代码示例?
Does anyone have any code sample?
推荐答案
为了回答你的问题,如何用圆角做框架,你可以尝试这样的东西,但是你会对 CreateRoundRectRgn
没有抗锯齿。 p>
To answer your question how to make frame with rounded corners you can try something like this, but you will be dissatisfied with the result since the CreateRoundRectRgn
used here has no antialiasing.
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;
更新:
Update:
由于GDI没有任何支持反渲染的功能,所以我在这里发布了一个使用GDI +(的圆形矩形)为此,您将需要GDI +包装器 从这里
)。
Since GDI doesn't have any function that would support antialiasing for arc rendering, I've posted here an example of a round rectangle shape (just a pure filled round rectangle) that uses GDI+ (for this you will need GDI+ wrappers from here
).
以下属性对于其使用非常重要:
The following properties are important for its use:
- 颜色 - 是形状填充颜色(可以增强笔颜色,渐变等)
- 半径 - 是用于绘制圆形的圆的半径(以像素为单位)角色
- 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
平滑模式应用):
And the result (with SmoothingModeAntiAlias
smoothing mode applied):
可以说这是一个很大的开销,使用GDI +这样的小东西,但纯GDI渲染没有抗锯齿,使得结果看起来很丑陋。以下是使用纯GDI渲染的相同圆形矩形的示例:
One can say it's a big overhead to use GDI+ for such tiny thing but pure GDI render without antialiasing what makes the results looks ugly. Here is the example of the same round rectangle rendered by using pure GDI:
这篇关于如何使TFrame与圆角?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!