1日でわかるMFC (GARAさんのページ)
Sample_D ダイアログボックスを持つWindowsプログラム
プログラム概要
・ 画面上でマウスを右クリックするとダイアログボックス(簡易電卓)を表示します。
・ ダイアログボックスを終了すると、計算結果をメインウィンドウに表示します。
共通ファイル
1)
Sample_D.h
#define MENU_NAME NULL // メニュー名
#define WIN_W 500 // Window の幅
#define WIN_H 220 // Window の高
#define WIN_X 100 // Window の水平座標
#define WIN_Y 50 // Window の垂直座標
// リソース
#define IDD_DIALOG1 101 // ダイアログID
#define IDC_EDIT1 301 // エディットボックスID
#define IDC_EDIT2 302 //
#define IDC_RADIO1 401 // ラジオボタンID
#define IDC_RADIO2 402 //
#define IDC_RADIO3 403 //
#define IDC_RADIO4 404 //
2)Sample_D.rc
#include <windows.h>
#include "Sample_D.h"
IDD_DIALOG1 DIALOG DISCARDABLE 50, 20, 120, 88
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "簡易電卓"
FONT 10, "MS ゴシック"
BEGIN
DEFPUSHBUTTON "計算", IDOK, 20, 68, 28, 14
PUSHBUTTON "キャンセル", IDCANCEL, 66, 68, 28, 14
EDITTEXT IDC_EDIT1, 16, 28, 22, 12
EDITTEXT IDC_EDIT2, 78, 28, 22, 12
CONTROL "+", IDC_RADIO1, "Button", BS_RADIOBUTTON, 50, 12, 16, 8
CONTROL "−", IDC_RADIO2, "Button", BS_RADIOBUTTON, 50, 24, 16, 8
CONTROL "×", IDC_RADIO3, "Button", BS_RADIOBUTTON, 50, 36, 16, 8
CONTROL "÷", IDC_RADIO4, "Button", BS_RADIOBUTTON, 50, 48, 16, 8
END
Sample_D1.c SDKのプログラム (緑色の部分は各 .c ファイル共通です)
/** Sample_D1.c:ダイアログボックスの使用 (by GARA) **/
#include <windows.h>
#include <stdio.h>
#include "Sample_D.h"
/* Define */
#define CLASS_NAME "Sample_D1Class" // クラス名
#define WIN_TITLE "Sample_D1" // タイトル
/* Global */
HINSTANCE hInst;
int gNum1;
int gNum2;
/* Proto Type */
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK DlgProc_1(HWND, UINT, WPARAM, LPARAM);
/* WinMain */
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
Sample_A1.c と同じ
}
/* ウィンドウクラスの登録 */
BOOL InitApplication(HINSTANCE hInstance)
{
Sample_A1.c と同じ
}
/* ウィンドウの作成と表示 */
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
Sample_A1.c と同じ
}
/* ウィンドウプロシージャ */
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
int ret;
int Num;
char WkBuf[80];
switch(uMsg) {
case WM_PAINT:
BeginPaint(hWnd, &ps);
hDC = ps.hdc;
TextOut(hDC, 10, 10, "SDK -> MFC", 10);
EndPaint(hWnd, &ps);
break;
case WM_RBUTTONDOWN: // マウス右ボタンのクリック
// モーダルダイアログボックスを作成
ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, (DLGPROC)DlgProc_1);
if(ret == 0)
break;
switch(ret) {
case 1: Num = gNum1 + gNum2;
break;
case 2: Num = gNum1 - gNum2;
break;
case 3: Num = gNum1 * gNum2;
break;
case 4: Num = gNum1 / gNum2;
break;
}
hDC = GetDC(hWnd);
sprintf(WkBuf, "答えは %d です", Num);
TextOut(hDC, LOWORD(lParam), HIWORD(lParam), WkBuf, strlen(WkBuf));
ReleaseDC(hWnd, hDC);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return(DefWindowProc(hWnd, uMsg, wParam, lParam));
}
return 0;
}
/* ダイアログプロシージャ */
LRESULT CALLBACK DlgProc_1(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int i, j;
char WkBuf[80];
switch(uMsg) { // メッセージ処理
case WM_INITDIALOG: // ダイヤログの初期処理
CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, IDC_RADIO1);
return TRUE;
case WM_COMMAND: // ダイヤログ内の処理
switch(LOWORD(wParam)) {
case IDC_RADIO1:
case IDC_RADIO2:
case IDC_RADIO3:
case IDC_RADIO4:
CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, LOWORD(wParam));
return TRUE;
case IDOK:
GetDlgItemText(hDlg, IDC_EDIT1, WkBuf, sizeof(WkBuf));
gNum1 = atoi(WkBuf);
GetDlgItemText(hDlg, IDC_EDIT2, WkBuf, sizeof(WkBuf));
gNum2 = atoi(WkBuf);
for(i = 0; i < 4; i ++) {
j = IsDlgButtonChecked(hDlg, IDC_RADIO1 + i);
if(j == BST_CHECKED)
break;
}
i ++;
if(i == 4 && gNum2 == 0) {
MessageBox(hDlg, "除数が誤りです ", "エラー", MB_OK);
SetFocus(GetDlgItem(hDlg, IDC_EDIT2));
return TRUE;
}
EndDialog(hDlg, i);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, 0);
return TRUE;
}
return FALSE;
}
return FALSE;
}
Sample_D2.cpp メインウィンドウをクラス化 (緑色の部分は各 .cpp ファイル共通です)
/** Sample_D2.cpp:ダイアログボックスの使用 (by GARA) **/
#include <afxwin.h>
#include <stdio.h>
#include "Sample_D.h"
/* Define */
#define CLASS_NAME "Sample_D2Class" // クラス名
#define WIN_TITLE "Sample_D2" // タイトル
/* Global */
int gNum1;
int gNum2;
/* Proto Type */
LRESULT CALLBACK DlgProc_1(HWND, UINT, WPARAM, LPARAM);
/* ウィンドウクラスの宣言 */
class CMainFrame : public CFrameWnd // ウィンドウクラス CWnd -> CFrameWnd
{
public:
// コンストラクタ
CMainFrame();
// メンバ関数
virtual BOOL PreCreateWindow(CREATESTRUCT&);
// メッセージハンドラ
afx_msg void OnPaint(); // WM_PAINT に対応
afx_msg void OnRButtonDown(UINT, CPoint); // WM_RBUTTONDOWN に対応
afx_msg void OnDestroy(); // WM_DESTROY に対応
DECLARE_MESSAGE_MAP()
};
/* メッセージマップの定義 */
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) // 第1引数:メッセージマップを所有するクラスの名前、第2引数:基本クラス名
ON_WM_PAINT()
ON_WM_RBUTTONDOWN()
ON_WM_DESTROY()
END_MESSAGE_MAP()
/* アプリケーションクラスの宣言 */
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance(); // インスタンスを初期化する関数
};
/* ウィンドウクラスのメンバ */
// コンストラクタ
CMainFrame::CMainFrame() // コンストラクタ
{
Create(NULL, ""); // ウィンドウの作成。第1引数:クラス名、第2引数:ウィンドウ名
}
// メンバ関数
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) // PreCreateWindow() のオーバーライド
{
Sample_A2.cpp と同じ
}
// メッセージハンドラ
void CMainFrame::OnPaint() // OnPaint() のオーバーライド
{
HWND hWnd;
HDC hDC;
PAINTSTRUCT ps;
hWnd = m_hWnd; // m_hWnd は CWnd のメンバ変数
::BeginPaint(hWnd, &ps); // ::(グローバルスコープ解決演算子)をつける
hDC = ps.hdc;
TextOut(hDC, 10, 10, "SDK -> MFC", 10);
::EndPaint(hWnd, &ps);
return;
}
void CMainFrame::OnRButtonDown(UINT wParam, CPoint pt) // OnRButtonDown() のオーバーライド
{
HINSTANCE hInst;
HWND hWnd;
HDC hDC;
int ret;
int Num;
char WkBuf[80];
hInst = AfxGetInstanceHandle(); // インスタンスハンドルの取得
hWnd = m_hWnd;
// モーダルダイアログボックスを作成
ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, (DLGPROC)DlgProc_1);
if(ret == 0)
return;
switch(ret) {
case 1: Num = gNum1 + gNum2;
break;
case 2: Num = gNum1 - gNum2;
break;
case 3: Num = gNum1 * gNum2;
break;
case 4: Num = gNum1 / gNum2;
break;
}
hDC = ::GetDC(hWnd);
sprintf(WkBuf, "答えは %d です", Num);
TextOut(hDC, pt.x, pt.y, WkBuf, strlen(WkBuf));
::ReleaseDC(hWnd, hDC);
return;
}
void CMainFrame::OnDestroy() // OnDestroy() のオーバーライド
{
PostQuitMessage(0);
return;
}
/* アプリケーションクラスのメンバ */
// メンバ関数
BOOL CMyApp::InitInstance() // InitInstance() のオーバーライド
{
m_pMainWnd = new CMainFrame(); // メインウィンドウの作成
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
/* アプリケーションの生成(実行)*/
CMyApp MyApp;
/* ダイアログプロシージャ */
LRESULT CALLBACK DlgProc_1(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int i, j;
char WkBuf[80];
switch(uMsg) { // メッセージ処理
case WM_INITDIALOG: // ダイヤログの初期処理
CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, IDC_RADIO1);
return TRUE;
case WM_COMMAND: // ダイヤログ内の処理
switch(LOWORD(wParam)) {
case IDC_RADIO1:
case IDC_RADIO2:
case IDC_RADIO3:
case IDC_RADIO4:
CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, LOWORD(wParam));
return TRUE;
case IDOK:
GetDlgItemText(hDlg, IDC_EDIT1, WkBuf, sizeof(WkBuf));
gNum1 = atoi(WkBuf);
GetDlgItemText(hDlg, IDC_EDIT2, WkBuf, sizeof(WkBuf));
gNum2 = atoi(WkBuf);
for(i = 0; i < 4; i ++) {
j = IsDlgButtonChecked(hDlg, IDC_RADIO1 + i);
if(j == BST_CHECKED)
break;
}
i ++;
if(i == 4 && gNum2 == 0) {
MessageBox(hDlg, "除数が誤りです ", "エラー", MB_OK);
SetFocus(GetDlgItem(hDlg, IDC_EDIT2));
return TRUE;
}
EndDialog(hDlg, i);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, 0);
return TRUE;
}
return FALSE;
}
return FALSE;
}
Sample_D3.cpp メインウィンドウとダイアログボックスをクラス化 (緑色の部分は各 .cpp ファイル共通です)
・ OnRButtonDown の TextOut() で CDC を使用しています。
/** Sample_D3.cpp:ダイアログボックスの使用 (by GARA) **/
#include <afxwin.h>
#include <stdio.h>
#include "Sample_D.h"
/* Define */
#define CLASS_NAME "Sample_D3Class" // クラス名
#define WIN_TITLE "Sample_D3" // タイトル
/* Global */
int gNum1;
int gNum2;
/* ウィンドウクラスの宣言 */
class CMainFrame : public CFrameWnd // ウィンドウクラス CWnd -> CFrameWnd
{
public:
// コンストラクタ
CMainFrame();
// メンバ関数
virtual BOOL PreCreateWindow(CREATESTRUCT&);
// メッセージハンドラ
afx_msg void OnPaint(); // WM_PAINT に対応
afx_msg void OnRButtonDown(UINT, CPoint); // WM_RBUTTONDOWN に対応
afx_msg void OnDestroy(); // WM_DESTROY に対応
DECLARE_MESSAGE_MAP()
};
/* メッセージマップの定義 */
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) // 第1引数:メッセージマップを所有するクラスの名前、第2引数:基本クラス名
ON_WM_PAINT()
ON_WM_RBUTTONDOWN()
ON_WM_DESTROY()
END_MESSAGE_MAP()
/* アプリケーションクラスの宣言 */
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance(); // インスタンスを初期化する関数
};
/* ダイアログクラスの宣言 */
class CDialog_1 : public CDialog // ウィンドウクラス CWnd -> CDialog
{
public:
// コンストラクタ
CDialog_1();
// メッセージハンドラ
afx_msg BOOL OnInitDialog(); // WM_INITDIALOG に対応
afx_msg void OnOk(); // OK ボタンに対応
afx_msg void OnCancel(); // Cancel ボタンに対応
afx_msg void OnRadio(UINT); // ラジオボタンに対応
DECLARE_MESSAGE_MAP()
};
/* ダイアログボックスのメッセージマップの定義 */
BEGIN_MESSAGE_MAP(CDialog_1, CDialog) // 第1引数:メッセージマップを所有するクラスの名前、第2引数:基本クラス名
// ON_WM_INITDIALOG // ON_WM_INITDIALOG は不要
ON_COMMAND(IDOK, OnOk)
ON_COMMAND(IDCANCEL, OnCancel)
ON_COMMAND_RANGE(IDC_RADIO1, IDC_RADIO4, OnRadio)
END_MESSAGE_MAP()
/* ウィンドウクラスのメンバ */
// コンストラクタ
CMainFrame::CMainFrame() // コンストラクタ
{
Create(NULL, ""); // ウィンドウの作成。第1引数:クラス名、第2引数:ウィンドウ名
}
// メンバ関数
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) // PreCreateWindow() のオーバーライド
{
Sample_A2.cpp と同じ
}
// メッセージハンドラ
void CMainFrame::OnPaint() // OnPaint() のオーバーライド
{
HWND hWnd;
HDC hDC;
PAINTSTRUCT ps;
hWnd = m_hWnd; // m_hWnd は CWnd のメンバ変数
::BeginPaint(hWnd, &ps); // ::(グローバルスコープ解決演算子)をつける
hDC = ps.hdc;
TextOut(hDC, 10, 10, "SDK -> MFC", 10);
::EndPaint(hWnd, &ps);
return;
}
void CMainFrame::OnRButtonDown(UINT wParam, CPoint pt) // OnRButtonDown() のオーバーライド
{
CDC *pDC;
int ret;
int Num;
char WkBuf[80];
// モーダルダイアログボックスを作成
CDialog_1 Dialog_1; // ダイアログボックスの作成
ret = Dialog_1.DoModal(); // ダイアログボックスを起動
if(ret == 0)
return;
switch(ret) {
case 1: Num = gNum1 + gNum2;
break;
case 2: Num = gNum1 - gNum2;
break;
case 3: Num = gNum1 * gNum2;
break;
case 4: Num = gNum1 / gNum2;
break;
}
pDC = GetDC(); // CWnd のメンバ関数
sprintf(WkBuf, "答えは %d です", Num);
pDC->TextOut(pt.x, pt.y, WkBuf, strlen(WkBuf)); // CDC のメンバ関数
ReleaseDC(pDC); // CWnd のメンバ関数
return;
}
void CMainFrame::OnDestroy() // OnDestroy() のオーバーライド
{
PostQuitMessage(0);
return;
}
/* アプリケーションクラスのメンバ */
// メンバ関数
BOOL CMyApp::InitInstance() // InitInstance() のオーバーライド
{
m_pMainWnd = new CMainFrame(); // メインウィンドウの作成
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
/* アプリケーションの生成(実行)*/
CMyApp MyApp;
/* ダイアログクラスのメンバ */
// コンストラクタ
CDialog_1::CDialog_1() : CDialog(IDD_DIALOG1) // コンストラクタ
{
}
// メッセージハンドラ
BOOL CDialog_1::OnInitDialog() // OnInitDialog() のオーバーライド
{
HWND hDlg;
hDlg = m_hWnd;
::CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, IDC_RADIO1);
return TRUE;
}
void CDialog_1::OnOk() // OnOk() のオーバーライド
{
HWND hDlg;
int i, j;
char WkBuf[80];
hDlg = m_hWnd;
::GetDlgItemText(hDlg, IDC_EDIT1, WkBuf, sizeof(WkBuf));
gNum1 = atoi(WkBuf);
::GetDlgItemText(hDlg, IDC_EDIT2, WkBuf, sizeof(WkBuf));
gNum2 = atoi(WkBuf);
for(i = 0; i < 4; i ++) {
j = ::IsDlgButtonChecked(hDlg, IDC_RADIO1 + i);
if(j == BST_CHECKED)
break;
}
i ++;
if(i == 4 && gNum2 == 0) {
::MessageBox(hDlg, "除数が誤りです ", "エラー", MB_OK);
::SetFocus(::GetDlgItem(hDlg, IDC_EDIT2));
return;
}
// ::EndDialog(hDlg, i); // 第2引数をダイアログボックス作成側で取得できない。
EndDialog(i); // CDialog のメンバ関数
return;
}
void CDialog_1::OnCancel() // OnCancel() のオーバーライド
{
HWND hDlg;
hDlg = m_hWnd;
// ::EndDialog(hDlg, 0); // 第2引数をダイアログボックス作成側で取得できない。
EndDialog(0); // CDialog のメンバ関数
return;
}
void CDialog_1::OnRadio(UINT wParam) // 独自メンバー関数(オーバーライドでない)
{
HWND hDlg;
hDlg = m_hWnd;
::CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO4, LOWORD(wParam));
return;
}
BACK TOP