今回はMFCアプリで頻繁に使うコントロールの一つ、
CButtonクラスの操作方法について。
自分がよく使う操作の備忘録です。
準備
プロジェクト作成
プロジェクトの作成方法、コントロールの配置方法は
こちらをご覧ください。
今回のプロジェクト名は「CButtonTest」にします。
コントロールID
今回は、コントロールを3種類用意します。
ボタン、チェックボックス、ラジオボタンです。
ラジオボタンは2つ用意します。
それぞれを配置後、IDを変更します。
変更方法は、以前CStaticの操作時に書いてますのでご参考に。
今回はボタンをIDC_BUTTON_TEST、
チェックボックスをIDC_CHECK_TEST、
ラジオボタンをIDC_RADIO_TEST1、IDC_RADIO_TEST2に設定します。
ビルド
一度ビルドしておきます。

テキスト設定
今回もGetDlgItem方式で進めていきます。
プロジェクト名をCButtonTestで作成したので、
CButtonTestDlg.cppを開きます。
OnInitDialog内に処理を記述。
BOOL CCButtonTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CButton* pButton = (CButton*)GetDlgItem(IDC_BUTTON_TEST); // ボタンポインタ
pButton->SetWindowText(_T("ボタン変更"));
pButton = (CButton*)GetDlgItem(IDC_CHECK_TEST); // チェックボックスポインタ
pButton->SetWindowText(_T("チェックボックス変更"));
pButton = (CButton*)GetDlgItem(IDC_RADIO_TEST1); // ラジオボタン1ポインタ
pButton->SetWindowText(_T("ラジオボタン1変更"));
pButton = (CButton*)GetDlgItem(IDC_RADIO_TEST2); // ラジオボタン2ポインタ
pButton->SetWindowText(_T("ラジオボタン2変更"));
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}テキストを変更できます。

状態変更
チェックボックス、ラジオボタンには、
チェックされている状態、されていない状態があります。
まずはチェックを付けてみます。
チェック状態設定
BOOL CCButtonTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_TEST); // チェックボックスポインタ
pButton->SetCheck(BST_CHECKED); // チェックボックスにチェックします
pButton = (CButton*)GetDlgItem(IDC_RADIO_TEST1); // ラジオボタン1ポインタ
pButton->SetCheck(BST_CHECKED); // ラジオボタン1にチェックします
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}これでビルドしてみます。
初期状態は、チェックボックスとラジオボタン1にチェックが入ってます。

もちろん、この後手動でチェックを付け外しできます。
チェック状態を外すのは、
引数をBST_UNCHECKEDにすればチェックが外れます。
イベント処理
リソースから画面を出します。
その後、各ボタンを選択し、
右クリックから「イベントハンドラーの追加」を選択します。

