次の方法で共有


テクニカル ノート 29: 分割ウィンドウ

更新 : 2007 年 11 月

ここでは MFC の CSplitterWnd クラス について説明します。このクラスは、ウィンドウの分割やペイン ウィンドウのサイズ調節を行うために使用します。

分割スタイル

CSplitterWnd では 2 種類のウィンドウ分割スタイルがサポートされています。

"静的分割ウィンドウ" では、分割ウィンドウの作成時に各ペインが作成されます。ペインの順序や数は変わりません。各ペインのサイズ調節には分割バーを使用します。このスタイルを使用すると、ペインごとに別々のビュー クラスを表示できます。Visual C++ グラフィック エディタや Windows ファイル マネージャは、静的分割ウィンドウを利用しているアプリケーションの例です。このスタイルの分割ウィンドウでは分割ボックスを使用しません。

"動的分割ウィンドウ" では、ユーザーの操作によって新しいペインが生成、削除されます。このスタイルの分割ウィンドウには初期状態では 1 個のビューしかありませんが、ユーザーがビューを分割するための分割ボックスが用意されています。ビューが 1 つの方向に分割されると、分割ウィンドウによって新しいビュー オブジェクトが動的に作成されます。その新しいビュー オブジェクトが新しいペインになります。キーボード インターフェイスの操作によってビューが 2 方向に分割されると、分割ウィンドウによって 3 個のビュー オブジェクトが新しく生成されて 3 個のペインになります。分割がアクティブになっていると、各ペイン間の分割バーとして分割ボックスが表示されます。分割によって追加されたビュー オブジェクトは、ユーザーが分割を解除したときに破棄されますが、元のビューは分割ウィンドウ自体が破棄されるまで残ります。動的分割ウィンドウを利用したアプリケーションの例としては Microsoft Excel や Microsoft Word などがあります。

いずれの分割ウィンドウを作成する場合も、分割ウィンドウに管理させる行と列の最大数を指定する必要があります。静的分割ウィンドウでは、行と列がすべて埋まる数のペインが生成されます。動的分割ウィンドウでは、CSplitterWnd が生成されるときに、初期状態の 1 つ目のペインだけが生成されます。

静的分割ウィンドウで指定できるペインの最大数は、16 行 × 16 列です。次の構成をお勧めします。

  • 1 行 × 2 列 : 通常は異種ペイン

  • 2 行 × 1 列 : 通常は異種ペイン

  • 2 行 × 2 列 : 通常は同種ペイン

動的分割ウィンドウで指定できるペインの最大数は、2 行 × 2 列です。次の構成をお勧めします。

  • 1 行 × 2 列 : 縦方向に長いデータの表示

  • 2 行 × 1 列 : テキスト データなどの表示

  • 2 行 × 2 列 : 表形式のデータの表示

分割ウィンドウの例

MFC サンプル プログラムの多くは、分割ウィンドウを直接または間接的に利用しています。サンプル アプリケーション VIEWEX では静的分割ウィンドウの使い方を紹介します。このサンプルでは、分割ウィンドウの中でさらに分割ウィンドウを使用する方法も検討します。

ClassWizard を使用して、分割ウィンドウを含むマルチ ドキュメント インターフェイス (MDI: Multiple Document Interface) 子フレーム ウィンドウ クラスを新しく作成することもできます。分割ウィンドウの詳細については、「複数のドキュメント タイプ、ビュー、フレーム ウィンドウ」を参照してください。

分割ウィンドウ プログラミングで使用される用語

分割ウィンドウに関連した用語を以下にまとめます。

  • CSplitterWnd:
    ペイン分割用コントロールやスクロール バーを備えたウィンドウです。これらのコントロールやスクロール バーは、行または列内のすべてのペインで共有されます。行や列は 0 から始まる番号で指定します。つまり、左上のペインは第 0 行第 0 列になります。

  • ペイン
    CSplitterWnd によって管理される、アプリケーション固有のウィンドウです。ペインは、基本的に CView クラス から派生したクラスのオブジェクトですが、適切な子ウィンドウ ID を持つ任意の CWnd オブジェクトを使うこともできます。

    CWnd 派生オブジェクトを使用する場合は、CView の派生クラスを使用する場合と同じように、そのオブジェクトの RUNTIME_CLASSCreateView 関数に渡します。派生クラスでは DECLARE_DYNCREATEIMPLEMENT_DYNCREATE を使用する必要があります。フレームワークは実行時に動的生成を行うからです。CSplitterWnd には CView クラスに固有のコードが多く含まれていますが、このようなコードが実行される前には必ず CObject::IsKindOf が使用されます。

  • 分割バー
    ペインとペインの間に配置されるコントロールです。各ペインのサイズを調節するときに使います。

  • 分割ボックス
    ペインの新しい行または列を作成するために使用できる、動的 CSplitterWnd のコントロール。垂直スクロール バー上端または水平スクロール バー左端に表示されます。

  • 分割交点
    垂直分割バーと水平分割バーの交点です。ペインの縦方向と横方向に同時にサイズを調節するときに使います。

共有スクロール バー

CSplitterWnd クラスでは共有スクロール バーも使用できます。このスクロール バーは CSplitterWnd の子コントロールで、分割ウィンドウ中の複数のペイン間で共有されます。

たとえば 1 行 × 2 列の分割ウィンドウを使用するときは、CSplitterWnd の作成時に WS_VSCROLL を指定します。これによって、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();
    キーボード分割コマンドを実行します。通常は、"ウィンドウ分割" キーです。

参照

その他の技術情報

番号順テクニカル ノート

カテゴリ別テクニカル ノート