home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / acdual / server / aclikdoc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  10.4 KB  |  436 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(CAutoClickDoc, "text", m_str, VT_BSTR)
  40.     DISP_PROPERTY_EX(CAutoClickDoc, "x", GetX, SetX, VT_I2)
  41.     DISP_PROPERTY_EX(CAutoClickDoc, "y", GetY, SetY, VT_I2)
  42.     DISP_PROPERTY_EX(CAutoClickDoc, "Position", GetPosition, SetPosition, VT_DISPATCH)
  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. void CAutoClickDoc::SetAllProps(short x, short y, LPCTSTR text)
  182. {
  183.     m_pt.x = x;
  184.     m_pt.y = y;
  185.     m_str = text;
  186.     Refresh();
  187. }
  188.  
  189. void CAutoClickDoc::ShowWindow()
  190. {
  191.     POSITION pos = GetFirstViewPosition();
  192.     CView* pView = GetNextView(pos);
  193.     if (pView != NULL)
  194.     {
  195.         CFrameWnd* pFrameWnd = pView->GetParentFrame();
  196.         pFrameWnd->ActivateFrame(SW_SHOW);
  197.         pFrameWnd = pFrameWnd->GetParentFrame();
  198.         if (pFrameWnd != NULL)
  199.             pFrameWnd->ActivateFrame(SW_SHOW);
  200.     }
  201. }
  202.  
  203. LPDISPATCH CAutoClickDoc::GetPosition()
  204. {
  205.     CAutoClickPoint* pPos = new CAutoClickPoint;
  206.     pPos->SetClickPoint(m_pt);
  207.  
  208.     LPDISPATCH lpResult = pPos->GetIDispatch(FALSE);
  209.     return lpResult;
  210. }
  211.  
  212. void CAutoClickDoc::SetPosition(LPDISPATCH newValue)
  213. {
  214.     CAutoClickPoint* pPos = (CAutoClickPoint*)CCmdTarget::FromIDispatch(newValue);
  215.     if (pPos != NULL && pPos->IsKindOf(RUNTIME_CLASS(CAutoClickPoint)))
  216.     {
  217.         m_pt = pPos->GetClickPoint();
  218.         Refresh();
  219.     }
  220. }
  221.  
  222. void CAutoClickDoc::TestErrorHandler(short wCode)
  223. {
  224.     CString strError;
  225.     strError.Format(IDS_TESTERROR, wCode);
  226.     AfxThrowOleDispatchException((WORD)wCode,
  227.                                  strError,
  228.                                  (UINT)wCode);
  229. }
  230.  
  231. // DUAL_SUPPORT_START
  232.  
  233. // delegate standard IDispatch methods to MFC IDispatch implementation
  234. DELEGATE_DUAL_INTERFACE(CAutoClickDoc, DualAClick)
  235.  
  236. // Our method and property functions can generally just
  237. // delegate back to the methods we generated using
  238. // ClassWizard. However, if we set up properties to
  239. // access variables directly, we will need to write the
  240. //  code to get/put the value into the variable.
  241.  
  242. STDMETHODIMP CAutoClickDoc::XDualAClick::put_text(BSTR newText)
  243. {
  244.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  245.  
  246.     TRY_DUAL(IID_IDualAClick)
  247.     {
  248.         // MFC automatically converts from Unicode BSTR to
  249.         // Ansi CString, if necessary...
  250.         pThis->m_str = newText;
  251.         return NOERROR;
  252.     }
  253.     CATCH_ALL_DUAL
  254. }
  255.  
  256. STDMETHODIMP CAutoClickDoc::XDualAClick::get_text(BSTR* retval)
  257. {
  258.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  259.  
  260.     TRY_DUAL(IID_IDualAClick)
  261.     {
  262.         // MFC automatically converts from Ansi CString to
  263.         // Unicode BSTR, if necessary...
  264.         pThis->m_str.SetSysString(retval);
  265.         return NOERROR;
  266.     }
  267.     CATCH_ALL_DUAL
  268. }
  269.  
  270. STDMETHODIMP CAutoClickDoc::XDualAClick::put_x(short newX)
  271. {
  272.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  273.  
  274.     TRY_DUAL(IID_IDualAClick)
  275.     {
  276.         pThis->SetX(newX);
  277.         return NOERROR;
  278.     }
  279.     CATCH_ALL_DUAL
  280. }
  281.  
  282. STDMETHODIMP CAutoClickDoc::XDualAClick::get_x(short FAR* retval)
  283. {
  284.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  285.  
  286.     TRY_DUAL(IID_IDualAClick)
  287.     {
  288.         *retval = pThis->GetX();
  289.         return NOERROR;
  290.     }
  291.     CATCH_ALL_DUAL
  292. }
  293.  
  294. STDMETHODIMP CAutoClickDoc::XDualAClick::put_y(short newY)
  295. {
  296.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  297.  
  298.     TRY_DUAL(IID_IDualAClick)
  299.     {
  300.         pThis->SetY(newY);
  301.         return NOERROR;
  302.     }
  303.     CATCH_ALL_DUAL
  304. }
  305.  
  306. STDMETHODIMP CAutoClickDoc::XDualAClick::get_y(short FAR* retval)
  307. {
  308.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  309.  
  310.     TRY_DUAL(IID_IDualAClick)
  311.     {
  312.         *retval = pThis->GetY();
  313.         return NOERROR;
  314.     }
  315.     CATCH_ALL_DUAL
  316. }
  317.  
  318. STDMETHODIMP CAutoClickDoc::XDualAClick::put_Position(
  319.     IDualAutoClickPoint FAR* newPosition)
  320. {
  321.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  322.  
  323.     TRY_DUAL(IID_IDualAClick)
  324.     {
  325.         // Passing IDispatch-based interface pointers around doesn't
  326.         // work quite as smoothly as you might think, especially if
  327.         // you need to call CCmdTarget::FromIDispatch(), as our
  328.         // SetPosition method does. Here's one way to work around this -
  329.         // give SetPosition the original IDispatch that MFC sets up.
  330.  
  331.         LPDISPATCH lpDisp = NULL;
  332.         newPosition->QueryInterface(IID_IDispatch, (LPVOID*)&lpDisp);
  333.         pThis->SetPosition(lpDisp);
  334.         lpDisp->Release();
  335.         return NOERROR;
  336.     }
  337.     CATCH_ALL_DUAL
  338. }
  339.  
  340. STDMETHODIMP CAutoClickDoc::XDualAClick::putref_Position(
  341.     IDualAutoClickPoint FAR* newPosition)
  342. {
  343.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  344.  
  345.     TRY_DUAL(IID_IDualAClick)
  346.     {
  347.         // Passing IDispatch-based interface pointers around doesn't
  348.         // work quite as smoothly as you might think, especially if
  349.         // you need to call CCmdTarget::FromIDispatch(), as our
  350.         // SetPosition method does. Here's one way to work around this -
  351.         // give SetPosition the original IDispatch that MFC sets up.
  352.  
  353.         LPDISPATCH lpDisp = NULL;
  354.         newPosition->QueryInterface(IID_IDispatch, (LPVOID*)&lpDisp);
  355.         pThis->SetPosition(lpDisp);
  356.         lpDisp->Release();
  357.         return NOERROR;
  358.     }
  359.     CATCH_ALL_DUAL
  360. }
  361.  
  362. STDMETHODIMP CAutoClickDoc::XDualAClick::get_Position(
  363.     IDualAutoClickPoint FAR* FAR* retval)
  364. {
  365.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  366.  
  367.     TRY_DUAL(IID_IDualAClick)
  368.     {
  369.         // GetPosition gives us the original IDispatch that MFC
  370.         // sets up, so we need to QI for the custom interface.
  371.         LPDISPATCH lpDisp;
  372.         lpDisp = pThis->GetPosition();
  373.         lpDisp->QueryInterface(IID_IDualAutoClickPoint, (LPVOID*)retval);
  374.         lpDisp->Release();
  375.  
  376.         return NOERROR;
  377.     }
  378.     CATCH_ALL_DUAL
  379. }
  380.  
  381. STDMETHODIMP CAutoClickDoc::XDualAClick::RefreshWindow()
  382. {
  383.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  384.  
  385.     TRY_DUAL(IID_IDualAClick)
  386.     {
  387.         pThis->Refresh();
  388.         return NOERROR;
  389.     }
  390.     CATCH_ALL_DUAL
  391. }
  392.  
  393. STDMETHODIMP CAutoClickDoc::XDualAClick::SetAllProps(
  394.     short x, short y, BSTR text)
  395. {
  396.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  397.  
  398.     TRY_DUAL(IID_IDualAClick)
  399.     {
  400.         CString strTemp(text);
  401.         pThis->SetAllProps(x, y, strTemp);
  402.         return NOERROR;
  403.     }
  404.     CATCH_ALL_DUAL
  405. }
  406.  
  407. STDMETHODIMP CAutoClickDoc::XDualAClick::ShowWindow()
  408. {
  409.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  410.  
  411.     TRY_DUAL(IID_IDualAClick)
  412.     {
  413.         pThis->ShowWindow();
  414.         return NOERROR;
  415.     }
  416.     CATCH_ALL_DUAL
  417. }
  418.  
  419. STDMETHODIMP CAutoClickDoc::XDualAClick::TestError(short wCode)
  420. {
  421.     METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
  422.  
  423.     TRY_DUAL(IID_IDualAClick)
  424.     {
  425.         pThis->TestErrorHandler(wCode);
  426.         return NOERROR;
  427.     }
  428.     CATCH_ALL_DUAL
  429. }
  430.  
  431. // Implement ISupportErrorInfo to indicate we support the
  432. // OLE Automation error handler.
  433. IMPLEMENT_DUAL_ERRORINFO(CAutoClickDoc, IID_IDualAClick)
  434.  
  435. // DUAL_SUPPORT_END
  436.