Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

851 lines
24 KiB

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