複数ビューの切替え

■ 概略説明
VC5.0以前には、これに似たサンプルがあったようですが、それ以降はなくなってしまったみたいなので、このサンプルを作成しました。
サンプルは、SDIでメニューにより3つのビューを切替えます。下図のようにツールバーのボタンまたは、表示メニューから画面を切り替えることが出来ます。
■ プログラムの説明
このサンプルにおける、SDIタイプへの複数ビューの追加方法を説明します。
@ 通常通りアプリウィザードでMFC・SDIを指定し、プロジェクトを作成します。このサンプルのビューはデフォルトのCViewクラスのままです。デフォルトのビューが画面1になります。名前はCMyView1にします。
A 画面2、3を追加します。クラスの新規作成を開き、クラスの種類はMFCクラス、基本クラスはCViewクラス名はそれぞれCMyView2、CMyView3にします。
B それぞれの画面を作成します。このサンプルでは単に画面ごとの背景色を変え、中央に画面を表す文字列を表示してあるだけです。例として画面1の描画部分は次のようになります。
void CMyView1::OnDraw(CDC* pDC)
{
        CChgvwDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        // TODO: この場所にネイティブ データ用の描画コードを追加します。
        CRect           cr;
        CFont*          pOldFont;

        GetClientRect( &cr);

        pOldFont = pDC->SelectObject( &m_font);
        pDC->FillSolidRect( &cr, RGB( 200, 255, 200));
        pDC->DrawText( "画面 T", &cr, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        pDC->SelectObject( pOldFont);
}
C それぞれの画面クラスのポインターをグローバル変数として登録します。たとえばCMyView1の場合は、
CMyView1*                       pView1          = NULL;
のようにして、外部から参照できるようにします。
D 画面切り替えメニューを追加します。このサンプルの場合は、分かりやすいようにツールバーにもボタンを追加しました。IDはそれぞれID_VIEW1、ID_VIEW2、ID_VIEW3です。
E 最後に、メインの処理である画面の切り替えの処理を追加します。例として、画面2に切り替え(ID_VIEW2)の処理は次のようになります。
void CMainFrame::OnView2() 
{
        if ( m_nViewType == VIEW2)
                return;

        CView* pOldActiveView = GetActiveView();                // 現在のビュー取得.
        CView* pNewActiveView;
        m_nViewType = VIEW2;

        if ( !pView2)                   // 画面2の新規作成.
        {
                new CMyView2;
                CCreateContext context;                   
                context.m_pCurrentDoc = pOldActiveView->GetDocument(); 
                pView2->Create( NULL, NULL, WS_BORDER, CFrameWnd::rectDefault,
                                                this, m_nViewType, &context);       
                pView2->OnInitialUpdate();
        }

        pNewActiveView = (CView*)pView2;

        SetActiveView( pNewActiveView);                         // ActiveViewの変更.
        pNewActiveView->ShowWindow( SW_SHOW);                   // 新しい画面を表示.
        pOldActiveView->ShowWindow( SW_HIDE);                   // 古い画面を隠す.
        pOldActiveView->SetDlgCtrlID( m_nViewType);             // IDを変更.
        pNewActiveView->SetDlgCtrlID( AFX_IDW_PANE_FIRST);      // SDIのしきたりらしい.
        RecalcLayout();                                         // ツールバーなどを変更する場合有効.
}
上記ソースコード内で、新規作成部分は画面1は必要ありません。
基本的には、SetActiveView関数にて現在のビューを変更し、後は新旧ビューの表示状態を切り替えることにより、画面の切り替えをおこないます。
プログラム終了時のビューの消去は、元のCMyView1と同様に他のビューも自動的に消去されます。
■ ファイルのダウンロード
 (VC++6.0プロジェクトファイル25Kb)