zoukankan      html  css  js  c++  java
  • C++ Builder XE2随意学习 (14) > 窗口透明处理

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

    之前实现方式:

    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.

    哦!




  • 相关阅读:
    003 01 Android 零基础入门 01 Java基础语法 01 Java初识 03 Java程序的执行流程
    002 01 Android 零基础入门 01 Java基础语法 01 Java初识 02 Java简介
    001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学
    001 Android Studio 首次编译执行项目过程中遇到的几个常见问题
    Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器
    Dora.Interception,为.NET Core度身打造的AOP框架 [1]:更加简练的编程体验
    监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile
    轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑
    轻量级ORM框架——第一篇:Dapper快速学习
    CF888G Xor-MST(异或生成树模板)
  • 原文地址:https://www.cnblogs.com/drgraph/p/2351831.html
Copyright © 2011-2022 走看看