MFC:手動でモーダルダイアログアプリケーションを作成する

MFCにおいて、モーダルダイアログアプリケーションを生成する際は、Visual Studioのガイドに従ってドラッグ&ドロップを行うだけで簡単に作成できます。しかし今回はその逆のアプローチを取り、手動で同様の機能を持つプログラムを構築します。この方法により、自動生成されたコードの理解力を深めることができます。 以下の手順とコードで実装します: 0. Win32空プロジェクトを作成し、ダイアログなどのリソースを追加します。 リソース追加手順: a. リソースファイルを右クリック→追加→リソース→ダイアログ→新規作成(ダイアログを右クリック→プロパティでIDがIDD_DIALOG1であることが確認できます); b. ビュー→ツールボックスからエディットコントロールを追加し、右クリック→プロパティでIDがIDC_EDIT1であることを確認; c. ツールボックスからボタンを追加し、右クリック→プロパティでラベルを「コントロール→変数」に変更し、IDがIDC_BUTTON1であることを確認; d. 同様にボタンをもう一つ追加し、ラベルを「変数→コントロール」に設定し、IDはIDC_BUTTON2となります。 これらのIDはリソースの一意な識別子であり、後で使用します。簡単のため、「OK」、「キャンセル」ボタンは削除します。

  1. 環境設定 プロジェクト→プロパティ→構成プロパティ→高度→マルチバイト文字セットを使用 プロジェクト→プロパティ→構成プロパティ→リンカ→システム→Windowsアプリケーション
  2. ソリューションエクスプローラー→ソースファイルを右クリック→cppファイルを追加し、mdlDlg.cppという名前を付ける。以降のすべてのコードはこのファイルに記述します。 mdlDlg.cppでは、ヘッダファイル<afxwin.h>と"resource.h"を含める。resource.hはダイアログリソース追加時に自動生成されます。コードは以下の通りです:
#include<afxwin.h>
#include"resource.h"
  1. CDialogクラスを継承したカスタムダイアログクラスCMyDlgの宣言 a. クラス内にメッセージマップマクロを宣言し、クラス外で実装 b. コンストラクタ(親クラスのコンストラクタを明示的に呼び出し、ダイアログリソースIDを引数として渡す) c. 必要なデータメンバを宣言。ここでは以下の2つのオブジェクトを定義: CString m_strEdit; //データ型オブジェクト、つまり「変数」 CEdit m_ctrlEdit; //コントロール型オブジェクト、つまり「コントロール」 d. 親クラスの仮想関数DoDataExchangeを宣言し、クラス外で再定義実装。関数パラメータCDataExchange* pDXは構造体。 e. クラス内にメッセージハンドラ関数を宣言(2つのボタンがクリックされたときの処理)し、クラス外で実装。 関連する関数:UpdateData(BOOL bool); 引数=TRUE: コントロールから変数へデータ転送;引数=FALSE: 逆方向。この関数は内部でDoDataExchangeを呼び出します。 この部分のコードとコメントは以下の通りです:
class CMyDlg :public CDialog {
public:
	DECLARE_MESSAGE_MAP() //メッセージマップマクロの宣言
	enum { IDD = IDD_DIALOG1 };
public:
	CMyDlg() :CDialog(IDD) {};//
public:
	CString m_strEdit;//データ型オブジェクト
	CEdit m_ctrlEdit;//コントロール型オブジェクト
	virtual void DoDataExchange(CDataExchange* pDX);//親クラスのDoDataExchangeの再定義
public:
	afx_msg void OnBtn1(); //ボタン1クリック時の処理
	afx_msg void OnBtn2(); //ボタン2クリック時の処理
};
void CMyDlg::OnBtn1() {
	UpdateData(TRUE);//DoDataExchangeを呼び出し、エディットコントロールの内容を変数m_strEditに転送
	AfxMessageBox(m_strEdit);
}
void CMyDlg::OnBtn2() {
	m_strEdit = "初期値";
	UpdateData(FALSE);//DoDataExchangeを呼び出し、変数の内容をエディットコントロールに表示
}

void CMyDlg::DoDataExchange(CDataExchange* pDX) {//アプリケーション起動時に自動的に呼び出される
	DDX_Text(pDX, IDC_EDIT1, m_strEdit);//自動生成ツールによって追加される関数
	DDX_Control(pDX, IDC_EDIT1, m_ctrlEdit);
}

BEGIN_MESSAGE_MAP(CMyDlg, CDialog) //メッセージマップマクロの実装
	ON_BN_CLICKED(IDC_BUTTON1, OnBtn1) 
	ON_BN_CLICKED(IDC_BUTTON2, OnBtn2) 
END_MESSAGE_MAP()
  1. CWinAppを継承したカスタムアプリケーションクラスCMyWinAppの宣言 クラス内にInitInstance仮想関数を宣言し、クラス外で実装: <1>. カスタムダイアログクラスのオブジェクトを宣言 <2>. ダイアログオブジェクトのアドレスをm_pMainWndに代入 <3>. ダイアログクラスのDoModal()メンバ関数を呼び出し、モーダルダイアログを表示。モーダルダイアログは応答を必須とするため、続行できない。非モーダルダイアログは応答しなくてもプログラムは継続可能。 <4>. return FALSE
  2. 自作アプリケーションクラスのオブジェクトを宣言。 上記のコードとコメントは以下の通りです:
class CMyWinApp :public CWinApp {
public:
	virtual BOOL InitInstance();
};
BOOL CMyWinApp::InitInstance() { //初期化関数の再定義
	CMyDlg dlg;
	m_pMainWnd = &dlg;
	dlg.DoModal(); //ダイアログを表示
	return FALSE;
}
CMyWinApp theApp; //グローバルアプリケーションオブジェクト、main関数はこれに含まれる
  1. 実行結果:

実行すると以下の画面が表示されます。 エディットボックスにテキストを入力し、「コントロール→変数」ボタンをクリックすると、変数の内容が表示されるメッセージボックスが現れます。入力した内容が表示されます。 「変数→コントロール」ボタンをクリックすると、エディットボックスの内容が初期値に戻ります。

タグ: MFC ダイアログ モーダル win32 VisualStudio

7月4日 22:07 投稿