DRAW.H
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

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