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.

825 lines
22 KiB

  1. //**********************************************************************
  2. // File name: DOC.CPP
  3. //
  4. // Implementation file for CSimpleDoc.
  5. //
  6. // Functions:
  7. //
  8. // See DOC.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. #include "dxferobj.h"
  20. //**********************************************************************
  21. //
  22. // CSimpleDoc::Create
  23. //
  24. // Purpose:
  25. //
  26. // Creation for the CSimpleDoc Class
  27. //
  28. // Parameters:
  29. //
  30. // CSimpleApp FAR * lpApp - Pointer to the CSimpleApp Class
  31. //
  32. // LPRECT lpRect - Client area rect of "frame" window
  33. //
  34. // HWND hWnd - Window Handle of "frame" window
  35. //
  36. // Return Value:
  37. //
  38. // None
  39. //
  40. // Function Calls:
  41. // Function Location
  42. //
  43. // StgCreateDocfile OLE API
  44. // RegisterDragDrop OLE API
  45. // CoLockObjectExternal OLE API
  46. // CreateWindow Windows API
  47. // ShowWindow Windows API
  48. // UpdateWindow Windows API
  49. // EnableMenuItem Windows API
  50. //
  51. // Comments:
  52. //
  53. // This routine was added so that failure could be returned
  54. // from object creation.
  55. //
  56. //********************************************************************
  57. CSimpleDoc FAR * CSimpleDoc::Create(CSimpleApp FAR *lpApp, LPRECT lpRect,
  58. HWND hWnd)
  59. {
  60. CSimpleDoc FAR * lpTemp = new CSimpleDoc(lpApp, hWnd);
  61. if (!lpTemp)
  62. {
  63. TestDebugOut("Memory allocation error\n");
  64. return NULL;
  65. }
  66. // create storage for the doc.
  67. HRESULT hErr = StgCreateDocfile (
  68. NULL, // generate temp name
  69. STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE,
  70. 0, &lpTemp->m_lpStorage);
  71. if (hErr != NOERROR)
  72. goto error;
  73. // create the document Window
  74. lpTemp->m_hDocWnd = CreateWindow(
  75. TEXT("SimpDndDocWClass"),
  76. NULL,
  77. WS_CHILD | WS_CLIPCHILDREN,
  78. lpRect->left,
  79. lpRect->top,
  80. lpRect->right,
  81. lpRect->bottom,
  82. hWnd,
  83. NULL,
  84. lpApp->m_hInst,
  85. NULL);
  86. if (!lpTemp->m_hDocWnd)
  87. goto error;
  88. ShowWindow(lpTemp->m_hDocWnd, SW_SHOWNORMAL); // Show the window
  89. UpdateWindow(lpTemp->m_hDocWnd); // Sends WM_PAINT message
  90. #ifdef NOTREADY
  91. // Ensable InsertObject menu choice
  92. EnableMenuItem( lpApp->m_hEditMenu, 0, MF_BYPOSITION | MF_ENABLED);
  93. #else
  94. // Ensable InsertObject menu choice
  95. EnableMenuItem( lpApp->m_hEditMenu, 1, MF_BYPOSITION | MF_ENABLED);
  96. // Disable Copy menu choice
  97. EnableMenuItem( lpApp->m_hEditMenu, 0, MF_BYPOSITION | MF_DISABLED |
  98. MF_GRAYED);
  99. #endif // NOTREADY
  100. HRESULT hRes;
  101. // It is *REQUIRED* to hold a strong LOCK on the object that is
  102. // registered as drop target. this call will result in at least one
  103. // ref count held on our document. later in CSimpleDoc::Close we will
  104. // unlock this lock which will make our document's ref count go to 0.
  105. // when the document's ref count goes to 0, it will be deleted.
  106. if ( (hRes=CoLockObjectExternal (&lpTemp->m_DropTarget, TRUE, 0))
  107. != ResultFromScode(S_OK) )
  108. {
  109. /* CoLockObjectExternal should never fail. If it fails, we don't want
  110. * to carry on since we don't have a guaranteed object lock.
  111. */
  112. goto error;
  113. }
  114. // Register our window as a DropTarget
  115. if (((hRes=RegisterDragDrop(lpTemp->m_hDocWnd, &lpTemp->m_DropTarget))
  116. !=ResultFromScode(S_OK))
  117. && (hRes != ResultFromScode(DRAGDROP_E_ALREADYREGISTERED)))
  118. {
  119. lpTemp->m_fRegDragDrop = FALSE;
  120. }
  121. else
  122. {
  123. lpTemp->m_fRegDragDrop = TRUE;
  124. }
  125. return (lpTemp);
  126. error:
  127. TestDebugOut("Fail in CSimpleDoc::Create\n");
  128. delete (lpTemp);
  129. return NULL;
  130. }
  131. //**********************************************************************
  132. //
  133. // CSimpleDoc::Close
  134. //
  135. // Purpose:
  136. //
  137. // Close CSimpleDoc object.
  138. // when the document's reference count goes to 0, the document
  139. // will be destroyed.
  140. //
  141. // Parameters:
  142. //
  143. // None
  144. //
  145. // Return Value:
  146. //
  147. // None
  148. //
  149. // Function Calls:
  150. // Function Location
  151. //
  152. // RevokeDragDrop OLE API
  153. // CoLockObjectExternal OLE API
  154. // OleFlushClipboard OLE API
  155. // ShowWindow Windows API
  156. // CSimpleSite::CloseOleObject SITE.CPP
  157. //
  158. //
  159. //********************************************************************
  160. void CSimpleDoc::Close(void)
  161. {
  162. TestDebugOut("In CSimpleDoc::Close\r\n");
  163. HRESULT hRes;
  164. ShowWindow(m_hDocWnd, SW_HIDE); // Hide the window
  165. // Remove our data transfer object from clipboard if it is there.
  166. // this will leave HGLOBAL based data behind on the clipboard
  167. // including OLE 1.0 compatibility formats.
  168. if (OleFlushClipboard() != ResultFromScode(S_OK))
  169. {
  170. TestDebugOut("Fail in OleFlushClipBoard\n");
  171. }
  172. // Revoke our window as a DropTarget
  173. if (m_fRegDragDrop)
  174. {
  175. if (((hRes=RevokeDragDrop(m_hDocWnd)) != ResultFromScode(S_OK)) &&
  176. (hRes!=ResultFromScode(DRAGDROP_E_NOTREGISTERED)))
  177. {
  178. /* if we fail in revoking the drag-drop, we will probably be
  179. * having memory leakage.
  180. */
  181. TestDebugOut("Fail in RevokeDragDrop\n");
  182. }
  183. else
  184. {
  185. m_fRegDragDrop = FALSE;
  186. }
  187. }
  188. // Close the OLE object in our document
  189. if (m_lpSite)
  190. m_lpSite->CloseOleObject();
  191. // Unlock the lock added in CSimpleDoc::Create. this will make
  192. // the document's ref count go to 0, and the document will be deleted.
  193. if ((hRes=CoLockObjectExternal (&m_DropTarget, FALSE, TRUE))
  194. !=ResultFromScode(S_OK))
  195. {
  196. /* if CoLockObjectExternal fails, this means that we cannot release
  197. * the reference count to our destinated object. This will cause
  198. * memory leakage.
  199. */
  200. TestDebugOut("Fail in CoLockObjectExternal\n");
  201. }
  202. }
  203. //**********************************************************************
  204. //
  205. // CSimpleDoc::CSimpleDoc
  206. //
  207. // Purpose:
  208. //
  209. // Constructor for the CSimpleDoc Class
  210. //
  211. // Parameters:
  212. //
  213. // CSimpleApp FAR * lpApp - Pointer to the CSimpleApp Class
  214. //
  215. // HWND hWnd - Window Handle of "frame" window
  216. //
  217. // Return Value:
  218. //
  219. // None
  220. //
  221. // Function Calls:
  222. // Function Location
  223. //
  224. // TestDebugOut Windows API
  225. // GetMenu Windows API
  226. // GetSubMenu Windows API
  227. //
  228. //
  229. //********************************************************************
  230. #pragma warning(disable : 4355) // turn off this warning. This warning
  231. // tells us that we are passing this in
  232. // an initializer, before "this" is through
  233. // initializing. This is ok, because
  234. // we just store the ptr in the other
  235. // constructor
  236. CSimpleDoc::CSimpleDoc(CSimpleApp FAR * lpApp,HWND hWnd)
  237. : m_DropTarget(this), m_DropSource(this)
  238. #pragma warning (default : 4355) // Turn the warning back on
  239. {
  240. TestDebugOut("In CSimpleDoc's Constructor\r\n");
  241. m_lpApp = lpApp;
  242. m_lpSite = NULL;
  243. m_nCount = 0;
  244. // set up menu handles
  245. lpApp->m_hMainMenu = GetMenu(hWnd);
  246. lpApp->m_hFileMenu = GetSubMenu(lpApp->m_hMainMenu, 0);
  247. lpApp->m_hEditMenu = GetSubMenu(lpApp->m_hMainMenu, 1);
  248. lpApp->m_hHelpMenu = GetSubMenu(lpApp->m_hMainMenu, 2);
  249. lpApp->m_hCascadeMenu = NULL;
  250. m_fModifiedMenu = FALSE;
  251. // drag/drop related stuff
  252. m_fRegDragDrop = FALSE; // is doc registered as drop target?
  253. m_fLocalDrag = FALSE; // is doc source of the drag
  254. m_fLocalDrop = FALSE; // was doc target of the drop
  255. m_fCanDropCopy = FALSE; // is Drag/Drop copy/move possible?
  256. m_fCanDropLink = FALSE; // is Drag/Drop link possible?
  257. m_fDragLeave = FALSE; // has drag left
  258. m_fPendingDrag = FALSE; // LButtonDown--possible drag pending
  259. m_ptButDown.x = m_ptButDown.y = 0; // LButtonDown coordinates
  260. }
  261. //**********************************************************************
  262. //
  263. // CSimpleDoc::~CSimpleDoc
  264. //
  265. // Purpose:
  266. //
  267. // Destructor for CSimpleDoc
  268. //
  269. // Parameters:
  270. //
  271. // None
  272. //
  273. // Return Value:
  274. //
  275. // None
  276. //
  277. // Function Calls:
  278. // Function Location
  279. //
  280. // TestDebugOut Windows API
  281. // GetMenuItemCount Windows API
  282. // RemoveMenu Windows API
  283. // DestroyMenu Windows API
  284. // DestroyWindow Windows API
  285. // CSimpleSite::Release SITE.CPP
  286. // CSimpleSite::UnloadOleObject SITE.CPP
  287. // IStorage::Release OLE API
  288. //
  289. //
  290. //********************************************************************
  291. CSimpleDoc::~CSimpleDoc()
  292. {
  293. TestDebugOut("In CSimpleDoc's Destructor\r\n");
  294. // Release all pointers we hold to the OLE object, also release
  295. // the ref count added in CSimpleSite::Create. this will make
  296. // the Site's ref count go to 0, and the Site will be deleted.
  297. if (m_lpSite)
  298. {
  299. m_lpSite->UnloadOleObject();
  300. m_lpSite->Release();
  301. m_lpSite = NULL;
  302. }
  303. // Release the Storage
  304. if (m_lpStorage)
  305. {
  306. m_lpStorage->Release();
  307. m_lpStorage = NULL;
  308. }
  309. // if the edit menu was modified, remove the menu item and
  310. // destroy the popup if it exists
  311. if (m_fModifiedMenu)
  312. {
  313. int nCount = GetMenuItemCount(m_lpApp->m_hEditMenu);
  314. RemoveMenu(m_lpApp->m_hEditMenu, nCount-1, MF_BYPOSITION);
  315. if (m_lpApp->m_hCascadeMenu)
  316. DestroyMenu(m_lpApp->m_hCascadeMenu);
  317. }
  318. DestroyWindow(m_hDocWnd);
  319. }
  320. //**********************************************************************
  321. //
  322. // CSimpleDoc::QueryInterface
  323. //
  324. // Purpose:
  325. //
  326. // Used for interface negotiation at the Document level.
  327. //
  328. // Parameters:
  329. //
  330. // REFIID riid - ID of interface to be returned
  331. // LPVOID FAR* ppvObj - Location to return the interface
  332. //
  333. // Return Value:
  334. //
  335. // S_OK - Interface supported
  336. // E_NOINTERFACE - Interface NOT supported
  337. //
  338. // Function Calls:
  339. // Function Location
  340. //
  341. // TestDebugOut Windows API
  342. // ResultFromScode OLE API
  343. //
  344. //
  345. //********************************************************************
  346. STDMETHODIMP CSimpleDoc::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  347. {
  348. TestDebugOut("In CSimpleDoc::QueryInterface\r\n");
  349. *ppvObj = NULL; // must set out pointer parameters to NULL
  350. // looking for IUnknown
  351. if (IsEqualIID( riid, IID_IUnknown))
  352. {
  353. AddRef();
  354. *ppvObj = this;
  355. return ResultFromScode(S_OK);
  356. }
  357. // looking for IDropTarget
  358. if (IsEqualIID( riid, IID_IDropTarget))
  359. {
  360. m_DropTarget.AddRef();
  361. *ppvObj=&m_DropTarget;
  362. return ResultFromScode(S_OK);
  363. }
  364. // looking for IDropSource
  365. if (IsEqualIID( riid, IID_IDropSource))
  366. {
  367. m_DropSource.AddRef();
  368. *ppvObj=&m_DropSource;
  369. return ResultFromScode(S_OK);
  370. }
  371. // Not a supported interface
  372. return ResultFromScode(E_NOINTERFACE);
  373. }
  374. //**********************************************************************
  375. //
  376. // CSimpleDoc::AddRef
  377. //
  378. // Purpose:
  379. //
  380. // Increments the document reference count
  381. //
  382. // Parameters:
  383. //
  384. // None
  385. //
  386. // Return Value:
  387. //
  388. // UINT - The new reference count on the document object
  389. //
  390. // Function Calls:
  391. // Function Location
  392. //
  393. // TestDebugOut Windows API
  394. // CSimpleApp::AddRef APP.CPP
  395. //
  396. //
  397. //********************************************************************
  398. STDMETHODIMP_(ULONG) CSimpleDoc::AddRef()
  399. {
  400. TestDebugOut("In CSimpleDoc::AddRef\r\n");
  401. return ++m_nCount;
  402. }
  403. //**********************************************************************
  404. //
  405. // CSimpleDoc::Release
  406. //
  407. // Purpose:
  408. //
  409. // Decrements the document reference count
  410. //
  411. // Parameters:
  412. //
  413. // None
  414. //
  415. // Return Value:
  416. //
  417. // UINT - The new reference count on the document
  418. //
  419. // Function Calls:
  420. // Function Location
  421. //
  422. // TestDebugOut Windows API
  423. //
  424. //
  425. //********************************************************************
  426. STDMETHODIMP_(ULONG) CSimpleDoc::Release()
  427. {
  428. TestDebugOut("In CSimpleDoc::Release\r\n");
  429. if (--m_nCount == 0)
  430. {
  431. delete this;
  432. return 0;
  433. }
  434. return m_nCount;
  435. }
  436. //**********************************************************************
  437. //
  438. // CSimpleDoc::InsertObject
  439. //
  440. // Purpose:
  441. //
  442. // Inserts a new object to this document
  443. //
  444. // Parameters:
  445. //
  446. // None
  447. //
  448. // Return Value:
  449. //
  450. // None
  451. //
  452. // Function Calls:
  453. // Function Location
  454. //
  455. // CSimpleSite::Create SITE.CPP
  456. // CSimpleSite::InitObject SITE.CPP
  457. // CSimpleSite::Release SITE.CPP
  458. // CSimpleSite::Revert SITE.CPP
  459. // memset C Runtime
  460. // OleUIInsertObject OLE2UI function
  461. // CSimpleDoc::DisableInsertObject DOC.CPP
  462. //
  463. // Comments:
  464. //
  465. // This implementation only allows one object to be inserted
  466. // into a document. Once the object has been inserted, then
  467. // the Insert Object menu choice is greyed out, to prevent
  468. // the user from inserting another.
  469. //
  470. //********************************************************************
  471. void CSimpleDoc::InsertObject()
  472. {
  473. OLEUIINSERTOBJECT io;
  474. UINT iret;
  475. TCHAR szFile[OLEUI_CCHPATHMAX];
  476. HRESULT hRes;
  477. m_lpSite = CSimpleSite::Create(this);
  478. if (!m_lpSite)
  479. {
  480. /* memory allocation problem. cannot continue.
  481. */
  482. TestDebugOut("Memory allocation error\n");
  483. return;
  484. }
  485. // clear the structure
  486. _fmemset(&io, 0, sizeof(OLEUIINSERTOBJECT));
  487. // fill the structure
  488. io.cbStruct = sizeof(OLEUIINSERTOBJECT);
  489. io.dwFlags = IOF_SELECTCREATENEW | IOF_DISABLELINK |
  490. IOF_DISABLEDISPLAYASICON | IOF_CREATENEWOBJECT |
  491. IOF_CREATEFILEOBJECT;
  492. io.hWndOwner = m_hDocWnd;
  493. io.lpszCaption = (LPTSTR)TEXT("Insert Object");
  494. io.iid = IID_IOleObject;
  495. io.oleRender = OLERENDER_DRAW;
  496. io.lpIOleClientSite = &m_lpSite->m_OleClientSite;
  497. io.lpIStorage = m_lpSite->m_lpObjStorage;
  498. io.ppvObj = (LPVOID FAR *)&m_lpSite->m_lpOleObject;
  499. io.lpszFile = szFile;
  500. io.cchFile = sizeof(szFile)/sizeof(TCHAR);
  501. // cchFile is the number of characters
  502. _fmemset((LPTSTR)szFile, 0, sizeof(szFile));
  503. // call OUTLUI to do all the hard work
  504. iret = OleUIInsertObject(&io);
  505. if (iret == OLEUI_OK)
  506. {
  507. m_lpSite->InitObject((BOOL)(io.dwFlags & IOF_SELECTCREATENEW));
  508. // disable Insert Object menu item
  509. DisableInsertObject();
  510. }
  511. else
  512. {
  513. m_lpSite->Release();
  514. m_lpSite = NULL;
  515. if (((hRes=m_lpStorage->Revert()) != ResultFromScode(S_OK)) &&
  516. (hRes!=ResultFromScode(STG_E_REVERTED)))
  517. {
  518. TestDebugOut("Fail in IStorage::Revert\n");
  519. }
  520. }
  521. }
  522. //**********************************************************************
  523. //
  524. // CSimpleDoc::lResizeDoc
  525. //
  526. // Purpose:
  527. //
  528. // Resizes the document
  529. //
  530. // Parameters:
  531. //
  532. // LPRECT lpRect - The size of the client are of the "frame"
  533. // Window.
  534. //
  535. // Return Value:
  536. //
  537. // NULL
  538. //
  539. // Function Calls:
  540. // Function Location
  541. //
  542. // MoveWindow Windows API
  543. //
  544. //
  545. //********************************************************************
  546. long CSimpleDoc::lResizeDoc(LPRECT lpRect)
  547. {
  548. MoveWindow(
  549. m_hDocWnd,
  550. lpRect->left, lpRect->top,
  551. lpRect->right, lpRect->bottom, TRUE);
  552. return NULL;
  553. }
  554. //**********************************************************************
  555. //
  556. // CSimpleDoc::lAddVerbs
  557. //
  558. // Purpose:
  559. //
  560. // Adds the objects verbs to the edit menu.
  561. //
  562. // Parameters:
  563. //
  564. // None
  565. //
  566. // Return Value:
  567. //
  568. // NULL
  569. //
  570. // Function Calls:
  571. // Function Location
  572. //
  573. // GetMenuItemCount Windows API
  574. // OleUIAddVerbMenu OLE2UI function
  575. //
  576. //
  577. //********************************************************************
  578. long CSimpleDoc::lAddVerbs(void)
  579. {
  580. // m_fModifiedMenu is TRUE if the menu has already been modified
  581. // once. Since we only support one obect every time the application
  582. // is run, then once the menu is modified, it doesn't have
  583. // to be done again.
  584. if (m_lpSite && !m_fModifiedMenu)
  585. {
  586. int nCount = GetMenuItemCount(m_lpApp->m_hEditMenu);
  587. if (!OleUIAddVerbMenu ( m_lpSite->m_lpOleObject,
  588. NULL,
  589. m_lpApp->m_hEditMenu,
  590. nCount + 1,
  591. IDM_VERB0,
  592. 0, // no maximum verb IDM enforced
  593. FALSE,
  594. 1,
  595. &m_lpApp->m_hCascadeMenu) )
  596. {
  597. TestDebugOut("Fail in OleUIAddVerbMenu\n");
  598. }
  599. m_fModifiedMenu = TRUE;
  600. }
  601. return (NULL);
  602. }
  603. //**********************************************************************
  604. //
  605. // CSimpleDoc::PaintDoc
  606. //
  607. // Purpose:
  608. //
  609. // Paints the Document
  610. //
  611. // Parameters:
  612. //
  613. // HDC hDC - hDC of the document Window
  614. //
  615. // Return Value:
  616. //
  617. // None
  618. //
  619. // Function Calls:
  620. // Function Location
  621. //
  622. // CSimpleSite::PaintObj SITE.CPP
  623. //
  624. //
  625. //********************************************************************
  626. void CSimpleDoc::PaintDoc (HDC hDC)
  627. {
  628. // if we supported multiple objects, then we would enumerate
  629. // the objects and call paint on each of them from here.
  630. if (m_lpSite)
  631. m_lpSite->PaintObj(hDC);
  632. }
  633. //**********************************************************************
  634. //
  635. // CSimpleDoc::DisableInsertObject
  636. //
  637. // Purpose:
  638. //
  639. // Disable the ability to insert a new object in this document.
  640. //
  641. // Parameters:
  642. //
  643. // None
  644. //
  645. // Return Value:
  646. //
  647. // None
  648. //
  649. // Function Calls:
  650. // Function Location
  651. //
  652. // RevokeDragDrop OLE API
  653. // EnableMenuItem Windows API
  654. //
  655. // Comments:
  656. //
  657. // This implementation only allows one object to be inserted
  658. // into a document. Once the object has been inserted, then
  659. // the Insert Object menu choice is greyed out, to prevent
  660. // the user from inserting another. Also we revoke ourself as
  661. // a potential drop target.
  662. //
  663. //********************************************************************
  664. void CSimpleDoc::DisableInsertObject(void)
  665. {
  666. #ifdef NOTREADY
  667. // Disable InsertObject menu choice
  668. EnableMenuItem( m_lpApp->m_hEditMenu, 0, MF_BYPOSITION | MF_DISABLED |
  669. MF_GRAYED);
  670. #else
  671. // Disable InsertObject menu choice
  672. EnableMenuItem( m_lpApp->m_hEditMenu, 1, MF_BYPOSITION | MF_DISABLED |
  673. MF_GRAYED);
  674. // Enable Copy menu choice
  675. EnableMenuItem( m_lpApp->m_hEditMenu, 0, MF_BYPOSITION | MF_ENABLED);
  676. #endif // NOTREADY
  677. // We no longer accept dropping of objects
  678. if (m_fRegDragDrop)
  679. {
  680. HRESULT hRes;
  681. if (((hRes=RevokeDragDrop(m_hDocWnd))!=ResultFromScode(S_OK)) &&
  682. (hRes!=ResultFromScode(DRAGDROP_E_NOTREGISTERED)))
  683. {
  684. /* if we fail in revoking the drag-drop, we will probably be
  685. * having memory leakage.
  686. */
  687. TestDebugOut("Fail in RevokeDragDrop\n");
  688. }
  689. else
  690. {
  691. m_fRegDragDrop = FALSE;
  692. }
  693. }
  694. }
  695. //**********************************************************************
  696. //
  697. // CSimpleDoc::CopyObjectToClip
  698. //
  699. // Purpose:
  700. //
  701. // Copy the embedded OLE object to the clipboard
  702. //
  703. // Parameters:
  704. //
  705. // None
  706. //
  707. // Return Value:
  708. //
  709. // None
  710. //
  711. // Function Calls:
  712. // Function Location
  713. //
  714. // CDataXferObj::Create DXFEROBJ.CPP
  715. // CDataXferObj::Release DXFEROBJ.CPP
  716. // CDataXferObj::QueryInterface DXFEROBJ.CPP
  717. // OleSetClipboard OLE API
  718. //
  719. // Comments:
  720. //
  721. // This implementation only allows one object to be inserted
  722. // into a document. Once the object has been inserted, then
  723. // the Copy menu choice is enabled.
  724. //
  725. //********************************************************************
  726. void CSimpleDoc::CopyObjectToClip(void)
  727. {
  728. LPDATAOBJECT lpDataObj;
  729. // Create a data transfer object by cloning the existing OLE object
  730. CDataXferObj FAR* pDataXferObj = CDataXferObj::Create(m_lpSite,NULL);
  731. if (! pDataXferObj)
  732. {
  733. /* memory allocation error !
  734. */
  735. MessageBox(NULL, TEXT("Out-of-memory"), TEXT("SimpDnD"),
  736. MB_SYSTEMMODAL | MB_ICONHAND);
  737. return;
  738. }
  739. // initially obj is created with 0 refcnt. this QI will make it go to 1.
  740. pDataXferObj->QueryInterface(IID_IDataObject, (LPVOID FAR*)&lpDataObj);
  741. // put out data transfer object on the clipboard. this API will AddRef.
  742. if (OleSetClipboard(lpDataObj) != ResultFromScode(S_OK))
  743. {
  744. TestDebugOut("Fail in OleSetClipboard\n");
  745. lpDataObj->Release();
  746. }
  747. // Give ownership of data transfer object to clipboard
  748. pDataXferObj->Release();
  749. }