ファイルをバイナリ形式で表示する (C/C++編)
アプリケーション ウィザードで生成されたプロジェクトに、ディレクトリツリー、ファイル一覧ビューおよびバイナリデータ表示ビューの各クラスファイルを追加します。
デフォルトで生成されたビューのクラスファイルは使用しないので削除します。
これに伴い、ドキュメントとビューを関連付けを実行するコードを修正します。
分割ウインドウの作成がまだできていないので、分割ウインドウの作成も併せて行います。
ディレクトリツリー、ファイル一覧ビューおよびバイナリデータ表示ビューのクラスファイルを追加します。
「ソリューションエクスプローラ」で右クリックしてメニューを表示して、「追加」→「新しい項目」を選択します。
「MFCクラス」を選択して、「追加」を押します。
アプリケーションウィザードで作られたビューのクラスファイル「MFCApp001View.cpp」と「MFCApp001View.h」は使用しないので削除します。
「MFCApp001View.cpp」で右クリックしてメニューを表示して、「削除」を選択します。
「削除」を押します。
「MFCApp001View.h」で右クリックしてメニューを表示して、「削除」を選択します。
「削除」を押します。
今回のプログラムでは1つのドキュメントに対して、3つのビューがあります。
しかし、ドキュメント テンプレートを登録するための「CSingleDocTemplate」では、複数のビューを1つのドキュメントに結合できません。
以下のようにディレクトリツリー・ビュー、ファイル一覧ビュー、バイナリデータ表示ビューのそれぞれをCSingleDocTemplateで個別にドキュメントと結合させてみてはどうでしょうか?
    // ディレクトリツリー・ビューとドキュメントを結合.
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CMFCApp001Doc),
        RUNTIME_CLASS(CMainFrame),
        RUNTIME_CLASS(CFileTreeView));
    if (!pDocTemplate)
        return FALSE;
    AddDocTemplate(pDocTemplate);
    // ファイル一覧ビューとドキュメントを結合.
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CMFCApp001Doc),
        RUNTIME_CLASS(CMainFrame),
        RUNTIME_CLASS(CFileListView));
    if (!pDocTemplate)
        return FALSE;
    AddDocTemplate(pDocTemplate);
    // バイナリデータ表示ビューとドキュメントを結合.
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CMFCApp001Doc),
        RUNTIME_CLASS(CMainFrame),
        RUNTIME_CLASS(CFileDataView));
    if (!pDocTemplate)
        return FALSE;
    AddDocTemplate(pDocTemplate);
	
	この場合、実行時に以下のような選択ダイアログが出て、分割ウインドウになりません。
では、いっそのことドキュメント テンプレートを登録をしないというのはどうでしょうか?
残念ながらこの場合はプログラム起動直後に強制終了してしまいます。
今回のように1つのドキュメントに対して複数のビューがある場合は、ビューを指定しないでドキュメント テンプレートを登録すればよいようです。
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CMFCApp001Doc),
        RUNTIME_CLASS(CMainFrame),
        NULL);                          // 複数のビューがあるときはNULLにする.
    if (!pDocTemplate)
        return FALSE;
    AddDocTemplate(pDocTemplate);
	
	分割ウインドウの設定はメイン画面の生成時に行うので、「OnCreateClient()」をオーバーライドします。
「ソリューションエクスプローラ」で右クリックしてメニューを表示して、「クラスウィザード」を選択します。
「仮想関数」タブをクリックして「仮想関数」リストから「OnCreateClient」を選択して「関数の追加」を押します。
ウインドウを分割するには「CSplitterWnd」クラスを使用します。
CSplitterWndはウインドウを上下または左右に2分割しますので、3分割するにはCSplitterWndを2つ使用します。
ウインドウを3分割する手順は以下のようにします。
- メイン画面を左右に2分割します。
 - 分割したウインドウの右側をさらに上下に分割します。
 - 分割した各ウインドウにビューを割り付けます。
 
分割ウインドウを作成するメソッドは「CSplitterWnd::CreateStatic()」です。
  virtual BOOL CreateStatic(
                  CWnd* pParentWnd,
                  int nRows,
                  int nCols,
                  DWORD dwStyle = WS_CHILD | WS_VISIBLE,
                  UINT nID = AFX_IDW_PANE_FIRST 
               );
	
	| 引数 | 説明 | 
|---|---|
| pParentWnd | 分割ウィンドウの親ウィンドウ。 | 
| nRows | 行の番号。 | 
| nCols | 列の番号。 | 
| dwStyle | ウィンドウ スタイル。(省略可) | 
| nID | 子ウィンドウの ID。(省略可) | 
分割ウインドウにビューを割り付けるメソッドは「CSplitterWnd::CreateView()」です。
  virtual BOOL CreateView(
                  int row,
                  int col,
                  CRuntimeClass* pViewClass,
                  SIZE sizeInit,
                  CCreateContext* pContext
               );
	
	| 引数 | 説明 | 
|---|---|
| row | ビューを設定する分割ウィンドウの行。 | 
| col | ビューを設定する分割ウィンドウの列。 | 
| pViewClass | 設定するビューのCRuntimeClass。 | 
| sizeInit | ビューの初期サイズ。 | 
| pContext | ビューの作成コンテキストへのポインタ。 (OnCreateClient()の引数で貰える。)  | 
ソースコードを以下に示します。
MainFrm.cpp
/****************************************************************************/
/*!
 *  @brief  OnCreateの実行中に呼ばれる処理.
 *
 *  @param  [in]    lpcs        ウインドウの生成情報構造体のポインタ.
 *  @param  [in]    pContext    ウインドウ生成のコンテキスト.
 *
 *  @retval 0 = OK. / -1 = NG.
 */
BOOL CMainFrame::OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext )
{
    //! 左右の分割ウインドウを作成する
    m_SplitWndMain.CreateStatic( this, 1, 2 );
    //! 右側のウインドウを上下に分割する.
    m_SplitWndSub.CreateStatic( &m_SplitWndMain, 2, 1, WS_CHILD | WS_VISIBLE, m_SplitWndMain.IdFromRowCol( 0, 1 ) );
    //! 分割した各ウインドウにビューを割り付ける.
    m_SplitWndMain.CreateView( 0, 0, RUNTIME_CLASS( CFileTreeView ), CSize( 200,   0 ), pContext );
    m_SplitWndSub.CreateView(  0, 0, RUNTIME_CLASS( CFileListView ), CSize(   0, 200 ), pContext );
    m_SplitWndSub.CreateView(  1, 0, RUNTIME_CLASS( CFileDataView ), CSize(   0,   0 ), pContext );
    //! 最後に基本クラスのメソッドを呼び出す.
    return CFrameWnd::OnCreateClient( lpcs, pContext );
}
	
	












