2014-11-24 106 views
0

有关Delphi XE的快速问题。delphi透明背景组件

我正在尝试制作具有透明背景的自定义圆形组件,以便在窗体上添加时,组件可以与其他组件重叠。我试过Brush.Style:=bsTransparent;ellipse()等......但仍然找不到使边缘区域透明的方法。

是否有反正我可以使组件的边缘区域透明而不使用其他lib或api?

+0

你认为ExtCtrls.TShape为例吗? (如果TGraphicControl适合您) – MBo 2014-11-24 14:55:13

+2

TGraphicControl在父级的画布上绘制颜色,因此不会像按钮或面板那样绘制窗口控件。一个TWinControl后裔不能透明,但是在绘制圆之前,可以通过绘制它下面的内容来将其伪造。你也需要处理WM_ERASEBACKGROUND。或者有一个类可以轻松地继承我从未使用过的类,但看起来它会做到这一点:TCustomTransparentControl。有关如何使用它的详细信息,请参阅http://stackoverflow.com/questions/6682396/transparent-tcustomcontrol。 – 2014-11-24 17:53:40

回答

5

那么这里有一个快速的答案,应该让你去。

type 
    TEllipticPanel = class(Vcl.ExtCtrls.TPanel) 
    procedure CreateWnd; override; 
    procedure Paint; override; 
    procedure Resize; override; 
    procedure RecreateHRGN; 
end; 

    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    private 
    { Private declarations } 
    panl: TEllipticPanel; 
    public 
    { Public declarations } 
    end; 

implementation 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    panl := TEllipticPanel.Create(self); 
    panl.Left := 10; 
    panl.Top := 10; 
    panl.Width := 100; 
    panl.Height := 50; 
    panl.ParentBackground := False; 
    panl.ParentColor := False; 
    panl.Color := clYellow; 
    panl.Parent := self; 
end; 

{ TEllipticPanel } 

procedure TEllipticPanel.RecreateHRGN; 
var 
    hr: hRgn; 
begin 
    inherited; 
    hr := CreateEllipticRgn(0,0,Width,Height); 
    SetWindowRgn(Handle, hr, True); 
end; 

procedure TEllipticPanel.CreateWnd; 
begin 
    inherited; 
    RecreateHRGN; 
end; 

procedure TEllipticPanel.Paint; 
begin 
    inherited; 
    Canvas.Brush.Style := bsClear; 
    Canvas.Pen.Style := TPenStyle(psSolid); 
    Canvas.Pen.Width := 1; 
    Canvas.Pen.Color := clGray; 
    Canvas.Ellipse(1,1,Width-2,Height-2); 
end; 

procedure TEllipticPanel.Resize; 
begin 
    inherited; 
    RecreateHRGN; 
end; 

的关键是Windows CreateEllipticRgn和GDI函数的SetWindowRgn。

有关窗口区域的更多信息,请参阅Regions

+1

每次重新创建Panel的'Handle'时,您都必须调用'SetWindowRgn()'。 – 2014-11-24 21:51:10

+0

@RemyLebeau感谢您的支持。但是旧的hRgn泄露了,还是Windows处理了它? – 2014-11-24 22:43:42

+3

根据[文档](http://msdn.microsoft.com/en-us/library/dd145102.aspx):“**成功调用SetWindowRgn后,系统拥有区域句柄hRgn * *。系统不会创建该区域的副本,因此,您不应该使用该区域句柄进行任何进一步的函数调用。**特别是,不要删除该区域句柄。系统不再删除区域句柄**“ – 2014-11-24 23:09:21