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.

814 lines
22 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. // 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 = 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 = 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 OLE2UI 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. // TestDebugOut Windows API
  410. // CSimpleDoc::QueryInterface DOC.CPP
  411. //
  412. // Comments:
  413. //
  414. //********************************************************************
  415. STDMETHODIMP CDropTarget::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  416. {
  417. TestDebugOut("In IDT::QueryInterface\r\n");
  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. // TestDebugOut 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. TestDebugOut("In IDT::AddRef\r\n");
  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. // TestDebugOut 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. TestDebugOut("In IDT::Release\r\n");
  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. // TestDebugOut 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. TestDebugOut("In IDT::DragEnter\r\n");
  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. // TestDebugOut 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. TestDebugOut("In IDT::DragOver\r\n");
  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. // TestDebugOut Windows API
  621. // UndrawDragFeedback IDT.CPP
  622. // ResultFromScode OLE2 API
  623. //
  624. // Comments:
  625. //
  626. //********************************************************************
  627. STDMETHODIMP CDropTarget::DragLeave ()
  628. {
  629. TestDebugOut("In IDT::DragLeave\r\n");
  630. UndrawDragFeedback();
  631. return ResultFromScode(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. // TestDebugOut 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. // GetScode OLE2 API
  670. // ResultFromScode 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. TestDebugOut("In IDT::Drop\r\n");
  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 = GetScode(hrErr);
  710. }
  711. return ResultFromScode(sc);
  712. }