2013年1月12日土曜日

SDIでマルチビューの実装(VC++ MFC)

Windows Visual Studio 2010 MFC
SDI(Single Document Interface)でマルチビューを使う。

MFCアプリケーションのウィザードから作成。

「SDI」にチェック
「ドキュメント/ビュー アーキテクチャのサポート」にチェック
「分割ウィンドウ」をチェック


動的生成の機能を備えたViewクラスを用意しておく。
(DECLARE_DYNCREATEマクロとIMPLEMENT_DYNCREATEマクロで定義したクラス)

「分割ウィンドウ」をチェックしているので、CMainFrameにはCSplitterWndのメンバ変数m_wndSplitterが定義されている。ウィザードで作成した状態では同じViewを分割して表示するだけなので、OnCreateClientメソッドを書き換える。
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT  lpcs,
                                CCreateContext* pContext)
{
    // 分割ウィンドウの作成
    m_wndSplitter.CreateStatic(this, 1, 2);

    // Create FirstView 
    CRuntimeClass*  firstViewClass = RUNTIME_CLASS( CFirstView);
    pContext->m_pNewViewClass = firstViewClass;
    m_wndSplitter.CreateView(0,0, 
        pContext->m_pNewViewClass, CSize(0,0), pContext);

    // Create SecondView
    CRuntimeClass* secondViewClass = RUNTIME_CLASS(CSecondView);
    pContext->m_pNewViewClass = secondViewClass;
    m_wndSplitter.CreateView(0,1, 
        pContext->m_pNewViewClass, CSize(0,0), pContext);

    return TRUE;
}

CWinAppから派生したCMyAppのInitInstanceメソッドで記述されているCSingleDocTemplateのViewの引数はNULLにしておく。
BOOL CMyApp::InitInstance()
{
    CWinAppEx::InitInstance();

    // SDI
    CSingleDocTemplate* pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CMyDoc),
        RUNTIME_CLASS(CMainFrame),
        NULL);                    // ViewにNULLを渡しておく
    if (!pDocTemplate)
        return FALSE;
    AddDocTemplate(pDocTemplate);

    m_pMainWnd->ShowWindow(SW_SHOW);
    m_pMainWnd->UpdateWindow();
    return TRUE;
}

2 件のコメント:

  1. ありがとうございます
    ただ初心者には
    動的生成の機能を備えたViewクラスを用意しておく。
    (DECLARE_DYNCREATEマクロとIMPLEMENT_DYNCREATEマクロで定義したクラス)
    の部分がどのようにすれば良いか分かりません ご指導宜しくお願いします。

    返信削除
    返信
    1. > DECLARE_DYNCREATEマクロとIMPLEMENT_DYNCREATEマクロで定義したクラス
      確かに分かりにくいのかもしれませんね。笑

      MFCのフレームワーク側で動的に作成してもらうには,RUNTIME_CLASS( CFirstView)のように、ランライムクラスを作成する必要があるのですが、普通のクラス定義ではダメで、DECLARE_DYNCREATEマクロとIMPLEMENT_DYNCREATEマクロを使って定義されたクラスでないといけません。
      MFCアプリケーションでプロジェクトを作成した時にCMainFrameクラスなどに自動で付くのでそれが参考になると思います。
      具体的に云うと、記事に記載のCFirstViewクラスであれば、下記のようにクラス定義にDECLARE_DYNCREATEマクロ、クラス実装にIMPLEMENT_DYNCREATEマクロで記載したクラスの事です。

      // firstview.h
      class CFirstView: public CView {
      public:
      DECLARE_DYNCREATE(CFirstView) // フレームワーク側で動的生成したいクラス名
      }

      // firstview.cpp
      IMPLEMENT_DYNCREATE(CFirstView, CView) //フレームワーク側で動的生成したいクラス名と、継承クラス


      下記のリファレンスが参考になるかと思いますので、合わせてご覧ください。

      DECLARE_DYNCREATE
      http://msdn.microsoft.com/ja-jp/library/56302tyt(v=vs.90).aspx

      IMPLEMENT_DYNCREATE
      http://msdn.microsoft.com/ja-jp/library/5fsfk9dy(v=vs.90).aspx

      RUNTIME_CLASS
      http://msdn.microsoft.com/ja-jp/library/a3tc49sy(v=vs.90).aspx

      少しは参考になったでしょうか、コメントありがとうございました。

      削除