calcdlg.cpp
上传用户:biuytresa
上传日期:2007-12-07
资源大小:721k
文件大小:11k
源码类别:

DNA

开发平台:

Visual C++

  1. // calcdlg.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include "stdafx.h"
  13. #include "mfccalc.h"
  14. #include "calcdlg.h"
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char BASED_CODE THIS_FILE[] = __FILE__;
  18. #endif
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CAboutDlg dialog used for App About
  21. class CAboutDlg : public CDialog
  22. {
  23. public:
  24. CAboutDlg();
  25. // Dialog Data
  26. //{{AFX_DATA(CAboutDlg)
  27. enum { IDD = IDD_ABOUTBOX };
  28. //}}AFX_DATA
  29. // Implementation
  30. protected:
  31. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  32. //{{AFX_MSG(CAboutDlg)
  33. virtual BOOL OnInitDialog();
  34. //}}AFX_MSG
  35. DECLARE_MESSAGE_MAP()
  36. };
  37. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  38. {
  39. //{{AFX_DATA_INIT(CAboutDlg)
  40. //}}AFX_DATA_INIT
  41. }
  42. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  43. {
  44. CDialog::DoDataExchange(pDX);
  45. //{{AFX_DATA_MAP(CAboutDlg)
  46. //}}AFX_DATA_MAP
  47. }
  48. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  49. //{{AFX_MSG_MAP(CAboutDlg)
  50. // No message handlers
  51. //}}AFX_MSG_MAP
  52. END_MESSAGE_MAP()
  53. /////////////////////////////////////////////////////////////////////////////
  54. // CAboutDlg message handlers
  55. BOOL CAboutDlg::OnInitDialog()
  56. {
  57. CDialog::OnInitDialog();
  58. // TODO: Add extra initialization here
  59. return TRUE;
  60. }
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CCalcDlg dialog
  63. IMPLEMENT_DYNCREATE(CCalcDlg, CDialog)
  64. BEGIN_DISPATCH_MAP(CCalcDlg, CDialog)
  65. //{{AFX_DISPATCH_MAP(CCalcDlg)
  66. DISP_PROPERTY_EX(CCalcDlg, "Accum", GetAccum, SetAccum, VT_I4)
  67. DISP_PROPERTY_EX(CCalcDlg, "Operand", GetOperand, SetOperand, VT_I4)
  68. DISP_PROPERTY_EX(CCalcDlg, "Operation", GetOperation, SetOperation, VT_I2)
  69. DISP_PROPERTY_EX(CCalcDlg, "Visible", GetVisible, SetVisible, VT_BOOL)
  70. DISP_FUNCTION(CCalcDlg, "Evaluate", Evaluate, VT_BOOL, VTS_NONE)
  71. DISP_FUNCTION(CCalcDlg, "Clear", Clear, VT_EMPTY, VTS_NONE)
  72. DISP_FUNCTION(CCalcDlg, "Display", Display, VT_EMPTY, VTS_NONE)
  73. DISP_FUNCTION(CCalcDlg, "Close", Close, VT_EMPTY, VTS_NONE)
  74. DISP_FUNCTION(CCalcDlg, "Button", Button, VT_BOOL, VTS_BSTR)
  75. //}}AFX_DISPATCH_MAP
  76. END_DISPATCH_MAP()
  77. #ifndef IMPLEMENT_OLECREATE_SINGLE
  78. // MFC will provide this macro in the future.  For now, we define it.
  79. #define IMPLEMENT_OLECREATE_SINGLE(class_name, external_name, 
  80. l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) 
  81. AFX_DATADEF COleObjectFactory class_name::factory(class_name::guid, 
  82. RUNTIME_CLASS(class_name), TRUE, _T(external_name)); 
  83. const AFX_DATADEF GUID class_name::guid = 
  84. { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } };
  85. #endif
  86. // {62C4DD10-F45E-11cd-8C3D-00AA004BB3B7}
  87. IMPLEMENT_OLECREATE_SINGLE(CCalcDlg, "mfccalc.calculator",
  88. 0x62c4dd10, 0xf45e, 0x11cd, 0x8c, 0x3d, 0x0, 0xaa, 0x0, 0x4b, 0xb3, 0xb7);
  89. CCalcDlg::CCalcDlg(CWnd* pParent /*=NULL*/)
  90. : CDialog(CCalcDlg::IDD, pParent)
  91. {
  92. m_bAutoDelete = TRUE;       // default to auto-delete
  93. m_dwRegister = 0;               // not registered as active by default
  94. //{{AFX_DATA_INIT(CCalcDlg)
  95. // NOTE: the ClassWizard will add member initialization here
  96. //}}AFX_DATA_INIT
  97. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  98. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  99. // Note that LoadAccelerator does not require DestroyAcceleratorTable
  100. m_hAccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDD));
  101. // clear the contents of the calculator and reset state
  102. OnClickedClear();
  103. // enable this object for OLE automation
  104. EnableAutomation();
  105. }
  106. CCalcDlg::~CCalcDlg()
  107. {
  108. if (m_dwRegister != 0)
  109. RevokeActiveObject(m_dwRegister, NULL);
  110. }
  111. void CCalcDlg::DoDataExchange(CDataExchange* pDX)
  112. {
  113. CDialog::DoDataExchange(pDX);
  114. //{{AFX_DATA_MAP(CCalcDlg)
  115. // NOTE: the ClassWizard will add DDX and DDV calls here
  116. //}}AFX_DATA_MAP
  117. }
  118. /////////////////////////////////////////////////////////////////////////////
  119. // CCalcDlg implementation
  120. void CCalcDlg::PerformOperation()
  121. {
  122. if (m_errorState != ErrNone)
  123. return;
  124. if (m_bOperandAvail)
  125. {
  126. if (m_operator == OpNone)
  127. m_accum = m_operand;
  128. else if (m_operator == OpMultiply)
  129. m_accum *= m_operand;
  130. else if (m_operator == OpDivide)
  131. {
  132. if (m_operand == 0)
  133. m_errorState = ErrDivideByZero;
  134. else
  135. m_accum /= m_operand;
  136. }
  137. else if (m_operator == OpAdd)
  138. m_accum += m_operand;
  139. else if (m_operator == OpSubtract)
  140. m_accum -= m_operand;
  141. }
  142. m_bOperandAvail = FALSE;
  143. UpdateDisplay();
  144. }
  145. void CCalcDlg::ClickedNumber(long l)
  146. {
  147. if (m_errorState != ErrNone)
  148. return;
  149. if (!m_bOperandAvail)
  150. m_operand = 0L;
  151. SetOperand(m_operand*10+l);
  152. UpdateDisplay();
  153. }
  154. void CCalcDlg::UpdateDisplay()
  155. {
  156. if (GetSafeHwnd() == NULL)
  157. return;
  158. CString str;
  159. if (m_errorState != ErrNone)
  160. str.LoadString(IDS_ERROR);
  161. else
  162. {
  163. long lVal = (m_bOperandAvail) ? m_operand : m_accum;
  164. str.Format(_T("%ld"), lVal);
  165. }
  166. GetDlgItem(IDE_ACCUM)->SetWindowText(str);
  167. GetDlgItem(IDC_INVISIBLE_FOCUS)->SetFocus();
  168. }
  169. BEGIN_MESSAGE_MAP(CCalcDlg, CDialog)
  170. //{{AFX_MSG_MAP(CCalcDlg)
  171. ON_WM_SYSCOMMAND()
  172. ON_WM_PAINT()
  173. ON_WM_QUERYDRAGICON()
  174. ON_COMMAND_RANGE(IDB_0, IDB_9, OnClickedNumber)
  175. ON_BN_CLICKED(IDB_CLEAR, OnClickedClear)
  176. ON_BN_CLICKED(IDB_DIVIDE, OnClickedDivide)
  177. ON_BN_CLICKED(IDB_EQUAL, OnClickedEqual)
  178. ON_BN_CLICKED(IDB_MINUS, OnClickedMinus)
  179. ON_BN_CLICKED(IDB_PLUS, OnClickedPlus)
  180. ON_BN_CLICKED(IDB_TIMES, OnClickedTimes)
  181. ON_EN_SETFOCUS(IDE_ACCUM, OnSetFocusAccum)
  182. //}}AFX_MSG_MAP
  183. END_MESSAGE_MAP()
  184. /////////////////////////////////////////////////////////////////////////////
  185. // CCalcDlg message handlers
  186. BOOL CCalcDlg::OnInitDialog()
  187. {
  188. CDialog::OnInitDialog();
  189. // Add "About..." menu item to system menu.
  190. // IDM_ABOUTBOX must be in the system command range.
  191. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  192. ASSERT(IDM_ABOUTBOX < 0xF000);
  193. CMenu* pSysMenu = GetSystemMenu(FALSE);
  194. CString strAboutMenu;
  195. strAboutMenu.LoadString(IDS_ABOUTBOX);
  196. if (!strAboutMenu.IsEmpty())
  197. {
  198. pSysMenu->AppendMenu(MF_SEPARATOR);
  199. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  200. }
  201. pSysMenu->RemoveMenu(SC_MAXIMIZE, MF_BYCOMMAND);
  202. pSysMenu->RemoveMenu(SC_SIZE, MF_BYCOMMAND);
  203. // want focus to stay on the dialog itself (until a button is clicked)
  204. SetFocus();
  205. return FALSE;
  206. }
  207. void CCalcDlg::OnSysCommand(UINT nID, LPARAM lParam)
  208. {
  209. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  210. {
  211. CAboutDlg dlgAbout;
  212. dlgAbout.DoModal();
  213. }
  214. else
  215. {
  216. CDialog::OnSysCommand(nID, lParam);
  217. }
  218. }
  219. // If you add a minimize button to your dialog, you will need the code below
  220. //  to draw the icon.  For MFC applications using the document/view model,
  221. //  this is automatically done for you by the framework.
  222. void CCalcDlg::OnPaint()
  223. {
  224. if (!IsIconic())
  225. {
  226. CDialog::OnPaint();
  227. return;
  228. }
  229. CPaintDC dc(this); // device context for painting
  230. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  231. // Center icon in client rectangle
  232. int cxIcon = GetSystemMetrics(SM_CXICON);
  233. int cyIcon = GetSystemMetrics(SM_CYICON);
  234. CRect rect;
  235. GetClientRect(&rect);
  236. int x = (rect.Width() - cxIcon + 1) / 2;
  237. int y = (rect.Height() - cyIcon + 1) / 2;
  238. // Draw the icon
  239. dc.DrawIcon(x, y, m_hIcon);
  240. }
  241. // The system calls this to obtain the cursor to display while the user drags
  242. //  the minimized window.
  243. HCURSOR CCalcDlg::OnQueryDragIcon()
  244. {
  245. return (HCURSOR)m_hIcon;
  246. }
  247. void CCalcDlg::OnClickedNumber(UINT nID)
  248. {
  249. ASSERT(nID >= IDB_0 && nID <= IDB_9);
  250. ClickedNumber(nID - IDB_0);
  251. }
  252. void CCalcDlg::OnClickedClear()
  253. {
  254. m_operator = OpNone;
  255. m_operand = 0L;
  256. m_accum = 0L;
  257. m_bOperandAvail = FALSE;
  258. m_errorState = ErrNone;
  259. UpdateDisplay();
  260. }
  261. void CCalcDlg::OnClickedDivide()
  262. {
  263. PerformOperation();
  264. m_operator = OpDivide;
  265. }
  266. void CCalcDlg::OnClickedEqual()
  267. {
  268. PerformOperation();
  269. m_operator = OpNone;
  270. }
  271. void CCalcDlg::OnClickedMinus()
  272. {
  273. PerformOperation();
  274. m_operator = OpSubtract;
  275. }
  276. void CCalcDlg::OnClickedPlus()
  277. {
  278. PerformOperation();
  279. m_operator = OpAdd;
  280. }
  281. void CCalcDlg::OnClickedTimes()
  282. {
  283. PerformOperation();
  284. m_operator = OpMultiply;
  285. }
  286. BOOL CCalcDlg::PreTranslateMessage(MSG* pMsg)
  287. {
  288. if (m_hAccel != NULL && TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
  289. return TRUE;
  290. return CDialog::PreTranslateMessage(pMsg);
  291. }
  292. void CCalcDlg::PostNcDestroy()
  293. {
  294. if (m_bAutoDelete)
  295. delete this;
  296. }
  297. void CCalcDlg::OnCancel()
  298. {
  299. DestroyWindow();
  300. }
  301. void CCalcDlg::OnOK()
  302. {
  303. }
  304. void CCalcDlg::OnSetFocusAccum()
  305. {
  306. GetDlgItem(IDC_INVISIBLE_FOCUS)->SetFocus();
  307. }
  308. /////////////////////////////////////////////////////////////////////////////
  309. // CCalcDlg automation
  310. BOOL CCalcDlg::RegisterActive()
  311. {
  312. // attempt to register as the active object for the CCalcDlg CLSID
  313. return RegisterActiveObject(GetInterface(&IID_IUnknown),
  314. CCalcDlg::guid, NULL, &m_dwRegister) == NOERROR;
  315. }
  316. long CCalcDlg::GetAccum()
  317. {
  318. return m_accum;
  319. }
  320. void CCalcDlg::SetAccum(long nNewValue)
  321. {
  322. m_accum = nNewValue;
  323. }
  324. long CCalcDlg::GetOperand()
  325. {
  326. return m_operand;
  327. }
  328. void CCalcDlg::SetOperand(long nNewValue)
  329. {
  330. m_operand = nNewValue;
  331. m_bOperandAvail = TRUE;
  332. }
  333. short CCalcDlg::GetOperation()
  334. {
  335. return m_operator;
  336. }
  337. void CCalcDlg::SetOperation(short nNewValue)
  338. {
  339. m_operator = (Operator)nNewValue;
  340. }
  341. BOOL CCalcDlg::GetVisible()
  342. {
  343. return m_hWnd != NULL && (GetStyle() & WS_VISIBLE) != 0;
  344. }
  345. void CCalcDlg::SetVisible(BOOL bNewValue)
  346. {
  347. if (bNewValue == GetVisible())
  348. return;
  349. if (bNewValue)
  350. {
  351. // create it if necessary
  352. if (m_hWnd == NULL && !Create(CCalcDlg::IDD))
  353. return;
  354. // set up as the active window for the application
  355. if (AfxGetThread()->m_pMainWnd == NULL)
  356. AfxGetThread()->m_pMainWnd = this;
  357. // show it
  358. ShowWindow(SW_SHOWNORMAL);
  359. }
  360. else
  361. {
  362. if (m_hWnd != NULL)
  363. ShowWindow(SW_HIDE);
  364. }
  365. }
  366. BOOL CCalcDlg::Evaluate()
  367. {
  368. OnClickedEqual();
  369. return m_errorState == ErrNone;
  370. }
  371. void CCalcDlg::Clear()
  372. {
  373. OnClickedClear();
  374. }
  375. void CCalcDlg::Display()
  376. {
  377. UpdateDisplay();
  378. }
  379. void CCalcDlg::Close()
  380. {
  381. if (m_hWnd == NULL)
  382. {
  383. AfxPostQuitMessage(0);
  384. return;
  385. }
  386. BOOL bAutoDelete = m_bAutoDelete;
  387. m_bAutoDelete = FALSE;
  388. DestroyWindow();
  389. m_bAutoDelete = bAutoDelete;
  390. }
  391. BOOL CCalcDlg::Button(LPCTSTR szButton)
  392. {
  393. switch (szButton[0])
  394. {
  395. case 'c':
  396. case 'C':
  397. OnClickedClear();
  398. break;
  399. case '/':
  400. OnClickedDivide();
  401. break;
  402. case '+':
  403. OnClickedPlus();
  404. break;
  405. case '-':
  406. OnClickedMinus();
  407. break;
  408. case '*':
  409. OnClickedTimes();
  410. break;
  411. case '=':
  412. OnClickedEqual();
  413. break;
  414. default:
  415. if (szButton[0] >= '0' && szButton[0] <= '9')
  416. ClickedNumber(szButton[0] - '0');
  417. else
  418. return FALSE;
  419. break;
  420. }
  421. return TRUE;
  422. }