MFCコントロール - 分割ウインドウ

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
2019年10月29日 (火) 00:41時点における192.168.1.24 (トーク)による版 (ページの作成:「== 概要 == 分割ウインドウとは、ウインドウが2つ以上に分割されているウィンドウの事である。<br> Visual C++ではそれぞれの分割…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

概要

分割ウインドウとは、ウインドウが2つ以上に分割されているウィンドウの事である。
Visual C++ではそれぞれの分割された個々のウインドウを「ペイン」と呼ぶ。


左右2分割の分割ウインドウの作成

MFCでは、分割ウインドウを作成するAPIが標準で用意されている。それが、CSplitterWnd::CreateStatic関数である。
下図のような1行2列の2ペインを持つ分割ウインドウのプログラムを記述する。

まず、各ペインを管理するViewクラスを作成する。
Viewクラスは、ペインの数だけ必要になるので、上図のように左右2つに分割すると、Viewクラスは全部で2つ必要になる。
paneA(左ペイン)にはプロジェクト作成時で用意されているViewクラスを利用し、paneB(右ペイン)のViewクラスは新規で作成する。

プロジェクトに新規Viewクラスを追加する。
流れは以下の通りである。
[挿入(I)]->[クラスの新規作成(N)]

  [クラスの種類(T)]   MFCクラスを選択
[クラス名(N)]     好きなクラス名(ここではCPaneAView)
[基本クラス(B)]    CFormViewクラス(CViewの派生クラスならどれでもよい)


まず、CMainFrm.hファイルを開いて、以下のコードを入力する。
※MDIアプリケーションの場合は、CChildFrm.hファイルのCChildFrameクラスに同様のコードを追加する。

 CMainFrame.h
 
 class CMainFrame : public CFrameWnd
 {
    // ...
    public:
       CSplitterWnd    m_SplitWndMain;     // スプリッタウィンドウ
    // ...
 }


次に、CMainFrm.cppファイルのCMainFrameクラスにOnCreateClientメンバ関数をオーバーライドする。
手順は以下の通りである。
[表示(V)]->[ClassWizard(W)]

  [プロジェクト(P)]  PaneTest
[クラス名(N)]    CMainFrame
[オブジェクトID(I)] CPaneBView
[メッセージ(G)]   OnCreateClient


そして、CMainFrm.cppファイルに、以下のコードを追加する。

 #include  "CPaneTestDoc.h"  // CPaneAView.hよりも先にインクルード
 #include  "CPaneAView.h"    // CPaneAViewクラスのヘッダをインクルード
 #include  "CPaneBView.h"    // CPaneBViewクラスのヘッダをインクルード
 
 // ...
 
 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
 {
    // ...
    // ...
    m_SplitWndMain.CreateStatic(  // スプリッタウィンドウの作成
       this,                      // スプリッタウィンドウの親ウィンドウを指定。ここではメインフレームを分割するのでthisを指定。
       1,                         // 行の分割数を指定。ここでは縦分割は無いので1を指定
       2);                        // 列の分割数を指定。ここでは左右分割なので2を指定
 
    m_SplitWndMain.CreateView(     // paneA(ペイン場所1x1)を作成。
       0,                          // スプリッタの行番号を指定
       0,                          // スプリッタの列番号を指定
       RUNTIME_CLASS(CPaneAView),  // 指定ペインを管理するViewクラスCPaneAViewを指定
       CSize(20, 0),               // ペインのサイズ
       pContext);
 
    m_SplitWndMain.CreateView(     // paneB(ペイン場所1x2)を作成。
       0,                          // スプリッタの行番号を指定
       1,                          // スプリッタの列番号を指定
       RUNTIME_CLASS(CPaneBView),  // paneBを管理するViewクラスCPaneBViewを指定
       CSize(0,0),                 // ペインのサイズ
       pContext);
    // ...
    // ...
 }


ここで注意するのが、CSplitterWnd::CreateView関数の第3引数である。
第3引数において、指定ペインを管理するViewクラスを指定する。
paneAを管理するのはCPaneAViewなのでこれを指定する。同様に、paneBを管理するのはCPaneBViewクラスなので、CPaneBViewを指定する。
尚、MDIアプリケーションの場合も同様に、CChildFrameクラスにOnCreateClient関数をオーバーライドして、OnCreateClient関数内に同様のコードを追加する。