C++ 6日目:ACボタンのイベント処理

この章からは、各ボタンの処理を記述していきます
各数字ボタンが押された時、小数点ボタンが押された時、演算子ボタンが押された時、=ボタンが押された時、ACボタンが押された時のイベントについて、5日間にわたり説明します
この章では、ACボタンが押されたときの処理を見てみましょう

処理内容

計算結果や最後の演算子を表示するディスプレイをクリアし変数の値も初期化します
また、エラーが発生した場合、ACボタン以外押せない状態になっているので、エラー状態を解除しすべてのボタンを押せるようにします

ACボタンのイベント処理フロー

UIの変更

  1. 数値表示ディスプレイをクリアします
  2. 演算子表示ディスプレイをクリアします
  3. 無効化されているすべてのボタンを有効化します

内部ロジック

  1. current_bufferを空にします
  2. last_operatorを空にします
  3. stackの値をすべて空にします

実装

イベントハンドラの設定

VisualC++の機能を使用してACボタンのイベントハンドラを作成します
ACボタンをダブルクリックし、作成された関数は次の通りです

  1. MyCalculatorDlg.h
afx_msg void OnBnClickedButtonAc();

ACボタンの処理は、MyCalculatorDlg.cppのイベントハンドラへ記述していきます

追加したソース

  1. MyCalculatorDlg.h

OnBnClickedButtonAc()以外に以下の関数を追加します
void setEditBoxText(LPCTSTR lpText); 表示ディスプレイに文字を表示する関数
void setOperatorText(LPCTSTR lpText); 演算子ディスプレイに現在の演算子の文字を表示する関数
void initVariable(); 内部で管理する変数を初期化する関数
void enableButton(); すべてのボタンを押すことができるようにする関数

// CMyCalculatorDlg ダイアログ
class CMyCalculatorDlg : public CDialogEx
{
// コンストラクション
public:
    CMyCalculatorDlg(CWnd* pParent = nullptr);  // 標準コンストラクター

// ダイアログ データ
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_MYCALCULATOR_DIALOG };
#endif

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV サポート


// 実装
private:
// 関数の定義の追加 --ここから
    void setEditBoxText(LPCTSTR lpText);
    void setOperatorText(LPCTSTR lpText);
    void initVariable();
    void enableButton();
// ここまで
    CString current_buffer = _T("");
    CString last_operator = _T("");
    CString stack[2] = {_T(""),_T("")};

protected:
    HICON m_hIcon;

    // 生成された、メッセージ割り当て関数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnBnClickedButtonAc(); // ACボタンが押された時に呼び出される関数
};
  1. MyCalculatorDlg.cpp

今回追加する関数の実体をそれぞれ記述していきます

enableButton()

// すべてのボタンを押せるようにする
void CMyCalculatorDlg::enableButton()
{
	CWnd* pCtrl = GetTopWindow();
	do {
		pCtrl->EnableWindow(TRUE);
	} while (pCtrl = pCtrl->GetNextWindow());

}

すべてのボタンをenable化します
GetTopWindow() : 自分自身のウィンドウに関連付けられている子ウィンドウ(このサンプルではボタン)へのハンドルを取得します

pCtrl->EnableWindow(TRUE); 指定したウィンドウまたはコントロールへのマウスとキーボードの入力を有効または無効にする関数を呼び出しています。引数がTRUEのとき有効、FALSEのとき無効を指定します

pCtrl->GetNextWindow():次の子ウインドウのハンドルを返します。見つからなければNULLが返ってきます。do~whileにより、次の子ウインドウが見つからなくなるまで、処理を繰り返します

setEditBoxText()

// エディットボックスに値をセット
// 引数 lpText セットする文字列
void CMyCalculatorDlg::setEditBoxText(LPCTSTR lpText)
{
	// IDC_EDIT_RESULT は文字を追加するエディットボックスのID
	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_RESULT);

	// エディットボックスに新しいテキストを設定
	pEdit->SetWindowText(lpText);

}

引数の文字列lpTextを表示ディスプレイのコントロールに表示させる役割を持ちます
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_RESULT); GetDlgItem関数にコントロールIDを引数として、指定したコントロールへのハンドルを取得しています

pEdit->SetWindowText(lpText); 取得したコントロールのタイトルバーのテキストを変更します

setOperatorText()

/* 演算子をディスプレイに表示する */
void CMyCalculatorDlg::setOperatorText(LPCTSTR lpText)
{
	// IDC_EDIT1 は文字を追加するエディットボックスのID
	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_OPERATOR);

	if (lpText == _T("*")) 
	{
		pEdit->SetWindowText(_T("×"));
	}
	else if (lpText == _T("/")) {
		pEdit->SetWindowText(_T("÷"));
	}
	else
	{
		pEdit->SetWindowText(lpText);
	}
}

演算子表示ディスプレイに引数の文字列を表示させています
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_OPERATOR); 演算子表示ディスプレイのハンドルを取得します

initVariable()

// 変数の初期化
void CMyCalculatorDlg::initVariable()
{
	clearCurrentBuffer(); // current_bufferを初期化する関数
	last_operator = "";
	stack[0] = "";
	stack[1] = "";
}

すべての変数を初期化します

OcBnClickedButtonAc()

/*  ACボタンが押された時のハンドラ */
void CMyCalculatorDlg::OnBnClickedButtonAc()
{
	// TODO: ここにコントロール通知ハンドラー コードを追加します。
	setEditBoxText(_T(""));
	setOperatorText(_T(""));

	initVariable();

	enableButton();
}

ACボタンが押された時に呼び出される関数の内部を記述します
表示ディスプレイ、演算子表示ディスプレイをそれぞれクリアしたあと、変数を初期化します

以上が、ACボタンが押された時の説明です。次は数字ボタンのイベント処理について実装していきます

コメント

この記事へのコメントはありません。

関連記事

C++ 12日目:+/-ボタン

C++ 発展編 2日目

C言語 応用編 ~7日目~

PAGE TOP