この章からはフェーズ2の実装を行います
まず、戻るボタンがおされたときの処理の説明をしていきます
処理概要
戻るボタンは、入力中の数字の一部を訂正したい場合に使用します
このボタンを押すことで、入力した数字を1文字ずつ後ろから消していきます
current_bufferの値の末尾の文字を1文字ずつ消去し、表示ディスプレイにも表示します
ただし、演算子ボタンや=ボタンが押された後に表示されている文字には、適用されません
戻るボタンが押された位置で以下のことを考慮します
ケース1. current_bufferが空文字のとき
ACボタンが押されたあとや、=ボタン、演算子ボタンが押されたあとの状態をさします
このときは、何も処理を実行しません
ケース2. current_bufferが0のとき
このときは、何も処理を実行しません
ケース3. current_bufferが空文字になったとき
戻るボタンを押し続け、空文字になった状態をさします
たとえば、current_bufferに1など1桁の数字や小数点が入っているときを想定します
この場合、current_bufferは0お代入し、表示ディスプレイに0を表示します
前提条件
戻るボタンが押される直前の電卓は、処理概要および「考慮すること」に対して、それぞれどのような状態の場合があるかを考えてみます
| 演算子の表示部分 | 数値の表示部分 | current_buffer | stack[0] | 状態の説明 |
|---|---|---|---|---|
| 空 | 空 | 空 | 空 | 入力の先頭で戻るボタンを押す |
| ―、+、×、÷、= | 数値 | 空 | 数値 | 演算子が押された後の状態 |
| ―、+、×、÷、= | 数値 | 数値 | 数値 | 演算子のあとに数字が入力された状態 |
| 空 | 数値 | 数値 | 空 | 数字が入力された状態 |
処理内容
戻るボタンのイベント処理フロー
1. 直前の入力に値が入っているかをチェックする
- もし
current_bufferが空の(=数値が入力されていない)場合:- 何もしない
- もし
current_bufferが空ではない(数値を入力中)の場合:- current_bufferの末尾を1文字消去する
- current_bufferの値をディスプレイに表示する
- もし、current_bufferが空文字になったとき、0を代入する
実装
イベントハンドラの設定
VisualC++の機能を使用して戻るボタンのイベントハンドラを作成します
作成されたイベントハンドラはafx_msg void OnBnClickedButtonBack();です
その後、イベントハンドラに処理を記述していきます
1. MyCalculatorDlg.h
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 AddEditBoxText(LPCTSTR lpText);
void setEditBoxText(LPCTSTR lpText);
void initVariable();
void clickOperatorButton(LPCTSTR lpText);
void setOperatorText(LPCTSTR lpText);
void clearCurrentBuffer();
double calculate();
void HandleNumberClick(LPCTSTR number_char);
void disableButton();
void enableButton();
double IsNumberAndConvert(const TCHAR* lpText);
CString ConvertDoubleToCString(double result);
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();
afx_msg void OnBnClickedButtonZero();
afx_msg void OnBnClickedButtonOne();
afx_msg void OnBnClickedButtonTwo();
afx_msg void OnBnClickedButtonThree();
afx_msg void OnBnClickedButtonFour();
afx_msg void OnBnClickedButtonFive();
afx_msg void OnBnClickedButtonSix();
afx_msg void OnBnClickedButtonSeven();
afx_msg void OnBnClickedButtonEight();
afx_msg void OnBnClickedButtonNine();
afx_msg void OnBnClickedButtonPlus();
afx_msg void OnBnClickedButton1Minus();
afx_msg void OnBnClickedButtonMulti();
afx_msg void OnBnClickedButtonDiv();
afx_msg void OnBnClickedButtonEqual();
afx_msg void OnBnClickedButtonDecimal();
afx_msg void OnBnClickedButtonBack();// Backボタン
};2. MyCalculatorDlg.cpp
void CMyCalculatorDlg::OnBnClickedButtonBack()
{
// TODO: ここにコントロール通知ハンドラー コードを追加します。
if (current_buffer.IsEmpty()) {
return;
}
// 末尾を削除
current_buffer = current_buffer.Left(current_buffer.GetLength() - 1);
// ディスプレイにも表示する
setEditBoxText(current_buffer);
// もしcurrent_bufferが空になったら、0という初期値を代入し、次の入力に備える
if (current_buffer.IsEmpty()) {
current_buffer = "0";
}
}
以上が、「戻る」ボタンを実装したプログラムです
次回は「+/-ボタン」の実装を行います
コメント