gpt4 book ai didi

delphi - 启用VCL样式时如何制作透明表单?

转载 作者:行者123 更新时间:2023-12-03 14:43:13 27 4
gpt4 key购买 nike

我使用以下代码使表单透明,但是当应用程序启用了 VCL 样式时,表单将使用 VCL 样式的背景颜色进行绘制,而不是透明。

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure CreateParams(var Params:TCreateParams); override;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := WS_EX_TRANSPARENT or WS_EX_TOPMOST;
//Params.ExStyle := Params.ExStyle or WS_EX_LAYERED;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Brush.Style:=bsClear;
BorderStyle:=bsNone;
//SetLayeredWindowAttributes(Handle, 0, 230, $00000002);
end;

仅供引用,如果 vcl 样式设置为 Windows,则代码可以正常工作。

是否存在另一种使表单透明的方法来解决此问题?

最佳答案

对我来说这似乎是一个错误。 VCL 样式使用样式钩子(Hook)来拦截绘制方法以及与这些操作相关的 Windows 消息,因此在这种情况下,您必须将注意力集中在 TFormStyleHookPaintBackground 方法上类位于 Vcl.Forms 中,从这里创建一个新的样式钩子(Hook)类(继承自 TFormStyleHook),覆盖 PaintBackground 方法,修复代码,最后在使用它之前调用 RegisterStyleHook 方法来注册新样式 Hook 。查看这篇文章 Fixing a VCL Style bug in the TPageControl and TTabControl components 查看示例。

更新检查此示例

unit Unit138;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
TForm138 = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure CreateParams(var Params:TCreateParams); override;
public
end;


var
Form138: TForm138;

implementation

Uses
Vcl.Themes,
Vcl.Styles,
uPatch;

{$R *.dfm}

procedure TForm138.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := WS_EX_TRANSPARENT or WS_EX_TOPMOST;
end;

procedure TForm138.FormCreate(Sender: TObject);
begin
Brush.Style:=bsClear;
BorderStyle:=bsNone;
end;

initialization
TStyleManager.Engine.UnRegisterStyleHook(TForm, TFormStyleHook);//unregister the original style hook
TStyleManager.Engine.RegisterStyleHook(TForm, TMyStyleHookClass); //register the new style hook

end.

新样式 Hook 类

unit uPatch;

interface

uses
Vcl.Graphics,
Vcl.Forms;

type
TMyStyleHookClass= class(TFormStyleHook)
protected
procedure PaintBackground(Canvas: TCanvas); override;
end;

implementation

uses
Winapi.Windows,
System.Types,
Vcl.Themes;


procedure TMyStyleHookClass.PaintBackground(Canvas: TCanvas);
{This is only a basic sample for fix a specific scenario}
var
Details: TThemedElementDetails;
R: TRect;
begin
if StyleServices.Available then
begin
if (GetWindowLong(Form.Handle,GWL_EXSTYLE) AND WS_EX_TRANSPARENT) = WS_EX_TRANSPARENT then
if Form.Brush.Style = bsClear then Exit;

Details.Element := teWindow;
Details.Part := 0;
R := Rect(0, 0, Control.ClientWidth, Control.ClientHeight);
StyleServices.DrawElement(Canvas.Handle, Details, R);
end;
end;

end.

关于delphi - 启用VCL样式时如何制作透明表单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8317617/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com