この章からは、各ボタンの処理を記述していきます
各数字ボタンが押された時、小数点ボタンが押された時、演算子ボタンが押された時、=ボタンが押された時、ACボタンが押された時のイベントについて、5日間にわたり説明します
この章では、ACボタンが押されたときの処理を見てみましょう
処理内容
計算結果や最後の演算子を表示するディスプレイをクリアし変数の値も初期化します
また、エラーが発生した場合、ACボタン以外押せない状態になっているので、エラー状態を解除しすべてのボタンを押せるようにします
ACボタンのイベント処理フロー
UIの変更
- 数値表示ディスプレイをクリアします
- 演算子表示ディスプレイをクリアします
- 無効化されているすべてのボタンを有効化します
内部ロジック
current_bufferを空にしますlast_operatorを空にしますstackの値をすべて空にします
実装
イベントハンドラの設定
VisualC++の機能を使用してACボタンのイベントハンドラを作成します
ACボタンをダブルクリックし、作成された関数は次の通りです
- MyCalculatorDlg.h
afx_msg void OnBnClickedButtonAc();
ACボタンの処理は、MyCalculatorDlg.cppのイベントハンドラへ記述していきます
追加したソース
- 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ボタンが押された時に呼び出される関数
};- 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ボタンが押された時の説明です。次は数字ボタンのイベント処理について実装していきます
コメント