6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FireMonkey と Windows

Posted at

FireMonkey と Windows

OSへの依存が排除されている

FireMonkey はマルチプラットフォームのライブラリなので、プラットフォームに依存した処理は(気軽には)使えないようになっています。
でも、例えば Windows でしか使わないアプリケーションの作成では Windows に依存した処理を使いたいこともあります。

Windows に依存した処理をする

Windows に依存した処理の多くは Win32 API を使うことになるでしょう。
(その他にはファイルパスだったり、改行コードなどがあります)

TWindowHandle

Win32 API を使うということは基本的には Window Handle が必要です。
FireMonkey は Window Handle を隠蔽していますが、簡単に取得できます。

ただし、ここで注意したいのは TCommonCustomForm が持っている Handle は、FireMonkey が管理するための独自のハンドルで Window Handle とは別物ということです。
FireMonkey は、この独自のハンドルと Window Handle を結びつけて管理しています。
その管理をするクラスが TWindowHandle です。

このクラスを取得するためには、WindowHandleToPlatformという関数を使います。

この関数は FMX.Platform.Winに定義されていおり、また TWindowHandle を継承して Windows に特化させた TWinWindowHandleも定義されています。

WindowHandleToPlatform は、この TWinWindowHandle を返します。

TWinWindowHandle.Wnd で Window Handle が取得できます。

ここまでをコードにすると…

function GetWnd(const iForm: TCommonCustomForm): HWND;
begin
  Result := WindowHandleToPlatform(iForm.Handle).Wnd;
end;

と、こんな風になります。
ですが!
Window Handle を取るだけなら更に簡単な方法があります。
それは、FormToHWNDです。

これを使うと

function GetWnd(const iForm: TCommonCustoForm): HWND;
begin
  Result := FormToHWND(Form);
end;

と、こんな感じになります。

Windows Message に反応する

WindowHandle が取得できたので、Window Procedure を置き換えてみます。
Win32 API の SetWindowLong 関数を使うと Window Procedure を置き換えられます。
具体的なコードは次の通りです。

var
  WndProc: Pointer;

function ChangeWndProc(const iForm: TCommonCustomForm): Boolean;
var
  Wnd: HWND;
begin
  Wnd := FormToHWND(iForm);
  WndProc := Pointer(SetWindowLong(Wnd, GWL_WNDPROC, Integer(@WndProc)));
  Exit(WndProc <> nil);
end;

ここで、SetWindowLong に渡している Wndproc は下のような関数です。

function WndProc(
  hWnd: HWND;
  uMsg: DWORD;
  wParam: WPARAM;
  lParam: LPARAM): LRESULT; stdcall;
begin
  case uMsg of
    WM_MOUSEMOVE: // などなど
    begin
    end;
  end;

  Result := CallWindowProc(WndProc, hWnd, uMsg, wParam, lParam);
end;

これで、置き換え完了です。
あとは uMsg に対して、いくらでも自由に反応できます。

まとめ

Window Handle は FormToHWND や WindowHandleToPlatform を使って取得できます。

#次回
macOS 編に続きます。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?