1日でわかるMFC (GARAさんのページ)
BACK  
 Sample_D ダイアログボックスを持つWindowsプログラム

Sample_D1.c はSDKのプログラムです。
Sample_D2.cpp はメインウィンドウのみクラス化しています。
Sample_D3.cpp はメインウィンドウとダイアログボックスをクラス化しています。

プログラム概要
・ 画面上でマウスを右クリックするとダイアログボックス(簡易電卓)を表示します。
・ ダイアログボックスを終了すると、計算結果をメインウィンドウに表示します。



共通ファイル
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 ファイル共通です)
TOP  
/** 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 ファイル共通です)
TOP  
/** 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 ファイル共通です)
TOP  
・ 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