激战2盗贼打战士:如何用VC++6.0 MFC 实现计算器

来源:百度文库 编辑:高校问答 时间:2024/04/27 13:09:56

Figure 8-10. The DlgCalc application.

DlgCalc.h
// DlgCalc.h : main header file for the DLGCALC application
//

#if !defined(AFX_DLGCALC_H__F42970C4_9047_11D2_8E53_006008A82731__INCLUDED_)
#define
AFX_DLGCALC_H__F42970C4_9047_11D2_8E53_006008A82731__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include `stdafx.h' before including this file for PCH
#endif

#include "resource.h" // main symbols

///////////////////////////////////////////////////////////////////////////
// CDlgCalcApp:
// See DlgCalc.cpp for the implementation of this class
//

class CDlgCalcApp : public CWinApp
{
public:
CDlgCalcApp();

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgCalcApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL

// Implementation

//{{AFX_MSG(CDlgCalcApp)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

///////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately
// before the previous line.

#endif
// !defined(AFX_DLGCALC_H__F42970C4_9047_11D2_8E53_006008A82731__INCLUDED_)

DlgCalc.cpp
// DlgCalc.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "DlgCalc.h"
#include "DlgCalcDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////////////////////////////////////////
// CDlgCalcApp

BEGIN_MESSAGE_MAP(CDlgCalcApp, CWinApp)
//{{AFX_MSG_MAP(CDlgCalcApp)
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////
// CDlgCalcApp construction

CDlgCalcApp::CDlgCalcApp()
{
}

///////////////////////////////////////////////////////////////////////////
// The one and only CDlgCalcApp object

CDlgCalcApp theApp;

///////////////////////////////////////////////////////////////////////////
// CDlgCalcApp initialization

BOOL CDlgCalcApp::InitInstance()
{
CDlgCalcDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal ();
return FALSE;
}
DlgCalcDlg.h
// DlgCalcDlg.h : header file
//

#if !defined(AFX_DLGCALCDLG_H__F42970C6_9047_11D2_8E53_006008A82731__INCLUDED_)
#define AFX_DLGCALCDLG_H__F42970C6_9047_11D2_8E53_006008A82731__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

///////////////////////////////////////////////////////////////////////////
// CDlgCalcDlg dialog

class CDlgCalcDlg : public CDialog
{
// Construction
public:
void UpdateDisplay (LPCTSTR pszDisplay);
CDlgCalcDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
//{{AFX_DATA(CDlgCalcDlg)
enum { IDD = IDD_DLGCALC_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgCalcDlg)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL

// Implementation
protected:
void DropStack();
void LiftStack();
void DisplayXRegister();

double m_dblStack[4];
double m_dblMemory;
CString m_strDisplay;
CString m_strFormat;
CRect m_rect;
int m_cxChar;
int m_cyChar;

BOOL m_bFixPending;
BOOL m_bErrorFlag;
BOOL m_bDecimalInString;
BOOL m_bStackLiftEnabled;
BOOL m_bNewX;

HICON m_hIcon;
HACCEL m_hAccel;

// Generated message map functions
//{{AFX_MSG(CDlgCalcDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg void OnAdd();
afx_msg void OnSubtract();
afx_msg void OnMultiply();
afx_msg void OnDivide();
afx_msg void OnEnter();
afx_msg void OnChangeSign();
afx_msg void OnExponent();
afx_msg void OnStore();
afx_msg void OnRecall();
afx_msg void OnFix();
afx_msg void OnClear();
afx_msg void OnDecimal();
afx_msg void OnDelete();
//}}AFX_MSG
afx_msg void OnDigit(UINT nID);
DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately
// before the previous line.

#endif
// !defined(
// AFX_DLGCALCDLG_H__F42970C6_9047_11D2_8E53_006008A82731__INCLUDED_)

DlgCalcDlg.cpp
// DlgCalcDlg.cpp : implementation file
//

#include "stdafx.h"
#include "DlgCalc.h"
#include "DlgCalcDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////////////////////////////////////////
// CDlgCalcDlg dialog

CDlgCalcDlg::CDlgCalcDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDlgCalcDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlgCalcDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_hAccel = ::LoadAccelerators (AfxGetInstanceHandle (),
MAKEINTRESOURCE (IDR_ACCEL));

m_bFixPending = FALSE;
m_bErrorFlag = FALSE;
m_bDecimalInString = FALSE;
m_bStackLiftEnabled = FALSE;
m_bNewX = TRUE;

for (int i=0; i<4; i++)
m_dblStack[i] = 0.0;
m_dblMemory = 0.0;
m_strFormat = _T ("%0.2f");
}

void CDlgCalcDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgCalcDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDlgCalcDlg, CDialog)
//{{AFX_MSG_MAP(CDlgCalcDlg)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_ADD, OnAdd)
ON_BN_CLICKED(IDC_SUBTRACT, OnSubtract)
ON_BN_CLICKED(IDC_MULTIPLY, OnMultiply)
ON_BN_CLICKED(IDC_DIVIDE, OnDivide)
ON_BN_CLICKED(IDC_ENTER, OnEnter)
ON_BN_CLICKED(IDC_CHGSIGN, OnChangeSign)
ON_BN_CLICKED(IDC_EXP, OnExponent)
ON_BN_CLICKED(IDC_STO, OnStore)
ON_BN_CLICKED(IDC_RCL, OnRecall)
ON_BN_CLICKED(IDC_FIX, OnFix)
ON_BN_CLICKED(IDC_CLX, OnClear)
ON_BN_CLICKED(IDC_DECIMAL, OnDecimal)
ON_BN_CLICKED(IDC_DEL, OnDelete)
//}}AFX_MSG_MAP
ON_CONTROL_RANGE (BN_CLICKED, IDC_0, IDC_9, OnDigit)
END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////
// CDlgCalcDlg message handlers

BOOL CDlgCalcDlg::OnInitDialog()
{
CDialog::OnInitDialog();

//
// Set the application's icon.
//
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);

//
// Remove the Size and Maximize commands from the system menu.
//
CMenu* pMenu = GetSystemMenu (FALSE);
pMenu->DeleteMenu (SC_SIZE, MF_BYCOMMAND);
pMenu->DeleteMenu (SC_MAXIMIZE, MF_BYCOMMAND);

//
// Initialize m_rect with the coordinates of the control representing
// the calculator's output window. Then destroy the control.
//
CWnd* pWnd = GetDlgItem (IDC_DISPLAYRECT);
pWnd->GetWindowRect (&m_rect);
pWnd->DestroyWindow ();
ScreenToClient (&m_rect);

//
// Initialize m_cxChar and m_cyChar with the average character width
// and height.
//
TEXTMETRIC tm;
CClientDC dc (this);
dc.GetTextMetrics (&tm);
m_cxChar = tm.tmAveCharWidth;
m_cyChar = tm.tmHeight - tm.tmDescent;

//
// Initialize the calculator's output window and return.
//
DisplayXRegister ();
return TRUE;
}

void CDlgCalcDlg::OnPaint()
{
CPaintDC dc (this);
dc.DrawEdge (m_rect, EDGE_SUNKEN, BF_RECT);
UpdateDisplay (m_strDisplay);
}
BOOL CDlgCalcDlg::PreTranslateMessage(MSG* pMsg)
{
if (m_hAccel != NULL)
if (::TranslateAccelerator (m_hWnd, m_hAccel, pMsg))
return TRUE;

return CDialog::PreTranslateMessage (pMsg);
}

BOOL CDlgCalcDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
int nID = (int) LOWORD (wParam);

if (m_bErrorFlag && (nID != IDC_CLX)) {
::MessageBeep (MB_ICONASTERISK);
return TRUE;
}

if (m_bFixPending &&
((nID < IDC_0) || (nID > IDC_9)) &&
(nID != IDC_CLX)) {
::MessageBeep (MB_ICONASTERISK);
return TRUE;
}
return CDialog::OnCommand (wParam, lParam);
}

void CDlgCalcDlg::OnDigit(UINT nID)
{
TCHAR cDigit = (char) nID;

if (m_bFixPending) {
m_strFormat.SetAt (3, cDigit - IDC_0 + 0x30);
DisplayXRegister ();
m_bFixPending = FALSE;
m_bStackLiftEnabled = TRUE;
m_bNewX = TRUE;
return;
}

if (m_bNewX) {
m_bNewX = FALSE;
if (m_bStackLiftEnabled) {
m_bStackLiftEnabled = FALSE;
LiftStack ();
}
m_bDecimalInString = FALSE;
m_strDisplay.Empty ();
}

int nLength = m_strDisplay.GetLength ();
if ((nLength == MAXCHARS) ||
((nLength == (MAXCHARS - 10)) && !m_bDecimalInString))
::MessageBeep (MB_ICONASTERISK);
else {
m_strDisplay += (cDigit - IDC_0 + 0x30);
UpdateDisplay (m_strDisplay);
m_dblStack[0] = _tcstod (m_strDisplay.GetBuffer (0), NULL);
}
}

void CDlgCalcDlg::OnAdd()
{
m_dblStack[0] += m_dblStack[1];
DisplayXRegister ();
DropStack ();
m_bStackLiftEnabled = TRUE;
m_bNewX = TRUE;
}

void CDlgCalcDlg::OnSubtract()
{
m_dblStack[0] = m_dblStack[1] - m_dblStack[0];
DisplayXRegister ();
DropStack ();
m_bStackLiftEnabled = TRUE;
m_bNewX = TRUE;
}

void CDlgCalcDlg::OnMultiply()
{
m_dblStack[0] *= m_dblStack[1];
DisplayXRegister ();
DropStack ();
m_bStackLiftEnabled = TRUE;
m_bNewX = TRUE;
}

void CDlgCalcDlg::OnDivide()
{
if (m_dblStack[0] == 0.0) {
m_bErrorFlag = TRUE;
::MessageBeep (MB_ICONASTERISK);
UpdateDisplay (CString (_T ("Divide by zero")));
}
else {
m_dblStack[0] = m_dblStack[1] / m_dblStack[0];
DisplayXRegister ();
DropStack ();
m_bStackLiftEnabled = TRUE;
m_bNewX = TRUE;
}
}

void CDlgCalcDlg::OnEnter()
{
LiftStack ();
DisplayXRegister ();
m_bStackLiftEnabled = FALSE;
m_bNewX = TRUE;
}

void CDlgCalcDlg::OnChangeSign()
{
if (m_dblStack[0] != 0.0) {
m_dblStack[0] = -m_dblStack[0];
if (m_strDisplay[0] == _T (`-')) {
int nLength = m_strDisplay.GetLength ();
m_strDisplay = m_strDisplay.Right (nLength - 1);