C++ 8日目:小数点の入力

この章では、小数点ボタンがおされたときの処理の説明をしていきます

前提条件

小数点ボタンが押される直前の電卓はどのような状態の場合があるかを考えてみます

演算子の表示部分数値の表示部分変数状態の説明
current_buffer:空
last_operator:空
stack[0]:空
stack[1]:空
電卓の起動時
数値current_buffer:数値
last_operator:空
stack[0]:空
stack[1]:空
電卓起動後数値または小数点を入力
数値.数値current_buffer:数値.数値
last_operator:空
stack[0]:空
stack[1]:空
電卓起動後数値または小数点を入力
-、+、×、÷数値current_buffer:空
last_operator:演算子
stack[0]:左辺値の値または計算結果
stack[1]:空
演算子を指定した状態
=数値current_buffer:空
last_operator:=
stack[0]:計算結果
stack[1]:空
計算完了後の状態

処理内容

ディスプレイに押された小数点ボタンを末尾に追加し、current_bufferに押された小数点ボタンを追加する処理を実行します

小数点ボタンのイベント処理フロー

1. 状態のチェック

current_bufferにすでに小数点が存在するかをチェックし、すでに小数点が存在する場合は、これ以上小数点が入力できないようにします

2. 処理内容

  1. current_bufferにすでに小数点が存在するかをチェック
    もし、current_bufferにすでに小数点が存在する場合、ブザーを鳴らすが、ディスプレイの表示もcurrent_bufferの値も変化しない
  2. 「新しい計算」が始まるかチェックする
    • last_operatorが’=’または演算子の場合、これは「新しい計算」が始まると判断する
      ・この時、ディスプレイと表示をリセットする
      ・UIの数値表示部分をクリアする
      ・current_bufferを0にする(※小数点から始まる入力に対応)
      ・last_operator が”=”のとき すべての変数をクリアする
  3. 小数点を追加
    ・current_bufferに小数点を追加する
    ・UIの数値表示部分を、更新されたcurrent_bufferの値で上書きする

実装

イベントハンドラの設定

VisualC++の機能を使用して小数点のボタンのイベントハンドラを作成します
小数点ボタンをダブルクリックし、OnBnClickedButtonDecimal()関数が生成されます
また、表示ディスプレイの末尾に文字を追加するAddEditBoxText(LPCTSTR lpText)関数を用意します

  1. MyCalculatorDlg.h
// 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 AddEditBoxText(LPCTSTR lpText);  // エディットボックスの最後に文字を追加する関数を追加
    void setEditBoxText(LPCTSTR lpText);  
    void initVariable();
    void setOperatorText(LPCTSTR lpText);
    void HandleNumberClick(LPCTSTR number_char);
    void enableButton();
    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 OnBnClickedButtonDecimal(); // 小数点ボタンが押された時に呼び出される関数
};
  1. MyCalculatorDlg.cpp

AddEditBoxText()

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

    // 現在のテキストを取得
    CString strCurrentText;
    pEdit->GetWindowText(strCurrentText);

    // 新しいテキストを追加
    strCurrentText += lpText;

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

    // カーソルを末尾に移動(任意)
    pEdit->SendMessage(EM_SETSEL, (WPARAM)strCurrentText.GetLength(), (LPARAM)strCurrentText.GetLength());

}

OnBnClickedButtonDecimal()

void CMyCalculatorDlg::OnBnClickedButtonDecimal()
{
//    current_bufferに小数点が1つ存在するかどうかをチェックし処理を分ける

    size_t pos = current_buffer.Find('.');
    CString chr = _T(".");

    if (pos == -1) {
//        存在しないとき
//        ディスプレイ:小数点を末尾に追加する
//        内部計算:current_bufferに小数点を追加する
//      最後に入力した演算子が=の場合
//    ディスプレイ表示をクリアし、最後の演算子もクリアする
        if (last_operator == _T("="))
        {
            OnBnClickedButtonAc();
        }
        else if (current_buffer.IsEmpty())
        { // =以外の演算子のあと
            setEditBoxText(_T(""));
            current_buffer = "0";
        }

        current_buffer += chr;
        AddEditBoxText(chr);

    }
    else {
        //      存在するとき
        //      ディスプレイ:ブザーを鳴らすが、表示は変わらない
        //      内部計算:current_bufferの値は変化しない
        MessageBeep(MB_OK);
    }
}

小数点ボタンが押された時の処理は以上の通りです
次回は演算子ボタンが押された時の処理を実装していきます

コメント

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

関連記事

Python(応用編)演習問題

C++ 基礎編 6日目

Java 応用編 3日目

PAGE TOP