(2015/07/01~)
2015/07/10

VCL と FireMonkey をミックスする

正直な話、業務系のアプリを作るなら FireMonkey よりも VCL の方が楽です。業務系のアプリというのは入力が多く、入力の手間を少なくするために様々な VCL コンポーネントが世に出ていますから。

でも、Flash みたいな事をやろうとすると VCL では途端に面倒な事になります。VCL のグラフィック関係は GDI のラッパーなので Direct2D はおろか GDI+ でさえ使うのはメンドイのです。ここは FireMonkey を使うのが簡単でいいです。この二律背反な命題を解決するには混ぜちゃえばいいのです…VCL と FireMonkey を。

FireMonky フォームと VCL フォームを混ぜる方法は何度か紹介しました。

…ところがもう一つあったんです。

次以降で "FireMonkey Container" の使い方を軽く説明します。

FireMonkey Container チュートリアル

FireMonkey Container は XE8 用のパッケージがなく、XE8 でコンパイルするとエラーになると思います。XE8 用のパッケージが存在しないようでしたら、以下のアーカイブを DL し、オリジナルに上書きしてください。

Download: firemonkey-container-master_mod.zip

下ごしらえができれば後は簡単です。パッケージをインストールし、ツールパレットの [FireMonkey] にある TFireMonkeyContainer を VCL フォームに貼れば準備完了となります。

使い方としては、VCL プロジェクトに FireMonkey フォームを追加し、(FireMonkey フォームを自分で生成/破棄するのなら) TFireMonkeyContainer の FireMonkeyForm プロパティに FireMonkey なフォームを指定するだけなのですが、デモプログラムではそうなっていません。

まぁ、TFireMonkeyContainer のイベント OnCreateFMXForm / OnDestroyFMXForm を記述するだけなのでそう難しい話じゃありません。frmuFMXTest という名の FireMonkey フォームのユニットがあり、フォームクラスが TfrmuFMXTest、フォーム用変数が frmFMXTest だったとすると、

uses
  FMX.Forms, ..., FMXContainer, frmuFMXTestprocedure TForm1.FireMonkeyContainer1CreateFMXForm(var Form: TCommonCustomForm);
begin
  if not Assigned(Form) then
    begin
      frmFMXTest := TfrmFMXTest.Create(nil);
      Form := frmFMXTest;
    end;
end;

procedure TForm1.FireMonkeyContainer1DestroyFMXForm(var Form: TCommonCustomForm;
  var Action: TCloseHostedFMXFormAction);
begin
  Action := fcaFree;
end;

こんな感じになります。注意点としては…

それより何より困るのは Application.ProcessMessages が使えない事じゃないでしょうか?Application.ProcessMessages を実行するとエラーが出ます。

回避方法はあります。Application.ProcessMessages が使えないのは FireMonkey フォーム側だけなので、コンテナとなっている VCL フォーム側で Application.ProcessMessages を実行すればいいのです。FireMonkey フォームで Application.ProcessMessages を実行したい場所で VCL フォームに PostMessage() し、VCL フォーム側でメッセージを受け取ったら Application.ProcessMessages すれば OK です。

  ...

  private
    { private 宣言 }
    FParentHandle: HWND;
    procedure FMXMessage(wparam: WPARAM; lparam: LPARAM = 0);
  public
    { public 宣言 }
    procedure ParentHandle: HWND read FParentHandle write FParentHandle

  ...

const
  WM_FMXMESSAGE = WM_APP + 10;

  ...

procedure TfrmTest.FMXMessage(wparam: WPARAM; lparam: LPARAM = 0);
begin
  PostMessage(ParentHandle, WM_FMXMESSAGE, wparam, lparam);
end;

VCL フォームのハンドルを保持するプロパティを FireMonkey フォーム側に持たせ、FireMonkey フォーム作成時に VCL フォームのハンドルを渡すようにすればそれを使って PostMessage() する事ができます。

  ...

  private
    { Private declarations }
    procedure WMFmxMessage(var Message: TMessage); message WM_FMXMESSAGE;

  ...

procedure TForm1.FireMonkeyContainer1CreateFMXForm(var Form: TCommonCustomForm);
begin
  if not Assigned(Form) then
    begin
      frmFMXTest := TfrmFMXTest.Create(nil);
      Form := frmFMXTest;
    end;
  frmFMXTest.ParentHandle := Self.Handle;
end;


procedure TForm1.WMFmxMessage(var Message: TMessage);
begin
  case Message.WParam of
    ...

    // ここで FireMonkey フォームからのメッセージを処理する

    ...
  end;
end;

フォーム間のやりとりは他にもイロイロやり方があるかとは思いますが、メッセージを使う方法だと親フォーム (VCL) と子フォーム (FireMoneky) で相互に依存したコードをあまり書かなくて済むのでいいかと思います。


2015/07/11

MonkeyMixer チュートリアル

MonkeyMixer は最も簡単に VCL と FireMonkey をミックスさせる事のできるプラグインです。

MonkeyMixer をインストールするには、グループオブジェクト grpMonkeyMixer???.groupproj を開いて MonkeyMixer???.dll の方をビルドし、MonkeyMixer_???.dproj の方をインストールすればいいです…なのですが、このプロジェクトは Enterprise 版で作られており、Professional 版でコンパイルするとパッケージ不足でエラーになってしまいます。エラーを回避するには、

  1. [新規作成 | VCL フォームアプリケーション]
  2. [プロジェクト | オプション]
  3. [パッケージ | 実行時パッケージ] にある "ターゲット" を "すべての構成 - 32 ビット Windows プラットフォーム" に変更
  4. 実行時パッケージにある文字列を全選択してコピー
  5. プロジェクトを破棄して grpMonkeyMixer???.groupproj を開く
  6. MonkeyMixer???.dll のプロジェクトオプションを開く
  7. [パッケージ | 実行時パッケージ] にある "ターゲット" を "すべての構成 - 32 ビット Windows プラットフォーム" に変更
  8. 先ほどコピーした文字列を貼り付ける

これで Professional 版でもビルド&インストールできるようになります。インストールが完了したら使うのは簡単です。VCL フォームアプリケーションを作成し、VCL フォーム や FireMonkey フォームを追加します。

普通にやれば VCL アプリケーションではマルチデバイスフォーム (FireMonkey のフォーム) は追加できませんし、逆もしかりなのですが、MonkeyMixer ではこれを切り替える事により VCL フォームアプリケーションへ FireMonkey フォームを追加する事ができます。

具体的にはプロジェクトマネージャでプロジェクト名を右クリックし、"Switch Project to FireMonkey" または "Switch Project to VCL" を選択します。

この切り替えにより、FireMonkey フォームを VCL プロジェクトで開いたり、新規に追加したりできるようになります。プロジェクト自体は VCL プロジェクトである必要があったように思いますので、最終的には (ビルド前には) VCL プロジェクトへ切り替えておかなくてはなりません。

DSharp.Windows.FMXAdapter.pasチュートリアル

え?DSharp.Windows.FMXAdapter.pas のチュートリアルはないのかって?それはもうデブキャンでやったでしょう?

おすすめのミックスツールは?

とりあえず試してみたいなら MonkeyMixer でしょう。

ただ、MonkeyMixerDSharp.Windows.FMXAdapter.pas にはちょっとだけ問題があります。FireMonkey フォームを埋め込んで使うという構造上、タスクバーにアプリケーションアイコンが二つ表示されてしまうのです。これは FireMonkey Container では発生しません。

ね、悩ましいでしょう? (^^;A


 BACK   古いのを読む   新しいのを読む