概要

ラジオボタンのサンプルです。
ラジオボタンの選択状態が変化するとリアルタイムにラベルに反映されます。
OKボタンをクリックするとコンボボックスで選択されている文字列をメッセージボックスを表示し、メッセージボックスのOKをクリックするとプログラムが終了します。
キャンセルボタンをクリックするとプログラムが終了します。
ダイアログボックスはリソースファイル(resource.rc)で定義しています。
ラジオボタンは、ダイアログボックスの子ウィンドウです。

ラジオボタンの属性はリソースファイルで定義しております。(1行のみ抽出して本文に記述)

CONTROL "男"  , IDC_RADIOBOX101, "BUTTON", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP, 14,21, 32, 14
性別と料金は違うカテゴリーであり、ラジオボタンは独立して動作する必要があります。
BS_AUTORADIOBUTTON属性を指定しWS_GROUPを指定すると次に現れるWS_GROUPまでの複数のラジオボタンのうち1個のみがチェックでき、チェック時には自動的に他のラジオボタンが非チェック状態になります。
WS_GROUPを2回指定することにより性別と料金が独立してチェックするようにできます。WS_GROUPを指定しないと全部のラジオボタンのうち1個しかチェックできなくなります。
複数の属性を適用するにはOR演算子 | を使用します。

ラジオボタンへのメッセージ

ラジオボタンへのメッセージは以下のようなものがあります。
hWndはラジオボタンのハンドル

ラジオボタンをチェック状態にする

SendMessage(hWnd, BM_SETCHECK, BST_CHECKED, 0);

ラジオボタンを非チェック状態にする

SendMessage(hWnd, BM_SETCHECK, BST_UNCHECKED, 0);

ラジオボタンのチェック状態を取得する

SendMessage(hWnd, BM_GETCHECK, 0, 0);
// 戻り値
// BST_UNHECKED 非チェック
// BST_INDETERMINATE グレイ
// BST_CHECKED チェック状態

テスト環境

コンパイラ

Visual C++ 2008 Standard 32/64bit
Visual C++ 2013 Express 32/64bit

実行環境

Windows 8.1 Enterprise 64bit
Windows 7 EnterPrise Service Pack 1 64bit
Windows Vista Ultimate Service Pack 2 32bit
Windows XP Professional Service Pack 3 32bit

プログラムソースの概要

radiobutton.cpp

_tWinMain

DialogBox APIを呼び出してモーダルダイアログボックスを表示します。

DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)

ダイアログボックスプロシージャーです。
必要な時にWindowsから呼び出されます。
第2引数にメッセージの種類が格納されていますので、switchステートメントによりメッセージごとの処理を振り分けます。
コントロール(ダイアログボックスに張り付けられているラジオボタンやプッシュボタン等 コントロールと呼ぶ)を操作するには、コントロールのハンドルが必要です。 ダイアログボックスのコントロール(子ウィンドウ)のハンドルを取得するには、 GetDlgItem APIを呼び出し、ダイアログボックスのハンドルとコントロールのID番号よりハンドルを取得します。
自分で処理しないメッセージは、ダイアログボックスプロシージャー終了時にFALSEを渡せば、Windowsが標準的な処理を行ってくれます。
case WM_INITDIALOG:
ダイアログボックスの初期化時に発生するメッセージです。
ここでは、ラジオボタンの初期状態を設定します。
SendMessage APIを呼び出しBM_SETCHECKメッセージによりラジオボタンの男と子供にチェックを入れます。
case WM_COMMAND:
ダイアログボックスの子ウィンドウ(ダイアログボックスに張り付けられているラジオボタンやプッシュボタン等)から発生したメッセージが届きます。
ダイアログボックスプロシージャーの第3引数であるWPARAMの下位16bitがコントロールのID番号、その上位16bitには通知内容が格納されています。
LOWORDマクロによりWPARAMの下位16bitを取り出し、switchステートメントによりコントロールごとに処理を振り分けます。
case IDC_RADIOBUTTON1nn:
ラジオボタンのID番号がです。IDC_RADIOBUTTON1nn
ラジオボタンからのメッセージが届きます。
ここではラジオボタンがクリックされたときに発生するBN_CLICKEDメッセージを処理します。
HIWORDマクロによりWPARAMの31~16bitの値を取り出し、ifステートメントによりのBN_CLICKED時 SetWindowText APIを呼び出し、ラベルに該当するテキストを表示します。
case IDOK:
OKプッシュボタンのID番号がIDOKです。
OKプッシュボタンをクリックするとこのメッセージが発生します。
リソースファイルでBS_DEFPUSHBUTTONと定義していますのでディフォルトプッシュボタンとなります。
ENTERキーを押した場合もこのメッセージが発生します。
SendMessage APIを呼び出し、BST_CHECKEDメッセージによりラジオボタンのチェック状態を調べます。
チェック状態により文字列を作成し、MessageBox APIを呼び出し結果を表示新す。 EndDialog APIを呼び出し、ダイアログボックスを終了させます。 このAPIの第2引数は、ダイアログボックスが終了し、DialogBox APIが返す値となります。
case IDCANCEL:
キャンセルプッシュボタンのID番号がIDCANCELKです。
キャンセルプッシュボタンをクリックするとこのメッセージが発生します。
ダイアログボックスの閉じるボタンまたはESCキーを押した場合もこのメッセージが発生します。
EndDialog APIを呼び出し、ダイアログボックスを終了させます。 このAPIの第2引数は、ダイアログボックスが終了し、DialogBox APIが返す値となります。

