C++ Builder XE2随意学习 (14) > 窗口透明处理
2012-02-14 21:35
846 查看
升级图形程序,中间有把窗口逐渐透明化的处理方式。
之前实现方式:
在CB XE2中,首先是不认识SetLayeredWindowAttributes,查帮助,在Vcl.Forms下,则实现为
Vcl::Forms::SetLayeredWindowAttributes(Form->Handle, 0, 128, 2);
期望出现半透明效果。
编译都通不过,参数类型不对,修改为
Vcl::Forms::SetLayeredWindowAttributes(unsigned(Form->Handle), 0, 128, 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.
解答:
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 the
UPDATE Check this sample
哦!
之前实现方式:
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 the
PaintBackgroundmethod of the
TFormStyleHookclass 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 componentsto 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.
哦!
相关文章推荐
- C++ Builder XE2随意学习 (3) > FireMonkey类结构初探
- C++ Builder XE2随意学习 (7) > RAD Studio XE2 – Setting it up for a Mac
- C++ Builder XE2随意学习 (11) > DevExpress Ribbon界面效果
- C++ Builder XE2随意学习 (12) > DevExpress Dock拖动框架实现
- C++ Builder XE2随意学习 (13) > Gdiplus
- C++ Builder XE2随意学习 (4) > Delphi XE2官方视频教程31天
- C++ Builder XE2随意学习 (2) > 准备工作
- C++ Builder XE2随意学习 (15) > 类静态数据的一个小问题
- C++ Builder XE2随意学习 (5) > 我的学习路线
- C++ Builder XE2随意学习 (6) > System
- C++ Builder XE2随意学习(9) > 安装实录
- C++ Builder XE2随意学习 (10) > AlphaControls控件使用初探
- C++ Builder XE2随意学习 (1)
- Android NDK学习 <六> 复杂结构动态库处理和第三方库的移植
- Android NDK学习 <六> 复杂结构动态库处理和第三方库的移植
- (转)Django ====> 实战学习篇十三 分页(Paginator)处理;Django使用内置的admin
- C++ Builder 实现动态生成窗口、控件,以及处理控件事件
- Windows学习笔记5——窗口与消息<三>
- 批处理学习笔记6 - 重定向符>和>>
- UNIX网络编程学习(14)--使用select正确处理EOF的str_cli函数修订版