home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap13 / cosmo / droptgt.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  6KB  |  293 lines

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