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

Windows编程

开发平台:

Visual C++

  1. //**********************************************************************
  2. // File name: IDT.CPP
  3. //
  4. //      Implementation file for CDropTarget
  5. //
  6. // Functions:
  7. //
  8. //      See IDT.H for class definition
  9. //
  10. // Copyright (c) 1992 - 1997 Microsoft Corporation. All rights reserved.
  11. //**********************************************************************
  12. #include "pre.h"
  13. #include "iocs.h"
  14. #include "ias.h"
  15. #include "app.h"
  16. #include "site.h"
  17. #include "doc.h"
  18. #include "idt.h"
  19. extern CLIPFORMAT g_cfObjectDescriptor;
  20. //**********************************************************************
  21. //
  22. // CDropTarget::QueryDrop
  23. //
  24. // Purpose:
  25. //
  26. //      Check if the desired drop operation (identified by the given key
  27. //      state) is possible at the current mouse position (pointl).
  28. //
  29. // Parameters:
  30. //
  31. //      DWORD grfKeyState       - current key state
  32. //      POINTL pointl           - position of mouse
  33. //      BOOL fDragScroll        - TRUE if drag scrolling cursor should
  34. //                                be shown.
  35. //      LPDWORD pdwEffect       - (OUT) drag effect that should occur
  36. //
  37. // Return Value:
  38. //
  39. //      BOOL                    - TRUE if drop could take place,
  40. //                                else FALSE
  41. //
  42. // Function Calls:
  43. //      Function                    Location
  44. //
  45. //      OleStdGetDropEffect         OLESTD API
  46. //
  47. // Comments:
  48. //
  49. //********************************************************************
  50. BOOL CDropTarget::QueryDrop (
  51.         DWORD           grfKeyState,
  52.         POINTL          pointl,
  53.         BOOL            fDragScroll,
  54.         LPDWORD         pdwEffect
  55. )
  56. {
  57.         DWORD      dwScrollEffect = 0L;
  58.         DWORD      dwOKEffects = *pdwEffect;
  59.         /* check if the cursor is in the active scroll area, if so need the
  60.         **    special scroll cursor.
  61.         */
  62.         if (fDragScroll)
  63.                 dwScrollEffect = DROPEFFECT_SCROLL;
  64.         /* if we have already determined that the source does NOT have any
  65.         **    acceptable data for us, the return NO-DROP
  66.         */
  67.         if (! m_fCanDropCopy && ! m_fCanDropLink)
  68.                 goto dropeffect_none;
  69.         /* OLE2NOTE: determine what type of drop should be performed given
  70.         **    the current modifier key state. we rely on the standard
  71.         **    interpretation of the modifier keys:
  72.         **          no modifier -- DROPEFFECT_MOVE or whatever is allowed by src
  73.         **          SHIFT       -- DROPEFFECT_MOVE
  74.         **          CTRL        -- DROPEFFECT_COPY
  75.         **          CTRL-SHIFT  -- DROPEFFECT_LINK
  76.         */
  77.         *pdwEffect = OleStdGetDropEffect(grfKeyState);
  78.         if (*pdwEffect == 0) {
  79.                 // No modifier keys given. Try in order MOVE, COPY, LINK.
  80.                 if ((DROPEFFECT_MOVE & dwOKEffects) && m_fCanDropCopy)
  81.                         *pdwEffect = DROPEFFECT_MOVE;
  82.                 else if ((DROPEFFECT_COPY & dwOKEffects) && m_fCanDropCopy)
  83.                         *pdwEffect = DROPEFFECT_COPY;
  84.                 else if ((DROPEFFECT_LINK & dwOKEffects) && m_fCanDropLink)
  85.                         *pdwEffect = DROPEFFECT_LINK;
  86.                 else
  87.                         goto dropeffect_none;
  88.         } else {
  89.                 /* OLE2NOTE: we should check if the drag source application allows
  90.                 **    the desired drop effect.
  91.                 */
  92.                 if (!(*pdwEffect & dwOKEffects))
  93.                         goto dropeffect_none;
  94.                 if ((*pdwEffect == DROPEFFECT_COPY || *pdwEffect == DROPEFFECT_MOVE)
  95.                                 && ! m_fCanDropCopy)
  96.                         goto dropeffect_none;
  97.                 if (*pdwEffect == DROPEFFECT_LINK && ! m_fCanDropLink)
  98.                         goto dropeffect_none;
  99.         }
  100.         *pdwEffect |= dwScrollEffect;
  101.         return TRUE;
  102. dropeffect_none:
  103.         *pdwEffect = DROPEFFECT_NONE;
  104.         return FALSE;
  105. }
  106. //**********************************************************************
  107. //
  108. // CDropTarget::QueryDrop
  109. //
  110. // Purpose:
  111. //
  112. //     Check to see if Drag scroll operation should be initiated.
  113. //
  114. // Parameters:
  115. //
  116. //      POINTL pointl           - position of mouse
  117. //
  118. // Return Value:
  119. //
  120. //      BOOL                    - TRUE if scroll cursor should be given
  121. //                                else FALSE
  122. //
  123. // Function Calls:
  124. //      Function                    Location
  125. //
  126. //      ScreenToClient              WINDOWS API
  127. //      GetClientRect               WINDOWS API
  128. //
  129. // Comments:
  130. //     A Drag scroll operation should be initiated when the mouse has
  131. //     remained in the active scroll area (11 pixels frame around border
  132. //     of window) for a specified amount of time (50ms).
  133. //
  134. //********************************************************************
  135. BOOL CDropTarget::DoDragScroll (POINTL pointl)
  136. {
  137.         DWORD dwScrollDir = SCROLLDIR_NULL;
  138.         DWORD dwTime = GetCurrentTime();
  139.         int nScrollInset = m_pDoc->m_lpApp->m_nScrollInset;
  140.         int nScrollDelay = m_pDoc->m_lpApp->m_nScrollDelay;
  141.         int nScrollInterval = m_pDoc->m_lpApp->m_nScrollInterval;
  142.         POINT point;
  143.         RECT rect;
  144.         point.x = (int)pointl.x;
  145.         point.y = (int)pointl.y;
  146.         ScreenToClient( m_pDoc->m_hDocWnd, &point);
  147.         GetClientRect ( m_pDoc->m_hDocWnd, (LPRECT) &rect );
  148.         if (rect.top <= point.y && point.y<=(rect.top+nScrollInset))
  149.                 dwScrollDir = SCROLLDIR_UP;
  150.         else if ((rect.bottom-nScrollInset) <= point.y && point.y <= rect.bottom)
  151.                 dwScrollDir = SCROLLDIR_DOWN;
  152.         else if (rect.left <= point.x && point.x <= (rect.left+nScrollInset))
  153.                 dwScrollDir = SCROLLDIR_LEFT;
  154.         else if ((rect.right-nScrollInset) <= point.x && point.x <= rect.right)
  155.                 dwScrollDir = SCROLLDIR_RIGHT;
  156.         if (m_dwTimeEnterScrollArea) {
  157.                 /* cursor was already in Scroll Area */
  158.                 if (! dwScrollDir) {
  159.                         /* cusor moved OUT of scroll area.
  160.                         **      clear "EnterScrollArea" time.
  161.                         */
  162.                         m_dwTimeEnterScrollArea = 0L;
  163.                         m_dwNextScrollTime = 0L;
  164.                         m_dwLastScrollDir = SCROLLDIR_NULL;
  165.                 } else if (dwScrollDir != m_dwLastScrollDir) {
  166.                         /* cusor moved into a different direction scroll area.
  167.                         **      reset "EnterScrollArea" time to start a new 50ms delay.
  168.                         */
  169.                         m_dwTimeEnterScrollArea = dwTime;
  170.                         m_dwNextScrollTime = dwTime + (DWORD)nScrollDelay;
  171.                         m_dwLastScrollDir = dwScrollDir;
  172.                 } else if (dwTime && dwTime >= m_dwNextScrollTime) {
  173.                         m_pDoc->Scroll ( dwScrollDir );    // Scroll document now
  174.                         m_dwNextScrollTime = dwTime + (DWORD)nScrollInterval;
  175.                 }
  176.         } else {
  177.                 if (dwScrollDir) {
  178.                         /* cusor moved INTO a scroll area.
  179.                         **      reset "EnterScrollArea" time to start a new 50ms delay.
  180.                         */
  181.                         m_dwTimeEnterScrollArea = dwTime;
  182.                         m_dwNextScrollTime = dwTime + (DWORD)nScrollDelay;
  183.                         m_dwLastScrollDir = dwScrollDir;
  184.                 }
  185.         }
  186.         return (dwScrollDir ? TRUE : FALSE);
  187. }
  188. // Support functions/macros
  189. #define SetTopLeft(rc, pt)      
  190.         ((rc)->top = (pt)->y,(rc)->left = (pt)->x)
  191. #define SetBottomRight(rc, pt)      
  192.         ((rc)->bottom = (pt)->y,(rc)->right = (pt)->x)
  193. #define OffsetPoint(pt, dx, dy)     
  194.         ((pt)->x += dx, (pt)->y += dy)
  195. /* HighlightRect
  196. ** -------------
  197. **    Invert rectangle on screen. used for drop target feedback.
  198. */
  199. static int HighlightRect(HWND hwnd, HDC hdc, LPRECT rc)
  200. {
  201.         POINT pt1, pt2;
  202.         int old = SetROP2(hdc, R2_NOT);
  203.         HPEN hpen;
  204.         HGDIOBJ hold;
  205.         pt1.x = rc->left;
  206.         pt1.y = rc->top;
  207.         pt2.x = rc->right;
  208.         pt2.y = rc->bottom;
  209.         ScreenToClient(hwnd, &pt1);
  210.         ScreenToClient(hwnd, &pt2);
  211.         hold = SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));
  212.         hpen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 2,
  213.                                                   GetSysColor(COLOR_ACTIVEBORDER)));
  214.         Rectangle(hdc, pt1.x, pt1.y, pt2.x, pt2.y);
  215.         SetROP2(hdc, old);
  216.         hold = SelectObject(hdc, hold);
  217.         hpen = (HPEN) SelectObject(hdc, hpen);
  218.         DeleteObject(hpen);
  219.   return 0;
  220. }
  221. //**********************************************************************
  222. //
  223. // CDropTarget::InitDragFeedback
  224. //
  225. // Purpose:
  226. //
  227. //      Initialize data used to draw drop target feedback.
  228. //      As feedback we draw a rectangle the size of the object.
  229. //
  230. // Parameters:
  231. //
  232. //      LPDATAOBJECT pDataObj   - IDataObject from Drop source
  233. //      POINTL pointl           - position of mouse
  234. //
  235. // Return Value:
  236. //
  237. //      none.
  238. //
  239. // Function Calls:
  240. //      Function                    Location
  241. //
  242. //      IDataObject::GetData        Object
  243. //      XformSizeInHimetricToPixels OLESTD Library
  244. //      GlobalLock                  WINDOWS API
  245. //      GlobalUnlock                WINDOWS API
  246. //      ReleaseStgMedium            OLE2 API
  247. //      OffsetPoint                 IDT.CPP
  248. //      SetTopLeft                  IDT.CPP
  249. //      SetBottomRight              IDT.CPP
  250. //
  251. // Comments:
  252. //      In order to known the size of the object before the object
  253. //      is actually dropped, we render CF_OBJECTDESCRIPTOR format.
  254. //      this data format tells us both the size of the object as
  255. //      well as which aspect is the object is displayed as in the
  256. //      source. if the object is currently displayed as DVASPECT_ICON
  257. //      then we want to create the object also as DVASPECT_ICON.
  258. //
  259. //********************************************************************
  260. void CDropTarget::InitDragFeedback(LPDATAOBJECT pDataObj, POINTL pointl)
  261. {
  262.         FORMATETC fmtetc;
  263.         STGMEDIUM stgmed;
  264.         POINT pt;
  265.         int height, width;
  266.         HRESULT hrErr;
  267.         height = width = 100; // some default values
  268.         pt.x = (int)pointl.x;
  269.         pt.y = (int)pointl.y;
  270.         // do a GetData for CF_OBJECTDESCRIPTOR format to get the size of the
  271.         // object as displayed in the source. using this size, initialize the
  272.         // size for the drag feedback rectangle.
  273.         fmtetc.cfFormat = g_cfObjectDescriptor;
  274.         fmtetc.ptd = NULL;
  275.         fmtetc.lindex = -1;
  276.         fmtetc.dwAspect = DVASPECT_CONTENT;
  277.         fmtetc.tymed = TYMED_HGLOBAL;
  278.         hrErr = pDataObj->GetData(&fmtetc, &stgmed);
  279.         if (hrErr == NOERROR) {
  280.                 LPOBJECTDESCRIPTOR pOD=(LPOBJECTDESCRIPTOR)GlobalLock(stgmed.hGlobal);
  281.                 if (pOD != NULL) {
  282.                         XformSizeInHimetricToPixels(NULL, &pOD->sizel, &pOD->sizel);
  283.                         width = (int)pOD->sizel.cx;
  284.                         height = (int)pOD->sizel.cy;
  285.                         m_dwSrcAspect = pOD->dwDrawAspect;
  286.                 }
  287.                 GlobalUnlock(stgmed.hGlobal);
  288.                 ReleaseStgMedium(&stgmed);
  289.         }
  290.         m_ptLast = pt;
  291.         m_fDragFeedbackDrawn = FALSE;
  292.         OffsetPoint(&pt, -(width/2), -(height/2));
  293.         SetTopLeft(&m_rcDragRect, &pt);
  294.         OffsetPoint(&pt, width, height);
  295.         SetBottomRight(&m_rcDragRect, &pt);
  296. }
  297. //**********************************************************************
  298. //
  299. // CDropTarget::UndrawDragFeedback
  300. //
  301. // Purpose:
  302. //
  303. //      Erase any drop target feedback.
  304. //      As feedback we draw a rectangle the size of the object.
  305. //
  306. // Parameters:
  307. //
  308. //      none.
  309. //
  310. // Return Value:
  311. //
  312. //      none.
  313. //
  314. // Function Calls:
  315. //      Function                    Location
  316. //
  317. //      GetDC                       WINDOWS API
  318. //      ReleaseDC                   WINDOWS API
  319. //      GlobalUnlock                WINDOWS API
  320. //      HighlightRect               IDT.CPP
  321. //
  322. // Comments:
  323. //      In order to known the size of the object before the object
  324. //      is actually dropped, we render CF_OBJECTDESCRIPTOR format.
  325. //      this data format tells us both the size of the object as
  326. //      well as which aspect is the object is displayed as in the
  327. //      source. if the object is currently displayed as DVASPECT_ICON
  328. //      then we want to create the object also as DVASPECT_ICON.
  329. //
  330. //********************************************************************
  331. void CDropTarget::UndrawDragFeedback( void )
  332. {
  333.         if (m_fDragFeedbackDrawn) {
  334.                 m_fDragFeedbackDrawn = FALSE;
  335.                 HDC hDC = GetDC(m_pDoc->m_hDocWnd);
  336.                 HighlightRect(m_pDoc->m_hDocWnd, hDC, &m_rcDragRect);
  337.                 ReleaseDC(m_pDoc->m_hDocWnd, hDC);
  338.         }
  339. }
  340. //**********************************************************************
  341. //
  342. // CDropTarget::DrawDragFeedback
  343. //
  344. // Purpose:
  345. //
  346. //      Compute new position of drop target feedback rectangle and
  347. //      erase old rectangle and draw new rectangle.
  348. //      As feedback we draw a rectangle the size of the object.
  349. //
  350. // Parameters:
  351. //
  352. //      POINTL pointl           - position of mouse
  353. //
  354. // Return Value:
  355. //
  356. //      none.
  357. //
  358. // Function Calls:
  359. //      Function                    Location
  360. //
  361. //      OffsetPoint                 IDT.CPP
  362. //      HighlightRect               IDT.CPP
  363. //      GetDC                       WINDOWS API
  364. //      ReleaseDC                   WINDOWS API
  365. //
  366. // Comments:
  367. //
  368. //********************************************************************
  369. void CDropTarget::DrawDragFeedback( POINTL pointl )
  370. {
  371.         POINT ptDiff;
  372.         ptDiff.x = (int)pointl.x - m_ptLast.x;
  373.         ptDiff.y = (int)pointl.y - m_ptLast.y;
  374.         if (m_fDragFeedbackDrawn && (ptDiff.x == 0 && ptDiff.y == 0))
  375.                 return;     // mouse did not move; leave rectangle as drawn
  376.         HDC hDC = GetDC(m_pDoc->m_hDocWnd);
  377.         if (m_fDragFeedbackDrawn) {
  378.                 m_fDragFeedbackDrawn = FALSE;
  379.                 HighlightRect(m_pDoc->m_hDocWnd, hDC, &m_rcDragRect);
  380.         }
  381.         OffsetRect(&m_rcDragRect, ptDiff.x, ptDiff.y);
  382.         HighlightRect(m_pDoc->m_hDocWnd, hDC, &m_rcDragRect);
  383.         m_fDragFeedbackDrawn = TRUE;
  384.         m_ptLast.x = (int)pointl.x;
  385.         m_ptLast.y = (int)pointl.y;
  386.         ReleaseDC(m_pDoc->m_hDocWnd, hDC);
  387. }
  388. //**********************************************************************
  389. //
  390. // CDropTarget::QueryInterface
  391. //
  392. // Purpose:
  393. //
  394. //      Return a pointer to a requested interface
  395. //
  396. // Parameters:
  397. //
  398. //      REFIID riid         -   ID of interface to be returned
  399. //      LPVOID FAR* ppvObj  -   Location to return the interface
  400. //
  401. // Return Value:
  402. //
  403. //      S_OK                -   Interface supported
  404. //      E_NOINTERFACE       -   Interface NOT supported
  405. //
  406. // Function Calls:
  407. //      Function                    Location
  408. //
  409. //      OutputDebugString           Windows API
  410. //      CSimpleDoc::QueryInterface  DOC.CPP
  411. //
  412. // Comments:
  413. //
  414. //********************************************************************
  415. STDMETHODIMP CDropTarget::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  416. {
  417.         OutputDebugString("In IDT::QueryInterfacern");
  418.         // delegate to the document
  419.         return m_pDoc->QueryInterface(riid, ppvObj);
  420. }
  421. //**********************************************************************
  422. //
  423. // CDropTarget::AddRef
  424. //
  425. // Purpose:
  426. //
  427. //      Increments the reference count on this interface
  428. //
  429. // Parameters:
  430. //
  431. //      None
  432. //
  433. // Return Value:
  434. //
  435. //      The current reference count on this interface.
  436. //
  437. // Function Calls:
  438. //      Function                    Location
  439. //
  440. //      CSimpleDoc::AddReff         DOC.CPP
  441. //      OutputDebugString           Windows API
  442. //
  443. // Comments:
  444. //
  445. //      This function adds one to the ref count of the interface,
  446. //      and calls then calls CSimpleObj to increment its ref.
  447. //      count.
  448. //
  449. //********************************************************************
  450. STDMETHODIMP_(ULONG) CDropTarget::AddRef()
  451. {
  452.         OutputDebugString("In IDT::AddRefrn");
  453.         // increment the interface reference count (for debugging only)
  454.         ++m_nCount;
  455.         // delegate to the document Object
  456.         return m_pDoc->AddRef();
  457. }
  458. //**********************************************************************
  459. //
  460. // CDropTarget::Release
  461. //
  462. // Purpose:
  463. //
  464. //      Decrements the reference count on this interface
  465. //
  466. // Parameters:
  467. //
  468. //      None
  469. //
  470. // Return Value:
  471. //
  472. //      The current reference count on this interface.
  473. //
  474. // Function Calls:
  475. //      Function                    Location
  476. //
  477. //      CSimpleDoc::Release         DOC.CPP
  478. //      OutputDebugString           Windows API
  479. //
  480. // Comments:
  481. //
  482. //      This function subtracts one from the ref count of the interface,
  483. //      and calls then calls CSimpleDoc to decrement its ref.
  484. //      count.
  485. //
  486. //********************************************************************
  487. STDMETHODIMP_(ULONG) CDropTarget::Release()
  488. {
  489.         OutputDebugString("In IDT::Releasern");
  490.         // decrement the interface reference count (for debugging only)
  491.         --m_nCount;
  492.         // delegate to the document object
  493.         return m_pDoc->Release();
  494. }
  495. //**********************************************************************
  496. //
  497. // CDropTarget::DragEnter
  498. //
  499. // Purpose:
  500. //
  501. //      Called when the mouse first enters our DropTarget window
  502. //
  503. // Parameters:
  504. //
  505. //      LPDATAOBJECT pDataObj   - IDataObject from Drop source
  506. //      DWORD grfKeyState       - current key state
  507. //      POINTL pointl           - position of mouse
  508. //      LPDWORD pdwEffect       - (IN-OUT) drag effect that should occur
  509. //                                ON INPUT, this is dwOKEffects that source
  510. //                                passed to DoDragDrop API.
  511. //                                ON OUTPUT, this is the effect that we
  512. //                                want to take effect (used to determine
  513. //                                cursor feedback).
  514. //
  515. // Return Value:
  516. //
  517. //      S_OK
  518. //
  519. // Function Calls:
  520. //      Function                    Location
  521. //
  522. //      OutputDebugString           Windows API
  523. //      OleQueryCreateFromData      OLE2 API
  524. //      DoDragScroll                IDT.CPP
  525. //      QueryDrop                   IDT.CPP
  526. //      InitDragFeedback            IDT.CPP
  527. //      DrawDragFeedback            IDT.CPP
  528. //      UndrawDragFeedback          IDT.CPP
  529. //
  530. // Comments:
  531. //      Callee should honor the dwEffects as passed in to determine
  532. //      if the caller allows DROPEFFECT_MOVE.
  533. //
  534. //********************************************************************
  535. STDMETHODIMP CDropTarget::DragEnter (LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pointl, LPDWORD pdwEffect)
  536. {
  537.         OutputDebugString("In IDT::DragEnterrn");
  538.         /* Determine if the drag source data object offers a data format
  539.         **  that we understand. we accept only creating embedded objects.
  540.         */
  541.         m_fCanDropCopy = ((OleQueryCreateFromData(pDataObj) == NOERROR) ?
  542.                         TRUE : FALSE);
  543.         m_fCanDropLink = FALSE; // linking NOT supported in this simple sample
  544.         if (m_fCanDropCopy || m_fCanDropLink)
  545.                 InitDragFeedback(pDataObj, pointl);
  546.         BOOL fDragScroll = DoDragScroll ( pointl );
  547.         if (QueryDrop(grfKeyState,pointl,fDragScroll,pdwEffect))
  548.                 DrawDragFeedback( pointl );
  549.         return NOERROR;
  550. }
  551. //**********************************************************************
  552. //
  553. // CDropTarget::DragOver
  554. //
  555. // Purpose:
  556. //
  557. //      Called when the mouse moves, key state changes, or a time
  558. //      interval passes while the mouse is still within our DropTarget
  559. //      window.
  560. //
  561. // Parameters:
  562. //
  563. //      DWORD grfKeyState       - current key state
  564. //      POINTL pointl           - position of mouse
  565. //      LPDWORD pdwEffect       - (IN-OUT) drag effect that should occur
  566. //                                ON INPUT, this is dwOKEffects that source
  567. //                                passed to DoDragDrop API.
  568. //                                ON OUTPUT, this is the effect that we
  569. //                                want to take effect (used to determine
  570. //                                cursor feedback).
  571. //
  572. // Return Value:
  573. //
  574. //      S_OK
  575. //
  576. // Function Calls:
  577. //      Function                    Location
  578. //
  579. //      OutputDebugString           Windows API
  580. //      DoDragScroll                IDT.CPP
  581. //      QueryDrop                   IDT.CPP
  582. //      DrawDragFeedback            IDT.CPP
  583. //      UndrawDragFeedback          IDT.CPP
  584. //
  585. // Comments:
  586. //      Callee should honor the dwEffects as passed in to determine
  587. //      if the caller allows DROPEFFECT_MOVE. OLE pulses the DragOver
  588. //      calls in order that the DropTarget can implement drag scrolling
  589. //
  590. //********************************************************************
  591. STDMETHODIMP CDropTarget::DragOver  (DWORD grfKeyState, POINTL pointl, LPDWORD pdwEffect)
  592. {
  593.         OutputDebugString("In IDT::DragOverrn");
  594.         BOOL fDragScroll = DoDragScroll ( pointl );
  595.         if (QueryDrop(grfKeyState,pointl,fDragScroll,pdwEffect))
  596.                 DrawDragFeedback( pointl );
  597.         else
  598.                 UndrawDragFeedback();
  599.         return NOERROR;
  600. }
  601. //**********************************************************************
  602. //
  603. // CDropTarget::DragLeave
  604. //
  605. // Purpose:
  606. //
  607. //      Called when the mouse leaves our DropTarget window
  608. //
  609. // Parameters:
  610. //
  611. //      none.
  612. //
  613. // Return Value:
  614. //
  615. //      S_OK
  616. //
  617. // Function Calls:
  618. //      Function                    Location
  619. //
  620. //      OutputDebugString           Windows API
  621. //      UndrawDragFeedback          IDT.CPP
  622. //                   OLE2 API
  623. //
  624. // Comments:
  625. //
  626. //********************************************************************
  627. STDMETHODIMP CDropTarget::DragLeave ()
  628. {
  629.         OutputDebugString("In IDT::DragLeavern");
  630.         UndrawDragFeedback();
  631.         return S_OK;
  632. }
  633. //**********************************************************************
  634. //
  635. // CDropTarget::Drop
  636. //
  637. // Purpose:
  638. //
  639. //      Called when a Drop operation should take place.
  640. //
  641. // Parameters:
  642. //
  643. //      LPDATAOBJECT pDataObj   - IDataObject from Drop source
  644. //      DWORD grfKeyState       - current key state
  645. //      POINTL pointl           - position of mouse
  646. //      LPDWORD pdwEffect       - (IN-OUT) drag effect that should occur
  647. //                                ON INPUT, this is dwOKEffects that source
  648. //                                passed to DoDragDrop API.
  649. //                                ON OUTPUT, this is the effect that we
  650. //                                want to take effect (used to determine
  651. //                                cursor feedback).
  652. //
  653. // Return Value:
  654. //
  655. //      S_OK
  656. //
  657. // Function Calls:
  658. //      Function                    Location
  659. //
  660. //      OutputDebugString           Windows API
  661. //      CSimpleSite::Create         SITE.CPP
  662. //      CSimpleSite::InitObject     SITE.CPP
  663. //      OleCreateFromData           OLE2 API
  664. //      DoDragScroll                IDT.CPP
  665. //      QueryDrop                   IDT.CPP
  666. //      InitDragFeedback            IDT.CPP
  667. //      DrawDragFeedback            IDT.CPP
  668. //      UndrawDragFeedback          IDT.CPP
  669. //                          OLE2 API
  670. //                   OLE2 API
  671. //
  672. // Comments:
  673. //      Callee should honor the dwEffects as passed in to determine
  674. //      if the caller allows DROPEFFECT_MOVE.
  675. //
  676. //********************************************************************
  677. STDMETHODIMP CDropTarget::Drop (LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pointl, LPDWORD pdwEffect)
  678. {
  679.         FORMATETC fmtetc;
  680.         SCODE sc = S_OK;
  681.         OutputDebugString("In IDT::Droprn");
  682.         UndrawDragFeedback();
  683.         if (pDataObj && QueryDrop(grfKeyState,pointl,FALSE,pdwEffect))
  684.                 {
  685.                 m_pDoc->m_lpSite = CSimpleSite::Create(m_pDoc);
  686.                 // keep same aspect as drop source
  687.                 m_pDoc->m_lpSite->m_dwDrawAspect = m_dwSrcAspect;
  688.                 // in order to specify a particular drawing Aspect we must
  689.                 // pass a FORMATETC* to OleCreateFromData
  690.                 fmtetc.cfFormat = NULL;             // use whatever for drawing
  691.                 fmtetc.ptd = NULL;
  692.                 fmtetc.lindex = -1;
  693.                 fmtetc.dwAspect = m_dwSrcAspect;    // desired drawing aspect
  694.                 fmtetc.tymed = TYMED_NULL;
  695.                 HRESULT hrErr = OleCreateFromData (
  696.                                                         pDataObj,
  697.                                                         IID_IOleObject,
  698.                                                         OLERENDER_DRAW,
  699.                                                         &fmtetc,
  700.                                                         &m_pDoc->m_lpSite->m_OleClientSite,
  701.                                                         m_pDoc->m_lpSite->m_lpObjStorage,
  702.                                                         (LPVOID FAR *)&m_pDoc->m_lpSite->m_lpOleObject);
  703.                 if (hrErr == NOERROR)
  704.                         {
  705.                         m_pDoc->m_lpSite->InitObject(FALSE /* fCreateNew */);
  706.                         m_pDoc->DisableInsertObject();
  707.                         }
  708.                 else
  709.                         sc = hrErr;
  710.                 }
  711.         return sc;
  712. }