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

Windows编程

开发平台:

Visual C++

  1. /*
  2.  * DROPTGT.CPP
  3.  * Cosmo Chapter 21
  4.  *
  5.  * Implementation of the IDropTarget interface.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13. #include "cosmo.h"
  14. /*
  15.  * CDropTarget::CDropTarget
  16.  * CDropTarget::~CDropTarget
  17.  *
  18.  * Constructor Parameters:
  19.  *  pDoc            PCCosmoDoc of the document containing us.
  20.  */
  21. CDropTarget::CDropTarget(PCCosmoDoc pDoc)
  22.     {
  23.     m_cRef=0;
  24.     m_pDoc=pDoc;
  25.     m_pIDataObject=NULL;
  26.     return;
  27.     }
  28. CDropTarget::~CDropTarget(void)
  29.     {
  30.     return;
  31.     }
  32. /*
  33.  * CDropTarget::QueryInterface
  34.  * CDropTarget::AddRef
  35.  * CDropTarget::Release
  36.  *
  37.  * Purpose:
  38.  *  IUnknown members for CDropTarget object.
  39.  */
  40. STDMETHODIMP CDropTarget::QueryInterface(REFIID riid, PPVOID ppv)
  41.     {
  42.     *ppv=NULL;
  43.     if (IID_IUnknown==riid || IID_IDropTarget==riid)
  44.         *ppv=this;
  45.     if (NULL!=*ppv)
  46.         {
  47.         ((LPUNKNOWN)*ppv)->AddRef();
  48.         return NOERROR;
  49.         }
  50.     return ResultFromScode(E_NOINTERFACE);
  51.     }
  52. STDMETHODIMP_(ULONG) CDropTarget::AddRef(void)
  53.     {
  54.     return ++m_cRef;
  55.     }
  56. STDMETHODIMP_(ULONG) CDropTarget::Release(void)
  57.     {
  58.     if (0!=--m_cRef)
  59.         return m_cRef;
  60.     delete this;
  61.     return 0;
  62.     }
  63. /*
  64.  * CDropTarget::DragEnter
  65.  *
  66.  * Purpose:
  67.  *  Indicates that data in a drag operation has been dragged over
  68.  *  our window that's a potential target.  We are to decide if it's
  69.  *  something we're interested in or not.
  70.  *
  71.  * Parameters:
  72.  *  pIDataSource    LPDATAOBJECT providing the source data.
  73.  *  grfKeyState     DWORD flags: states of keys and mouse buttons.
  74.  *  pt              POINTL coordinates in the document client space.
  75.  *  pdwEffect       LPDWORD into which we'll place the
  76.  *                  appropriate effect flag for this point.
  77.  *
  78.  * Return Value:
  79.  *  HRESULT         NOERROR
  80.  */
  81. STDMETHODIMP CDropTarget::DragEnter(LPDATAOBJECT pIDataSource
  82.     , DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
  83.     {
  84.     HWND        hWnd;
  85.     /*
  86.      * 1.  Check if we can paste from the pIDataSource we're
  87.      *     provided. We already made this nice useful function
  88.      *     to test.
  89.      */
  90.     m_pIDataObject=NULL;
  91.     if (!m_pDoc->FQueryPasteFromData(pIDataSource))
  92.         {
  93.         *pdwEffect=DROPEFFECT_NONE;
  94.         return NOERROR;
  95.         }
  96.     /*
  97.      * 2.  We can always drop anywhere in our document,
  98.      *     so pt is uninteresting.
  99.      */
  100.     /*
  101.      * 3. We return either a COPY or MOVE effect flag, depending on
  102.      *    the state of the grfKeyState flags.  We MOVE on no key or
  103.      *    Shift key, COPY on Ctrl key.
  104.      */
  105.     //Default is move
  106.     *pdwEffect=DROPEFFECT_MOVE;
  107.     if (grfKeyState & MK_CONTROL)
  108.         *pdwEffect=DROPEFFECT_COPY;
  109.     /*
  110.      * 4. We really don't need to keep the IDataObject around since
  111.      *    we're not interested in it in DragOver.  However, we'll
  112.      *    save it just for demonstration.
  113.      */
  114.     m_pIDataObject=pIDataSource;
  115.     m_pIDataObject->AddRef();
  116.     /*
  117.      * 5.  We always accept drops of our data on us, so we only need
  118.      *     to provide some UI feedback here which we do by inverting
  119.      *     the edge of the polyline window in this document.  We'll
  120.      *     remove this in DragLeave and in Drop.  DragOver won't
  121.      *     effect it since we can always drop.
  122.      *
  123.      *     Since we're inverting a border, insure that this window is
  124.      *     on top.
  125.      */
  126.     hWnd=m_pDoc->Window();
  127.     BringWindowToTop(hWnd);
  128.     UpdateWindow(hWnd);
  129.     m_pDoc->DropSelectTargetWindow();
  130.     return NOERROR;
  131.     }
  132. /*
  133.  * CDropTarget::DragOver
  134.  *
  135.  * Purpose:
  136.  *  Indicates that the mouse was moved inside the window represented
  137.  *  by this drop target. This happens on every WM_MOUSEMOVE, so this
  138.  *  function should be very efficient.
  139.  *
  140.  * Parameters:
  141.  *  grfKeyState     DWORD providing current keyboard/mouse states
  142.  *  pt              POINTL where the mouse currently is.
  143.  *  pdwEffect       LPDWORD to store the effect flag for this point.
  144.  *
  145.  * Return Value:
  146.  *  HRESULT         NOERROR
  147.  */
  148. STDMETHODIMP CDropTarget::DragOver(DWORD grfKeyState, POINTL pt
  149.     , LPDWORD pdwEffect)
  150.     {
  151.     if (NULL==m_pIDataObject)
  152.         {
  153.         *pdwEffect=DROPEFFECT_NONE;
  154.         return NOERROR;
  155.         }
  156.     //We can always drop; return effect flags based on keys.
  157.     *pdwEffect=DROPEFFECT_MOVE;
  158.     if (grfKeyState & MK_CONTROL)
  159.         *pdwEffect=DROPEFFECT_COPY;
  160.     return NOERROR;
  161.     }
  162. /*
  163.  * CDropTarget::DragLeave
  164.  *
  165.  * Purpose:
  166.  *  Informs the drop target that the operation has left its window.
  167.  *
  168.  * Parameters:
  169.  *  None
  170.  *
  171.  * Return Value:
  172.  *  HRESULT         NOERROR
  173.  */
  174. STDMETHODIMP CDropTarget::DragLeave(void)
  175.     {
  176.     //1.  Remove the UI feedback
  177.     m_pDoc->DropSelectTargetWindow();
  178.     //2.  Release the held IDataObject
  179.     ReleaseInterface(m_pIDataObject);
  180.         
  181.     return NOERROR;
  182.     }
  183. /*
  184.  * CDropTarget::Drop
  185.  *
  186.  * Purpose:
  187.  *  Instructs the drop target to paste data that was just now
  188.  *  dropped on it.
  189.  *
  190.  * Parameters:
  191.  *  pIDataSource    LPDATAOBJECT from which we'll paste.
  192.  *  grfKeyState     DWORD providing current keyboard/mouse state.
  193.  *  pt              POINTL at which the drop occurred.
  194.  *  pdwEffect       LPDWORD to store what you do with the data.
  195.  *
  196.  * Return Value:
  197.  *  HRESULT         NOERROR
  198.  */
  199. STDMETHODIMP CDropTarget::Drop(LPDATAOBJECT pIDataSource
  200.     , DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
  201.     {
  202.     BOOL        fRet=TRUE;
  203.     *pdwEffect=DROPEFFECT_NONE;
  204.     if (NULL==m_pIDataObject)
  205.         return ResultFromScode(E_FAIL);
  206.     //1.  Remove the UI feedback, release pointer
  207.     DragLeave();
  208.     
  209.     //No point in drag-drop to ourselves (for Cosmo, at least)
  210.     if (m_pDoc->m_fDragSource)
  211.         return ResultFromScode(E_FAIL);
  212.     //2.  Try a paste
  213.     fRet=m_pDoc->PasteFromData(pIDataSource);
  214.     //3.  Store the effect
  215.     if (!fRet)
  216.         return ResultFromScode(E_FAIL);
  217.     *pdwEffect=DROPEFFECT_MOVE;
  218.     if (grfKeyState & MK_CONTROL)
  219.         *pdwEffect=DROPEFFECT_COPY;
  220.     return NOERROR;
  221.     }