• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++BuilderXE2随意学习(14)窗口透明处理

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

升级图形程序,中间有把窗口逐渐透明化的处理方式。

之前实现方式:

SetLayeredWindowAttributes(Form->Handle, 0, 0, 2);  // 全透明

SetLayeredWindowAttributes(Form->Handle, 0, 128, 2);  // 半透明

SetLayeredWindowAttributes(Form->Handle, 0, 255, 2);  // 不透明

...



在CB XE2中,首先是不认识SetLayeredWindowAttributes,查帮助,在Vcl.Forms下,则实现为

Vcl::Forms::SetLayeredWindowAttributes(Form->Handle, 0, 128, 2);

期望出现半透明效果。

编译都通不过,参数类型不对,修改为

Vcl::Forms::SetLayeredWindowAttributes(unsigned(Form->Handle), 0, 128, 2);

不错,编译通过了,但无法看到效果。

编一段测试代码:

void __fastcall TForm1::FormClick(TObject *Sender) {

  static int times = 0;

  times += 10;

  Vcl::Forms::SetLayeredWindowAttributes(unsigned(Form->Handle), 0, times, 2);

}



运行后单击,无效果,仍然是不透明状。难道是unsigned转换的问题,不得其解。

网上搜索找到一些解决方式:

提问:

I'm using the following code to make a form transparent, but when the application has a VCL style enabled the form is paint with the background color of the VCL style instead of be transparent.


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(varParams:TCreateParams);override;
public
{Public declarations }
end;

var
Form1:TForm1;

implementation

{$R *.dfm}

procedure TForm1.CreateParams(varParams: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;

解答:

It seems like a bug to me. The VCL Styles use Style hooks to intercept the paint methods and the Windows messages related to these operations, So in this case you must focus your atention in thePaintBackground method of the TFormStyleHook class located in the Vcl.Forms, from here you create a new style hook class (which descends from TFormStyleHook), override the PaintBackgroundmethod, fix the code and finally before to use it call the RegisterStyleHook method to register the Newstyle hook. check this article Fixing a VCL Style bug in the TPageControl and TTabControl components to see an example.


UPDATE Check this sample

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.

The New Style Hook Class

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.

哦!





鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#list.toArraylist与数组的转换发布时间:2022-07-13
下一篇:
C++vector容器删除操作发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap