2012-07-26 51 views
9

我想根據TFrameTLMDShapeControl(用於繪製圓角背景)和TEdit控件(也可以是TComboBoxTDBEdit等)製作組件。 之後,我將使用「添加到調色板」命令將其變成可重用組件控制。如何製作帶圓角的TFrame?

問題在於我需要它是寬度靈活的,爲此我有了將框架內的所有內容翻轉爲alClientTEdit以及5個像素邊距的想法,以便用戶可以看到圓角。

這很糟糕,因爲我不能使用Align並將組件放置在另一個頂部。現在我必須在每次必須使用它時複製和粘貼組件! : - (((

我看到正確的做法是隻與alClient和5px的利潤率,沒有TShape使用TEdit相反,我可以使TFrame是圓角與透明,只有這樣,所以不會旁觀的不同顏色或TImages難看。

可是我該怎麼做呢?

沒有人有任何的代碼示例?

this is the goal: transparent rounded corners

+2

如果我想這樣才能正常工作,我會做我自己控制,我安裝一個軟件包,包含外部和內部控制,幷包含我想使所有工作的所有代碼。 'TFrame'不是正確的父類。我會用一個簡單的'TCustomControl'。框架用於在設計時而不是在編譯時組成視覺控件。但是編譯自己的定製控件是更可靠和靈活的解決方案。 – 2012-07-26 18:20:12

+1

我已經完成了,使用內置的TShape而不是'TLMDShapeControl',它工作正常。但最後,我放棄了這些風格,因爲我的客戶憎恨這些非本土風格,並希望他們離開。 – 2012-07-26 20:00:11

+0

是的,'TShape'可以是圓角,但輸出非常麻煩。我沒有機組人員,所以我是調查需求,制定項目,代碼和系統設計以及項目數據庫的人員,我沒有可能成爲這些項目中的專家事情......還沒有! :-) – PSyLoCKe 2012-07-26 23:38:25

回答

13

要回答你的問題如何使框架與圓角你可以嘗試這樣的事情,但你會不滿意的結果,因爲這裏使用的CreateRoundRectRgn沒有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; 

更新:

由於GDI不具有將支持抗鋸齒電弧渲染任何功能,我在這裏公佈一個圓角矩形形狀(只是一個純粹的填充的例子圓形矩形)使用GDI +(爲此,您將需要GDI +包裝from here)。

以下屬性及其使用重要:

  • 顏色 - 是形狀填充顏色(可以提高筆的顏色,梯度等)
  • 半徑 - 是半徑(以像素爲單位)用於繪製圓角
  • 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平滑處理模式):

enter image description here

可以說這是一個很大的開銷使用GDI +這樣的小事情,但純GDI渲染不抗鋸齒是什麼讓結果看起來很醜。下面是使用純GDI呈現相同的圓角矩形的例子:

enter image description here

+0

這回答了我的問題。我會嘗試製作一個組件,以便我們可以選擇我們想要的高於圓形的控件類型,並查看它是否比框架方式更好。謝謝! – PSyLoCKe 2012-07-27 00:00:32

+0

不客氣!但我必須警告你;如果你像上面評論中提到的那樣遵循'TCustomControl'的方式,請注意透明度。我一直試圖讓Windows主題被禁用時,容器控件(例如'TPanel')是透明的,但它從來沒有令人滿意。 – TLama 2012-07-27 00:10:35

+0

我已經添加了具有抗鋸齒圓角的形狀組件示例... – TLama 2012-07-27 01:19:18