Delphi/400にはドッキングと呼ばれる機能が用意されており、
画面の結合や分離をプロパティの設定やコーディングで制御することができます。
今回はこの手順を紹介します。
ドッキングの仕組み
画面の結合(ドッキング)を行うには
ドッキング元(子)とドッキング先(親)がそれぞれ必要となります。
ドッキング先(親)には、以下のようなコンテナコンポーネント(土台)を指定可能です。
- TForm
- TPanel
- TPageControl(TTabSheet)
- TScrollBox
- TDockTabSet・・・など
ドッキング元(子)は、基本的には別のフォームとなります。
ドッキングを行うと、ドッキング元(子)をドッキング先(親)の中に
格納したような見た目になります。
画面をドッキング/ドッキング解除する手順
ドッキング先(親)には、以下のプロパティを設定しておきます。
DockSite = True
またドッキング元(子)には、以下のプロパティを設定しておきます。
DragKind = dkDock
DragMode = dmAutomatic
この状態でドッキング先(親)を含むフォームからドッキング元(子)のフォームを生成し、
Showで表示した状態からドラッグ&ドロップすると、画面がドッキングされます。
ドッキング元の種類にもよりますが、
ドラッグ&ドロップで引き剥がす(ドッキング解除)ことも可能です。
プログラムでドッキング/ドッキング解除する手順
ドラッグ&ドロップする以外にも、
以下のようなロジックでドッキングが可能です。
(先述のドラッグ&ドロップ時のようなプロパティ設定は不要です。)
ロジックでドッキングする場合は、以下のようにManualDockを使用します。
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Application); // 画面(子)を作成
Form2.ManualDock(PageControl1); // 画面(子)をPagecontrolにドッキングさせる
Form2.Show; // 画面(子)を表示
end;
ロジックでドッキングを解除するには、以下のようにManualFloatを使用します。
以下の例では、ドッキング元フォーム(Form2)のカレンダー(Calendar1)を
ダブルクリックした時に切り替えができるようになっています。
※ドッキングの状態はFloatingという内部プロパティで判断できます。
※ドッキング元のフォームでuses節にドッキング先のフォームを追加する必要があります。
procedure TForm2.Calendar1DblClick(Sender: TObject);
begin
if Floating then // フロート(ドッキング解除状態)であればドッキング
begin
ManualDock(Form1.PageControl1);
end
else // ドッキング状態であればドッキング解除
begin
ManualFloat(Rect(0, 0, Width, Height));
end;
end;
応用テクニック
以下のようなロジックで、ドッキング先を制御することが可能です。
ドッキング先(親)のOnGetSiteInfoイベントで条件を付けることで、
ドッキングを無効にできます。
procedure TForm1.PageControl1GetSiteInfo(Sender: TObject; DockClient: TControl;
var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
begin
if DockClient is TForm3 then //ドッキングする画面がXXXXであれば
begin
CanDock := False; //ドッキングを無効にする
end;
end;
また、PageControlなどを使用していて合計の項目数が非常に多い画面がある場合、
単独画面にすべてのコンポーネントを配置していると
画面の起動だけでもかなりの時間を要したり、プログラムを修正する際に
どこを直せばいいのか煩雑になりすぎる場合があります。
(DelphiのIDEで設計画面を表示するだけでもかなりの時間を要するでしょう。)
このような場合に、個々のタブの情報を独立した画面として設計しておき、
ドッキング先(親)の画面の生成時に各画面(タブ)をドッキングさせることで
レスポンスや開発・修正工数の削減が期待できます。
以下のロジック例では、Form1のPageControl1に対して
項目がいっぱいのForm2・3・4を生成時にドッキングさせることで
あたかもForm1に項目が多い3タブが最初からあったかのような画面を表示できます。
procedure TForm1.FormCreate(Sender: TObject);
begin
Form2 := TForm2.Create(Application); // 画面(子)を作成
Form2.ManualDock(TabSheet1); // 画面(子)をTabSheetにドッキングさせる
Form2.Show; // 画面(子)を表示
Form3 := TForm3.Create(Application);
Form3.ManualDock(PageControl1); // Pagecontrolにドッキングすると新規タブになる
Form3.Show; // Showしないと非表示のまま
Form4 := TForm4.Create(Application);
Form4.ManualDock(PageControl1);
Form4.Show;
end;
<上記のサンプルロジックを実行した際のイメージ>
注意ポイント
ここまで便利なドッキング機能をご紹介しましたが、以下のポイントにはご注意ください。
ドッキング先(親)を含む画面がドッキングしたまま閉じられた場合、
ドッキング元(子)の画面も閉じてしまいます。
ここまでは当たり前かと思われますが、
逆にドッキング元(子)の画面でTBitBtnのKind=bkcloseを使って
閉じるボタンを作成すると、このボタンがドッキング中に押されることで
ドッキング先(親)を含む画面ごと閉じてしまうのでご注意ください。
(ロジックで「Self.Close;」などを使って閉じた場合は、正しくドッキング元のみが閉じられます。)
(第10回 ミガロ. テクニカルセミナー
知って得する!現役ヘルプデスクが答えるDelphiテクニカルエッセンス 10.0 より)