home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / com / mfccalc / calcdriv / calcdriv.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-03  |  8.3 KB  |  283 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-1995 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. //This routine is used where you want to dump com exception info, 
  22. //especially in catch blocks 
  23. void dump_com_error(_com_error &e)
  24. {
  25.     _bstr_t bstrSource(e.Source());
  26.     _bstr_t bstrDescription(e.Description());
  27.     TCHAR szTemp[1024];
  28.     CString csMsg = "Oops - hit an error!\n";
  29.     wsprintf(szTemp, _T("Code = %08lx\n"), e.Error());
  30.     csMsg += szTemp;
  31.     wsprintf(szTemp, _T("Code meaning = %s\n"), e.ErrorMessage());
  32.     csMsg += szTemp;
  33.     wsprintf(szTemp, _T("Source = %s\n"), bstrSource.length() ? (LPCTSTR)bstrSource : _T("null"));
  34.     csMsg += szTemp;
  35.     wsprintf(szTemp, _T("Description = %s\n"), bstrDescription.length() ? (LPCTSTR)bstrDescription : _T("null"));
  36.     csMsg += szTemp;
  37.     AfxMessageBox(csMsg);
  38. }
  39.  
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CCalcDrivApp
  42.  
  43. BEGIN_MESSAGE_MAP(CCalcDrivApp, CWinApp)
  44.     //{{AFX_MSG_MAP(CCalcDrivApp)
  45.         // NOTE - the ClassWizard will add and remove mapping macros here.
  46.         //    DO NOT EDIT what you see in these blocks of generated code!
  47.     //}}AFX_MSG_MAP
  48.     // Standard file based document commands
  49. END_MESSAGE_MAP()
  50.  
  51. /////////////////////////////////////////////////////////////////////////////
  52. // CCalcDrivApp construction
  53.  
  54. CCalcDrivApp::CCalcDrivApp()
  55. {
  56.     // TODO: add construction code here,
  57.     // Place all significant initialization in InitInstance
  58. }
  59.  
  60. /////////////////////////////////////////////////////////////////////////////
  61. // The one and only CCalcDrivApp object
  62.  
  63. CCalcDrivApp theApp;
  64.  
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CCalcDrivApp initialization
  67.  
  68. BOOL CCalcDrivApp::InitInstance()
  69. {   
  70. #ifdef _DEBUG
  71.     #ifndef _MAC
  72.         // turn on extra memory tracking
  73.         afxMemDF |= checkAlwaysMemDF;
  74.     #endif
  75. #endif
  76.  
  77.     // Initialize OLE 2.0 libraries
  78.     if (S_OK != OleInitialize(NULL))
  79.     {
  80.         AfxMessageBox(IDP_OLE_INIT_FAILED);
  81.         return FALSE;
  82.     }
  83.  
  84.     // Standard initialization
  85.     // If you are not using these features and wish to reduce the size
  86.     //  of your final executable, you should remove from the following
  87.     //  the specific initialization routines you do not need.
  88.  
  89.     Enable3dControls();    // Use 3d controls in dialogs
  90.  
  91.     // Simple application that simply invokes a dialog
  92.     CDriverDlg dlg;
  93.     m_pMainWnd = &dlg;
  94.     dlg.DoModal();
  95.  
  96.     return FALSE;   // don't run after the dialog is done
  97. }
  98.  
  99. int CCalcDrivApp::ExitInstance()
  100. {
  101.     OleUninitialize();
  102.     return CWinApp::ExitInstance();
  103. }
  104.  
  105. /////////////////////////////////////////////////////////////////////////////
  106. // CDriverDlg dialog
  107.  
  108. CDriverDlg::CDriverDlg(CWnd* pParent /*=NULL*/)
  109.     : CDialog(CDriverDlg::IDD, pParent)
  110. {
  111.     //{{AFX_DATA_INIT(CDriverDlg)
  112.     //}}AFX_DATA_INIT
  113. }
  114.  
  115. CDriverDlg::~CDriverDlg()
  116. {
  117.     
  118.     try {
  119.         // shut down the calculator
  120.         //  (since calculator shows its user-interface, it would stay active
  121.         //  if we didn't shut it down with a call to its Quit method)
  122.         m_calc->Close();
  123.         m_calc.Release(); // decrement reference count and if 0, delete server
  124.     } catch(_com_error& e) {
  125.         dump_com_error(e);
  126.     }
  127. }
  128.  
  129. void CDriverDlg::DoDataExchange(CDataExchange* pDX)
  130. {
  131.     CDialog::DoDataExchange(pDX);
  132.     //{{AFX_DATA_MAP(CDriverDlg)
  133.     DDX_Control(pDX, IDD_LAST_OPERATOR, m_stcOperator);
  134.     DDX_Control(pDX, IDD_LAST_OPERAND, m_stcOperand);
  135.     DDX_Control(pDX, IDC_LAST_ACCUM, m_stcAccum);
  136.     DDX_Control(pDX, IDC_EXPRESSION, m_editExpression);
  137.     //}}AFX_DATA_MAP
  138. }
  139.  
  140. BEGIN_MESSAGE_MAP(CDriverDlg, CDialog)
  141.     //{{AFX_MSG_MAP(CDriverDlg)
  142.     ON_BN_CLICKED(IDC_GO, OnGo)
  143.     ON_BN_CLICKED(IDC_SINGLE_STEP, OnSingleStep)
  144.     ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
  145.     //}}AFX_MSG_MAP
  146. END_MESSAGE_MAP()
  147.  
  148.  
  149. /////////////////////////////////////////////////////////////////////////////
  150. // CDriverDlg message handlers
  151.  
  152. void CDriverDlg::OnGo()
  153. {
  154.     // get current expression from the edit control
  155.     CString strExpression;
  156.     m_editExpression.GetWindowText(strExpression);
  157.     LPCTSTR psz = strExpression;
  158.  
  159.     // send all characters in the edit control from start to end
  160.     int nLen = strExpression.GetLength();
  161.     int nStart=0, nEnd=0;
  162.     m_editExpression.GetSel(nStart, nEnd);
  163.     if (nStart == nLen)
  164.         nStart = 0;
  165.     psz += nStart;
  166.     while (*psz != '\0')
  167.     {
  168.         TCHAR szTemp[2];
  169.         szTemp[0] = *psz;
  170.         szTemp[1] = '\0';
  171.         m_calc->Button(szTemp);  //Call the Button method to pass the button to the server
  172.         ++psz;
  173.     }
  174.     m_editExpression.SetSel(nLen, nLen);
  175.  
  176.     OnRefresh();    // refresh after all button commands sent
  177.     m_calc->Evaluate();  //Tell the server to evaluate the expression
  178.     m_calc->Display();
  179. }
  180.  
  181. void CDriverDlg::OnSingleStep()
  182. {
  183.     // get current expression from the edit control
  184.     CString strExpression;
  185.     m_editExpression.GetWindowText(strExpression);
  186.     LPCTSTR psz = strExpression;
  187.  
  188.     // send first character in selection, then move selection to next
  189.     int nLen = strExpression.GetLength();
  190.     int nStart=0, nEnd=0;
  191.     m_editExpression.GetSel(nStart, nEnd);
  192.     if (nStart == nLen)
  193.         nStart = 0;
  194.     psz += nStart;
  195.     if (*psz != '\0')
  196.     {
  197.         TCHAR szTemp[2];
  198.         szTemp[0] = *psz;
  199.         szTemp[1] = '\0';
  200.         m_calc->Button(szTemp);
  201.  
  202.         OnRefresh();        // refresh after each step
  203.  
  204.         // move to next character for next single-step
  205.         m_editExpression.SetSel(nStart+1,
  206.             min(strExpression.GetLength(), nStart+2));
  207.     }
  208.     else
  209.     {
  210.         m_calc->Evaluate();
  211.         m_calc->Display();
  212.         // stepping from end will start at beginning next time
  213.         m_editExpression.SetSel(0, min(strExpression.GetLength(), 1));
  214.     }
  215.     OnRefresh();    // refresh after all button commands sent
  216. }
  217.  
  218. void CDriverDlg::OnRefresh()
  219. {
  220.     TCHAR buf[64];
  221.     long lResult = m_calc->Operand;  //Get the value of the Operand property
  222.     wsprintf(buf, _T("%ld"), lResult);
  223.     m_stcOperand.SetWindowText(buf);
  224.  
  225.     long lAccum = m_calc->Accum;    //Get the value of the Accum property
  226.     wsprintf(buf, _T("%ld"), lAccum);
  227.     m_stcAccum.SetWindowText(buf);
  228.  
  229.     short nOp = m_calc->Operation;  //Get the value of the Operation property
  230.     static TCHAR operators[5] = { '?', '+', '-', '*', '/'};
  231.     if (nOp < 0 || nOp > 4)
  232.         nOp = 0;
  233.     wsprintf(buf, _T("%c"), operators[nOp]);
  234.     m_stcOperator.SetWindowText(buf);
  235. }
  236.  
  237. BOOL CDriverDlg::OnInitDialog()
  238. {
  239.     CDialog::OnInitDialog();
  240.  
  241.     // create the calculator object that we'll drive through OLE automation
  242.     // and init the COM object smart pointer
  243.  
  244.     try 
  245.     {
  246.         HRESULT hr = m_calc.GetActiveObject(__uuidof(CCCalcDlg));
  247.         if (FAILED(hr))
  248.         {
  249.             hr = m_calc.CreateInstance(__uuidof(CCCalcDlg));
  250.             if (FAILED(hr)) 
  251.                 _com_issue_error(hr);
  252.         }
  253.     }
  254.     catch (_com_error& ce)
  255.     {
  256.         dump_com_error (ce);
  257.         AfxMessageBox(IDP_UNABLE_TO_CREATE);
  258.         EndDialog(IDABORT);
  259.         return FALSE;
  260.     }
  261.     catch (...)
  262.     {
  263.         AfxMessageBox (_T("Unanticipated exception initializing ICalcDlgPtr object."));
  264.         EndDialog(IDABORT);
  265.         return FALSE;
  266.     }
  267.  
  268.     // attempt to make it visible
  269.     m_calc->Visible = VARIANT_TRUE;  //Set the Visible property
  270.     if (!m_calc->Visible)   //If the object can't be made visible...
  271.     {
  272.         AfxMessageBox(IDP_UNABLE_TO_SHOW);
  273.         EndDialog(IDABORT);
  274.         return FALSE;
  275.     }
  276.  
  277.     // refresh display to contents of the automation calculator
  278.     OnRefresh();
  279.  
  280.     return TRUE;  // return TRUE  unless you set the focus to a control
  281. }
  282.  
  283.