【问题标题】:delphi transparent background componentdelphi透明背景组件
【发布时间】:2015-01-22 04:34:19
【问题描述】:

关于 Delphi XE 的快速问题。

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

无论如何我可以在不使用其他 lib 或 api 的情况下使组件的边缘区域透明吗?

【问题讨论】:

  • 您是否考虑过 ExtCtrls.TShape 作为示例? (如果 TGraphicControl 适合您)
  • TGraphicControl 在其父级的画布上进行绘制,因此永远不会在按钮或面板等窗口控件上进行绘制。 TWinControl 后代不能是透明的,但您可以通过在绘制圆圈之前绘制其下方的内容来伪造它。您也需要处理 WM_ERASEBACKGROUND。或者有一个你可以轻松继承的类,我从未使用过它,但看起来它可以解决问题:TCustomTransparentControl。有关如何使用它的详细信息,请参阅stackoverflow.com/questions/6682396/transparent-tcustomcontrol

标签: delphi components transparent shape


【解决方案1】:

这里有一个快速的答案,应该可以帮助您。

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 函数。

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

【讨论】:

  • 每次重新创建面板的Handle 时,您都必须致电SetWindowRgn()
  • @RemyLebeau 感谢您的提醒。但是旧的 hRgn 是否泄露了,还是 Windows 会处理它?
  • Per the documentation: "成功调用 SetWindowRgn 后,系统拥有区域句柄 hRgn 指定的区域。系统不会复制区域。因此,您不应使用此区域句柄进行任何进一步的函数调用。尤其不要删除此区域句柄。系统在不再需要时删除该区域句柄。"
  • @RemyLebeau,不仅在重新创建Handle时,而且在调整控件大小时。
  • @eesther 欢迎您!如果您认为答案是正确的,则将其标记为正确。很快(1 小时)还会有另一项更新
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-08
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多