MFC 對話框計算機經典入門:數字鍵 0-9、運算符 + - * / %、顯示框累加輸入、等號計算結果。本文提供完整實現邏輯與代碼架構。
IDC_EDIT_DISPLAY → 變量 CString m_strDisplay(顯示用)IDC_BTN_0~IDC_BTN_9、IDC_BTN_ADD、IDC_BTN_SUB...、IDC_BTN_EQ、IDC_BTN_CLEAR
class CCalcDlg : public CDialogEx {
CString m_strDisplay; // 顯示緩衝
double m_dCurrentVal; // 當前輸入值
double m_dPrevVal; // 前一運算元
char m_chOp; // 當前運算符 '+','-','*','/','%'
bool m_bOpPressed; // 是否剛按下運算符
// ...
};
void CCalcDlg::OnNumber(UINT nID) {
CString strNum;
strNum.Format(_T("%d"), nID - IDC_BTN_0); // 假設 ID 連續
if (m_bOpPressed || m_strDisplay == _T("0")) {
m_strDisplay = strNum; // 運算符後或初始狀態,替換
m_bOpPressed = false;
} else {
m_strDisplay += strNum; // 累加顯示
}
UpdateData(FALSE);
}
// 消息映射
ON_COMMAND_RANGE(IDC_BTN_0, IDC_BTN_9, OnNumber)
void CCalcDlg::OnOperator(UINT nID) {
// 先計算上一個運算(若有)
if (m_chOp != 0) OnEqual();
m_dPrevVal = _tstof(m_strDisplay); // 保存左運算元
m_bOpPressed = true;
switch (nID) {
case IDC_BTN_ADD: m_chOp = '+'; break;
case IDC_BTN_SUB: m_chOp = '-'; break;
case IDC_BTN_MUL: m_chOp = '*'; break;
case IDC_BTN_DIV: m_chOp = '/'; break;
case IDC_BTN_MOD: m_chOp = '%'; break;
}
}
ON_COMMAND_RANGE(IDC_BTN_ADD, IDC_BTN_MOD, OnOperator)
void CCalcDlg::OnEqual() {
if (m_chOp == 0) return; // 無運算符
m_dCurrentVal = _tstof(m_strDisplay); // 右運算元
double result = 0;
switch (m_chOp) {
case '+': result = m_dPrevVal + m_dCurrentVal; break;
case '-': result = m_dPrevVal - m_dCurrentVal; break;
case '*': result = m_dPrevVal * m_dCurrentVal; break;
case '/':
if (m_dCurrentVal != 0) result = m_dPrevVal / m_dCurrentVal;
else { m_strDisplay = _T("Error"); UpdateData(FALSE); return; }
break;
case '%':
result = fmod(m_dPrevVal, m_dCurrentVal); break;
}
m_strDisplay.Format(_T("%.10g"), result); // 格式化輸出
UpdateData(FALSE);
m_dPrevVal = result; // 連續運算支持
m_chOp = 0;
m_bOpPressed = true;
}
void CCalcDlg::OnClear() {
m_strDisplay = _T("0");
m_dPrevVal = m_dCurrentVal = 0;
m_chOp = 0;
m_bOpPressed = false;
UpdateData(FALSE);
}
m_strDisplay 只負責顯示,運算用 double 變量m_bOpPressed 區分「輸入數字中」與「剛按完運算符」OnOperator 調用 OnEqual)%.10g 去除多餘尾隨零,避免科學計數法m_strDisplay.Find('.') == -1 才允許加點PreTranslateMessage 攔截數字鍵、Enter、EscCListBox 記錄每步運算MFC 計算機核心是狀態管理:數字累加顯示、運算符觸發計算並保存狀態、等號輸出結果。用 ON_COMMAND_RANGE 統一處理同類按鈕,變量分離顯示與計算,邏輯清晰易維護。