Как сделать прозрачную форму, когда включен стиль VCL? - PullRequest
9 голосов
/ 30 ноября 2011

Я использую следующий код, чтобы сделать форму прозрачной, но когда в приложении включен стиль 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.

Существует ли другой способ сделать форму прозрачной, чтобы обойти эту проблему?

Ответы [ 3 ]

12 голосов
/ 30 ноября 2011

Мне кажется, это ошибка. Стили VCL используют перехватчики стиля для перехвата методов рисования и сообщений Windows, связанных с этими операциями, поэтому в этом случае вы должны сосредоточить свое внимание на методе PaintBackground TFormStyleHook* Класс 1006 *, расположенный в Vcl.Forms, отсюда вы создаете новый класс ловушек стиля (который происходит от TFormStyleHook ), переопределяете метод PaintBackground, исправляете код и, наконец, перед его использованием вызываете Метод RegisterStyleHook для регистрации нового хука style . проверьте эту статью Fixing a VCL Style bug in the TPageControl and TTabControl components, чтобы увидеть пример.

UPDATE Проверьте этот образец

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.

Класс крючков нового стиля

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.
2 голосов
/ 30 ноября 2011

В отдельной заметке вы пытались использовать свойства TransparentColor и TranparentColorValue вместо манипулирования стилями окна в CreateParams()?

1 голос
/ 30 ноября 2011

Я использую OverridePaintNC: = False для предотвращения рисования стилей в области ЧПУИ есть OverrideEraseBkgnd тоже.Может быть, это поможет.

...