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.

628 lines
15 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 "ioipf.h"
  16. #include "ioips.h"
  17. #include "app.h"
  18. #include "site.h"
  19. #include "doc.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. // CreateWindow Windows API
  45. // ShowWindow Windows API
  46. // UpdateWindow Windows API
  47. // EnableMenuItem Windows API
  48. //
  49. // Comments:
  50. //
  51. // This routine was added so that failure could be returned
  52. // from object creation.
  53. //
  54. //********************************************************************
  55. CSimpleDoc FAR * CSimpleDoc::Create(CSimpleApp FAR *lpApp, LPRECT lpRect,
  56. 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 (NULL,
  63. STGM_READWRITE | STGM_TRANSACTED |
  64. 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. TEXT("SimpCntrDocWClass"),
  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( lpTemp->m_hEditMenu, 0, MF_BYPOSITION | MF_ENABLED);
  87. // we will add one ref count on our document. later in CSimpleDoc::Close
  88. // we will release this ref count. when the document's ref count goes
  89. // to 0, the document will be deleted.
  90. lpTemp->AddRef();
  91. return (lpTemp);
  92. error:
  93. delete (lpTemp);
  94. return NULL;
  95. }
  96. //**********************************************************************
  97. //
  98. // CSimpleDoc::Close
  99. //
  100. // Purpose:
  101. //
  102. // Close CSimpleDoc object.
  103. // when the document's reference count goes to 0, the document
  104. // will be destroyed.
  105. //
  106. // Parameters:
  107. // None
  108. //
  109. //
  110. // Return Value:
  111. //
  112. // None
  113. //
  114. // Function Calls:
  115. // Function Location
  116. //
  117. // CSimpleSite::CloseOleObject SITE.CPP
  118. // ShowWindow Windows API
  119. // TestDebugOut Windows API
  120. //
  121. //
  122. //********************************************************************
  123. void CSimpleDoc::Close(void)
  124. {
  125. TestDebugOut(TEXT("In CSimpleDoc::Close\r\n"));
  126. ShowWindow(m_hDocWnd, SW_HIDE); // Hide the window
  127. // Close the OLE object in our document
  128. if (m_lpSite)
  129. m_lpSite->CloseOleObject();
  130. // Release the ref count added in CSimpleDoc::Create. this will make
  131. // the document's ref count go to 0, and the document will be deleted.
  132. Release();
  133. }
  134. //**********************************************************************
  135. //
  136. // CSimpleDoc::CSimpleDoc
  137. //
  138. // Purpose:
  139. //
  140. // Constructor for the CSimpleDoc Class
  141. //
  142. // Parameters:
  143. //
  144. // CSimpleApp FAR * lpApp - Pointer to the CSimpleApp Class
  145. //
  146. // HWND hWnd - Window Handle of "frame" window
  147. //
  148. // Return Value:
  149. //
  150. // None
  151. //
  152. // Function Calls:
  153. // Function Location
  154. //
  155. // TestDebugOut Windows API
  156. // GetMenu Windows API
  157. // GetSubMenu Windows API
  158. //
  159. //
  160. //********************************************************************
  161. CSimpleDoc::CSimpleDoc(CSimpleApp FAR * lpApp,HWND hWnd)
  162. {
  163. TestDebugOut(TEXT("In CSimpleDoc's Constructor\r\n"));
  164. m_lpApp = lpApp;
  165. m_lpSite = NULL;
  166. m_nCount = 0;
  167. // set up menu handles
  168. m_hMainMenu = GetMenu(hWnd);
  169. m_hFileMenu = GetSubMenu(m_hMainMenu, 0);
  170. m_hEditMenu = GetSubMenu(m_hMainMenu, 1);
  171. m_hHelpMenu = GetSubMenu(m_hMainMenu, 2);
  172. m_hCascadeMenu = NULL;
  173. m_lpActiveObject = NULL;
  174. // flags
  175. m_fInPlaceActive = FALSE;
  176. m_fAddMyUI = FALSE;
  177. m_fModifiedMenu = FALSE;
  178. }
  179. //**********************************************************************
  180. //
  181. // CSimpleDoc::~CSimpleDoc
  182. //
  183. // Purpose:
  184. //
  185. // Destructor for CSimpleDoc
  186. //
  187. // Parameters:
  188. //
  189. // None
  190. //
  191. // Return Value:
  192. //
  193. // None
  194. //
  195. // Function Calls:
  196. // Function Location
  197. //
  198. // TestDebugOut Windows API
  199. // CSimpleSite::UnloadOleObject SITE.CPP
  200. // CSimpleSite::Release SITE.CPP
  201. // IStorage::Release OLE API
  202. // GetMenuItemCount Windows API
  203. // RemoveMenu Windows API
  204. // DestroyMenu Windows API
  205. // DestroyWindows Windows API
  206. //
  207. //
  208. //********************************************************************
  209. CSimpleDoc::~CSimpleDoc()
  210. {
  211. TestDebugOut(TEXT("In CSimpleDoc's Destructor\r\n"));
  212. // Release all pointers we hold to the OLE object. also release
  213. // the ref count added in CSimpleSite::Create. this will make
  214. // the Site's ref count go to 0, and the Site will be deleted.
  215. if (m_lpSite)
  216. {
  217. m_lpSite->UnloadOleObject();
  218. m_lpSite->Release();
  219. m_lpSite = NULL;
  220. }
  221. // Release the Storage
  222. if (m_lpStorage)
  223. {
  224. m_lpStorage->Release();
  225. m_lpStorage = NULL;
  226. }
  227. // if the edit menu was modified, remove the menu item and
  228. // destroy the popup if it exists
  229. if (m_fModifiedMenu)
  230. {
  231. int nCount = GetMenuItemCount(m_hEditMenu);
  232. RemoveMenu(m_hEditMenu, nCount-1, MF_BYPOSITION);
  233. if (m_hCascadeMenu)
  234. DestroyMenu(m_hCascadeMenu);
  235. }
  236. DestroyWindow(m_hDocWnd);
  237. }
  238. //**********************************************************************
  239. //
  240. // CSimpleDoc::QueryInterface
  241. //
  242. // Purpose:
  243. //
  244. // interface negotiation at document level
  245. //
  246. // Parameters:
  247. //
  248. // REFIID riid - ID of interface to be returned
  249. // LPVOID FAR* ppvObj - Location to return the interface
  250. //
  251. // Return Value:
  252. //
  253. // E_NOINTERFACE - Always
  254. //
  255. // Function Calls:
  256. // Function Location
  257. //
  258. // TestDebugOut Windows API
  259. // ResultFromScode OLE API
  260. //
  261. // Comments:
  262. //
  263. // In this implementation, there are no doc level interfaces.
  264. // In an MDI application, there would be an IOleInPlaceUIWindow
  265. // associated with the document to provide document level tool
  266. // space negotiation.
  267. //
  268. //********************************************************************
  269. STDMETHODIMP CSimpleDoc::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  270. {
  271. TestDebugOut(TEXT("In CSimpleDoc::QueryInterface\r\n"));
  272. *ppvObj = NULL; // must set out pointer parameters to NULL
  273. // Not a supported interface
  274. return ResultFromScode(E_NOINTERFACE);
  275. }
  276. //**********************************************************************
  277. //
  278. // CSimpleDoc::AddRef
  279. //
  280. // Purpose:
  281. //
  282. // Increments the document reference count
  283. //
  284. // Parameters:
  285. //
  286. // None
  287. //
  288. // Return Value:
  289. //
  290. // UINT - The new reference count of CSimpleDoc
  291. //
  292. // Function Calls:
  293. // Function Location
  294. //
  295. // TestDebugOut Windows API
  296. //
  297. //
  298. //********************************************************************
  299. STDMETHODIMP_(ULONG) CSimpleDoc::AddRef()
  300. {
  301. TestDebugOut(TEXT("In CSimpleDoc::AddRef\r\n"));
  302. return ++m_nCount;
  303. }
  304. //**********************************************************************
  305. //
  306. // CSimpleDoc::Release
  307. //
  308. // Purpose:
  309. //
  310. // Decrements the document reference count
  311. //
  312. // Parameters:
  313. //
  314. // None
  315. //
  316. // Return Value:
  317. //
  318. // UINT - The new reference count of CSimpleDoc
  319. //
  320. // Function Calls:
  321. // Function Location
  322. //
  323. // TestDebugOut Windows API
  324. //
  325. //
  326. //********************************************************************
  327. STDMETHODIMP_(ULONG) CSimpleDoc::Release()
  328. {
  329. TestDebugOut(TEXT("In CSimpleDoc::Release\r\n"));
  330. if (--m_nCount == 0)
  331. {
  332. delete this;
  333. return 0;
  334. }
  335. return m_nCount;
  336. }
  337. //**********************************************************************
  338. //
  339. // CSimpleDoc::InsertObject
  340. //
  341. // Purpose:
  342. //
  343. // Inserts a new object to this document
  344. //
  345. // Parameters:
  346. //
  347. // None
  348. //
  349. // Return Value:
  350. //
  351. // None
  352. //
  353. // Function Calls:
  354. // Function Location
  355. //
  356. // CSimpleSite::CSimpleSite SITE.CPP
  357. // CSimpleSite::InitObject SITE.CPP
  358. // CSimpleSite::Release SITE.CPP
  359. // memset C Runtime
  360. // OleUIInsertObject OLE2UI function
  361. // CSimpleDoc::DisableInsertObject DOC.CPP
  362. // IStorage::Revert OLE API
  363. //
  364. // Comments:
  365. //
  366. // This implementation only allows one object to be inserted
  367. // into a document. Once the object has been inserted, then
  368. // the Insert Object menu choice is greyed out, to prevent
  369. // the user from inserting another.
  370. //
  371. //********************************************************************
  372. void CSimpleDoc::InsertObject()
  373. {
  374. OLEUIINSERTOBJECT io;
  375. UINT iret;
  376. TCHAR szFile[OLEUI_CCHPATHMAX];
  377. m_lpSite = CSimpleSite::Create(this);
  378. if (!m_lpSite)
  379. {
  380. /* memory allocation problem! cannot carry on.
  381. */
  382. TestDebugOut(TEXT("Memory allocation error!\n"));
  383. return;
  384. }
  385. // clear the structure
  386. _fmemset(&io, 0, sizeof(OLEUIINSERTOBJECT));
  387. // fill the structure
  388. io.cbStruct = sizeof(OLEUIINSERTOBJECT);
  389. io.dwFlags = IOF_SELECTCREATENEW | IOF_DISABLELINK |
  390. IOF_DISABLEDISPLAYASICON | IOF_CREATENEWOBJECT |
  391. IOF_CREATEFILEOBJECT;
  392. io.hWndOwner = m_hDocWnd;
  393. io.lpszCaption = (LPTSTR) TEXT("Insert Object");
  394. io.iid = IID_IOleObject;
  395. io.oleRender = OLERENDER_DRAW;
  396. io.lpIOleClientSite = &m_lpSite->m_OleClientSite;
  397. io.lpIStorage = m_lpSite->m_lpObjStorage;
  398. io.ppvObj = (LPVOID FAR *)&m_lpSite->m_lpOleObject;
  399. io.lpszFile = szFile;
  400. io.cchFile = sizeof(szFile)/sizeof(TCHAR);
  401. // cchFile is the number of characters of szFile
  402. _fmemset((LPTSTR)szFile, 0, sizeof(szFile));
  403. // call OUTLUI to do all the hard work
  404. iret = OleUIInsertObject(&io);
  405. if (iret == OLEUI_OK)
  406. {
  407. m_lpSite->InitObject((BOOL)(io.dwFlags & IOF_SELECTCREATENEW));
  408. // disable Insert Object menu item
  409. DisableInsertObject();
  410. }
  411. else
  412. {
  413. m_lpSite->Release();
  414. m_lpSite = NULL;
  415. m_lpStorage->Revert();
  416. }
  417. }
  418. //**********************************************************************
  419. //
  420. // CSimpleDoc::lResizeDoc
  421. //
  422. // Purpose:
  423. //
  424. // Resizes the document
  425. //
  426. // Parameters:
  427. //
  428. // LPRECT lpRect - The size of the client are of the "frame"
  429. // Window.
  430. //
  431. // Return Value:
  432. //
  433. // NULL
  434. //
  435. // Function Calls:
  436. // Function Location
  437. //
  438. // IOleInPlaceActiveObject::ResizeBorder Object
  439. // MoveWindow Windows API
  440. //
  441. //
  442. //********************************************************************
  443. long CSimpleDoc::lResizeDoc(LPRECT lpRect)
  444. {
  445. // if we are InPlace, then call ResizeBorder on the object, otherwise
  446. // just move the document window.
  447. if (m_fInPlaceActive)
  448. m_lpActiveObject->ResizeBorder(lpRect, &m_lpApp->m_OleInPlaceFrame,
  449. TRUE);
  450. else
  451. MoveWindow(m_hDocWnd, lpRect->left, lpRect->top, lpRect->right,
  452. lpRect->bottom, TRUE);
  453. return NULL;
  454. }
  455. //**********************************************************************
  456. //
  457. // CSimpleDoc::lAddVerbs
  458. //
  459. // Purpose:
  460. //
  461. // Adds the objects verbs to the edit menu.
  462. //
  463. // Parameters:
  464. //
  465. // None
  466. //
  467. // Return Value:
  468. //
  469. // NULL
  470. //
  471. // Function Calls:
  472. // Function Location
  473. //
  474. // GetMenuItemCount Windows API
  475. // OleUIAddVerbMenu OLE2UI function
  476. //
  477. //
  478. //********************************************************************
  479. long CSimpleDoc::lAddVerbs(void)
  480. {
  481. // m_fModifiedMenu is TRUE if the menu has already been modified
  482. // once. Since we only support one obect every time the application
  483. // is run, then once the menu is modified, it doesn't have
  484. // to be done again.
  485. if (m_lpSite && !m_fInPlaceActive && !m_fModifiedMenu)
  486. {
  487. int nCount = GetMenuItemCount(m_hEditMenu);
  488. if (!OleUIAddVerbMenu ( m_lpSite->m_lpOleObject,
  489. NULL,
  490. m_hEditMenu,
  491. nCount + 1,
  492. IDM_VERB0,
  493. 0, // no maximum verb IDM enforced
  494. FALSE,
  495. 0,
  496. &m_hCascadeMenu))
  497. {
  498. TestDebugOut(TEXT("Fail in OleUIAddVerbMenu"));
  499. }
  500. m_fModifiedMenu = TRUE;
  501. }
  502. return (NULL);
  503. }
  504. //**********************************************************************
  505. //
  506. // CSimpleDoc::PaintDoc
  507. //
  508. // Purpose:
  509. //
  510. // Paints the Document
  511. //
  512. // Parameters:
  513. //
  514. // HDC hDC - hDC of the document Window
  515. //
  516. // Return Value:
  517. //
  518. // None
  519. //
  520. // Function Calls:
  521. // Function Location
  522. //
  523. // CSimpleSite::PaintObj SITE.CPP
  524. //
  525. //
  526. //********************************************************************
  527. void CSimpleDoc::PaintDoc (HDC hDC)
  528. {
  529. // if we supported multiple objects, then we would enumerate
  530. // the objects and call paint on each of them from here.
  531. if (m_lpSite)
  532. m_lpSite->PaintObj(hDC);
  533. }
  534. //**********************************************************************
  535. //
  536. // CSimpleDoc::DisableInsertObject
  537. //
  538. // Purpose:
  539. //
  540. // Disable the ability to insert a new object in this document.
  541. //
  542. // Parameters:
  543. //
  544. // None
  545. //
  546. // Return Value:
  547. //
  548. // None
  549. //
  550. // Function Calls:
  551. // Function Location
  552. //
  553. // EnableMenuItem Windows API
  554. //
  555. // Comments:
  556. //
  557. // This implementation only allows one object to be inserted
  558. // into a document. Once the object has been inserted, then
  559. // the Insert Object menu choice is greyed out, to prevent
  560. // the user from inserting another.
  561. //
  562. //********************************************************************
  563. void CSimpleDoc::DisableInsertObject(void)
  564. {
  565. // Disable InsertObject menu choice
  566. EnableMenuItem( m_hEditMenu, 0, MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
  567. }