Delphi のフォームファイル(.dfmまたは .fmx)は、データベースのコンテナとして利用することができます。このフォームファイルをリソースとしてアプリに組み込む用例を紹介します。
Delphiのフォームファイル
Delphi では、フォームおよびフォームのコンポーネントをフォームファイル(VCL アプリケーションでは .dfm ファイル、FireMonkey アプリケーションでは .fmx ファイル)に保存します。このDelphiの仕組みを利用して、TDataModuleをコンテナ(TFormの代わりの入れ物)としてデータコンポネントの保管場所(Owner)とすることで、ReadComponentResFileとWriteReadComponentResFileによってファイルに読み書き(つまり、データコンポーネントの保存と復元)することが簡単に実現できます。
ここでは、フォームファイルとして保存したデータコンポネントをリソースとしてアプリに組み込む用例を紹介します。
フォームファイルのデータベースとしての利用
まずは、フォームファイルをデータベースとして利用することについて簡単に説明します。
データを保持するコンポーネントについては、例えばTMenuItemのように、それ自体がデータを格納するプロパティを持つと同時に子のItemを持つことができるコンポネントをイメージしてください。子のItemを次々に追加することで、好きなだけデータを保管することができます。データを取り出すときは、各コンポーネントに名前やインデックスでアクセスします。名前からコンポーネントを見つけるにはTDataModule.FindComponent(’名前’)を使うことができます。親コンポーネントの名前を決めておけば、FindComponentで親を見つけることができるので、あとは親のItems[ ]から子Itemにアクセスできるような仕組みにしておくと便利です。なお、親Itemも子ItemもCreateするときはTDataModuleをOwnerとします。
フォームファイルをリソースにする
それでは、本題の「フォームファイルをリソースにする」について説明します。
アプリの動作に必要なデータをフォームファイルに保存し、起動時にReadComponentResFileでファイルから読み込むことは、もちろん可能です。しかし、フォームファイルをアプリに組み込んでしまいたいこともあると思います。そこでリソースの活用を考えました。
Delphiのリソース
Delphiでは、そのプロジェクトで作成されるアプリのリソースをリソースマネージャで管理します。リソースマネージャはRAD Studioのプロジェクトメニューの「リソースと画像」で呼び出します。txtやpngなどをリソースとして扱うことは多いと思います。
txtやpngと同じようにフォームファイルを扱うことはできるのでしょうか。
残念ながらできませんでした。
リソースマネージャの画面上でtxtやpngと同じようにフォームファイルを「追加」することはできるのですが、一旦、リソースマネージャを閉じてから再びリソースマネージャを呼び出すと、追加されたはずのフォームファイルが消えています。もちろん、リソースとして実行時に読み込むこともできません。
(図)リソースマネージャで.fmxを追加してみた・・・
(図)リソースマネージャを一旦閉じて再び開くと何もない・・・
フォームファイルを偽装する
仕方ないので、フォームファイルを偽装することにしました。例えば、拡張子のdfmをgifに変えて画像ファイルに偽装してから、リソースマネージャで「追加」します。一旦、リソースマネージャを閉じてから再びリソースマネージャを呼び出すと、今回はちゃんと残っていました。
(図)拡張子をgifにして追加したところ・・・
実行中にフォームファイルを読み込む
それでは、画像に偽装したフォームファイルは実行中にフォームファイルとして読み込めるのでしょうか。
結果は、読み込めました。
コードは以下に示す通りです。
var
Stream: TResourceStream;
Container: TDatamodule;
begin
Stream := TResourceStream.Create(HInstance, 'GifImage_1', RT_RCDATA);
Container:= TDatamodule.Create(Layout1);
Stream.ReadComponentRes(Container);
Stream.Free;
{以下、ReadComponentResFile(FileName, Container);とした場合と同じように使うことができた}
今回は偽装という手段を用いてフォームファイルをリソースにしましたが、おそらく正当な方法ではないと思います。ご利用は自己責任でお願いします。また、ちゃんとした方法をご存じの方は教えて頂けるとうれしいです。是非ともよろしくお願いいたします。