home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / com / mfccalc / server / calcdlg.cpp next >
Encoding:
C/C++ Source or Header  |  1998-04-03  |  12.4 KB  |  519 lines

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