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

Windows编程

开发平台:

Visual C++

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