S-JIS[1998-08-14]

ダイアログバーの作り方

AppWizardで作成したMDIのMFCアプリケーションの子ウィンドウに ダイアログバーを付ける方法を書きます。
たぶん、SDIでも同じように出来ると思います。


  1. ダイアログバーリソースを作成します。

    1. メニューの「挿入」→「リソース」で「リソースの挿入」ダイアログを開き、 「リソースの種類」から「Dialog」の中の「IDD_DIALOGBAR」を選び、OKボタンをクリックします。

    2. デフォルトのダイアログバーのエディタが開いたら、 まずIDを変更しておきましょう。

    3. そして、エディットボックスやらコンボボックスやらボタンコントロールやら、好きな物を載せて下さい。 やり方は、普通のダイアログと同じです。


  2. 次に、このダイアログバー用のクラスを作成します。

    1. ダイアログバーのエディタを開いた状態のままClassWizardを起ち上げると、 クラスを新規に追加するかどうか聞いてくるので、新規クラスを作成して下さい。

      この時、基本クラスとしてCDialogBarを選びたい所ですが、選択肢の中に無いので CDialogを選んでおきます。

      この例では、IDをIDD_DLG_TEST、クラス名をCTestDlgBar、ファイルをTestDlgBar.cpp、TestDlgBar.hとします。

    2. ソースファイルとヘッダファイルを開き、「CDialog」を「CDialogBar」に手で変えていきます。 「編集」→「置換」→「全て置換」を使えば、すぐです。

    3. コンストラクタの引数がCDialogBarとCDialogでは異なるので、直します。
      やる事は、引数を無くすだけです。

    TestDlgBar.h:

    class CTestDlgBar : public CDialogBar
    {
    // コンストラクション
    public:
    	CTestDlgBar();   // 標準のコンストラクタ
    〜
    };
    
    TestDlgBar.cpp:
    CTestDlgBar::CTestDlgBar()
    	: CDialogBar()
    {
    	//{{AFX_DATA_INIT(CTestDlgBar)
    		// メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。
    	//}}AFX_DATA_INIT
    }
    

  3. そして、ダイアログバーを表示する部分をコーディングします。
    やり方はいたって簡単で、CChildFrameクラスをいじります。

    1. ChildFrm.hの先頭で、TestDlgBar.hをインクルードします。

    2. CChildFrameに、ダイアログバーのオブジェクトを保持する為のメンバー変数を付加します。

    3. CChildFrameに、WM_CREATEメッセージのハンドラ(OnCreate関数)を追加します。

    4. OnCreateの中に、ダイアログバーを作成する命令を入れます。

    ChildFrm.h:

    #include "TestDlgBar.h"
    
    class CChildFrame : public CMDIChildWnd
    {
    〜
    // 生成したメッセージ マップ関数
    protected:
    	//{{AFX_MSG(CChildFrame)
    	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    
    private:
    	CTestDlgBar m_TestDlgBar;
    };
    

    ChildFrm.cpp:

    int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    	if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
    		return -1;
    
    	// TODO: この位置に固有の作成用コードを追加してください
    	m_TestDlgBar.Create(this,IDD_DLG_TEST,CBRS_TOP,IDD_DLG_TEST);
    
    	return 0;
    }
    

    ここまでやれば、コンパイル・実行するとダイアログバーが表示されるはずです。


さて、ダイアログバーは、通常のダイアログとは異なり いろいろ不便な制約があります。 でも書籍等で確認したわけでは無いので、もしかすると勘違いかも…


  1. ボタンコントロールの注意

    ボタンがクリックされた時のイベントは CDialogBarには来ないので、 CChildFrameの方にハンドラを作成します。
    しかしClassWizardでは、CChildFrameにダイアログバー上のコントロールのIDが表示されないので ハンドラを作る事が出来ません。仕方が無いので自分で書くか、 CDialogBar用に作成して、マクロやソースをCChildFrameに移す必要があります。
    この例では、ボタンコントロールのIDをIDC_BUTTON1としています。

    ChildFrm.h:

    class CChildFrame : public CMDIChildWnd
    {
    〜
    // 生成したメッセージ マップ関数
    protected:
    	//{{AFX_MSG(CChildFrame)
    	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    	//}}AFX_MSG
    	afx_msg void OnButton1();	//←これを追加
    	DECLARE_MESSAGE_MAP()
    〜
    };
    

    ChildFrm.cpp:

    〜
    BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
    	//{{AFX_MSG_MAP(CChildFrame)
    	ON_WM_CREATE()
    	//}}AFX_MSG_MAP
    	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)	//←これを追加
    END_MESSAGE_MAP()
    〜
    void CChildFrame::OnButton1() 
    {
    	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    }
    

    ちなみに、ボタンをクリックした時に、デバッグウィンドウに表示される 「Warning: no message line prompt for ID なんちゃら.」が気になる人は、 IDC_BUTTON1に対して、StringTableリソースを適当に割り当ててみて下さい。
    このリソースに記した文字列は、ボタンをクリックした時にステータスバーに表示されます。
    そして、デバッグウィンドウには何も出なくなるはずです。


  2. エディットボックスの注意

    DDVが使えないので、例えば「数値しか入れられないようにしよう」という事が出来ません。
    でもスピンコントロールをくっつける事は出来ます。

    値を取得したい時は、下の様にします。
    この例では、エディットボックスのIDをIDC_EDIT1としています。 ボタンがクリックされた時に値を取得するサンプルです。

    ChildFrm.cpp:

    void CChildFrame::OnButton1() 
    {
    	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    	CEdit *pEdit=(CEdit*)m_TestDlgBar.GetDlgItem(IDC_EDIT1);
    	CString str;
    	pEdit->GetWindowText(str);	//strに値が入って来る
    〜
    }
    

  3. コンボボックスの注意

    何故か、コンボボックスのメッセージはCDialogBarに送られてくるみたいです。
    したがって、素直にClassWizardを使う事が出来ます。

    この例では、コンボボックスのIDをIDC_COMBO1としています。

    TestDlgBar.h:

    class CTestDlgBar : public CDialogBar
    {
    〜
    	// 生成されたメッセージ マップ関数
    	//{{AFX_MSG(CTestDlgBar)
    	afx_msg void OnSelchangeCombo1();
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    〜
    };
    

    TestDlgBar.cpp:

    〜
    BEGIN_MESSAGE_MAP(CTestDlgBar, CDialogBar)
    	//{{AFX_MSG_MAP(CTestDlgBar)
    	ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1)
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    〜
    void CTestDlgBar::OnSelchangeCombo1() 
    {
    	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    	CComboBox *pCmb=(CComboBox*)GetDlgItem(IDC_COMBO1);
    	int nIndex=pCmb->GetCurSel();
    	if(nIndex!=CB_ERR){
    		CString str;
    		pCmb->GetLBText(nIndex,str);
    〜
    	}
    }
    

VC++ページへ戻る / 技術メモへ戻る
メールの送信先:ひしだま