テクニカル ノート 29: 分割ウィンドウ
ここでは、ウィンドウ分割を提供し、他のペイン ウィンドウのサイズ変更を管理する MFC CSplitterWnd クラスについて説明します。
スプリッターのスタイル
CSplitterWnd
は、2 つの異なるスタイルの分割ウィンドウをサポートしています。
「静的スプリッター」では、スプリッター ウィンドウによって、作成時にペインが作成されます。 ペインの順序と数が変更されることはありません。 スプリッター バーは、さまざまなペインのサイズを変更するために使用します。 このスタイルを使用して、各ペインに異なるビュー クラスを表示できます。 このスプリッター スタイルを使用するプラグラムの例として、Visual C++ グラフィック エディターと Windows ファイル マネージャーがあります。 このスタイルのスプリッター ウィンドウでは、スプリッター ボックスは使用されません。
「動的スプリッター」では、ユーザーが新しいビューを分割および分割解除するときに、追加のペインが作成され、破棄されます。 このスプリッターは、1 つのビューから開始し、ユーザーが分割を開始するためのスプリッター ボックスを提供します。 スプリッター ウィンドウでは、ビューが一方向に分割されると、新しいビュー オブジェクトが動的に作成されます。 この新しいビュー オブジェクトは、新しいペインを表します。 キーボード インターフェイスを使用してビューが二方向に分割されると、スプリッター ウィンドウによって、3 つの新しいペイン用に 3 つの新しいビュー オブジェクトが作成されます。 分割がアクティブになっている間、Windows は、ペイン間のスプリッター バーとしてスプリッター ボックスを表示します。 ユーザーが分割を削除すると、Windows は追加のビュー オブジェクトを破棄しますが、元のビューはスプリッター ウィンドウ自体が破棄されるまで保持されます。 動的スプリッター スタイルを使用するアプリケーションの例として、Microsoft Excel と Microsoft Word があります。
どちらの種類のスプリッター ウィンドウを作成する場合でも、スプリッターが管理する行と列の最大数を指定する必要があります。 静的スプリッターでは、すべての行と列を埋めるためのペインが作成されます。 動的スプリッターでは、CSplitterWnd
の作成時に最初のペインのみが作成されます。
静的スプリッターに指定できるペインの最大数は、16行 x 16 列です。 推奨される構成は、以下のとおりです。
1 行 x 2 列: 通常、類似しないペインがある
2 行 x 1 列: 通常、類似しないペインがある
2 行 x 2 列: 通常、類似するペインがある
動的スプリッターに指定できるペインの最大数は、2 行 x 2 列です。 推奨される構成は、以下のとおりです。
1行 x 2 列: 列形式データ用
2行 x 1 列: テキストまたはその他のデータ用
2行 x 2 列: グリッドまたはテーブル指向データ用
スプリッターの例
MFC サンプル プログラムの多くは、スプリッター ウィンドウを直接的または間接的に使用します。 MFC の一般的なサンプル VIEWEX は、スプリッターをスプリッターに配置する方法など、静的スプリッターのいくつかの用途を示しています。
また、ClassWizard を使用して、スプリッター ウィンドウを含む新しいマルチ ドキュメント インターフェイス (MDI) 子フレーム ウィンドウ クラスを作成することもできます。 スプリッター ウィンドウの詳細については、「複数のドキュメント タイプ、ビュー、フレーム ウィンドウ」を参照してください。
実装で使用される用語
スプリッター ウィンドウに固有の用語の一覧を次に示します。
CSplitterWnd
: 行または列のすべてのペイン間で共有されるペイン分割コントロールとスクロール バーを提供するウィンドウ。 0 から始まる行と列を指定します (最初のペインは row = 0、column = 0)。
ペイン: CSplitterWnd
が管理するアプリケーション固有のウィンドウ。 通常、ペインは、 CView クラスから派生したオブジェクトですが、適切な子ウィンドウ ID を持つ任意の CWnd オブジェクトにすることができます。
CWnd
派生オブジェクトを使用するには、CView
派生クラスを使用する場合と同様に、オブジェクトの RUNTIME_CLASS を CreateView
関数に渡します。 フレームワークはランタイムに動的作成を使用するため、クラスは DECLARE_DYNCREATE と IMPLEMENT_DYNCREATE を使用する必要があります。 CSplitterWnd
には CView
クラスに固有のコードが多数ありますが、CObject::IsKindOf は常にこれらのアクションが実行される前に使用されます。
スプリッター バー: ペインの行と列の間に配置されるコントロール。 これを使用して、ペインの行または列のサイズを調整できます。
スプリッター ボックス: ペインの新しい行または列を作成するために使用できる動的 CSplitterWnd
のコントロール。 垂直スクロール バーの上部または水平スクロール バーの左側にあります。
スプリッター交差: 垂直スプリッター バーと水平スプリッター バーの交差部分。 これをドラッグして、ペインの行と列のサイズを同時に調整できます。
共有スクロール バー
CSplitterWnd
クラスは、共有スクロール バーもサポートしています。 これらのスクロール バー コントロールは、CSplitterWnd
の子であり、スプリッターのさまざまなペインで共有されます。
たとえば、1行 x 2 列ウィンドウでは、CSplitterWnd
を作成するときに WS_VSCROLL を指定できます。 Windows は、2 つのペイン間で共有される特殊なスクロール バー コントロールを作成します。
[ ][ ][^]
[pane00][pane01][|]
[ ][ ][v]
ユーザーがスクロール バーを移動すると、WM_VSCROLL メッセージが両方のビューに送信されます。 どちらかのビューでスクロール バーの位置が設定されると、共有スクロール バーが設定されます。
共有スクロール バーは、類似するビュー オブジェクトで最も役に立ちます。 スプリッターで異なる種類のビューを混在させる場合、スクロール位置を調整するための特殊なコードを記述する必要が生じることがあります。 CWnd
スクロール バー API を使用する CView
派生クラスは、存在する場合は共有スクロール バーにデリゲートされます。 CScrollView
の実装は、共有スクロール バーをサポートする CView
クラスの一例です。 CView
から派生していないクラス、非コントロール スクロール バーに依存しているクラス、または標準の Windows 実装を使用するクラス (CEditView
など) は、CSplitterWnd
の共有スクロール バー機能では動作しません。
最小サイズ
行ごとに行の高さの最小値があり、各ごとに列の幅の最小値があります。 この最小値により、ペインが小さすぎて完全な詳細情報を表示できなくなることが避けられます。
静的スプリッター ウィンドウでは、初期の最小の行の高さと列の幅は 0 です。 動的スプリッター ウィンドウでは、初期の最小の行の高さと列の幅は、CSplitterWnd::Create
関数の sizeMin パラメーターによって設定されます。
これらの最小サイズは、CSplitterWnd::SetRowInfo 関数と CSplitterWnd::SetColumnInfo 関数を使用して変更できます。
実際のサイズと理想的なサイズ
スプリッター ウィンドウのペインのレイアウトは、それらが含まれているフレームのサイズによって異なります。 含まれているフレームのサイズをユーザーが変更すると、CSplitterWnd
は可能な限り適合するように、ペインの位置を変更し、サイズを調整します。
ユーザーは、行の高さと列の幅のサイズを手動で設定できます。また、プログラムで CSplitterWnd
クラスを使用して理想的なサイズを設定することもできます。 実際のサイズが、最適なサイズより小さすぎたり、大きすぎたりする場合があります。 最適なサイズを表示するのに十分な空き領域がない場合や、スプリッター ウィンドウの右側または下部の空白が多すぎる場合、Windows によって実際のサイズが調整されます。
カスタム コントロール
多数の関数をオーバーライドして、カスタマイズされた動作やカスタマイズされたインターフェイスを提供できます。 この最初のセットをオーバーライドして、スプリッター ウィンドウのさまざまなグラフィカル コンポーネントに別の画像を提供できます。
virtual void OnDrawSpltter(CDC* pDC, ESplitType nType, const CRect& rect);
virtual void OnInvertTracker(const CRect& rect);
この関数を呼び出して、共有スクロール バー コントロールを作成します。 これをオーバーライドして、スクロール バーの横に追加のコントロールを作成できます。
virtual BOOL CreateScrollBarCtrl(DWORD dwStyle, UINT nID);
これらの関数によって、動的スプリッター ウィンドウのロジックが実装されます。 これらをオーバーライドして、より高度なスプリッター ロジックを提供できます。
virtual void DeleteView(int row, int col);
virtual BOOL SplitRow(int cyBefore);
virtual BOOL SplitColumn(int cxBefore);
virtual void DeleteRow(int rowDelete);
virtual void DeleteColumn(int colDelete);
CView の機能
CView
クラスは次の高レベル コマンドを使用して、CSplitterWnd
実装にデリゲートします。 これらのコマンドは仮想であるため、標準の CView
実装では、CSplitterWnd
の実装全体をリンクする必要はありません。 CView
は使用するが CSplitterWnd
は使用しないアプリケーションの場合、CSplitterWnd
実装はアプリケーションにリンクされません。
virtual BOOL CanActivateNext(BOOL bPrev = FALSE);
ID_NEXT_PANE または ID_PREV_PANE が現在可能であるかを確認します。
virtual void ActivateNext(BOOL bPrev = FALSE);
"Next Pane" または "Previous Pane" コマンドを実行します。
virtual BOOL DoKeyboardSplit();
キーワード分割コマンドを実行します。通常は、"Window Split" を使用します。