2012-07-26 15 views
9

Ich möchte eine Komponente basierend auf einem TFrame mit TLMDShapeControl (zum Zeichnen von runden Ecke Hintergrund) und einem Steuerelement (das kann auch ein TComboBox oder ein TDBEdit und so weiter). Danach werde ich den "Add to Palette" -Befehl verwenden, um es in ein wiederverwendbares Component Control zu verwandeln.Wie macht man TFrame mit abgerundeten Ecken?

Das Problem, dass ich brauche es für die Breite flexibel und sein hatte ich die Idee von alClient alles innerhalb des Rahmens drehen und die TEdit mit 5 Pixel breiten Rand, damit der Benutzer die abgerundeten Ecken sehen.

Es war schrecklich, weil ich Align nicht verwenden und Komponenten eins in die Spitze eines anderen setzen kann. Jetzt muss ich die Komponenten jedes Mal kopieren und einfügen, wenn ich sie benutzen muss! : -. (((

Die einzige Art, wie ich das Richtige zu sehen ist nur die TEdit mit alClient und 5px Rand und ohne TShape zu verwenden, anstatt mit Transparenz abgerundete Ecke sein, ich konnte die TFrame machen, so wird es nicht hässlich aussehen auf den verschiedenen Farben oder TImages.

Aber wie mache ich das?

Hat jemand ein Codebeispiel?

this is the goal: transparent rounded corners

+2

Wenn ich das wollte, richtig arbeiten, werde ich meine eigene Kontrolle machen, die ich als Paket zu installieren, welche die äußere enthält und innere Kontrolle, und enthält den ganzen Code, den ich alles arbeiten lassen will. 'TFrame' ist nicht die korrekte Elternklasse. Ich würde ein einfaches 'TCustomControl' verwenden. Frames dienen zur Erstellung visueller Steuerelemente zur Entwurfszeit und nicht zur Kompilierungszeit. Aber das Erstellen Ihrer eigenen benutzerdefinierten Steuerung ist die zuverlässigere und belastbarere Lösung. –

+1

Ich habe genau das gemacht, mit der eingebauten TShape anstelle von 'TLMDShapeControl' und es hat gut funktioniert. Aber am Ende habe ich diese Stile aufgegeben, weil meine Kunden diese nicht-einheimischen Stile hassen und wollten, dass sie weg sind. –

+0

Ja, 'TShape' kann abgerundet werden, aber die Ausgabe ist sehr fehlerhaft. Ich habe keine Crew, also bin ich derjenige, der die Anforderungen untersucht, das Projekt, den Code und das Design des Systems und die Datenbank meiner Projekte erstellt hat und ich hatte nicht die Möglichkeit, Experte in einem dieser Projekte zu werden Dinge ... noch! :-) – PSyLoCKe

Antwort

13

Um Ihre Frage zu beantworten, wie man Rahmen mit abgerundeten Ecken macht, können Sie etwas wie dieses versuchen, aber Sie werden mit dem Ergebnis unzufrieden sein, da die hier verwendete CreateRoundRectRgn kein Antialiasing hat.

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:

Da GDI keine Funktion hat, das Anti-Aliasing für das Lichtbogen Rendering unterstützen würde, ich habe ein Beispiel für eine abgerundetes Rechteck Form hier gepostet (nur ein reinen gefüllten rundes Rechteck), das GDI + verwendet (hierfür benötigen Sie GDI + -Wrapper from here).

die folgenden Eigenschaften für die Verwendung von Bedeutung sind:

  • Farbe - die Farbformfüllung ist
  • Radius (kann von Stiftfarbe, Gradient usw. verbessert werden), - der Radius (in Pixel) der Kreises, die abgerundeten Ecken
  • AlphaValue zu zeichnen verwendet - ist der Wert des Opazität abgerundeten Rechtecks ​​gerendert (nur zum Spaß :-)

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. 

Und das Ergebnis (mit SmoothingModeAntiAlias Glättungsmodus angewendet):

enter image description here

Man kann sagen, es ein großer Aufwand ist GDI + für eine solche kleine Sache zu verwenden, sondern reine GDI machen ohne Anti-Aliasing, was die Ergebnisse macht sieht hässlich aus.Hier ist das Beispiel aus dem gleichen abgerundeten Rechteck gemacht unter Verwendung von reinem GDI:

enter image description here

+0

Das beantwortet meine Frage. Ich werde versuchen, eine Komponente zu machen, in der wir die Art der Kontrolle wählen können, die wir über der abgerundeten Form haben wollen, und sehen, ob es besser ist als der T-Rahmen. Vielen Dank! – PSyLoCKe

+0

Gern geschehen! Aber ich muss dich warnen; Wenn Sie dem "TCustomControl" -Weg folgen, wie ich es im obigen Kommentar erwähnt habe, seien Sie vorsichtig mit Transparenz. Ich habe versucht, die Container-Kontrolle (wie zum Beispiel 'TPanel') transparent zu machen, wenn Windows-Themen deaktiviert sind, aber es war nie zufriedenstellend. – TLama

+0

Ich habe ein Beispiel für eine Formkomponente mit gerundeten Ecken mit Antialiasing hinzugefügt ... – TLama