第31章 ラジオボタン


今回は、前章で出てきたラジオボタンについての解説を します。ラジオボタンについては、なぜか入門書に あまり解説が載っていないように思います。 ラジオボタンの特徴は、そのグループでただ1つだけ オンにできるということです。A,B,Cというボタンが 同じグループでもしAがオンになっていたらBやCはオンに なることができません。 ラジオボタンのオン・オフの設定はマクロを使うか、 SendMessage関数を使います。

Button_SetCheck(GetDlgItem(hWnd, IDC_RED), BST_CHECKED);

これで、IDC_REDがオンにセットされます。 関数では

((void)SendMessage((hwndCtl), BM_SETCHECK, (WPARAM)(int)(check), 0L));

となります。(check)のところにBST_CHECKEDまたは、BST_UNCHECKEDがきます。 これに対して、ボタンの状態を取得するには、

Button_GetCheck(hwndCtl);

関数では、

((int)(DWORD)SendMessage((hwndCtl), BM_GETCHECK, 0L, 0L));

もし、オンになっていれば、BST_CHECKEDを返します。オフならBST_UNCHECKEDを返します。

つぎに、リソースエジタでこれらのボタンの、 グループを決める方法ですが、まず同一のグループにしたい ボタンのタブオーダーが並んでいる必要があります。 タブオーダーは、「レイアウト」「タブオーダーの設定」で 決めることができます。モードレスダイアログボックスで タプオーダーを有効にするには (タブを押したときに実際にそのとおりにフォーカスを移動させるには) 前章で示したメッセージループの書き換えが必要です。

赤、青、緑のラジオボタンは同一グループなので、 1,2,3というように並んでいます。 そして、先頭の赤のプロパティに「グループ」を 設定します。(他の物にはグループを設定してはいけません) 次に、明朝、ゴシックは同一グループなので4,5番と 続き番号になっています。そして、先頭の明朝に「グループ」 を設定します。そして、このままだと4番以降がすべて 同一グループと見なされるので、6番にも「グループ」を設定します。
では、プログラムの方を少し解説します。 ダイアログプロシージャから見ていきましょう。

LRESULT CALLBACK MyDlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { static HWND hParent; hParent = GetParent(hWnd); switch (msg) { case WM_INITDIALOG: SetMyDlg(hWnd); return TRUE; case WM_COMMAND: switch(LOWORD(wp)) { case IDOK: GetMyDlg(hWnd); InvalidateRect(hParent, NULL, TRUE); return TRUE; case IDCANCEL: SendMessage(hParent, WM_CLOSE, 0, 0L); return TRUE; } } return FALSE; }

ダイアログボックスの初期化のところで自作関数の SetMyDlg関数を呼んでいます。 これは、

int SetMyDlg(HWND hWnd) { Button_SetCheck(GetDlgItem(hWnd, IDC_RED), BST_CHECKED); Button_SetCheck(GetDlgItem(hWnd, IDC_MIN), BST_CHECKED); GetMyDlg(hWnd); InvalidateRect(hWnd, NULL, TRUE); return 0; }

のようになっています。ダイアログボックスが作られるとすぐに 「あか」と「明朝体」ボタンがチェックされた状態にしておきます。 そして、自作関数のGetMyDlg関数を呼び出します。 これは、

int GetMyDlg(HWND hWnd) { int i, id[5]; id[0] = IDC_RED; id[1] = IDC_GREEN; id[2] = IDC_BLUE; id[3] = IDC_MIN; id[4] = IDC_GO; for (i = 0; i <= 4; i++) nCF[i] = Button_GetCheck(GetDlgItem(hWnd, id[i])); return 0; }

のようになっています。 ボタンの状態をチェックしてそれをグローバル変数のnCFに代入します。 この値をみて、ウィンドウプロシージャの WM_PAINTのところで描画を行うという物です。

また、「更新」ボタン(IDOK)が押されたら、InvalidateRect関数を 使って、クライアント領域の再描画をさせています。

「終了」(IDCANCEL)ボタンが押されたら、親ウィンドウに WM_CLOSEメッセージを送ってプログラムを終了するようにしています。

次に、ウィンドウプロシージャを見てみましょう。

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; HDC hdc; PAINTSTRUCT ps; static HFONT hFont, hFontOld; switch (msg) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); if (nCF[0] > 0) SetTextColor(hdc, RGB(255, 0, 0)); if (nCF[1] > 0) SetTextColor(hdc, RGB(0, 255, 0)); if (nCF[2] > 0) SetTextColor(hdc, RGB(0, 0, 255)); if (nCF[3] > 0) hFont = SetMyFont("MS 明朝"); hFontOld = SelectObject(hdc, hFont); if (nCF[4] > 0) hFont = SetMyFont("MS ゴシック"); hFontOld = SelectObject(hdc, hFont); DrawMyText(hdc); SelectObject(hdc, hFontOld); DeleteObject(hFont); EndPaint(hWnd, &ps); break; case WM_CLOSE: id = MessageBox(hWnd, (LPCSTR)"終了してもよいですか", (LPCSTR)"終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { DestroyWindow(hDlg); DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; }

WM_PAINTが来たら、グローバル変数のnCFを調べて、描画する内容を 変えています。ところで、BST_CHECKEDは1と定義されています。 BST_UNCHECKEDは0と定義されています。 if (nCF[0] > 0)は、if (nCF[0] == BST_CHECKED)と同じことです。 また、TRUEは1,FALSEは0と定義されているのでif (nCF[0] == TRUE) としても同じことです。 さて、このような説明でラジオボタンの使い方がわかったでしょうか。


[SDK Index] [総合Index] [Previous Chapter] [Next Chapter]

Update May/10/1997 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。