home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / com / acdual / server / aclikdoc.cpp < prev    next >
C/C++ Source or Header  |  1998-04-02  |  10KB  |  427 lines

  1. // AClikDoc.cpp : implementation of the CAutoClickDoc class
  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 "AutoClik.h"
  15.  
  16. #include "AClikDoc.h"
  17. #include "Dialogs.h"
  18. #include "ClikPnt.h"
  19.  
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25.  
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CAutoClickDoc
  28.  
  29. IMPLEMENT_DYNCREATE(CAutoClickDoc, CDocument)
  30.  
  31. BEGIN_MESSAGE_MAP(CAutoClickDoc, CDocument)
  32.     //{{AFX_MSG_MAP(CAutoClickDoc)
  33.     ON_COMMAND(ID_EDIT_CHANGETEXT, OnEditChangetext)
  34.     //}}AFX_MSG_MAP
  35. END_MESSAGE_MAP()
  36.  
  37. BEGIN_DISPATCH_MAP(CAutoClickDoc, CDocument)
  38.     //{{AFX_DISPATCH_MAP(CAutoClickDoc)
  39.     DISP_PROPERTY_EX(CAutoClickDoc, "x", GetX, SetX, VT_I2)
  40.     DISP_PROPERTY_EX(CAutoClickDoc, "y", GetY, SetY, VT_I2)
  41.     DISP_PROPERTY_EX(CAutoClickDoc, "Position", GetPosition, SetPosition, VT_DISPATCH)
  42.     DISP_PROPERTY_EX(CAutoClickDoc, "text", GetText, SetText, VT_BSTR)
  43.     DISP_FUNCTION(CAutoClickDoc, "RefreshWindow", Refresh, VT_EMPTY, VTS_NONE)
  44.     DISP_FUNCTION(CAutoClickDoc, "SetAllProps", SetAllProps, VT_EMPTY, VTS_I2 VTS_I2 VTS_BSTR)
  45.     DISP_FUNCTION(CAutoClickDoc, "ShowWindow", ShowWindow, VT_EMPTY, VTS_NONE)
  46.     DISP_FUNCTION(CAutoClickDoc, "TestError", TestErrorHandler, VT_EMPTY, VTS_I2)
  47.     //}}AFX_DISPATCH_MAP
  48. END_DISPATCH_MAP()
  49.  
  50. // DUAL_SUPPORT_START
  51. //    Original code:
  52. //       // Note: we add support for IID_IAClick to support typesafe binding
  53. //       //  from VBA.  This IID must match the GUID that is attached to the
  54. //       //  dispinterface in the .ODL file.
  55. //
  56. //       // {47D53E05-CC33-11CE-8F35-00DD01109044}
  57. //       static const IID IID_IAClick =
  58. //       { 0x47d53e05, 0xcc33, 0x11ce, { 0x8f, 0x35, 0x0, 0xdd, 0x1, 0x10, 0x90, 0x44 } };
  59. //
  60. //       BEGIN_INTERFACE_MAP(CAutoClickDoc, CDocument)
  61. //          INTERFACE_PART(CAutoClickDoc, IID_IAClick, Dispatch)
  62. //       END_INTERFACE_MAP()
  63. //
  64.  
  65. // Note: we add support for DIID_IAClick to support typesafe binding
  66. // from VBA.  We add support for IID_IDualAClick to support our dual
  67. // interface. See ACDual.H for the definition of DIID_IAClick and
  68. // IID_IDualAClick.
  69. //
  70. // DUAL_ERRORINFO_PART indicates we support OLE Automation
  71. // error handling.
  72. //
  73. BEGIN_INTERFACE_MAP(CAutoClickDoc, CDocument)
  74.     INTERFACE_PART(CAutoClickDoc, DIID_IAClick, Dispatch)
  75.     INTERFACE_PART(CAutoClickDoc, IID_IDualAClick, DualAClick)
  76.     DUAL_ERRORINFO_PART(CAutoClickDoc)
  77. END_INTERFACE_MAP()
  78.  
  79. // DUAL_SUPPORT_END
  80.  
  81. /////////////////////////////////////////////////////////////////////////////
  82. // CAutoClickDoc construction/destruction
  83.  
  84. CAutoClickDoc::CAutoClickDoc()
  85. {
  86.     EnableAutomation();
  87.     m_pt = CPoint(10, 10);
  88.     m_str = _T("Automation!");
  89.  
  90.     AfxOleLockApp();
  91. }
  92.  
  93. CAutoClickDoc::~CAutoClickDoc()
  94. {
  95.     AfxOleUnlockApp();
  96. }
  97.  
  98. BOOL CAutoClickDoc::OnNewDocument()
  99. {
  100.     if (!CDocument::OnNewDocument())
  101.         return FALSE;
  102.  
  103.     // TODO: add reinitialization code here
  104.     // (SDI documents will reuse this document)
  105.  
  106.     return TRUE;
  107. }
  108.  
  109. void CAutoClickDoc::Refresh()
  110. {
  111.     UpdateAllViews(NULL);
  112.     SetModifiedFlag();
  113. }
  114.  
  115. /////////////////////////////////////////////////////////////////////////////
  116. // CAutoClickDoc serialization
  117.  
  118. void CAutoClickDoc::Serialize(CArchive& ar)
  119. {
  120.     if (ar.IsStoring())
  121.     {
  122.         ar << m_pt << m_str;
  123.     }
  124.     else
  125.     {
  126.         ar >> m_pt >> m_str;
  127.     }
  128. }
  129.  
  130. /////////////////////////////////////////////////////////////////////////////
  131. // CAutoClickDoc diagnostics
  132.  
  133. #ifdef _DEBUG
  134. void CAutoClickDoc::AssertValid() const
  135. {
  136.     CDocument::AssertValid();
  137. }
  138.  
  139. void CAutoClickDoc::Dump(CDumpContext& dc) const
  140. {
  141.     CDocument::Dump(dc);
  142. }
  143. #endif //_DEBUG
  144.  
  145. /////////////////////////////////////////////////////////////////////////////
  146. // CAutoClickDoc commands
  147.  
  148. void CAutoClickDoc::OnEditChangetext()
  149. {
  150.     CChangeText dlg;
  151.     dlg.m_str = m_str;
  152.     if (dlg.DoModal())
  153.     {
  154.         m_str = dlg.m_str;
  155.         Refresh();
  156.     }
  157. }
  158.  
  159. short CAutoClickDoc::GetX()
  160. {
  161.     return (short)m_pt.x;
  162. }
  163.  
  164. void CAutoClickDoc::SetX(short nNewValue)
  165. {
  166.     m_pt.x = nNewValue;
  167.     Refresh();
  168. }
  169.  
  170. short CAutoClickDoc::GetY()
  171. {
  172.     return (short)m_pt.y;
  173. }
  174.  
  175. void CAutoClickDoc::SetY(short nNewValue)
  176. {
  177.     m_pt.y = nNewValue;
  178.     Refresh();
  179. }
  180.  
  181. BSTR CAutoClickDoc::GetText()
  182. {
  183.     return m_str.AllocSysString();
  184. }
  185.  
  186. void CAutoClickDoc::SetText(LPCTSTR lpszNewValue)
  187. {
  188.     m_str = lpszNewValue;
  189.     Refresh();
  190. }
  191.  
  192. void CAutoClickDoc::SetAllProps(short x, short y, LPCTSTR text)
  193. {
  194.     m_pt.x = x;
  195.     m_pt.y = y;
  196.     m_str = text;
  197.     Refresh();
  198. }
  199.  
  200. void CAutoClickDoc::ShowWindow()
  201. {
  202.     POSITION pos = GetFirstViewPosition();
  203.     CView* pView = GetNextView(pos);
  204.     if (pView != NULL)
  205.     {
  206.         CFrameWnd* pFrameWnd = pView->GetParentFrame();
  207.         pFrameWnd->ActivateFrame(SW_SHOW);
  208.         pFrameWnd = pFrameWnd->GetParentFrame();
  209.         if (pFrameWnd != NULL)
  210.             pFrameWnd->ActivateFrame(SW_SHOW);
  211.     }
  212.     Refresh();
  213. }
  214.  
  215. LPDISPATCH CAutoClickDoc::GetPosition()
  216. {
  217.     CAutoClickPoint* pPos = new CAutoClickPoint;
  218.     pPos->SetClickPoint(m_pt);
  219.  
  220.     LPDISPATCH lpResult = pPos->GetIDispatch(FALSE);
  221.     return lpResult;
  222. }
  223.  
  224. void CAutoClickDoc::SetPosition(LPDISPATCH newValue)
  225. {
  226.     CAutoClickPoint* pPos = (CAutoClickPoint*)CCmdTarget::FromIDispatch(newValue);
  227.     if (pPos != NULL && pPos->IsKindOf(RUNTIME_CLASS(CAutoClickPoint)))
  228.     {
  229.         m_pt = pPos->GetClickPoint();
  230.         Refresh();
  231.     }
  232. }
  233.  
  234. void CAutoClickDoc::TestErrorHandler(short wCode)
  235. {
  236.     CString strError;
  237.     strError.Format(IDS_TESTERROR, wCode);
  238.     AfxThrowOleDispatchException((WORD)wCode,
  239.                                  strError,
  240.                                  (UINT)wCode);
  241. }
  242.  
  243. // DUAL_SUPPORT_START
  244.  
  245. // delegate standard IDispatch methods to MFC IDispatch implementation
  246. DELEGATE_DUAL_INTERFACE(CAutoClickDoc, DualAClick)
  247.  
  248. // Our method and property functions can generally just
  249. // delegate back to the methods we generated using
  250. // ClassWizard. However, if we set up properties to
  251. // access variables directly, we will need to write the
  252. //  code to get/put the value into the variable.
  253.  
  254. STDMETHODIMP CAutoClickDoc::XDualAClick::put_text(BSTR newText)
  255. {
  256.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  257.  
  258.     TRY_DUAL(IID_IDualAClick)
  259.     {
  260.         // MFC automatically converts from Unicode BSTR to
  261.         // Ansi CString, if necessary...
  262.         pThis->m_str = newText;
  263.         pThis->Refresh();
  264.         return NOERROR;
  265.     }
  266.     CATCH_ALL_DUAL
  267. }
  268.  
  269. STDMETHODIMP CAutoClickDoc::XDualAClick::get_text(BSTR* retval)
  270. {
  271.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  272.  
  273.     TRY_DUAL(IID_IDualAClick)
  274.     {
  275.         // MFC automatically converts from Ansi CString to
  276.         // Unicode BSTR, if necessary...
  277.         pThis->m_str.SetSysString(retval);
  278.         return NOERROR;
  279.     }
  280.     CATCH_ALL_DUAL
  281. }
  282.  
  283. STDMETHODIMP CAutoClickDoc::XDualAClick::put_x(short newX)
  284. {
  285.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  286.  
  287.     TRY_DUAL(IID_IDualAClick)
  288.     {
  289.         pThis->SetX(newX);
  290.         return NOERROR;
  291.     }
  292.     CATCH_ALL_DUAL
  293. }
  294.  
  295. STDMETHODIMP CAutoClickDoc::XDualAClick::get_x(short FAR* retval)
  296. {
  297.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  298.  
  299.     TRY_DUAL(IID_IDualAClick)
  300.     {
  301.         *retval = pThis->GetX();
  302.         return NOERROR;
  303.     }
  304.     CATCH_ALL_DUAL
  305. }
  306.  
  307. STDMETHODIMP CAutoClickDoc::XDualAClick::put_y(short newY)
  308. {
  309.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  310.  
  311.     TRY_DUAL(IID_IDualAClick)
  312.     {
  313.         pThis->SetY(newY);
  314.         return NOERROR;
  315.     }
  316.     CATCH_ALL_DUAL
  317. }
  318.  
  319. STDMETHODIMP CAutoClickDoc::XDualAClick::get_y(short FAR* retval)
  320. {
  321.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  322.  
  323.     TRY_DUAL(IID_IDualAClick)
  324.     {
  325.         *retval = pThis->GetY();
  326.         return NOERROR;
  327.     }
  328.     CATCH_ALL_DUAL
  329. }
  330.  
  331. STDMETHODIMP CAutoClickDoc::XDualAClick::put_Position(
  332.     IDualAutoClickPoint FAR* newPosition)
  333. {
  334.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  335.  
  336.     TRY_DUAL(IID_IDualAClick)
  337.     {
  338.         // Passing IDispatch-based interface pointers around doesn't
  339.         // work quite as smoothly as you might think, especially if
  340.         // you need to call CCmdTarget::FromIDispatch(), as our
  341.         // SetPosition method does. Here's one way to work around this -
  342.         // give SetPosition the original IDispatch that MFC sets up.
  343.  
  344.         LPDISPATCH lpDisp = NULL;
  345.         newPosition->QueryInterface(IID_IDispatch, (LPVOID*)&lpDisp);
  346.         pThis->SetPosition(lpDisp);
  347.         lpDisp->Release();
  348.         return NOERROR;
  349.     }
  350.     CATCH_ALL_DUAL
  351. }
  352.  
  353. STDMETHODIMP CAutoClickDoc::XDualAClick::get_Position(
  354.     IDualAutoClickPoint FAR* FAR* retval)
  355. {
  356.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  357.  
  358.     TRY_DUAL(IID_IDualAClick)
  359.     {
  360.         // GetPosition gives us the original IDispatch that MFC
  361.         // sets up, so we need to QI for the custom interface.
  362.         LPDISPATCH lpDisp;
  363.         lpDisp = pThis->GetPosition();
  364.         lpDisp->QueryInterface(IID_IDualAutoClickPoint, (LPVOID*)retval);
  365.         lpDisp->Release();
  366.  
  367.         return NOERROR;
  368.     }
  369.     CATCH_ALL_DUAL
  370. }
  371.  
  372. STDMETHODIMP CAutoClickDoc::XDualAClick::RefreshWindow()
  373. {
  374.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  375.  
  376.     TRY_DUAL(IID_IDualAClick)
  377.     {
  378.         pThis->Refresh();
  379.         return NOERROR;
  380.     }
  381.     CATCH_ALL_DUAL
  382. }
  383.  
  384. STDMETHODIMP CAutoClickDoc::XDualAClick::SetAllProps(
  385.     short x, short y, BSTR text)
  386. {
  387.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  388.  
  389.     TRY_DUAL(IID_IDualAClick)
  390.     {
  391.         CString strTemp(text);
  392.         pThis->SetAllProps(x, y, strTemp);
  393.         return NOERROR;
  394.     }
  395.     CATCH_ALL_DUAL
  396. }
  397.  
  398. STDMETHODIMP CAutoClickDoc::XDualAClick::ShowWindow()
  399. {
  400.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  401.  
  402.     TRY_DUAL(IID_IDualAClick)
  403.     {
  404.         pThis->ShowWindow();
  405.         return NOERROR;
  406.     }
  407.     CATCH_ALL_DUAL
  408. }
  409.  
  410. STDMETHODIMP CAutoClickDoc::XDualAClick::TestError(short wCode)
  411. {
  412.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  413.  
  414.     TRY_DUAL(IID_IDualAClick)
  415.     {
  416.         pThis->TestErrorHandler(wCode);
  417.         return NOERROR;
  418.     }
  419.     CATCH_ALL_DUAL
  420. }
  421.  
  422. // Implement ISupportErrorInfo to indicate we support the
  423. // OLE Automation error handler.
  424. IMPLEMENT_DUAL_ERRORINFO(CAutoClickDoc, IID_IDualAClick)
  425.  
  426. // DUAL_SUPPORT_END
  427.