クラスの一覧は、対象とするクラスに変更するのを忘れずに。
メッセージの種類はBN_CLICKEDです。
これはボタン・チェックボックス・ラジオボタンが押されたときに呼ばれる関数です。
4種類のコントロールに追加してみます。
CButtonTestDlg.cppに、4つ関数が自動で追加されます。
void CCButtonTestDlg::OnBnClickedButtonTest()
{
// TODO: ここにコントロール通知ハンドラー コードを追加します。
}
void CCButtonTestDlg::OnBnClickedCheckTest()
{
// TODO: ここにコントロール通知ハンドラー コードを追加します。
}
void CCButtonTestDlg::OnBnClickedRadioTest1()
{
// TODO: ここにコントロール通知ハンドラー コードを追加します。
}
void CCButtonTestDlg::OnBnClickedRadioTest2()
{
// TODO: ここにコントロール通知ハンドラー コードを追加します。
}メッセージを追加して、実際に動作を見てみます。
/**
* @fn
* @brief ボタンが押されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedButtonTest()
{
AfxMessageBox(_T("ボタンが押されました。"));
}
/**
* @fn
* @brief チェックボックスが変更されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedCheckTest()
{
AfxMessageBox(_T("チェックボックスが変更されました。"));
}
/**
* @fn
* @brief ラジオボタン1が押されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedRadioTest1()
{
AfxMessageBox(_T("ラジオボタン1が押されました。"));
}
/**
* @fn
* @brief ラジオボタン2が押されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedRadioTest2()
{
AfxMessageBox(_T("ラジオボタン2が押されました。"));
}ここで一度ビルドします。
ボタンを押すと、メッセージボックスが出現します。

他のコントロールも同じなので、試してみてください。
各メッセージボックス表示関数はもう必要ないので、
コメントアウトします。
状態取得
チェック状態を取得します。
今回は、ボタンが押されるとチェックボックス・ラジオボタンのチェック状態を取得してみます。
先ほど作った、ボタン押下時に呼ばれる関数内に記述。
/**
* @fn
* @brief ボタンが押されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedButtonTest()
{
//AfxMessageBox(_T("ボタンが押されました。"));
// チェックボックス状態取得
CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_TEST); // チェックボックスポインタ
if (pButton->GetCheck() == BST_CHECKED)
{
// チェックボックスはチェック状態
AfxMessageBox(_T("チェックボックスにチェックがあります"));
}
else
{
// チェックボックスはチェックされていない
AfxMessageBox(_T("チェックボックスにチェックがありません"));
}
// ラジオボタン状態取得
pButton = (CButton*)GetDlgItem(IDC_RADIO_TEST1); // ラジオボタン1ポインタ
if (pButton->GetCheck() == BST_CHECKED)
{
// ラジオボタン1はチェック状態
AfxMessageBox(_T("ラジオボタン1が選択されています"));
}
else
{
// ラジオボタン1はチェックされていない
AfxMessageBox(_T("ラジオボタン1が選択されていません"));
}
}ポインタ->GetCheckで状態を取得できます。
戻り値がBST_CHECKEDならばチェックされており、
BST_UNCHECKEDならばチェックされていません。
ビルドして確認です。
チェックボックス、ラジオボタン1にチェックがある状態でボタンを押してみます。


ちゃんとチェック状態を取得してくれました。
両方ともチェックがない場合は


こちらも取得できました。
色々な動作を組み合わせ
OnInitDialog、さらに今回追加した4つの関数(押されたときに呼ばれる関数)を使い、
色々処理を書いてみます。
こんな処理を作ってみました。
/**
* @fn
* @brief 初期表示処理
* @param なし
* @return BOOL TRUE
*/
BOOL CCButtonTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
SetWindowText(_T("ボタンを押してみよう!!"));
CButton* pButton = (CButton*)GetDlgItem(IDC_BUTTON_TEST); // ボタンポインタ
pButton->SetWindowText(_T("ここを押す"));
pButton = (CButton*)GetDlgItem(IDC_CHECK_TEST); // チェックボックスポインタ
pButton->SetWindowText(_T("チェック状態を考えよう!"));
pButton = (CButton*)GetDlgItem(IDC_RADIO_TEST1); // ラジオボタン1ポインタ
pButton->SetWindowText(_T("ラジオボタン1"));
pButton = (CButton*)GetDlgItem(IDC_RADIO_TEST2); // ラジオボタン2ポインタ
pButton->SetWindowText(_T("ラジオボタン2"));
pButton = (CButton*)GetDlgItem(IDC_BUTTON_TEST);
pButton->EnableWindow(FALSE); // 初期状態で、ボタンは非活性に
pButton = (CButton*)GetDlgItem(IDC_RADIO_TEST1);
pButton->EnableWindow(FALSE); // 初期状態で、ラジオボタン1は非活性に
pButton = (CButton*)GetDlgItem(IDC_RADIO_TEST2);
pButton->EnableWindow(FALSE); // 初期状態で、ラジオボタン2は非活性に
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
/**
* @fn
* @brief ボタンが押されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedButtonTest()
{
AfxMessageBox(_T("成功です!!"));
}
/**
* @fn
* @brief チェックボックスが変更されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedCheckTest()
{
// ポインタ宣言
CButton* pButton = (CButton*)GetDlgItem(IDC_BUTTON_TEST);
CButton* pButtonCheck = (CButton*)GetDlgItem(IDC_CHECK_TEST);
CButton* pButtonRadio1 = (CButton*)GetDlgItem(IDC_RADIO_TEST1);
CButton* pButtonRadio2 = (CButton*)GetDlgItem(IDC_RADIO_TEST2);
// チェックボックスの状態により、ラジオボタン押下可否を設定
if (pButtonCheck->GetCheck() == BST_CHECKED)
{
// チェックされました。⇒ラジオボタン1だけ押下可能に
pButtonRadio1->EnableWindow(TRUE);
pButton->EnableWindow(FALSE);
pButtonRadio2->EnableWindow(FALSE);
// ラジオボタンは初期化します
pButtonRadio1->SetCheck(BST_UNCHECKED);
pButtonRadio2->SetCheck(BST_UNCHECKED);
}
else
{
// ラジオボタン2がチェックされてる⇒ボタンが押せるように!!
if (pButtonRadio2->GetCheck() == BST_CHECKED)
{
pButton->EnableWindow(TRUE);
pButtonRadio1->EnableWindow(FALSE);
}
else
{
// ラジオボタン2が選択されてない場合、初めからやり直し
pButton->EnableWindow(FALSE);
pButtonRadio1->EnableWindow(FALSE);
pButtonRadio2->EnableWindow(FALSE);
// ラジオボタンは初期化します
pButtonRadio1->SetCheck(BST_UNCHECKED);
pButtonRadio2->SetCheck(BST_UNCHECKED);
}
}
}
/**
* @fn
* @brief ラジオボタン1が押されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedRadioTest1()
{
CButton* pButtonRadio1 = (CButton*)GetDlgItem(IDC_RADIO_TEST1);
if (pButtonRadio1->GetCheck() == BST_CHECKED)
{
// ラジオボタン1が選択されると、ラジオボタン2が押せるようになる
CButton* pButtonRadio2 = (CButton*)GetDlgItem(IDC_RADIO_TEST2);
pButtonRadio2->EnableWindow(TRUE);
}
}
/**
* @fn
* @brief ラジオボタン2が押されると呼ばれる
* @param なし
* @return なし
*/
void CCButtonTestDlg::OnBnClickedRadioTest2()
{
// 特にイベントは起こらない
}これだけ長いと、
CStaticクラス操作時に説明したDDX_Control方式の方がソース量少ないかもしれませんね。
仕様としては、
- 初期状態は、チェックボックスだけ操作可能
- ボタンを押すとクリア
- チェックボックスにチェックを付けると、ラジオボタン1が押せる
- ラジオボタン1を押すと、ラジオボタン2が押せる
- ラジオボタン2が押された状態でチェックボックスのチェックを外すと、
ボタンが押せるようになる - ラジオボタン2が押されてない状態でチェックボックスのチェックを外すと、
初期状態に戻る
こんな感じです。
組み合わせ次第で色々なゲーム(?)が作れます。
ソースはGitに上げているので、
確認したい方はビルドしてみてください。
終わりに
今回はCButtonクラスの操作をしてみました。
まだまだ関数はたくさんありますが、
個人的にSetCheck、GetCheckをよく使うので備忘録まとめでした。

コメント