■ Tips [Delphi] 2-1
 Delphi - Delphiでちょっと使える子ネタ集
 第2回 「SDIアプリケーションの子ウィンドウ管理について」

今回は「StarChat2」の開発段階で問題となったSDI(SingleDocumentInterface)アプリケーションにおける疑似子ウィンドウ管理についてです。MDIにしてもSDIにしても子ウィンドウはこんなようなものを指します。

・同一のクラスから生成される設定のみ違う複数のウィンドウ。・静的に生成されているのではなく、実行中に動的に生成される。

MDIとSDIではこれらの管理に大きな隔たりがあります。というのも、MDIでは複数のChildウィンドウに対して1つの親ウィンドウが存在するのに対し、SDIには親という考え方すら取り入れられません。その違いを見ていき、微妙にうまい解決法を考えましょう。

 2-1 MDIアプリケーションにおける子ウィンドウ管理

DelphiにおいてMDIアプリケーションを作るとき、親となるフォームのFormStyleプロパティをfsMDIFormと設定し、子を受容できるようにします。また、子となるフォームのFormStyleはfsMDIChildに設定します。その状態で

procedure TMainForm.CreateMDIChild(const Name: string);
var
 Child: TMDIChild;
begin
 { MDI 子ウィンドウを作成する }
 Child := TMDIChild.Create(Application);
 Child.Caption := Name;
 if FileExists(Name) then Child.Memo1.Lines.LoadFromFile(Name);
end;

このようなルーチンを実行してやればキャプションが引数Nameの内容となった子ウィンドウがTMainFormの内部に作成されます。fsMDIFormと設定されたフォームが存在しない場合、【有効なMDIアプリケーションではありません】と表示されてしまいます。

では、実行中にこれらの子ウィンドウにアクセスする方法はどうなっているのでしょうか?それは親としてあるフォームのMDIChildrenプロパティ及びMDIChildCountプロパティにアクセスする事で行えます。

property MDIChildren[I: Integer]: TForm;
property MDIChildCount: Integer;

これらのプロパティはFormStyleがfsMDIFormである親ウィンドウにしか提供されません。で、このMDIChildrenプロパティの特徴ですが、これがなかなか厄介です。基本的には作成された順番にリストに追加されますので、何もしなければ作った順に0,1,2...とインデックスが割り振られますが、ある子ウィンドウがActiveになった時点でその子ウィンドウのインデックスが先頭(Index=0)に移動します。つまり、インデックスだけで子ウィンドウを管理するのは結構大変です。

実は今までMDIアプリケーションは作ったことがないので、この辺にしておきます。 (^-^;

 NEXT