resource.h

ダイアログボックスで使用する各コントロールのID値をマクロで定義しています。

resource.rc

ダイアログボックスやコントロールの定義をしています。

プログラムソース

radiobutton.cpp


//      ラジオボタンサンプル
//      Visual C++ 2013 32/64bit

#include <windows.h>
#include <commctrl.h> 
#include <tchar.h>
#include "resource.h"

//      ダイアログボックスプロシージャー
LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);


int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
        TCHAR* lpszCmdLine, int nCmdShow){
        DialogBox(hInstance, TEXT("DLG1"), 0, (DLGPROC)DlgProc1);

        return (int)0;
}

//      ダイアログボックスプロシージャー

LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
        TCHAR buf[32];
        switch (msg) {
        case WM_INITDIALOG:
                SendMessage(GetDlgItem(hDlg, IDC_RADIOBUTTON101), BM_SETCHECK, BST_CHECKED, 0);
                SendMessage(GetDlgItem(hDlg, IDC_RADIOBUTTON111), BM_SETCHECK, BST_CHECKED, 0);
                return TRUE;
        case WM_COMMAND:
                switch (LOWORD(wParam)) {
                case IDC_RADIOBUTTON101:
                        if(HIWORD(wParam) == BN_CLICKED){
                                SetWindowText(GetDlgItem(hDlg, IDC_LABEL103), _TEXT("男"));
                        }
                        return FALSE;
                case IDC_RADIOBUTTON102:
                        if (HIWORD(wParam) == BN_CLICKED){
                                SetWindowText(GetDlgItem(hDlg, IDC_LABEL103), _TEXT("女"));
                        }
                        return FALSE;
                case IDC_RADIOBUTTON111:
                        if (HIWORD(wParam) == BN_CLICKED){
                                SetWindowText(GetDlgItem(hDlg, IDC_LABEL113), _TEXT("子供"));
                        }
                        return FALSE;
                case IDC_RADIOBUTTON112:
                        if (HIWORD(wParam) == BN_CLICKED){
                                SetWindowText(GetDlgItem(hDlg, IDC_LABEL113), _TEXT("大人"));
                        }
                        return FALSE;
                case IDOK:
                        if (SendMessage(GetDlgItem(hDlg, IDC_RADIOBUTTON101), BM_GETCHECK, 0, 0) == BST_CHECKED)
                                _tcscpy_s(buf,sizeof(buf)/sizeof(TCHAR), _TEXT("男 "));
                        else
                                _tcscpy_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("女 "));

                        if (SendMessage(GetDlgItem(hDlg, IDC_RADIOBUTTON111), BM_GETCHECK, 0, 0) == BST_CHECKED)
                                _tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("子供"));
                        else
                                _tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("大人"));
                        MessageBox(hDlg, buf, _TEXT("ラジオボタンの状態"), MB_OK);
                        EndDialog(hDlg, TRUE);
                        return TRUE;
                case IDCANCEL:
                        EndDialog(hDlg, FALSE);
                        return FALSE;
                default:
                        return FALSE;
                }
        default:
                return FALSE;
        }
        return TRUE;
}

resource.h


#define IDC_GROUPBOX100         100
#define IDC_RADIOBUTTON101              101
#define IDC_RADIOBUTTON102              102
#define IDC_LABEL103            103

#define IDC_GROUPBOX110         110
#define IDC_RADIOBUTTON111              111
#define IDC_RADIOBUTTON112              112
#define IDC_LABEL113            113

resource.rc


#include <windows.h>
#include "resource.h"

DLG1 DIALOG DISCARDABLE 0, 0, 129, 147
EXSTYLE WS_EX_DLGMODALFRAME
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SETFONT
CAPTION "ラジオボタン"
FONT 9, "MS Shell Dlg"
{
 CONTROL "性別", IDC_GROUPBOX100, "BUTTON", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 7, 7, 85, 35
 CONTROL "男"  , IDC_RADIOBUTTON101, "BUTTON", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP, 14,21, 32, 14
 CONTROL "女"  , IDC_RADIOBUTTON102, "BUTTON", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 53, 21, 32, 14
 CONTROL "男"  , IDC_LABEL103, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 100, 23, 128, 14

 CONTROL "料金", IDC_GROUPBOX110, "BUTTON", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 7, 56, 85, 35
 CONTROL "子供", IDC_RADIOBUTTON111, "BUTTON", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP, 14, 70, 32, 14
 CONTROL "大人", IDC_RADIOBUTTON112, "BUTTON", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 53, 70, 32, 14
 CONTROL "子供", IDC_LABEL113, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 100, 72, 128, 14

 CONTROL "OK", IDOK, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 7, 126, 54, 14
 CONTROL "キャンセル", IDCANCEL "BUTTON", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 68, 126, 54, 14
}

ソースファイルと実行ファイルのダウンロード

ダウンロード radiobutton.zip(37.6kByte)

ZIPファイルに含まれるファイル

radiobutton.cpp
radiobutton.exe
resource.h
resource.rc