FireMonkey で Window Drag


枠無しウィンドウを作る

下図のように Window の BorderStyle を None の状態にして

image.png

実行すると、↓枠もタイトルバーも無い Client 領域だけの白いウィンドウができます。

image.png

でも、これだと移動すらできなくてメッチャ不便!


移動

VCL の時は Window Message の WM_NCHITTEST を使って HTCAPTION を返してドラッグできるようにするっていうのが常套手段でした。

でも、FireMonkey はマルチプラットフォームのライブラリなので、Windows だけでしか使えないこの方法は、あまり使いたくないですよね。

そこで!

FireMonkey には StartWindowDrag というメソッドが TCommonCustomForm に用意されています。

これを OnMouseDown の時に呼んでやると

image.png

こんな風にドラッグできます!

drag.gif


んでんで?

ドラッグできるから何なのっていう…。

そこで、みんなお忘れかも知れないんですが TCommonCustomForm には Transparency っていうプロパティがあるんですよ。

そこには


すべてのコントロールが透明になるわけではなく、それらは通常通り表示される点に注意してください。フォームの背景のみが、透明の状態に設定されます。


とあります。

つまり、TImage とかを載せてそこに透過 png を置くと…

drag2.gif

ヤッター!

画像の形に切り抜かれたウィンドウができたよ!

ちなみに


Transparency を True に設定すると、フォームはタイトル バーやボーダーを表示しません。


とあるので最初に設定した BorderStyle は特にいじる必要は無いわけですね。


Desktop widget

ということで、Transparency と StartWindowDrag を使えば簡単にウィジェットが作れます。

ただ、ウィジェットなら Taskbar の表示を消したいですよね…

image.png

消す方法は下記の通り。

これに関してはどうしても別々に API を呼ばなくてはなりません。


Windows

uses

Winapi.Windows, FMX.Platform.Win;

procedure HideTaskbar;
begin
ShowWindow(ApplicationHWND, SW_HIDE);
end;



macOS

uses

Macapi.AppKit;

procedure HideTaskbar;
var
NSApp: NSApplication;
begin
NSApp := TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);
NSApp.setActivationPolicy(NSApplicationActivationPolicyAccessory);
end;


ちなみに、Windows 版で呼んでいる「ApplicationHWND」は FMX.Platform.Win に定義してある関数で Application の Window Handle を返してくれます。

さて、これで Taskbar から消えましたが、本当は TaskTray(Windows), StatusBar(macOS) にアイコン表示させたいですよね。

ただ、これはこの記事で紹介できる分量ではないので、また次の機会にします!

とりあえず、TPopupMenu を表示させてあげれば終了させたりできます。

image.png

※なお、FireMonkey の TForm には PopupMenu を結びつけられないので、ここでは TImage に PopupMenu を関連付けています。そのため StartWindowDrag も TImage の OnMouseDown で行うように変更しています。


まとめ

FireMonkey なら Windows / macOS の両方でデスクトップ・ウィジェットを簡単に作れますね!