home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / calcdriv / calcdriv.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  6.6 KB  |  254 lines

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