2012-07-26 23 views
9

Chcę utworzyć komponent oparty na TFrame z TLMDShapeControl (dla rysowania zaokrąglonego rogu tła) i kontrolką TEdit (która może być również TComboBox lub TDBEdit itd.). Następnie użyję polecenia "Dodaj do palety", aby przekształcić je w kontrolkę wielokrotnego użytku.Jak wykonać TFrame z zaokrąglonymi narożnikami?

Problem polegał na tym, że potrzebuję elastycznej szerokości i dlatego wpadłem na pomysł, aby wszystkie elementy wewnątrz ramki alClient i TEdit z marginesem 5 pikseli, aby użytkownik mógł zobaczyć zaokrąglone rogi.

To było okropne, ponieważ nie mogę użyć Align i ustawić komponentów jeden na drugim. Teraz muszę kopiować i wklejać komponenty za każdym razem, gdy muszę z niego korzystać! : -. (((

Jedynym sposobem, widzę słuszne jest, aby używać tylko TEdit z alClient i marży 5px i bez TShape Zamiast mogę dokonać TFrame być zaokrąglony narożnik z przejrzystością, więc nie będzie brzydko wyglądać na różnych kolorach lub TImages.

Ale jak mam to zrobić?

czy ktoś ma jakiś przykładowy kod?

this is the goal: transparent rounded corners

+2

Gdybym chciał ten działał prawidłowo, to bym zrobić własną kontrolę, że mogę zainstalować jako pakiet, który zawiera zewnętrzną i wewnętrzna kontrola i zawiera cały kod, który chcę, aby wszystko działało. 'TFrame' nie jest prawidłową klasą nadrzędną. Chciałbym użyć zwykłego 'TCustomControl'. Ramki są przeznaczone do kompozycji kontroli wizualnych w czasie projektowania, a nie podczas kompilacji. Ale skompilowanie własnej niestandardowej kontroli jest bardziej niezawodnym i odpornym rozwiązaniem. –

+1

Zrobiłem dokładnie to, używając wbudowanego TShape zamiast 'TLMDShapeControl' i działało dobrze. Ale w końcu porzuciłem te style, ponieważ moi klienci nienawidzą tych nie-rodzimych stylów i chcieli ich odejść. –

+0

Tak, 'TShape' może być zaokrąglony róg, ale wyjście jest bardzo błędne. Nie mam załogi, więc to ja badam wymagania, robię projekt, kod i projekt systemu oraz bazę danych moich projektów i nie miałem możliwości zostać ekspertem w jednym z nich rzeczy ... jeszcze! :-) – PSyLoCKe

Odpowiedz

13

Aby odpowiedzieć na pytanie, jak wykonać ramkę z zaokrąglonymi narożnikami, możesz wypróbować coś podobnego, ale będziesz niezadowolony z wyniku, ponieważ użyta tutaj kamera CreateRoundRectRgn nie ma antyaliasingu.

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; 

Aktualizacja:

Od GDI nie ma żadnej funkcji, która będzie wspierać antyaliasing dla łukowego renderowania, I zostały zaksięgowane tutaj przykładem okrągłym kształcie prostokąta (tylko czysty wypełniony okrągły prostokąt), który używa GDI + (do tego potrzebne będą owijarki GDI + from here).

następujące właściwości są ważne dla jego zastosowania:

  • kolorze - kolor wypełnienia kształtu (może być zwiększona koloru pióra, gradient etc.)
  • promienia - promień (w pikselach) koła służący do rysowania zaokrąglone narożniki
  • AlphaValue - oznacza wartość nieprzezroczystości wypełnioną zaokrąglonego prostokąta (dla zabawy :-)

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. 

A wynik (z zastosowane SmoothingModeAntiAlias tryb wygładzania):

enter image description here

Można powiedzieć, że jest to duży narzut używać GDI + dla takiej malutkiej rzeczy, ale czysty GDI renderowania bez antyaliasingu, co sprawia, że ​​wyniki wygląda brzydko.Oto przykład tej samej rundzie prostokąta świadczonych za pomocą czystego GDI:

enter image description here

+0

To odpowiada na moje pytanie. Spróbuję stworzyć komponent, w którym moglibyśmy wybrać rodzaj kontroli, który chcemy nad zaokrąglonym kształtem i sprawdzić, czy jest lepszy niż sposób tframe. Dzięki! – PSyLoCKe

+0

Nie ma za co! Ale muszę was ostrzec; jeśli będziesz postępował zgodnie z metodą 'TCustomControl', tak jak wspomniałem w powyższym komentarzu, bądź ostrożny z przezroczystością. Próbowałem uczynić kontrolę kontenera (np. 'TPanel' na przykład) przejrzyste, gdy motywy systemu Windows są wyłączone, ale nigdy nie były satysfakcjonujące. – TLama

+0

Dodałem przykład komponentu kształtu z wygładzonymi narożnikami ... – TLama

Powiązane problemy