home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / atl / dcom / drawctl / draw.h < prev    next >
C/C++ Source or Header  |  1998-03-26  |  8KB  |  290 lines

  1. // Draw.h : Declaration of the CDrawCtl
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12.  
  13. #include <objsafe.h>
  14. #include "resource.h"       // main symbols
  15. #include "..\\drawserv\\drawserv.h"
  16.  
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CDrawCtl
  19. class CDrawCtl :
  20.     public CComObjectRoot,
  21.     public CComCoClass<CDrawCtl, &CLSID_CDrawCtl>,
  22.     public CComControl<CDrawCtl>,
  23.     public IPersistStreamInitImpl<CDrawCtl>,
  24.     public IPersistStorageImpl<CDrawCtl>,
  25.     public IQuickActivateImpl<CDrawCtl>,
  26.     public IProvideClassInfo2Impl<&CLSID_CDrawCtl, NULL, &LIBID_DRAWCTLLib>,
  27.     public IOleControlImpl<CDrawCtl>,
  28.     public IOleObjectImpl<CDrawCtl>,
  29.     public IOleInPlaceActiveObjectImpl<CDrawCtl>,
  30.     public IViewObjectExImpl<CDrawCtl>,
  31.     public IOleInPlaceObjectWindowlessImpl<CDrawCtl>,
  32.     public IDataObjectImpl<CDrawCtl>,
  33.     public ISupportErrorInfo,
  34.     public IDispatchImpl<IDrawCtl, &IID_IDrawCtl, &LIBID_DRAWCTLLib>,
  35.     public IDispatchImpl<IDrawServ, &IID_IDrawServ, &LIBID_DRAWCTLLib>,
  36.     public IObjectSafetyImpl<CDrawCtl, INTERFACESAFE_FOR_UNTRUSTED_CALLER>
  37. {
  38. public:
  39.     CDrawCtl()
  40.     {
  41.         m_bDragging = FALSE;
  42.         m_col = RGB(255, 0, 0);
  43.         m_dwSafety = 0;     // We haven't been asked to be safe yet
  44.         m_pDrawServ = NULL; // We're not connected yet
  45.     }
  46.     ~CDrawCtl()
  47.     {
  48.         // Disconnect if necessary
  49.         Disconnect();
  50.     }
  51.  
  52. DECLARE_REGISTRY_RESOURCEID(IDR_DrawCtl)
  53. DECLARE_GET_CONTROLLING_UNKNOWN()
  54.  
  55. BEGIN_COM_MAP(CDrawCtl)
  56.     COM_INTERFACE_ENTRY(IDrawCtl)
  57.     COM_INTERFACE_ENTRY2(IDispatch,IDrawCtl)
  58.     COM_INTERFACE_ENTRY(IDrawServ)
  59.     COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
  60.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
  61.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
  62.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)
  63.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)
  64.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
  65.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
  66.     COM_INTERFACE_ENTRY_IMPL(IOleControl)
  67.     COM_INTERFACE_ENTRY_IMPL(IOleObject)
  68.     COM_INTERFACE_ENTRY_IMPL(IQuickActivate)
  69.     COM_INTERFACE_ENTRY_IMPL(IPersistStorage)
  70.     COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)
  71.     COM_INTERFACE_ENTRY_IMPL(IDataObject)
  72.     COM_INTERFACE_ENTRY(IObjectSafety)
  73.     COM_INTERFACE_ENTRY(IProvideClassInfo)
  74.     COM_INTERFACE_ENTRY(IProvideClassInfo2)
  75.     COM_INTERFACE_ENTRY(ISupportErrorInfo)
  76. END_COM_MAP()
  77.  
  78. BEGIN_MSG_MAP(CDrawCtl)
  79.     MESSAGE_HANDLER(WM_PAINT, OnPaint)
  80.     MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
  81.     MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
  82.     MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
  83. END_MSG_MAP()
  84.  
  85. BEGIN_PROPERTY_MAP(CDrawCtl)
  86. END_PROPERTY_MAP()
  87.  
  88. // ISupportsErrorInfo
  89.     STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
  90.  
  91. // IDrawCtl
  92. public:
  93.  
  94. // Implementation
  95.     // We currently don't repaint so do nothing
  96.     HRESULT OnDraw(ATL_DRAWINFO& di)
  97.     {
  98.         return 0;
  99.     }
  100.  
  101.     // Needed to resolve ambiguity with Draw method on IDrawServ interface
  102.     STDMETHOD(Draw)(DWORD dwDrawAspect, LONG lindex, void  *pvAspect,
  103.                     DVTARGETDEVICE  *ptd, HDC hicTargetDev, HDC hdcDraw,
  104.                     LPCRECTL prcBounds, LPCRECTL prcWBounds,
  105.                     BOOL (__stdcall  *pfnContinue)(DWORD dwContinue),
  106.                     DWORD dwContinue)
  107.     {
  108.         return IViewObjectExImpl<CDrawCtl>::Draw(dwDrawAspect, lindex, pvAspect,
  109.                     ptd, hicTargetDev, hdcDraw,
  110.                     prcBounds, prcWBounds,
  111.                     pfnContinue,
  112.                     dwContinue);
  113.     }
  114.  
  115.     // IDrawServ
  116.     STDMETHOD(Draw)(long x1, long y1, long x2, long y2, unsigned long col)
  117.     {
  118.         HRESULT hr;
  119.         HDC  hDC;
  120.         HPEN hOldPen;
  121.         POINT ptOld;
  122.  
  123.         // If we're not in place active then we don't necessarily have a window,
  124.         // so we can't draw.
  125.         if (!m_bInPlaceActive)
  126.             return S_OK;
  127.         if (m_bWndLess)
  128.         {
  129.             // We're windowless so we need the DC from the client
  130.             hr = m_spInPlaceSite->GetDC(NULL, 0, &hDC);
  131.             ATLASSERT(SUCCEEDED(hr));
  132.             // We need to reset the origin if we are drawing in client coordinates
  133.             ::SetWindowOrgEx(hDC, -m_rcPos.left, -m_rcPos.top, &ptOld);
  134.         }
  135.         else
  136.             hDC  = ::GetDC(m_hWnd);
  137.  
  138.         HPEN hPen = ::CreatePen(PS_SOLID, 2, (COLORREF)col);
  139.         hOldPen = (HPEN)::SelectObject(hDC, hPen);
  140.         ::MoveToEx(hDC, x1, y1, NULL);
  141.         ::LineTo(hDC, x2, y2);
  142.         ::SelectObject(hDC, hOldPen);
  143.         ::DeleteObject(hPen);
  144.  
  145.         if (m_bWndLess)
  146.         {
  147.             ::SetWindowOrgEx(hDC, ptOld.x, ptOld.y, NULL);
  148.             hr = m_spInPlaceSite->ReleaseDC(hDC);
  149.         }
  150.         else
  151.             ::ReleaseDC(m_hWnd, hDC);
  152.  
  153.         return S_OK;
  154.     }
  155.  
  156.     // IDrawCtl
  157.     STDMETHOD(Connect)(BSTR pFileName)
  158.     {
  159.         HRESULT hr;
  160.  
  161.         // Everyone can connect
  162.         hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
  163.             RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL);
  164.  
  165.         COSERVERINFO si;
  166.         MULTI_QI     qi;
  167.  
  168.         si.dwReserved1 = 0;
  169.         si.pwszName = OLE2W(pFileName);
  170.         si.pAuthInfo = NULL;
  171.         si.dwReserved2 = 0;
  172.  
  173.         qi.pIID = &IID_IDrawServ;
  174.         qi.pItf = NULL;
  175.         //qi.hr = 0;
  176.  
  177.         hr = CoCreateInstanceEx(CLSID_CDrawServ, NULL, CLSCTX_SERVER, &si, 1, &qi);
  178.         if (FAILED(hr))
  179.         {
  180.             ATLTRACE(_T("CoCreateInstanceEx failed"));
  181.             return hr;
  182.         }
  183.         if (FAILED(qi.hr))
  184.         {
  185.             ATLTRACE(_T("Failed to connect to server"));
  186.             return qi.hr;
  187.         }
  188.         m_pDrawServ = (IDrawServ*)qi.pItf;
  189.  
  190.  
  191.         if (FAILED(AtlAdvise(m_pDrawServ, GetUnknown(), IID_IDrawServ, &m_dwDrawServ)))
  192.         {
  193.             m_pDrawServ->Release();
  194.             m_pDrawServ = NULL;
  195.             hr = E_FAIL;
  196.         }
  197.         return hr;
  198.     }
  199.  
  200.     // IDrawCtl
  201.     STDMETHOD(Disconnect)()
  202.     {
  203.         if (m_pDrawServ != NULL)
  204.         {
  205.             AtlUnadvise(m_pDrawServ, IID_IDrawServ, m_dwDrawServ);
  206.             m_pDrawServ->Release();
  207.             m_pDrawServ = NULL;
  208.         }
  209.         return S_OK;
  210.     }
  211.  
  212. private:
  213.     LRESULT OnLButtonDown(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  214.     {
  215.         if (m_bWndLess)
  216.             m_spInPlaceSite->SetCapture(TRUE);
  217.         else
  218.             ::SetCapture(m_hWnd);
  219.  
  220.         m_xPos = LOWORD(lParam);  // horizontal position of cursor
  221.         m_yPos = HIWORD(lParam);  // vertical position of cursor
  222.         m_bDragging = TRUE;
  223.         {
  224.             TCHAR aMsg[80];
  225.             wsprintf(aMsg,_T("%d,%d\n"),m_xPos,m_yPos);
  226.             ATLTRACE(aMsg);
  227.         }
  228.         return 0;
  229.     }
  230.  
  231.     LRESULT OnLButtonUp(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  232.     {
  233.         if (m_bWndLess)
  234.             m_spInPlaceSite->SetCapture(FALSE);
  235.         else
  236.             ::ReleaseCapture();
  237.         m_bDragging = FALSE;
  238.         return 0;
  239.     }
  240.  
  241.     LRESULT OnMouseMove(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  242.     {
  243.         if (m_bDragging && m_pDrawServ)
  244.         {
  245.             HRESULT hr;
  246.             RECT rcObject;
  247.             POINT pt;
  248.             WORD xPos = LOWORD(lParam);
  249.             WORD yPos = HIWORD(lParam);
  250.             pt.x = xPos;
  251.             pt.y = yPos;
  252.  
  253.             // If we are windowless then we use the client's coordinates,
  254.             // otherwise we are offset from 0,0.
  255.             rcObject = m_rcPos;
  256.             if (!m_bWndLess)
  257.             {
  258.                 OffsetRect(&rcObject, -rcObject.left, -rcObject.top);
  259.             }
  260.  
  261.             if (PtInRect(&rcObject,pt))
  262.             {
  263.                 hr = m_pDrawServ->Draw(
  264.                     m_xPos - rcObject.left, m_yPos - rcObject.top,
  265.                     xPos - rcObject.left, yPos - rcObject.top,
  266.                     m_col);
  267.                 if (FAILED(hr))
  268.                 {
  269.                     TCHAR buf[32];
  270.                     // There's an error so we might as well disconnect to stop multiple errors
  271.                     Disconnect();
  272.                     wsprintf(buf, _T("Error calling server's Draw(%x)"), hr);
  273.                     ::MessageBox(NULL,buf,_T(""),0);
  274.                 }
  275.                 m_xPos = xPos;
  276.                 m_yPos = yPos;
  277.             }
  278.         }
  279.         return 0;
  280.     }
  281.  
  282.     IDrawServ*  m_pDrawServ;
  283.     DWORD       m_dwDrawServ;   // Connection cookie
  284.     WORD        m_xPos;         // Current position
  285.     WORD        m_yPos;         // when drawing.
  286.     BOOL        m_bDragging;    // Are we drawing? (left mouse button down)
  287.     COLORREF    m_col;
  288.     DWORD       m_dwSafety;     // Code safety level
  289. };
  290.