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

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