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:
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:
- Color - is the shape fill color (can be enhanced of pen color, gradient etc.)
- Radius - is the radius (in pixels) of the circle used to draw the rounded corners
- AlphaValue - is the opacity value of the rendered round rectangle (just for fun :-)
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.
And the result (with SmoothingModeAntiAlias
smoothing mode applied):
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
is not the correct parent class. I would use a plainTCustomControl
. Frames are for composition of visual controls at design-time rather than at compile time. But compiling your own custom control is the more reliable and resilient solution. – AldarcieTLMDShapeControl
and it worked fine. But in the end, I abandoned these styles, because my customers hate these non-native styles and wanted them gone. – AldarcieTShape
can be rounded corner, but the output is very buggy. I don't have a crew, so I am the one who investigate requirements, make the project, the code and the design of the system and the database of my projects and I did not had the possibility to become an expert at one of these things... yet! :-) – SuperposeCreateRoundRectRgn
. GDI just doesn't support any kind of antialiasing, thus you don't get smooth corners. If I were you, I would use aTCustomControl
like Warren suggested, e.g.this way
. Then there are just two problems, one is the transparency of such control and the second one is the need of a library that can render smooth arc for your corners. – StanchionTShape
in your last comment. But anyway would it be enough for you to have a shape under your components or you need a container ? – Stanchion