MFCプロジェクトでCButtonクラスを操作する

今回は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をよく使うので備忘録まとめでした。

SampleSrc/CPlusPlus/ControlOpeartion/ControlTest at main ?? Tatsumath/SampleSrc
Various sources, mostly C++. Contribute to Tatsumath/SampleSrc development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました