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

DNA

开发平台:

Visual C++

  1. // calcdriv.cpp : Defines the class behaviors for the application.
  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 "calcdriv.h"
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char BASED_CODE THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CCalcDrivApp
  20. BEGIN_MESSAGE_MAP(CCalcDrivApp, CWinApp)
  21. //{{AFX_MSG_MAP(CCalcDrivApp)
  22. // NOTE - the ClassWizard will add and remove mapping macros here.
  23. //    DO NOT EDIT what you see in these blocks of generated code!
  24. //}}AFX_MSG_MAP
  25. // Standard file based document commands
  26. END_MESSAGE_MAP()
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CCalcDrivApp construction
  29. CCalcDrivApp::CCalcDrivApp()
  30. {
  31. // TODO: add construction code here,
  32. // Place all significant initialization in InitInstance
  33. }
  34. /////////////////////////////////////////////////////////////////////////////
  35. // The one and only CCalcDrivApp object
  36. CCalcDrivApp NEAR theApp;
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CCalcDrivApp initialization
  39. BOOL CCalcDrivApp::InitInstance()
  40. {
  41. #ifdef _DEBUG
  42. // turn on extra memory tracking
  43. afxMemDF |= checkAlwaysMemDF;
  44. #endif
  45. // Initialize OLE 2.0 libraries
  46. if (!AfxOleInit())
  47. {
  48. AfxMessageBox(IDP_OLE_INIT_FAILED);
  49. return FALSE;
  50. }
  51. // Standard initialization
  52. // If you are not using these features and wish to reduce the size
  53. //  of your final executable, you should remove from the following
  54. //  the specific initialization routines you do not need.
  55. Enable3dControls();    // Use 3d controls in dialogs
  56. // Simple application that simply invokes a dialog
  57. CDriverDlg dlg;
  58. m_pMainWnd = &dlg;
  59. dlg.DoModal();
  60. return FALSE;   // don't run after the dialog is done
  61. }
  62. /////////////////////////////////////////////////////////////////////////////
  63. // CDriverDlg dialog
  64. CDriverDlg::CDriverDlg(CWnd* pParent /*=NULL*/)
  65. : CDialog(CDriverDlg::IDD, pParent)
  66. {
  67. //{{AFX_DATA_INIT(CDriverDlg)
  68. //}}AFX_DATA_INIT
  69. }
  70. CDriverDlg::~CDriverDlg()
  71. {
  72. TRY
  73. {
  74. // shut down the calculator
  75. //  (since calculator shows its user-interface, it would stay active
  76. //  if we didn't shut it down with a call to its Quit method)
  77. m_calc.Close();
  78. }
  79. END_TRY
  80. }
  81. void CDriverDlg::DoDataExchange(CDataExchange* pDX)
  82. {
  83. CDialog::DoDataExchange(pDX);
  84. //{{AFX_DATA_MAP(CDriverDlg)
  85. DDX_Control(pDX, IDD_LAST_OPERATOR, m_stcOperator);
  86. DDX_Control(pDX, IDD_LAST_OPERAND, m_stcOperand);
  87. DDX_Control(pDX, IDC_LAST_ACCUM, m_stcAccum);
  88. DDX_Control(pDX, IDC_EXPRESSION, m_editExpression);
  89. //}}AFX_DATA_MAP
  90. }
  91. BEGIN_MESSAGE_MAP(CDriverDlg, CDialog)
  92. //{{AFX_MSG_MAP(CDriverDlg)
  93. ON_BN_CLICKED(IDC_GO, OnGo)
  94. ON_BN_CLICKED(IDC_SINGLE_STEP, OnSingleStep)
  95. ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
  96. //}}AFX_MSG_MAP
  97. END_MESSAGE_MAP()
  98. /////////////////////////////////////////////////////////////////////////////
  99. // CDriverDlg message handlers
  100. void CDriverDlg::OnGo()
  101. {
  102. // get current expression from the edit control
  103. CString strExpression;
  104. m_editExpression.GetWindowText(strExpression);
  105. LPCTSTR psz = strExpression;
  106. // send all characters in the edit control from start to end
  107. int nLen = strExpression.GetLength();
  108. int nStart, nEnd;
  109. m_editExpression.GetSel(nStart, nEnd);
  110. if (nStart == nLen)
  111. nStart = 0;
  112. psz += nStart;
  113. while (*psz != '')
  114. {
  115. TCHAR szTemp[2];
  116. szTemp[0] = *psz;
  117. szTemp[1] = '';
  118. m_calc.Button(szTemp);
  119. ++psz;
  120. }
  121. m_editExpression.SetSel(nLen, nLen);
  122. OnRefresh();    // refresh after all button commands sent
  123. m_calc.Evaluate();
  124. m_calc.Display();
  125. }
  126. void CDriverDlg::OnSingleStep()
  127. {
  128. // get current expression from the edit control
  129. CString strExpression;
  130. m_editExpression.GetWindowText(strExpression);
  131. LPCTSTR psz = strExpression;
  132. // send first character in selection, then move selection to next
  133. int nStart, nEnd;
  134. m_editExpression.GetSel(nStart, nEnd);
  135. psz += nStart;
  136. if (*psz != '')
  137. {
  138. TCHAR szTemp[2];
  139. szTemp[0] = *psz;
  140. szTemp[1] = '';
  141. m_calc.Button(szTemp);
  142. OnRefresh();        // refresh after each step
  143. // move to next character for next single-step
  144. m_editExpression.SetSel(nStart+1,
  145. min(strExpression.GetLength(), nStart+2));
  146. }
  147. else
  148. {
  149. m_calc.Evaluate();
  150. m_calc.Display();
  151. // stepping from end will start at beginning next time
  152. m_editExpression.SetSel(0, min(strExpression.GetLength(), 1));
  153. }
  154. OnRefresh();    // refresh after all button commands sent
  155. }
  156. void CDriverDlg::OnRefresh()
  157. {
  158. TCHAR buf[64];
  159. long lResult = m_calc.GetOperand();
  160. wsprintf(buf, _T("%ld"), lResult);
  161. m_stcOperand.SetWindowText(buf);
  162. long lAccum = m_calc.GetAccum();
  163. wsprintf(buf, _T("%ld"), lAccum);
  164. m_stcAccum.SetWindowText(buf);
  165. short nOp = m_calc.GetOperation();
  166. static TCHAR operators[5] = { '?', '+', '-', '*', '/'};
  167. if (nOp < 0 || nOp > 4)
  168. nOp = 0;
  169. wsprintf(buf, _T("%c"), operators[nOp]);
  170. m_stcOperator.SetWindowText(buf);
  171. }
  172. BOOL CDriverDlg::OnInitDialog()
  173. {
  174. CDialog::OnInitDialog();
  175. // create the calculator object that we'll drive through OLE automation
  176. COleException e;
  177. CLSID clsid;
  178. if (CLSIDFromProgID(OLESTR("mfccalc.calculator"), &clsid) != NOERROR)
  179. {
  180. AfxMessageBox(IDP_UNABLE_TO_CREATE);
  181. EndDialog(IDABORT);
  182. return FALSE;
  183. }
  184. // try to get the active calculator before creating a new one
  185. LPUNKNOWN lpUnk;
  186. LPDISPATCH lpDispatch;
  187. if (GetActiveObject(clsid, NULL, &lpUnk) == NOERROR)
  188. {
  189. HRESULT hr = lpUnk->QueryInterface(IID_IDispatch,
  190. (LPVOID*)&lpDispatch);
  191. lpUnk->Release();
  192. if (hr == NOERROR)
  193. m_calc.AttachDispatch(lpDispatch, TRUE);
  194. }
  195. // if not dispatch ptr attached yet, need to create one
  196. if (m_calc.m_lpDispatch == NULL &&
  197. !m_calc.CreateDispatch(clsid, &e))
  198. {
  199. AfxMessageBox(IDP_UNABLE_TO_CREATE);
  200. EndDialog(IDABORT);
  201. return FALSE;
  202. }
  203. // attempt to make it visible
  204. m_calc.SetVisible(TRUE);
  205. if (!m_calc.GetVisible())
  206. {
  207. AfxMessageBox(IDP_UNABLE_TO_SHOW);
  208. EndDialog(IDABORT);
  209. return FALSE;
  210. }
  211. // refresh display to contents of the automation calculator
  212. OnRefresh();
  213. return TRUE;  // return TRUE  unless you set the focus to a control
  214. }