はじめに
RADStudio Users Group に「Delphiでマウス・キーボード操作をスルーする方法はありますか?」という質問がありました。
そこで、この記事では VCL / FireMonkey で実現する方法を紹介します。
VCL の場合
VCL の場合、2つのプロパティとCreateWindowEx の dwExStyle に値を設定してやるだけで簡単に実現できます。
プロパティの設定
VCL の TForm には AlphaBlend というプロパティと AlphaBrendValue というプロパティがあります。
AlphaBlend プロパティを True にすると Form が Layered Window という特殊なウィンドウになります。
Layered Window は半透明にしたり背景を透過したりできます。
Layered Window の半透明の度合いは AlphaBlendValue で制御できます。
AlphaBlendValue に 0 を指定すると完全に透明、255 で完全に不透明になります。
下はこのプロパティの値を変更した例です。
値によって透け具合が異なっています。
また、必要であれば FormStyle プロパティを fsStayOnTop にして最前面ウィンドウにします。
CreateWindowEx のカスタマイズ
CreateWindowEx のパラメータは VCL の場合簡単に変更できます。
VCL の TForm には CreateParams というメソッドがあるためです。
このメソッドは CreateWindowEx を呼ぶ前にパラメータを変更する機会を提供してくれます。
そこで、このメソッドを override して ExStyle を変更します。
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
var
Form1: TForm1;
implementation
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle :=
Params.ExStyle
or WS_EX_TRANSPARENT // 透明化
or WS_EX_NOACTIVATE; // アクティブにならない
end;
肝は WS_EX_TRANSPARENT と WS_EX_NOACTIVATE です。
Layered Window の場合、この2つを指定する事で、マウスクリックを透過します。
(Layered Window ではない場合は透過しません)
完成
上記の CreateParams の変更と AlphaBlend / AlphaBlendValue を設定すると完成です。
こんな風にクリックが透過します
コード全文 (CreateParams があるだけ…)
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages,
System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle :=
Params.ExStyle
or WS_EX_TRANSPARENT // 透明化
or WS_EX_NOACTIVATE; // アクティブにならない
end;
end.
FireMonkey の場合
これはもう力づくです。
FormCreate で必要な Win32 API を呼んでやります。
基本は VCL と同じです。
ちなみに FireMonkey の TForm には Transparency というプロパティがあるのですが、これはフォームの背景色(Fill.Color)を透明にしてしまうので使えません。
(VCL の TransparentColor と同等)
uses
Winapi.Windows
, FMX.Platform.Win
;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Window Handle の取得
var HWnd := FormToHWND(Self);
// ExStyle の取得
var ExStyle := GetWindowLong(HWnd, GWL_EXSTYLE);
// ExStyle に追加
ExStyle :=
ExStyle
or WS_EX_LAYERED // Layered Window
or WS_EX_TRANSPARENT // 透明化
or WS_EX_NOACTIVATE; // アクティブにならない
// ExStyle を設定
SetWindowLong(HWnd, GWL_EXSTYLE, ExStyle);
// Layered Window の透明度を指定
SetLayeredWindowAttributes(HWnd, 0, 128, LWA_ALPHA);
// 必要であれば Window を最前面に
SetWindowPos(
HWnd,
HWND_TOPMOST,
0,
0,
0,
0,
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
end;
ということで無事 FireMonkey でもクリック透過するようになりました。
さいごに
ガジェット系のアプリを作る時にたまに使うテクニックです。
Windows オンリーのアプリになるのでわざわざ FireMonkey で作る必要は無いですね…!