Leaked source code of windows server 2003
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.

2989 lines
102 KiB

  1. /*************************************************************************
  2. **
  3. ** OLE 2 Sample Code
  4. **
  5. ** oleapp.c
  6. **
  7. ** This file contains functions and methods that are common to
  8. ** server and the client version of the app. This includes the class
  9. ** factory methods and all OleApp functions.
  10. **
  11. ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
  12. **
  13. *************************************************************************/
  14. #include "outline.h"
  15. #include <ole2ver.h>
  16. OLEDBGDATA
  17. extern LPOUTLINEAPP g_lpApp;
  18. extern IUnknownVtbl g_OleApp_UnknownVtbl;
  19. extern IUnknownVtbl g_OleDoc_UnknownVtbl;
  20. extern IPersistFileVtbl g_OleDoc_PersistFileVtbl;
  21. extern IOleItemContainerVtbl g_OleDoc_OleItemContainerVtbl;
  22. extern IExternalConnectionVtbl g_OleDoc_ExternalConnectionVtbl;
  23. extern IDataObjectVtbl g_OleDoc_DataObjectVtbl;
  24. #if defined( USE_DRAGDROP )
  25. extern IDropTargetVtbl g_OleDoc_DropTargetVtbl;
  26. extern IDropSourceVtbl g_OleDoc_DropSourceVtbl;
  27. #endif // USE_DRAGDROP
  28. #if defined( OLE_SERVER )
  29. extern IOleObjectVtbl g_SvrDoc_OleObjectVtbl;
  30. extern IPersistStorageVtbl g_SvrDoc_PersistStorageVtbl;
  31. #if defined( SVR_TREATAS )
  32. extern IStdMarshalInfoVtbl g_SvrDoc_StdMarshalInfoVtbl;
  33. #endif // SVR_TREATAS
  34. extern IUnknownVtbl g_PseudoObj_UnknownVtbl;
  35. extern IOleObjectVtbl g_PseudoObj_OleObjectVtbl;
  36. extern IDataObjectVtbl g_PseudoObj_DataObjectVtbl;
  37. #if defined( INPLACE_SVR )
  38. extern IOleInPlaceObjectVtbl g_SvrDoc_OleInPlaceObjectVtbl;
  39. extern IOleInPlaceActiveObjectVtbl g_SvrDoc_OleInPlaceActiveObjectVtbl;
  40. #endif // INPLACE_SVR
  41. #endif // OLE_SERVER
  42. #if defined( OLE_CNTR )
  43. extern IOleUILinkContainerVtbl g_CntrDoc_OleUILinkContainerVtbl;
  44. extern IUnknownVtbl g_CntrLine_UnknownVtbl;
  45. extern IOleClientSiteVtbl g_CntrLine_OleClientSiteVtbl;
  46. extern IAdviseSinkVtbl g_CntrLine_AdviseSinkVtbl;
  47. #if defined( INPLACE_CNTR )
  48. extern IOleInPlaceSiteVtbl g_CntrLine_OleInPlaceSiteVtbl;
  49. extern IOleInPlaceFrameVtbl g_CntrApp_OleInPlaceFrameVtbl;
  50. extern BOOL g_fInsideOutContainer;
  51. #endif // INPLACE_CNTR
  52. #endif // OLE_CNTR
  53. // REVIEW: these are NOT useful end-user messages
  54. static char ErrMsgCreateCF[] = "Can't create Class Factory!";
  55. static char ErrMsgRegCF[] = "Can't register Class Factory!";
  56. static char ErrMsgRegMF[] = "Can't register Message Filter!";
  57. extern UINT g_uMsgHelp;
  58. /* OleApp_InitInstance
  59. * -------------------
  60. *
  61. * Initialize the app instance by creating the main frame window and
  62. * performing app instance specific initializations
  63. * (eg. initializing interface Vtbls).
  64. *
  65. * RETURNS: TRUE if the memory could be allocated, and the server app
  66. * was properly initialized.
  67. * FALSE otherwise
  68. *
  69. */
  70. BOOL OleApp_InitInstance(LPOLEAPP lpOleApp, HINSTANCE hInst, int nCmdShow)
  71. {
  72. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  73. HRESULT hrErr;
  74. DWORD dwBuildVersion = OleBuildVersion();
  75. LPMALLOC lpMalloc = NULL;
  76. OLEDBG_BEGIN3("OleApp_InitInstance\r\n")
  77. lpOleApp->m_fOleInitialized = FALSE;
  78. /* OLE2NOTE: check if the build version of the OLE2 DLL's match
  79. ** what our application is expecting.
  80. */
  81. if (HIWORD(dwBuildVersion) != rmm || LOWORD(dwBuildVersion) < rup) {
  82. OleDbgAssertSz(0, "ERROR: OLE 2.0 DLL's are NOT compatible!");
  83. #if !defined( _DEBUG )
  84. return FALSE; // Wrong version of DLL's
  85. #endif
  86. }
  87. #if defined( _DEBUG )
  88. /* OLE2NOTE: Use a special debug allocator to help track down
  89. ** memory leaks.
  90. */
  91. OleStdCreateDbAlloc(0, &lpMalloc);
  92. #endif
  93. /* OLE2NOTE: the OLE libraries must be properly initialized before
  94. ** making any calls. OleInitialize automatically calls
  95. ** CoInitialize. we will use the default task memory allocator
  96. ** therefore we pass NULL to OleInitialize.
  97. */
  98. OLEDBG_BEGIN2("OleInitialize called\r\n")
  99. hrErr = OleInitialize(lpMalloc);
  100. if (FAILED(hrErr))
  101. {
  102. // Replacing the allocator may not be legal - try initializing
  103. // without overriding the allocator
  104. hrErr = OleInitialize(NULL);
  105. }
  106. OLEDBG_END2
  107. #if defined( _DEBUG )
  108. /* OLE2NOTE: release the special debug allocator so that only OLE is
  109. ** holding on to it. later when OleUninitialize is called, then
  110. ** the debug allocator object will be destroyed. when the debug
  111. ** allocator object is destoyed, it will report (to the Output
  112. ** Debug Terminal) whether there are any memory leaks.
  113. */
  114. if (lpMalloc) lpMalloc->lpVtbl->Release(lpMalloc);
  115. #endif
  116. if (hrErr != NOERROR) {
  117. OutlineApp_ErrorMessage(lpOutlineApp,"OLE initialization failed!");
  118. goto error;
  119. }
  120. /*****************************************************************
  121. ** OLE2NOTE: we must remember the fact that OleInitialize has
  122. ** been call successfully. the very last thing an app must
  123. ** be do is properly shut down OLE by calling
  124. ** OleUninitialize. This call MUST be guarded! it is only
  125. ** allowable to call OleUninitialize if OleInitialize has
  126. ** been called SUCCESSFULLY.
  127. *****************************************************************/
  128. lpOleApp->m_fOleInitialized = TRUE;
  129. // Initialize the OLE 2.0 interface method tables.
  130. if (! OleApp_InitVtbls(lpOleApp))
  131. goto error;
  132. // Register OLE 2.0 clipboard formats.
  133. lpOleApp->m_cfEmbedSource = RegisterClipboardFormat(CF_EMBEDSOURCE);
  134. lpOleApp->m_cfEmbeddedObject = RegisterClipboardFormat(
  135. CF_EMBEDDEDOBJECT
  136. );
  137. lpOleApp->m_cfLinkSource = RegisterClipboardFormat(CF_LINKSOURCE);
  138. lpOleApp->m_cfFileName = RegisterClipboardFormat(CF_FILENAME);
  139. lpOleApp->m_cfObjectDescriptor =
  140. RegisterClipboardFormat(CF_OBJECTDESCRIPTOR);
  141. lpOleApp->m_cfLinkSrcDescriptor =
  142. RegisterClipboardFormat(CF_LINKSRCDESCRIPTOR);
  143. lpOleApp->m_cRef = 0;
  144. lpOleApp->m_cDoc = 0;
  145. lpOleApp->m_fUserCtrl = FALSE;
  146. lpOleApp->m_dwRegClassFac = 0;
  147. lpOleApp->m_lpClassFactory = NULL;
  148. lpOleApp->m_cModalDlgActive = 0;
  149. INIT_INTERFACEIMPL(
  150. &lpOleApp->m_Unknown,
  151. &g_OleApp_UnknownVtbl,
  152. lpOleApp
  153. );
  154. #if defined( USE_DRAGDROP )
  155. // delay before dragging should start, in milliseconds
  156. lpOleApp->m_nDragDelay = GetProfileInt(
  157. "windows",
  158. "DragDelay",
  159. DD_DEFDRAGDELAY
  160. );
  161. // minimum distance (radius) before drag should start, in pixels
  162. lpOleApp->m_nDragMinDist = GetProfileInt(
  163. "windows",
  164. "DragMinDist",
  165. DD_DEFDRAGMINDIST
  166. );
  167. // delay before scrolling, in milliseconds
  168. lpOleApp->m_nScrollDelay = GetProfileInt(
  169. "windows",
  170. "DragScrollDelay",
  171. DD_DEFSCROLLDELAY
  172. );
  173. // inset-width of the hot zone, in pixels
  174. lpOleApp->m_nScrollInset = GetProfileInt(
  175. "windows",
  176. "DragScrollInset",
  177. DD_DEFSCROLLINSET
  178. );
  179. // scroll interval, in milliseconds
  180. lpOleApp->m_nScrollInterval = GetProfileInt(
  181. "windows",
  182. "DragScrollInterval",
  183. DD_DEFSCROLLINTERVAL
  184. );
  185. #if defined( IF_SPECIAL_DD_CURSORS_NEEDED )
  186. // This would be used if the app wanted to have custom drag/drop cursors
  187. lpOleApp->m_hcursorDragNone = LoadCursor ( hInst, "DragNoneCur" );
  188. lpOleApp->m_hcursorDragCopy = LoadCursor ( hInst, "DragCopyCur" );
  189. lpOleApp->m_hcursorDragMove = LoadCursor ( hInst, "DragMoveCur" );
  190. lpOleApp->m_hcursorDragLink = LoadCursor ( hInst, "DragLinkCur" );
  191. #endif // IF_SPECIAL_DD_CURSORS_NEEDED
  192. #endif // USE_DRAGDROP
  193. lpOleApp->m_lpMsgFilter = NULL;
  194. #if defined( USE_MSGFILTER )
  195. /* OLE2NOTE: Register our message filter upon app startup. the
  196. ** message filter is used to handle concurrency.
  197. ** we will use a standard implementation of IMessageFilter that
  198. ** is included as part of the OLE2UI library.
  199. */
  200. lpOleApp->m_lpMsgFilter = NULL;
  201. if (! OleApp_RegisterMessageFilter(lpOleApp))
  202. goto error;
  203. /* OLE2NOTE: because our app is initially INVISIBLE, we must
  204. ** DISABLE the busy dialog. we should NOT put up any dialogs if
  205. ** our app is invisible. when our app window is made visible,
  206. ** then the busy dialog will be enabled.
  207. */
  208. OleStdMsgFilter_EnableBusyDialog(lpOleApp->m_lpMsgFilter, FALSE);
  209. #endif // USE_MSGFILTER
  210. #if defined( OLE_SERVER )
  211. /* OLE2NOTE: perform initialization specific for an OLE server */
  212. if (! ServerApp_InitInstance((LPSERVERAPP)lpOutlineApp, hInst, nCmdShow))
  213. goto error;
  214. #endif
  215. #if defined( OLE_CNTR )
  216. /* OLE2NOTE: perform initialization specific for an OLE container */
  217. // Register help message
  218. g_uMsgHelp = RegisterWindowMessage(SZOLEUI_MSG_HELP);
  219. if (! ContainerApp_InitInstance((LPCONTAINERAPP)lpOutlineApp, hInst, nCmdShow))
  220. goto error;
  221. #endif
  222. #if defined( OLE_CNTR )
  223. lpOleApp->m_hStdPal = OleStdCreateStandardPalette();
  224. #endif
  225. OLEDBG_END3
  226. return TRUE;
  227. error:
  228. OLEDBG_END3
  229. return FALSE;
  230. }
  231. /*
  232. * OleApp_TerminateApplication
  233. * ---------------------------
  234. * Perform proper OLE application cleanup before shutting down
  235. */
  236. void OleApp_TerminateApplication(LPOLEAPP lpOleApp)
  237. {
  238. OLEDBG_BEGIN3("OleApp_TerminateApplication\r\n")
  239. /* OLE2NOTE: perform a clean shut down for OLE. at this point our
  240. ** App refcnt should be 0, or else we should never have reached
  241. ** this point!
  242. */
  243. OleDbgAssertSz(lpOleApp->m_cRef == 0, "App NOT shut down properly");
  244. if(lpOleApp->m_fOleInitialized) {
  245. OLEDBG_BEGIN2("OleUninitialize called\r\n")
  246. OleUninitialize();
  247. OLEDBG_END2
  248. }
  249. OLEDBG_END3
  250. }
  251. /* OleApp_ParseCmdLine
  252. * -------------------
  253. *
  254. * Parse the command line for any execution flags/arguments.
  255. * OLE2NOTE: check if "-Embedding" switch is given.
  256. */
  257. BOOL OleApp_ParseCmdLine(LPOLEAPP lpOleApp, LPSTR lpszCmdLine, int nCmdShow)
  258. {
  259. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  260. char szFileName[256]; /* buffer for filename in command line */
  261. BOOL fStatus = TRUE;
  262. BOOL fEmbedding = FALSE;
  263. OLEDBG_BEGIN3("OleApp_ParseCmdLine\r\n")
  264. szFileName[0] = '\0';
  265. ParseCmdLine(lpszCmdLine, &fEmbedding, (LPSTR)szFileName);
  266. #if defined( MDI_VERSION )
  267. /* OLE2NOTE: an MDI app would ALWAYS register its ClassFactory. it
  268. ** can handle multiple objects at the same time, while an SDI
  269. ** application can only handle a single embedded or file-based
  270. ** object at a time.
  271. */
  272. fStatus = OleApp_RegisterClassFactory(lpOleApp);
  273. #endif
  274. if(fEmbedding) {
  275. if (szFileName[0] == '\0') {
  276. /*****************************************************************
  277. ** App was launched with /Embedding.
  278. ** We must register our ClassFactory with OLE, remain hidden
  279. ** (the app window is initially created not visible), and
  280. ** wait for OLE to call IClassFactory::CreateInstance
  281. ** method. We do not automatically create a document as we
  282. ** do when the app is launched by the user from the
  283. ** FileManager. We must NOT make our app window visible
  284. ** until told to do so by our container.
  285. **
  286. ** OLE2NOTE: Because we are an SDI app, we only register our
  287. ** ClassFactory if we are launched with the /Embedding
  288. ** flag WITHOUT a filename. an MDI app would ALWAYS
  289. ** register its ClassFactory. it can handle multiple
  290. ** objects at the same time, while an SDI application
  291. ** can only handle a single embedded or file-based
  292. ** object at a time.
  293. *****************************************************************/
  294. #if defined( SDI_VERSION )
  295. fStatus = OleApp_RegisterClassFactory(lpOleApp);
  296. #endif
  297. } else {
  298. /*****************************************************************
  299. ** App was launched with /Embedding <Filename>.
  300. ** We must create a document and load the file and
  301. ** register it in the RunningObjectTable BEFORE we
  302. ** enter our GetMessage loop (ie. before we yield).
  303. ** One way to perform these tasks is to call the same
  304. ** interface methods that OLE 2.0 calls for linking to a
  305. ** file:
  306. ** IClassFactory::CreateInstance
  307. ** IPersistFile::Load
  308. **
  309. ** We must NOT make our app window visible until told to
  310. ** do so by our container. An application will be
  311. ** launched in this manner by an OLE 1.0 application
  312. ** link situation (eg. double clicking a linked object
  313. ** or OleCreateLinkFromFile called).
  314. **
  315. ** OLE2NOTE: Because we are an SDI app, we should NOT
  316. ** register our ClassFactory when we are launched with the
  317. ** /Embedding <Filename> flag. our SDI instance can only
  318. ** handle a single embedded or file-based object.
  319. ** an MDI app WOULD register its ClassFactory at all
  320. ** times because it can handle multiple objects.
  321. *****************************************************************/
  322. // allocate a new document object
  323. lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
  324. if (! lpOutlineApp->m_lpDoc) {
  325. OLEDBG_END3
  326. return FALSE;
  327. }
  328. /* OLE2NOTE: initially the Doc object is created with a 0 ref
  329. ** count. in order to have a stable Doc object during the
  330. ** process of initializing the new Doc instance,
  331. ** we intially AddRef the Doc ref cnt and later
  332. ** Release it. This initial AddRef is artificial; it is simply
  333. ** done to guarantee that a harmless QueryInterface followed by
  334. ** a Release does not inadvertantly force our object to destroy
  335. ** itself prematurely.
  336. */
  337. OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
  338. /* OLE2NOTE: OutlineDoc_LoadFromFile will register our document
  339. ** in the RunningObjectTable. this registration will
  340. ** AddRef our document. therefore our document will not
  341. ** be destroyed when we release the artificial AddRef
  342. */
  343. fStatus = OutlineDoc_LoadFromFile(
  344. lpOutlineApp->m_lpDoc, (LPSTR)szFileName);
  345. OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel AddRef
  346. OLEDBG_END3
  347. return fStatus;
  348. }
  349. } else {
  350. /*****************************************************************
  351. ** App was launched by the user (without /Embedding) and
  352. ** therefore is marked to be under user control.
  353. ** In this case, because we are an SDI app, we do NOT
  354. ** register our ClassFactory with OLE. This app instance can
  355. ** only manage one document at a time (either a user
  356. ** document or an embedded object document). An MDI app
  357. ** would register its ClassFactory here.
  358. **
  359. ** We must create a document for the user (either
  360. ** initialized from a file given on the command line or
  361. ** initialized as an untitled document. We must also make
  362. ** our app window visible to the user.
  363. *****************************************************************/
  364. // allocate a new document object
  365. lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
  366. if (! lpOutlineApp->m_lpDoc) goto error;
  367. /* OLE2NOTE: initially the Doc object is created with a 0 ref
  368. ** count. in order to have a stable Doc object during the
  369. ** process of initializing the new Doc instance,
  370. ** we intially AddRef the Doc ref cnt and later
  371. ** Release it. This initial AddRef is artificial; it is simply
  372. ** done to guarantee that a harmless QueryInterface followed by
  373. ** a Release does not inadvertantly force our object to destroy
  374. ** itself prematurely.
  375. */
  376. OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
  377. if(*szFileName) {
  378. // initialize the document from the specified file
  379. if (! OutlineDoc_LoadFromFile(lpOutlineApp->m_lpDoc, szFileName))
  380. goto error;
  381. } else {
  382. // set the doc to an (Untitled) doc.
  383. if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc))
  384. goto error;
  385. }
  386. // position and size the new doc window
  387. OutlineApp_ResizeWindows(lpOutlineApp);
  388. OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc); // calls OleDoc_Lock
  389. OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);// rel AddRef above
  390. // show main app window
  391. ShowWindow(lpOutlineApp->m_hWndApp, nCmdShow);
  392. UpdateWindow(lpOutlineApp->m_hWndApp);
  393. #if defined( OLE_CNTR )
  394. ContainerDoc_UpdateLinks((LPCONTAINERDOC)lpOutlineApp->m_lpDoc);
  395. #endif
  396. }
  397. OLEDBG_END3
  398. return fStatus;
  399. error:
  400. // REVIEW: should load string from string resource
  401. OutlineApp_ErrorMessage(
  402. lpOutlineApp,
  403. "Could not create document--Out of Memory"
  404. );
  405. if (lpOutlineApp->m_lpDoc) // rel artificial AddRef above
  406. OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);
  407. OLEDBG_END3
  408. return FALSE;
  409. }
  410. /* OleApp_CloseAllDocsAndExitCommand
  411. * ---------------------------------
  412. *
  413. * Close all active documents and exit the app.
  414. * Because this is an SDI, there is only one document
  415. * If the doc was modified, prompt the user if he wants to save it.
  416. *
  417. * Returns:
  418. * TRUE if the app is successfully closed
  419. * FALSE if failed or aborted
  420. *
  421. * OLE2NOTE: in the OLE version, we can NOT directly
  422. * destroy the App object. we can only take all
  423. * necessary actions to ensure that our object receives
  424. * all of its Releases from clients holding onto
  425. * pointers (eg. closing all docs and flushing the
  426. * clipboard) and then we must hide our window and wait
  427. * actually for our refcnt to reach 0. when it reaches 0,
  428. * our destructor (OutlineApp_Destroy) will be called.
  429. * each document addref's the app object in order to
  430. * guarentee that the app does not shut down while the doc
  431. * is still open. closing all docs, will release these
  432. * refcnt's. if there are now more open documents AND the
  433. * app is not under the control of the user (ie. launched by
  434. * OLE) then the app will now shut down. the OleApp_Release
  435. * function executes this shut down procedure. after closing
  436. * all docs, then releasing the user refcnt will force the
  437. * app to shut down.
  438. */
  439. BOOL OleApp_CloseAllDocsAndExitCommand(
  440. LPOLEAPP lpOleApp,
  441. BOOL fForceEndSession
  442. )
  443. {
  444. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  445. DWORD dwSaveOption = (fForceEndSession ?
  446. OLECLOSE_NOSAVE : OLECLOSE_PROMPTSAVE);
  447. /* OLE2NOTE: in order to have a stable App object during the
  448. ** process of closing, we intially AddRef the App ref cnt and
  449. ** later Release it. This initial AddRef is artificial; it is
  450. ** simply done to guarantee that our App object does not
  451. ** destroy itself until the end of this routine.
  452. */
  453. OleApp_AddRef(lpOleApp);
  454. /* Because this is an SDI app, there is only one document.
  455. ** Close the doc. if it is successfully closed and the app will
  456. ** not automatically exit, then also exit the app.
  457. ** if this were an MDI app, we would loop through and close all
  458. ** open MDI child documents.
  459. */
  460. #if defined( OLE_SERVER )
  461. if (!fForceEndSession &&
  462. lpOutlineApp->m_lpDoc->m_docInitType == DOCTYPE_EMBEDDED)
  463. dwSaveOption = OLECLOSE_SAVEIFDIRTY;
  464. #endif
  465. if (! OutlineDoc_Close(lpOutlineApp->m_lpDoc, dwSaveOption)) {
  466. OleApp_Release(lpOleApp);
  467. return FALSE; // User Aborted shutdown
  468. }
  469. #if defined( _DEBUG )
  470. OleDbgAssertSz(
  471. lpOutlineApp->m_lpDoc==NULL,
  472. "Closed doc NOT properly destroyed"
  473. );
  474. #endif
  475. #if defined( OLE_CNTR )
  476. /* if we currently have data on the clipboard then we must tell
  477. ** the clipboard to release our clipboard data object
  478. ** (document)
  479. */
  480. if (lpOutlineApp->m_lpClipboardDoc)
  481. OleApp_FlushClipboard(lpOleApp);
  482. #endif
  483. OleApp_HideWindow(lpOleApp);
  484. /* OLE2NOTE: this call forces all external connections to our
  485. ** object to close down and therefore guarantees that we receive
  486. ** all releases associated with those external connections.
  487. */
  488. OLEDBG_BEGIN2("CoDisconnectObject(lpApp) called\r\n")
  489. CoDisconnectObject((LPUNKNOWN)&lpOleApp->m_Unknown, 0);
  490. OLEDBG_END2
  491. OleApp_Release(lpOleApp); // release artificial AddRef above
  492. return TRUE;
  493. }
  494. /* OleApp_ShowWindow
  495. * -----------------
  496. *
  497. * Show the window of the app to the user.
  498. * make sure app window is visible and bring the app to the top.
  499. * IF fGiveUserCtrl == TRUE
  500. * THEN give the user the control over the life-time of the app.
  501. */
  502. void OleApp_ShowWindow(LPOLEAPP lpOleApp, BOOL fGiveUserCtrl)
  503. {
  504. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  505. OLEDBG_BEGIN3("OleApp_ShowWindow\r\n")
  506. /* OLE2NOTE: while the application is visible and under user
  507. ** control, we do NOT want it to be prematurely destroyed when
  508. ** the user closes a document. thus we must inform OLE to hold
  509. ** an external lock on our application on behalf of the user.
  510. ** this arranges that OLE holds at least 1 reference to our
  511. ** application that will NOT be released until we release this
  512. ** external lock. later, when the application window is hidden, we
  513. ** will release this external lock.
  514. */
  515. if (fGiveUserCtrl && ! lpOleApp->m_fUserCtrl) {
  516. lpOleApp->m_fUserCtrl = TRUE;
  517. OleApp_Lock(lpOleApp, TRUE /* fLock */, 0 /* not applicable */);
  518. }
  519. // we must show our App window and force it to have input focus
  520. ShowWindow(lpOutlineApp->m_hWndApp, SW_SHOWNORMAL);
  521. SetFocus(lpOutlineApp->m_hWndApp);
  522. /* OLE2NOTE: because our app is now visible, we can enable the busy
  523. ** dialog. we should NOT put up any dialogs if our app is
  524. ** invisible.
  525. */
  526. OleApp_EnableBusyDialogs(lpOleApp, TRUE, TRUE);
  527. OLEDBG_END3
  528. }
  529. /* OleApp_HideWindow
  530. * -----------------
  531. *
  532. * Hide the window of the app from the user.
  533. * take away the control of the app by the user.
  534. */
  535. void OleApp_HideWindow(LPOLEAPP lpOleApp)
  536. {
  537. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  538. OLEDBG_BEGIN3("OleApp_HideWindow\r\n")
  539. /* OLE2NOTE: the application is now being hidden, so we must release
  540. ** the external lock that was made on behalf of the user.
  541. ** if this is that last external lock on our application, thus
  542. ** enabling our application to complete its shutdown operation.
  543. */
  544. if (lpOleApp->m_fUserCtrl) {
  545. lpOleApp->m_fUserCtrl = FALSE;
  546. OleApp_Lock(lpOleApp, FALSE /*fLock*/, TRUE /*fLastUnlockReleases*/);
  547. }
  548. ShowWindow(lpOutlineApp->m_hWndApp, SW_HIDE);
  549. /* OLE2NOTE: because our app is now INVISIBLE, we must DISABLE the busy
  550. ** dialog. we should NOT put up any dialogs if our app is
  551. ** invisible.
  552. */
  553. OleApp_EnableBusyDialogs(lpOleApp, FALSE, FALSE);
  554. OLEDBG_END3
  555. }
  556. /* OleApp_Lock
  557. ** -----------
  558. ** Lock/Unlock the App object. if the last lock is unlocked and
  559. ** fLastUnlockReleases == TRUE, then the app object will shut down
  560. ** (ie. it will recieve its final release and its refcnt will go to 0).
  561. */
  562. HRESULT OleApp_Lock(LPOLEAPP lpOleApp, BOOL fLock, BOOL fLastUnlockReleases)
  563. {
  564. HRESULT hrErr;
  565. #if defined( _DEBUG )
  566. if (fLock) {
  567. OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,TRUE) called\r\n")
  568. } else {
  569. if (fLastUnlockReleases)
  570. OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,FALSE,TRUE) called\r\n")
  571. else
  572. OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,FALSE,FALSE) called\r\n")
  573. }
  574. #endif // _DEBUG
  575. OleApp_AddRef(lpOleApp); // artificial AddRef to make object stable
  576. hrErr = CoLockObjectExternal(
  577. (LPUNKNOWN)&lpOleApp->m_Unknown, fLock, fLastUnlockReleases);
  578. OleApp_Release(lpOleApp); // release artificial AddRef above
  579. OLEDBG_END2
  580. return hrErr;
  581. }
  582. /* OleApp_Destroy
  583. * --------------
  584. *
  585. * Free all OLE related resources that had been allocated for the app.
  586. */
  587. void OleApp_Destroy(LPOLEAPP lpOleApp)
  588. {
  589. // OLE2NOTE: Revoke our message filter upon app shutdown.
  590. OleApp_RevokeMessageFilter(lpOleApp);
  591. // OLE2NOTE: Revoke our ClassFactory upon app shutdown.
  592. OleApp_RevokeClassFactory(lpOleApp);
  593. #if defined( IF_SPECIAL_DD_CURSORS_NEEDED )
  594. // This would be used if the app wanted to have custom drag/drop cursors
  595. DestroyCursor(lpOleApp->m_hcursorDragNone);
  596. DestroyCursor(lpOleApp->m_hcursorDragCopy);
  597. DestroyCursor(lpOleApp->m_hcursorDragLink);
  598. DestroyCursor(lpOleApp->m_hcursorDragMove);
  599. #endif // IF_SPECIAL_DD_CURSORS_NEEDED
  600. #if defined( OLE_CNTR )
  601. if (lpOleApp->m_hStdPal) {
  602. DeleteObject(lpOleApp->m_hStdPal);
  603. lpOleApp->m_hStdPal = NULL;
  604. }
  605. #endif
  606. }
  607. /* OleApp_DocLockApp
  608. ** -----------------
  609. ** Add a lock on the App on behalf of the Doc. the App may not close
  610. ** while the Doc exists.
  611. **
  612. ** when a document is first created, it calls this method to
  613. ** guarantee that the application stays alive (OleDoc_Init).
  614. ** when a document is destroyed, it calls
  615. ** OleApp_DocUnlockApp to release this hold on the app.
  616. */
  617. void OleApp_DocLockApp(LPOLEAPP lpOleApp)
  618. {
  619. ULONG cDoc;
  620. OLEDBG_BEGIN3("OleApp_DocLockApp\r\n")
  621. cDoc = ++lpOleApp->m_cDoc;
  622. OleDbgOutRefCnt3("OleApp_DocLockApp: cDoc++\r\n", lpOleApp, cDoc);
  623. OleApp_Lock(lpOleApp, TRUE /* fLock */, 0 /* not applicable */);
  624. OLEDBG_END3
  625. return;
  626. }
  627. /* OleApp_DocUnlockApp
  628. ** -------------------
  629. ** Forget all references to a closed document.
  630. ** Release the lock on the App on behalf of the Doc. if this was the
  631. ** last lock on the app, then it will shutdown.
  632. */
  633. void OleApp_DocUnlockApp(LPOLEAPP lpOleApp, LPOUTLINEDOC lpOutlineDoc)
  634. {
  635. ULONG cDoc;
  636. OLEDBG_BEGIN3("OleApp_DocUnlockApp\r\n")
  637. /* OLE2NOTE: when there are no open documents and the app is not
  638. ** under the control of the user then revoke our ClassFactory to
  639. ** enable the app to shut down.
  640. */
  641. cDoc = --lpOleApp->m_cDoc;
  642. #if defined( _DEBUG )
  643. OleDbgAssertSz (
  644. lpOleApp->m_cDoc >= 0, "DocUnlockApp called with cDoc == 0");
  645. OleDbgOutRefCnt3(
  646. "OleApp_DocUnlockApp: cDoc--\r\n", lpOleApp, cDoc);
  647. #endif
  648. OleApp_Lock(lpOleApp, FALSE /* fLock */, TRUE /* fLastUnlockReleases */);
  649. OLEDBG_END3
  650. return;
  651. }
  652. /* OleApp_HideIfNoReasonToStayVisible
  653. ** ----------------------------------
  654. **
  655. ** if there are no more documents visible to the user and the app
  656. ** itself is not under user control, then it has no reason to stay
  657. ** visible. we thus should hide the app. we can not directly destroy
  658. ** the app, because it may be validly being used programatically by
  659. ** another client application and should remain running. the app
  660. ** should simply be hidden from the user.
  661. */
  662. void OleApp_HideIfNoReasonToStayVisible(LPOLEAPP lpOleApp)
  663. {
  664. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  665. LPOUTLINEDOC lpOutlineDoc;
  666. OLEDBG_BEGIN3("OleApp_HideIfNoReasonToStayVisible\r\n")
  667. if (lpOleApp->m_fUserCtrl) {
  668. OLEDBG_END3
  669. return; // remain visible; user in control of app
  670. }
  671. /* Because this is an SDI app, there is only one user document.
  672. ** check if it is visible to the user. an MDI app would loop over
  673. ** all open MDI child documents to see if any are visible.
  674. */
  675. lpOutlineDoc = (LPOUTLINEDOC)lpOutlineApp->m_lpDoc;
  676. if (lpOutlineDoc && IsWindowVisible(lpOutlineDoc->m_hWndDoc))
  677. return; // remain visible; the doc is visible to the user
  678. // if we reached here, the app should be hidden
  679. OleApp_HideWindow(lpOleApp);
  680. OLEDBG_END3
  681. }
  682. /* OleApp_AddRef
  683. ** -------------
  684. **
  685. ** increment the ref count of the App object.
  686. **
  687. ** Returns the new ref count on the object
  688. */
  689. ULONG OleApp_AddRef(LPOLEAPP lpOleApp)
  690. {
  691. ++lpOleApp->m_cRef;
  692. #if defined( _DEBUG )
  693. OleDbgOutRefCnt4(
  694. "OleApp_AddRef: cRef++\r\n",
  695. lpOleApp,
  696. lpOleApp->m_cRef
  697. );
  698. #endif
  699. return lpOleApp->m_cRef;
  700. }
  701. /* OleApp_Release
  702. ** --------------
  703. **
  704. ** decrement the ref count of the App object.
  705. ** if the ref count goes to 0, then the app object is destroyed.
  706. **
  707. ** Returns the remaining ref count on the object
  708. */
  709. ULONG OleApp_Release (LPOLEAPP lpOleApp)
  710. {
  711. ULONG cRef;
  712. cRef = --lpOleApp->m_cRef;
  713. #if defined( _DEBUG )
  714. OleDbgAssertSz (lpOleApp->m_cRef >= 0, "Release called with cRef == 0");
  715. OleDbgOutRefCnt4(
  716. "OleApp_AddRef: cRef--\r\n", lpOleApp, cRef);
  717. #endif // _DEBUG
  718. /*********************************************************************
  719. ** OLE2NOTE: when the ClassFactory refcnt == 0, then destroy it. **
  720. ** otherwise the ClassFactory is still in use. **
  721. *********************************************************************/
  722. if(cRef == 0)
  723. OutlineApp_Destroy((LPOUTLINEAPP)lpOleApp);
  724. return cRef;
  725. }
  726. /* OleApp_QueryInterface
  727. ** ---------------------
  728. **
  729. ** Retrieve a pointer to an interface on the app object.
  730. **
  731. ** OLE2NOTE: this function will AddRef the ref cnt of the object.
  732. **
  733. ** Returns NOERROR if interface is successfully retrieved.
  734. ** E_NOINTERFACE if the interface is not supported
  735. */
  736. HRESULT OleApp_QueryInterface (
  737. LPOLEAPP lpOleApp,
  738. REFIID riid,
  739. LPVOID FAR* lplpvObj
  740. )
  741. {
  742. SCODE sc;
  743. /* OLE2NOTE: we must make sure to set all out ptr parameters to NULL. */
  744. *lplpvObj = NULL;
  745. if (IsEqualIID(riid, &IID_IUnknown)) {
  746. OleDbgOut4("OleApp_QueryInterface: IUnknown* RETURNED\r\n");
  747. *lplpvObj = (LPVOID) &lpOleApp->m_Unknown;
  748. OleApp_AddRef(lpOleApp);
  749. sc = S_OK;
  750. }
  751. else {
  752. sc = E_NOINTERFACE;
  753. }
  754. OleDbgQueryInterfaceMethod(*lplpvObj);
  755. return ResultFromScode(sc);
  756. }
  757. /* OleApp_RejectInComingCalls
  758. ** -------------------------
  759. ** Reject/Handle in coming OLE (LRPC) calls.
  760. **
  761. ** OLE2NOTE: if the app is in a state when it can NOT handle in
  762. ** coming OLE method calls from an external process (eg. the app has
  763. ** an application modal dialog up), then it should call
  764. ** OleApp_RejectInComingCalls(TRUE). in this state the
  765. ** IMessageFilter::HandleInComingCall method will return
  766. ** SERVERCALL_RETRYLATER. this tells the caller to try again in a
  767. ** little while. normally the calling app will put up a dialog (see
  768. ** OleUIBusy dialog) in this situation informing the user of the
  769. ** situation. the user then is normally given the option to
  770. ** "Switch To..." the busy application, retry, or cancel the
  771. ** operation. when the app is ready to continue processing such
  772. ** calls, it should call OleApp_RejectInComingCalls(FALSE). in this
  773. ** state, SERVERCALL_ISHANDLED is returned by
  774. ** IMessageFilter::HandleInComingCall.
  775. */
  776. void OleApp_RejectInComingCalls(LPOLEAPP lpOleApp, BOOL fReject)
  777. {
  778. #if defined( _DEBUG )
  779. if (fReject)
  780. OleDbgOut3("OleApp_RejectInComingCalls(TRUE)\r\n");
  781. else
  782. OleDbgOut3("OleApp_RejectInComingCalls(FALSE)\r\n");
  783. #endif // _DEBUG
  784. OleDbgAssert(lpOleApp->m_lpMsgFilter != NULL);
  785. if (! lpOleApp->m_lpMsgFilter)
  786. return;
  787. OleStdMsgFilter_SetInComingCallStatus(
  788. lpOleApp->m_lpMsgFilter,
  789. (fReject ? SERVERCALL_RETRYLATER : SERVERCALL_ISHANDLED)
  790. );
  791. }
  792. /* OleApp_DisableBusyDialogs
  793. ** -------------------------
  794. ** Disable the Busy and NotResponding dialogs.
  795. **
  796. ** Returns previous enable state so that it can be restored by
  797. ** calling OleApp_ReEnableBusyDialogs.
  798. */
  799. void OleApp_DisableBusyDialogs(
  800. LPOLEAPP lpOleApp,
  801. BOOL FAR* lpfPrevBusyEnable,
  802. BOOL FAR* lpfPrevNREnable
  803. )
  804. {
  805. if (lpOleApp->m_lpMsgFilter) {
  806. *lpfPrevNREnable = OleStdMsgFilter_EnableNotRespondingDialog(
  807. lpOleApp->m_lpMsgFilter, FALSE);
  808. *lpfPrevBusyEnable = OleStdMsgFilter_EnableBusyDialog(
  809. lpOleApp->m_lpMsgFilter, FALSE);
  810. }
  811. }
  812. /* OleApp_EnableBusyDialogs
  813. ** ------------------------
  814. ** Set the enable state of the Busy and NotResponding dialogs.
  815. **
  816. ** This function is typically used after a call to
  817. ** OleApp_DisableBusyDialogs in order to restore the previous enable
  818. ** state of the dialogs.
  819. */
  820. void OleApp_EnableBusyDialogs(
  821. LPOLEAPP lpOleApp,
  822. BOOL fPrevBusyEnable,
  823. BOOL fPrevNREnable
  824. )
  825. {
  826. if (lpOleApp->m_lpMsgFilter) {
  827. OleStdMsgFilter_EnableNotRespondingDialog(
  828. lpOleApp->m_lpMsgFilter, fPrevNREnable);
  829. OleStdMsgFilter_EnableBusyDialog(
  830. lpOleApp->m_lpMsgFilter, fPrevBusyEnable);
  831. }
  832. }
  833. /* OleApp_PreModalDialog
  834. ** ---------------------
  835. ** Keep track that a modal dialog is about to be brought up.
  836. **
  837. ** while a modal dialog is up we need to take special actions:
  838. ** 1. we do NOT want to initialize our tool bar buttons on
  839. ** WM_ACTIVATEAPP. the tool bar is not accessible.
  840. ** 2. we want to reject new top-level, incoming LRPC calls
  841. ** (return SERVERCALL_RETRYLATER from IMessageFilter::
  842. ** HandleInComingCall).
  843. ** 3. (IN-PLACE SERVER) tell our in-place container to disable
  844. ** modeless dialogs by calling IOleInPlaceFrame::
  845. ** EnableModeless(FALSE).
  846. ** 4. (IN-PLACE CONTAINER) tell our UIActive in-place object to
  847. ** disable modeless dialogs by calling IOleInPlaceActiveObject::
  848. ** EnableModeless(FALSE).
  849. */
  850. void OleApp_PreModalDialog(LPOLEAPP lpOleApp, LPOLEDOC lpOleDoc)
  851. {
  852. if (lpOleApp->m_cModalDlgActive == 0) {
  853. // top-level modal dialog is being brought up
  854. #if defined( USE_FRAMETOOLS )
  855. LPFRAMETOOLS lptb;
  856. if (lpOleDoc)
  857. lptb = ((LPOUTLINEDOC)lpOleDoc)->m_lpFrameTools;
  858. else
  859. lptb = OutlineApp_GetFrameTools((LPOUTLINEAPP)lpOleApp);
  860. if (lptb)
  861. FrameTools_EnableWindow(lptb, FALSE);
  862. #endif // USE_FRAMETOOLS
  863. OleApp_RejectInComingCalls(lpOleApp, TRUE);
  864. #if defined( INPLACE_SVR )
  865. {
  866. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
  867. /* if the document bringing up the modal dialog is
  868. ** currently a UIActive in-place object, then tell the
  869. ** top-level in-place frame to disable its modeless
  870. ** dialogs.
  871. */
  872. if (lpServerDoc && lpServerDoc->m_fUIActive &&
  873. lpServerDoc->m_lpIPData &&
  874. lpServerDoc->m_lpIPData->lpFrame) {
  875. OLEDBG_BEGIN2("IOleInPlaceFrame::EnableModless(FALSE) called\r\n");
  876. lpServerDoc->m_lpIPData->lpFrame->lpVtbl->EnableModeless(
  877. lpServerDoc->m_lpIPData->lpFrame, FALSE);
  878. OLEDBG_END2
  879. }
  880. }
  881. #endif // INPLACE_SVR
  882. #if defined( INPLACE_CNTR )
  883. {
  884. LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp;
  885. /* if the document bringing up the modal dialog is an
  886. ** in-place container that has a UIActive object, then
  887. ** tell the UIActive object to disable its modeless
  888. ** dialogs.
  889. */
  890. if (lpContainerApp->m_lpIPActiveObj) {
  891. OLEDBG_BEGIN2("IOleInPlaceActiveObject::EnableModless(FALSE) called\r\n");
  892. lpContainerApp->m_lpIPActiveObj->lpVtbl->EnableModeless(
  893. lpContainerApp->m_lpIPActiveObj, FALSE);
  894. OLEDBG_END2
  895. }
  896. }
  897. #endif // INPLACE_CNTR
  898. }
  899. lpOleApp->m_cModalDlgActive++;
  900. }
  901. /* OleApp_PostModalDialog
  902. ** ----------------------
  903. ** Keep track that a modal dialog is being brought down. this call
  904. ** balances the OleApp_PreModalDialog call.
  905. */
  906. void OleApp_PostModalDialog(LPOLEAPP lpOleApp, LPOLEDOC lpOleDoc)
  907. {
  908. lpOleApp->m_cModalDlgActive--;
  909. if (lpOleApp->m_cModalDlgActive == 0) {
  910. // last modal dialog is being brought down
  911. #if defined( USE_FRAMETOOLS )
  912. LPFRAMETOOLS lptb;
  913. if (lpOleDoc)
  914. lptb = ((LPOUTLINEDOC)lpOleDoc)->m_lpFrameTools;
  915. else
  916. lptb = OutlineApp_GetFrameTools((LPOUTLINEAPP)lpOleApp);
  917. if (lptb) {
  918. FrameTools_EnableWindow(lptb, TRUE);
  919. FrameTools_UpdateButtons(lptb, (LPOUTLINEDOC)lpOleDoc);
  920. }
  921. #endif // USE_FRAMETOOLS
  922. OleApp_RejectInComingCalls(lpOleApp, FALSE);
  923. #if defined( INPLACE_SVR )
  924. {
  925. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
  926. /* if the document bringing down the modal dialog is
  927. ** currently a UIActive in-place object, then tell the
  928. ** top-level in-place frame it can re-enable its
  929. ** modeless dialogs.
  930. */
  931. if (lpServerDoc && lpServerDoc->m_fUIActive &&
  932. lpServerDoc->m_lpIPData &&
  933. lpServerDoc->m_lpIPData->lpFrame) {
  934. OLEDBG_BEGIN2("IOleInPlaceFrame::EnableModless(TRUE) called\r\n");
  935. lpServerDoc->m_lpIPData->lpFrame->lpVtbl->EnableModeless(
  936. lpServerDoc->m_lpIPData->lpFrame, TRUE);
  937. OLEDBG_END2
  938. }
  939. }
  940. #endif // INPLACE_SVR
  941. #if defined( INPLACE_CNTR )
  942. {
  943. LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp;
  944. /* if the document bringing down the modal dialog is an
  945. ** in-place container that has a UIActive object, then
  946. ** tell the UIActive object it can re-enable its
  947. ** modeless dialogs.
  948. */
  949. if (lpContainerApp->m_lpIPActiveObj) {
  950. OLEDBG_BEGIN2("IOleInPlaceActiveObject::EnableModless(TRUE) called\r\n");
  951. lpContainerApp->m_lpIPActiveObj->lpVtbl->EnableModeless(
  952. lpContainerApp->m_lpIPActiveObj, TRUE);
  953. OLEDBG_END2
  954. }
  955. }
  956. #endif // INPLACE_CNTR
  957. }
  958. }
  959. /* OleApp_InitVtbls
  960. * ----------------
  961. *
  962. * initialize the methods in all of the interface Vtbl's
  963. *
  964. * OLE2NOTE: we only need one copy of each Vtbl. When an object which
  965. * exposes an interface is instantiated, its lpVtbl is intialized
  966. * to point to the single copy of the Vtbl.
  967. *
  968. */
  969. BOOL OleApp_InitVtbls (LPOLEAPP lpOleApp)
  970. {
  971. BOOL fStatus;
  972. // OleApp::IUnknown method table
  973. OleStdInitVtbl(&g_OleApp_UnknownVtbl, sizeof(IUnknownVtbl));
  974. g_OleApp_UnknownVtbl.QueryInterface = OleApp_Unk_QueryInterface;
  975. g_OleApp_UnknownVtbl.AddRef = OleApp_Unk_AddRef;
  976. g_OleApp_UnknownVtbl.Release = OleApp_Unk_Release;
  977. fStatus = OleStdCheckVtbl(
  978. &g_OleApp_UnknownVtbl,
  979. sizeof(IUnknownVtbl),
  980. "IUnknown"
  981. );
  982. if (! fStatus) return FALSE;
  983. // OleDoc::IUnknown method table
  984. OleStdInitVtbl(&g_OleDoc_UnknownVtbl, sizeof(IUnknownVtbl));
  985. g_OleDoc_UnknownVtbl.QueryInterface = OleDoc_Unk_QueryInterface;
  986. g_OleDoc_UnknownVtbl.AddRef = OleDoc_Unk_AddRef;
  987. g_OleDoc_UnknownVtbl.Release = OleDoc_Unk_Release;
  988. fStatus = OleStdCheckVtbl(
  989. &g_OleDoc_UnknownVtbl,
  990. sizeof(IUnknownVtbl),
  991. "IUnknown"
  992. );
  993. if (! fStatus) return FALSE;
  994. // OleDoc::IPersistFile method table
  995. OleStdInitVtbl(&g_OleDoc_PersistFileVtbl, sizeof(IPersistFileVtbl));
  996. g_OleDoc_PersistFileVtbl.QueryInterface = OleDoc_PFile_QueryInterface;
  997. g_OleDoc_PersistFileVtbl.AddRef = OleDoc_PFile_AddRef;
  998. g_OleDoc_PersistFileVtbl.Release = OleDoc_PFile_Release;
  999. g_OleDoc_PersistFileVtbl.GetClassID = OleDoc_PFile_GetClassID;
  1000. g_OleDoc_PersistFileVtbl.IsDirty = OleDoc_PFile_IsDirty;
  1001. g_OleDoc_PersistFileVtbl.Load = OleDoc_PFile_Load;
  1002. g_OleDoc_PersistFileVtbl.Save = OleDoc_PFile_Save;
  1003. g_OleDoc_PersistFileVtbl.SaveCompleted = OleDoc_PFile_SaveCompleted;
  1004. g_OleDoc_PersistFileVtbl.GetCurFile = OleDoc_PFile_GetCurFile;
  1005. fStatus = OleStdCheckVtbl(
  1006. &g_OleDoc_PersistFileVtbl,
  1007. sizeof(IPersistFileVtbl),
  1008. "IPersistFile"
  1009. );
  1010. if (! fStatus) return FALSE;
  1011. // OleDoc::IOleItemContainer method table
  1012. OleStdInitVtbl(&g_OleDoc_OleItemContainerVtbl, sizeof(IOleItemContainerVtbl));
  1013. g_OleDoc_OleItemContainerVtbl.QueryInterface =
  1014. OleDoc_ItemCont_QueryInterface;
  1015. g_OleDoc_OleItemContainerVtbl.AddRef = OleDoc_ItemCont_AddRef;
  1016. g_OleDoc_OleItemContainerVtbl.Release = OleDoc_ItemCont_Release;
  1017. g_OleDoc_OleItemContainerVtbl.ParseDisplayName =
  1018. OleDoc_ItemCont_ParseDisplayName;
  1019. g_OleDoc_OleItemContainerVtbl.EnumObjects= OleDoc_ItemCont_EnumObjects;
  1020. g_OleDoc_OleItemContainerVtbl.LockContainer =
  1021. OleDoc_ItemCont_LockContainer;
  1022. g_OleDoc_OleItemContainerVtbl.GetObject = OleDoc_ItemCont_GetObject;
  1023. g_OleDoc_OleItemContainerVtbl.GetObjectStorage =
  1024. OleDoc_ItemCont_GetObjectStorage;
  1025. g_OleDoc_OleItemContainerVtbl.IsRunning = OleDoc_ItemCont_IsRunning;
  1026. fStatus = OleStdCheckVtbl(
  1027. &g_OleDoc_OleItemContainerVtbl,
  1028. sizeof(IOleItemContainerVtbl),
  1029. "IOleItemContainer"
  1030. );
  1031. if (! fStatus) return FALSE;
  1032. // OleDoc::IExternalConnection method table
  1033. OleStdInitVtbl(
  1034. &g_OleDoc_ExternalConnectionVtbl,sizeof(IExternalConnectionVtbl));
  1035. g_OleDoc_ExternalConnectionVtbl.QueryInterface =
  1036. OleDoc_ExtConn_QueryInterface;
  1037. g_OleDoc_ExternalConnectionVtbl.AddRef = OleDoc_ExtConn_AddRef;
  1038. g_OleDoc_ExternalConnectionVtbl.Release = OleDoc_ExtConn_Release;
  1039. g_OleDoc_ExternalConnectionVtbl.AddConnection =
  1040. OleDoc_ExtConn_AddConnection;
  1041. g_OleDoc_ExternalConnectionVtbl.ReleaseConnection =
  1042. OleDoc_ExtConn_ReleaseConnection;
  1043. fStatus = OleStdCheckVtbl(
  1044. &g_OleDoc_ExternalConnectionVtbl,
  1045. sizeof(IExternalConnectionVtbl),
  1046. "IExternalConnection"
  1047. );
  1048. if (! fStatus) return FALSE;
  1049. // OleDoc::IDataObject method table
  1050. OleStdInitVtbl(&g_OleDoc_DataObjectVtbl, sizeof(IDataObjectVtbl));
  1051. g_OleDoc_DataObjectVtbl.QueryInterface = OleDoc_DataObj_QueryInterface;
  1052. g_OleDoc_DataObjectVtbl.AddRef = OleDoc_DataObj_AddRef;
  1053. g_OleDoc_DataObjectVtbl.Release = OleDoc_DataObj_Release;
  1054. g_OleDoc_DataObjectVtbl.GetData = OleDoc_DataObj_GetData;
  1055. g_OleDoc_DataObjectVtbl.GetDataHere = OleDoc_DataObj_GetDataHere;
  1056. g_OleDoc_DataObjectVtbl.QueryGetData = OleDoc_DataObj_QueryGetData;
  1057. g_OleDoc_DataObjectVtbl.GetCanonicalFormatEtc =
  1058. OleDoc_DataObj_GetCanonicalFormatEtc;
  1059. g_OleDoc_DataObjectVtbl.SetData = OleDoc_DataObj_SetData;
  1060. g_OleDoc_DataObjectVtbl.EnumFormatEtc = OleDoc_DataObj_EnumFormatEtc;
  1061. g_OleDoc_DataObjectVtbl.DAdvise = OleDoc_DataObj_DAdvise;
  1062. g_OleDoc_DataObjectVtbl.DUnadvise = OleDoc_DataObj_DUnadvise;
  1063. g_OleDoc_DataObjectVtbl.EnumDAdvise = OleDoc_DataObj_EnumDAdvise;
  1064. fStatus = OleStdCheckVtbl(
  1065. &g_OleDoc_DataObjectVtbl,
  1066. sizeof(IDataObjectVtbl),
  1067. "IDataObject"
  1068. );
  1069. if (! fStatus) return FALSE;
  1070. #if defined( USE_DRAGDROP )
  1071. // OleDoc::IDropTarget method table
  1072. OleStdInitVtbl(&g_OleDoc_DropTargetVtbl, sizeof(IDropTargetVtbl));
  1073. g_OleDoc_DropTargetVtbl.QueryInterface= OleDoc_DropTarget_QueryInterface;
  1074. g_OleDoc_DropTargetVtbl.AddRef = OleDoc_DropTarget_AddRef;
  1075. g_OleDoc_DropTargetVtbl.Release = OleDoc_DropTarget_Release;
  1076. g_OleDoc_DropTargetVtbl.DragEnter = OleDoc_DropTarget_DragEnter;
  1077. g_OleDoc_DropTargetVtbl.DragOver = OleDoc_DropTarget_DragOver;
  1078. g_OleDoc_DropTargetVtbl.DragLeave = OleDoc_DropTarget_DragLeave;
  1079. g_OleDoc_DropTargetVtbl.Drop = OleDoc_DropTarget_Drop;
  1080. fStatus = OleStdCheckVtbl(
  1081. &g_OleDoc_DropTargetVtbl,
  1082. sizeof(IDropTargetVtbl),
  1083. "IDropTarget"
  1084. );
  1085. if (! fStatus)
  1086. return FALSE;
  1087. // OleDoc::IDropSource method table
  1088. OleStdInitVtbl(&g_OleDoc_DropSourceVtbl, sizeof(IDropSourceVtbl));
  1089. g_OleDoc_DropSourceVtbl.QueryInterface =
  1090. OleDoc_DropSource_QueryInterface;
  1091. g_OleDoc_DropSourceVtbl.AddRef = OleDoc_DropSource_AddRef;
  1092. g_OleDoc_DropSourceVtbl.Release = OleDoc_DropSource_Release;
  1093. g_OleDoc_DropSourceVtbl.QueryContinueDrag =
  1094. OleDoc_DropSource_QueryContinueDrag;
  1095. g_OleDoc_DropSourceVtbl.GiveFeedback = OleDoc_DropSource_GiveFeedback;
  1096. fStatus = OleStdCheckVtbl(
  1097. &g_OleDoc_DropSourceVtbl,
  1098. sizeof(IDropSourceVtbl),
  1099. "IDropSource"
  1100. );
  1101. if (! fStatus) return FALSE;
  1102. #endif // USE_DRAGDROP
  1103. #if defined( OLE_SERVER )
  1104. // Initialize the server specific interface method tables.
  1105. if (! ServerApp_InitVtbls((LPSERVERAPP)lpOleApp))
  1106. return FALSE;
  1107. #endif
  1108. #if defined( OLE_CNTR )
  1109. // Initialize the container specific interface method tables.
  1110. if (! ContainerApp_InitVtbls((LPCONTAINERAPP)lpOleApp))
  1111. return FALSE;
  1112. #endif
  1113. return TRUE;
  1114. };
  1115. /* OleApp_InitMenu
  1116. * ---------------
  1117. *
  1118. * Enable or Disable menu items depending on the state of
  1119. * the appliation.
  1120. * The OLE versions of the Outline sample app add a PasteSpecial command.
  1121. * Also, the container version add InsertObject and ObjectVerb menu items.
  1122. */
  1123. void OleApp_InitMenu(
  1124. LPOLEAPP lpOleApp,
  1125. LPOLEDOC lpOleDoc,
  1126. HMENU hMenu
  1127. )
  1128. {
  1129. BOOL bMsgFilterInstalled = FALSE;
  1130. BOOL bRejecting = FALSE;
  1131. if (!lpOleApp || !hMenu)
  1132. return;
  1133. OLEDBG_BEGIN3("OleApp_InitMenu\r\n")
  1134. /*
  1135. ** Enable/disable menu items for Message Filter
  1136. */
  1137. bMsgFilterInstalled = (lpOleApp->m_lpMsgFilter != NULL);
  1138. bRejecting = bMsgFilterInstalled &&
  1139. OleStdMsgFilter_GetInComingCallStatus(lpOleApp->m_lpMsgFilter) != SERVERCALL_ISHANDLED;
  1140. CheckMenuItem(hMenu,
  1141. IDM_D_INSTALLMSGFILTER,
  1142. bMsgFilterInstalled ? MF_CHECKED : MF_UNCHECKED);
  1143. EnableMenuItem(hMenu,
  1144. IDM_D_REJECTINCOMING,
  1145. bMsgFilterInstalled ? MF_ENABLED : MF_GRAYED);
  1146. CheckMenuItem(hMenu,
  1147. IDM_D_REJECTINCOMING,
  1148. bRejecting ? MF_CHECKED : MF_UNCHECKED);
  1149. #if defined( OLE_CNTR )
  1150. {
  1151. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOleDoc;
  1152. BOOL fShowObject;
  1153. fShowObject = ContainerDoc_GetShowObjectFlag(lpContainerDoc);
  1154. CheckMenuItem(
  1155. hMenu,
  1156. IDM_O_SHOWOBJECT,
  1157. (fShowObject ? MF_CHECKED : MF_UNCHECKED)
  1158. );
  1159. #if defined( INPLACE_CNTR ) && defined( _DEBUG )
  1160. CheckMenuItem(
  1161. hMenu,
  1162. IDM_D_INSIDEOUT,
  1163. g_fInsideOutContainer ? MF_CHECKED:MF_UNCHECKED);
  1164. #endif // INPLACE_CNTR && _DEBUG
  1165. }
  1166. #endif // OLE_CNTR
  1167. OLEDBG_END3
  1168. }
  1169. /* OleApp_UpdateEditMenu
  1170. * ---------------------
  1171. *
  1172. * Purpose:
  1173. * Update the Edit menuitems of the App according to the state of
  1174. * OutlineDoc
  1175. *
  1176. * Parameter:
  1177. * lpOutlineDoc pointer to the document
  1178. * hMenuEdit edit menu handle
  1179. */
  1180. void OleApp_UpdateEditMenu(
  1181. LPOLEAPP lpOleApp,
  1182. LPOUTLINEDOC lpOutlineDoc,
  1183. HMENU hMenuEdit
  1184. )
  1185. {
  1186. int nFmtEtc;
  1187. UINT uEnablePaste = MF_GRAYED;
  1188. UINT uEnablePasteLink = MF_GRAYED;
  1189. LPDATAOBJECT lpClipboardDataObj;
  1190. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  1191. HRESULT hrErr;
  1192. BOOL fPrevEnable1;
  1193. BOOL fPrevEnable2;
  1194. if (!lpOleApp || !lpOutlineDoc || !hMenuEdit)
  1195. return;
  1196. if (!OleDoc_GetUpdateEditMenuFlag(lpOleDoc))
  1197. /* OLE2NOTE: if the flag is not set, we don't have to update
  1198. ** the edit menu again. This blocks repetitive updating when
  1199. ** the user move the mouse across Edit menu while holding
  1200. ** down the button
  1201. */
  1202. return;
  1203. OLEDBG_BEGIN3("OleApp_InitEditMenu\r\n")
  1204. /* OLE2NOTE: we do not want to ever give the busy dialog when we
  1205. ** are trying to put up our menus. eg. even if the source of
  1206. ** data on the clipboard is busy, we do not want put up the busy
  1207. ** dialog. thus we will disable the dialog and at the end
  1208. ** re-enable it.
  1209. */
  1210. OleApp_DisableBusyDialogs(lpOleApp, &fPrevEnable1, &fPrevEnable2);
  1211. // check if there is data on the clipboard that we can paste/paste link
  1212. OLEDBG_BEGIN2("OleGetClipboard called\r\n")
  1213. hrErr = OleGetClipboard((LPDATAOBJECT FAR*)&lpClipboardDataObj);
  1214. OLEDBG_END2
  1215. if (hrErr == NOERROR) {
  1216. nFmtEtc = OleStdGetPriorityClipboardFormat(
  1217. lpClipboardDataObj,
  1218. lpOleApp->m_arrPasteEntries,
  1219. lpOleApp->m_nPasteEntries
  1220. );
  1221. if (nFmtEtc >= 0)
  1222. uEnablePaste = MF_ENABLED; // there IS a format we like
  1223. OLEDBG_BEGIN2("OleQueryLinkFromData called\r\n")
  1224. hrErr = OleQueryLinkFromData(lpClipboardDataObj);
  1225. OLEDBG_END2
  1226. if(hrErr == NOERROR)
  1227. uEnablePasteLink = MF_ENABLED;
  1228. OleStdRelease((LPUNKNOWN)lpClipboardDataObj);
  1229. }
  1230. EnableMenuItem(hMenuEdit, IDM_E_PASTE, uEnablePaste);
  1231. EnableMenuItem(hMenuEdit, IDM_E_PASTESPECIAL, uEnablePaste);
  1232. #if defined( OLE_CNTR )
  1233. if (ContainerDoc_GetNextLink((LPCONTAINERDOC)lpOutlineDoc, NULL))
  1234. EnableMenuItem(hMenuEdit, IDM_E_EDITLINKS, MF_ENABLED);
  1235. else
  1236. EnableMenuItem(hMenuEdit, IDM_E_EDITLINKS, MF_GRAYED);
  1237. {
  1238. LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp;
  1239. HMENU hMenuVerb = NULL;
  1240. LPOLEOBJECT lpOleObj = NULL;
  1241. LPCONTAINERLINE lpContainerLine = NULL;
  1242. BOOL fSelIsOleObject;
  1243. EnableMenuItem(hMenuEdit, IDM_E_PASTELINK, uEnablePasteLink);
  1244. /* check if selection is a single line that contains an OleObject */
  1245. fSelIsOleObject = ContainerDoc_IsSelAnOleObject(
  1246. (LPCONTAINERDOC)lpOutlineDoc,
  1247. &IID_IOleObject,
  1248. (LPUNKNOWN FAR*)&lpOleObj,
  1249. NULL, /* we don't need the line index */
  1250. (LPCONTAINERLINE FAR*)&lpContainerLine
  1251. );
  1252. if (hMenuEdit != NULL) {
  1253. /* If the current line is an ContainerLine, add the object
  1254. ** verb sub menu to the Edit menu. if the line is not an
  1255. ** ContainerLine, (lpOleObj==NULL) then disable the
  1256. ** Edit.Object command. this helper API takes care of
  1257. ** building the verb menu as appropriate.
  1258. */
  1259. OleUIAddVerbMenu(
  1260. (LPOLEOBJECT)lpOleObj,
  1261. (lpContainerLine ? lpContainerLine->m_lpszShortType:NULL),
  1262. hMenuEdit,
  1263. POS_OBJECT,
  1264. IDM_E_OBJECTVERBMIN,
  1265. 0, // no uIDVerbMax enforced
  1266. TRUE, // Add Convert menu item
  1267. IDM_E_CONVERTVERB, // ID for Convert menu item
  1268. (HMENU FAR*) &hMenuVerb
  1269. );
  1270. #if defined( USE_STATUSBAR_LATER )
  1271. /* setup status messages for the object verb menu */
  1272. if (hMenuVerb) {
  1273. // REVIEW: this string should come from a string resource.
  1274. // REVIEW: this doesn't work for dynamically created menus
  1275. AssignPopupMessage(
  1276. hMenuVerb,
  1277. "Open, edit or interact with an object"
  1278. );
  1279. }
  1280. #endif // USE_STATUSBAR_LATER
  1281. }
  1282. if (lpOleObj)
  1283. OleStdRelease((LPUNKNOWN)lpOleObj);
  1284. }
  1285. #endif // OLE_CNTR
  1286. // re-enable the Busy/NotResponding dialogs
  1287. OleApp_EnableBusyDialogs(lpOleApp, fPrevEnable1, fPrevEnable2);
  1288. OleDoc_SetUpdateEditMenuFlag(lpOleDoc, FALSE);
  1289. OLEDBG_END3
  1290. }
  1291. /* OleApp_RegisterClassFactory
  1292. * ---------------------------
  1293. *
  1294. * Register our app's ClassFactory with OLE.
  1295. *
  1296. */
  1297. BOOL OleApp_RegisterClassFactory(LPOLEAPP lpOleApp)
  1298. {
  1299. HRESULT hrErr;
  1300. if (lpOleApp->m_lpClassFactory)
  1301. return TRUE; // already registered
  1302. OLEDBG_BEGIN3("OleApp_RegisterClassFactory\r\n")
  1303. /******************************************************************
  1304. ** An SDI app must register its ClassFactory if it is launched
  1305. ** for embedding (/Embedding command line option specified).
  1306. ** An MDI app must register its ClassFactory in all cases,
  1307. ******************************************************************/
  1308. lpOleApp->m_lpClassFactory = AppClassFactory_Create();
  1309. if (! lpOleApp->m_lpClassFactory) {
  1310. OutlineApp_ErrorMessage(g_lpApp, ErrMsgCreateCF);
  1311. goto error;
  1312. }
  1313. OLEDBG_BEGIN2("CoRegisterClassObject called\r\n")
  1314. hrErr = CoRegisterClassObject(
  1315. &CLSID_APP,
  1316. (LPUNKNOWN)lpOleApp->m_lpClassFactory,
  1317. CLSCTX_LOCAL_SERVER,
  1318. REGCLS_SINGLEUSE,
  1319. &lpOleApp->m_dwRegClassFac
  1320. );
  1321. OLEDBG_END2
  1322. if(hrErr != NOERROR) {
  1323. OleDbgOutHResult("CoRegisterClassObject returned", hrErr);
  1324. OutlineApp_ErrorMessage(g_lpApp, ErrMsgRegCF);
  1325. goto error;
  1326. }
  1327. OLEDBG_END3
  1328. return TRUE;
  1329. error:
  1330. if (lpOleApp->m_lpClassFactory) {
  1331. OleStdRelease((LPUNKNOWN)lpOleApp->m_lpClassFactory);
  1332. lpOleApp->m_lpClassFactory = NULL;
  1333. }
  1334. OLEDBG_END3
  1335. return FALSE;
  1336. }
  1337. /* OleApp_RevokeClassFactory
  1338. * -------------------------
  1339. *
  1340. * Revoke our app's ClassFactory.
  1341. *
  1342. */
  1343. void OleApp_RevokeClassFactory(LPOLEAPP lpOleApp)
  1344. {
  1345. HRESULT hrErr;
  1346. if (lpOleApp->m_lpClassFactory) {
  1347. OLEDBG_BEGIN2("CoRevokeClassObject called\r\n")
  1348. hrErr = CoRevokeClassObject(lpOleApp->m_dwRegClassFac);
  1349. OLEDBG_END2
  1350. #if defined( _DEBUG )
  1351. if (hrErr != NOERROR) {
  1352. OleDbgOutHResult("CoRevokeClassObject returned", hrErr);
  1353. }
  1354. #endif
  1355. // we just release here; other folks may still have
  1356. // a pointer to our class factory, so we can't
  1357. // do any checks on the reference count.
  1358. OleStdRelease((LPUNKNOWN)lpOleApp->m_lpClassFactory);
  1359. lpOleApp->m_lpClassFactory = NULL;
  1360. }
  1361. }
  1362. #if defined( USE_MSGFILTER )
  1363. /* OleApp_RegisterMessageFilter
  1364. * ----------------------------
  1365. * Register our IMessageFilter*. the message filter is used to handle
  1366. * concurrency. we will use a standard implementation of IMessageFilter
  1367. * that is included as part of the OLE2UI library.
  1368. */
  1369. BOOL OleApp_RegisterMessageFilter(LPOLEAPP lpOleApp)
  1370. {
  1371. HRESULT hrErr;
  1372. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  1373. if (lpOleApp->m_lpMsgFilter == NULL) {
  1374. // Register our message filter.
  1375. lpOleApp->m_lpfnMsgPending = (MSGPENDINGPROC)MessagePendingProc;
  1376. lpOleApp->m_lpMsgFilter = OleStdMsgFilter_Create(
  1377. g_lpApp->m_hWndApp,
  1378. (LPSTR)APPNAME,
  1379. lpOleApp->m_lpfnMsgPending,
  1380. NULL /* Busy dialog callback hook function */
  1381. );
  1382. OLEDBG_BEGIN2("CoRegisterMessageFilter called\r\n")
  1383. hrErr = CoRegisterMessageFilter(
  1384. lpOleApp->m_lpMsgFilter,
  1385. NULL /* don't need previous message filter */
  1386. );
  1387. OLEDBG_END2
  1388. if(hrErr != NOERROR) {
  1389. OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgRegMF);
  1390. return FALSE;
  1391. }
  1392. }
  1393. return TRUE;
  1394. }
  1395. /* OleApp_RevokeMessageFilter
  1396. * --------------------------
  1397. * Revoke our IMessageFilter*. the message filter is used to handle
  1398. * concurrency. we will use a standard implementation of IMessageFilter
  1399. * that is included as part of the OLE2UI library.
  1400. */
  1401. void OleApp_RevokeMessageFilter(LPOLEAPP lpOleApp)
  1402. {
  1403. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1404. if (lpOleApp->m_lpMsgFilter != NULL) {
  1405. // Revoke our message filter
  1406. OLEDBG_BEGIN2("CoRegisterMessageFilter(NULL) called\r\n")
  1407. CoRegisterMessageFilter(NULL, NULL);
  1408. OLEDBG_END2
  1409. if (lpOleApp->m_lpfnMsgPending) {
  1410. lpOleApp->m_lpfnMsgPending = NULL;
  1411. }
  1412. OleStdVerifyRelease(
  1413. (LPUNKNOWN)lpOleApp->m_lpMsgFilter,
  1414. "Release MessageFilter FAILED!"
  1415. );
  1416. lpOleApp->m_lpMsgFilter = NULL;
  1417. }
  1418. }
  1419. /* MessagePendingProc
  1420. * ------------------
  1421. *
  1422. * Callback function for the IMessageFilter::MessagePending procedure. This
  1423. * function is called when a message is received by our application while
  1424. * we are waiting for an OLE call to complete. We are essentially
  1425. * blocked at this point, waiting for a response from the other OLE application.
  1426. * We should not process any messages which might cause another OLE call
  1427. * to become blocked, or any other call which might cause re-entrancy problems.
  1428. *
  1429. * For this application, only process WM_PAINT messages. A more sophisticated
  1430. * application might allow certain menu messages and menu items to be processed
  1431. * also.
  1432. *
  1433. * RETURNS: TRUE if we processed the message, FALSE if we did not.
  1434. */
  1435. BOOL FAR PASCAL EXPORT MessagePendingProc(MSG FAR *lpMsg)
  1436. {
  1437. // Our application is only handling WM_PAINT messages when we are blocked
  1438. switch (lpMsg->message) {
  1439. case WM_PAINT:
  1440. OleDbgOut2("WM_PAINT dispatched while blocked\r\n");
  1441. DispatchMessage(lpMsg);
  1442. break;
  1443. }
  1444. return FALSE; // return PENDINGMSG_WAITDEFPROCESS from MessagePending
  1445. }
  1446. #endif // USE_MSGFILTER
  1447. /* OleApp_FlushClipboard
  1448. * ---------------------
  1449. *
  1450. * Force the Windows clipboard to release our clipboard DataObject.
  1451. */
  1452. void OleApp_FlushClipboard(LPOLEAPP lpOleApp)
  1453. {
  1454. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  1455. LPOLEDOC lpClipboardDoc = (LPOLEDOC)lpOutlineApp->m_lpClipboardDoc;
  1456. OLEDBG_BEGIN3("OleApp_FlushClipboard\r\n")
  1457. /* OLE2NOTE: if for some reason our clipboard data transfer
  1458. ** document is still held on to by an external client, we want
  1459. ** to forceably break all external connections.
  1460. */
  1461. OLEDBG_BEGIN2("CoDisconnectObject called\r\n")
  1462. CoDisconnectObject((LPUNKNOWN)&lpClipboardDoc->m_Unknown, 0);
  1463. OLEDBG_END2
  1464. OLEDBG_BEGIN2("OleFlushClipboard called\r\n")
  1465. OleFlushClipboard();
  1466. OLEDBG_END2
  1467. lpOutlineApp->m_lpClipboardDoc = NULL;
  1468. OLEDBG_END3
  1469. }
  1470. /* OleApp_NewCommand
  1471. * -----------------
  1472. *
  1473. * Start a new untitled document (File.New command).
  1474. */
  1475. void OleApp_NewCommand(LPOLEAPP lpOleApp)
  1476. {
  1477. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  1478. LPOUTLINEDOC lpOutlineDoc = lpOutlineApp->m_lpDoc;
  1479. if (! OutlineDoc_Close(lpOutlineDoc, OLECLOSE_PROMPTSAVE))
  1480. return;
  1481. OleDbgAssertSz(lpOutlineApp->m_lpDoc==NULL,"Closed doc NOT properly destroyed");
  1482. lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
  1483. if (! lpOutlineApp->m_lpDoc) goto error;
  1484. /* OLE2NOTE: initially the Doc object is created with a 0 ref
  1485. ** count. in order to have a stable Doc object during the
  1486. ** process of initializing the new Doc instance,
  1487. ** we intially AddRef the Doc ref cnt and later
  1488. ** Release it. This initial AddRef is artificial; it is simply
  1489. ** done to guarantee that a harmless QueryInterface followed by
  1490. ** a Release does not inadvertantly force our object to destroy
  1491. ** itself prematurely.
  1492. */
  1493. OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
  1494. // set the doc to an (Untitled) doc.
  1495. if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc))
  1496. goto error;
  1497. // position and size the new doc window
  1498. OutlineApp_ResizeWindows(lpOutlineApp);
  1499. OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc); // calls OleDoc_Lock
  1500. OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel artificial AddRef
  1501. return;
  1502. error:
  1503. // REVIEW: should load string from string resource
  1504. OutlineApp_ErrorMessage(lpOutlineApp, "Could not create new document");
  1505. if (lpOutlineApp->m_lpDoc) {
  1506. // releasing the artificial AddRef above will destroy the document
  1507. OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);
  1508. lpOutlineApp->m_lpDoc = NULL;
  1509. }
  1510. return;
  1511. }
  1512. /* OleApp_OpenCommand
  1513. * ------------------
  1514. *
  1515. * Load a document from file (File.Open command).
  1516. */
  1517. void OleApp_OpenCommand(LPOLEAPP lpOleApp)
  1518. {
  1519. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
  1520. LPOUTLINEDOC lpOutlineDoc = lpOutlineApp->m_lpDoc;
  1521. OPENFILENAME ofn;
  1522. char szFilter[]=APPFILENAMEFILTER;
  1523. char szFileName[256];
  1524. UINT i;
  1525. DWORD dwSaveOption = OLECLOSE_PROMPTSAVE;
  1526. BOOL fStatus = TRUE;
  1527. if (! OutlineDoc_CheckSaveChanges(lpOutlineDoc, &dwSaveOption))
  1528. return; // abort opening new doc
  1529. for(i=0; szFilter[i]; i++)
  1530. if(szFilter[i]=='|') szFilter[i]='\0';
  1531. _fmemset((LPOPENFILENAME)&ofn,0,sizeof(OPENFILENAME));
  1532. szFileName[0]='\0';
  1533. ofn.lStructSize=sizeof(OPENFILENAME);
  1534. ofn.hwndOwner=lpOutlineApp->m_hWndApp;
  1535. ofn.lpstrFilter=(LPSTR)szFilter;
  1536. ofn.lpstrFile=(LPSTR)szFileName;
  1537. ofn.nMaxFile=sizeof(szFileName);
  1538. ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  1539. ofn.lpstrDefExt=DEFEXTENSION;
  1540. OleApp_PreModalDialog(lpOleApp, (LPOLEDOC)lpOutlineApp->m_lpDoc);
  1541. fStatus = GetOpenFileName((LPOPENFILENAME)&ofn);
  1542. OleApp_PostModalDialog(lpOleApp, (LPOLEDOC)lpOutlineApp->m_lpDoc);
  1543. if(! fStatus)
  1544. return; // user canceled file open dialog
  1545. OutlineDoc_Close(lpOutlineDoc, OLECLOSE_NOSAVE);
  1546. OleDbgAssertSz(lpOutlineApp->m_lpDoc==NULL,"Closed doc NOT properly destroyed");
  1547. lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
  1548. if (! lpOutlineApp->m_lpDoc) goto error;
  1549. /* OLE2NOTE: initially the Doc object is created with a 0 ref
  1550. ** count. in order to have a stable Doc object during the
  1551. ** process of initializing the new Doc instance,
  1552. ** we intially AddRef the Doc ref cnt and later
  1553. ** Release it. This initial AddRef is artificial; it is simply
  1554. ** done to guarantee that a harmless QueryInterface followed by
  1555. ** a Release does not inadvertantly force our object to destroy
  1556. ** itself prematurely.
  1557. */
  1558. OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
  1559. fStatus=OutlineDoc_LoadFromFile(lpOutlineApp->m_lpDoc, (LPSTR)szFileName);
  1560. if (! fStatus) {
  1561. // loading the doc failed; create an untitled instead
  1562. // releasing the artificial AddRef above will destroy the document
  1563. OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);
  1564. lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
  1565. if (! lpOutlineApp->m_lpDoc) goto error;
  1566. OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
  1567. if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc))
  1568. goto error;
  1569. }
  1570. // position and size the new doc window
  1571. OutlineApp_ResizeWindows(lpOutlineApp);
  1572. OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc);
  1573. #if defined( OLE_CNTR )
  1574. UpdateWindow(lpOutlineApp->m_hWndApp);
  1575. ContainerDoc_UpdateLinks((LPCONTAINERDOC)lpOutlineApp->m_lpDoc);
  1576. #endif
  1577. OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel artificial AddRef
  1578. return;
  1579. error:
  1580. // REVIEW: should load string from string resource
  1581. OutlineApp_ErrorMessage(lpOutlineApp, "Could not create new document");
  1582. if (lpOutlineApp->m_lpDoc) {
  1583. // releasing the artificial AddRef above will destroy the document
  1584. OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);
  1585. lpOutlineApp->m_lpDoc = NULL;
  1586. }
  1587. return;
  1588. }
  1589. #if defined( OLE_CNTR )
  1590. /* OLE2NOTE: forward the WM_QUERYNEWPALETTE message (via
  1591. ** SendMessage) to UIActive in-place object if there is one.
  1592. ** this gives the UIActive object the opportunity to select
  1593. ** and realize its color palette as the FOREGROUND palette.
  1594. ** this is optional for in-place containers. if a container
  1595. ** prefers to force its color palette as the foreground
  1596. ** palette then it should NOT forward the this message. or
  1597. ** the container can give the UIActive object priority; if
  1598. ** the UIActive object returns 0 from the WM_QUERYNEWPALETTE
  1599. ** message (ie. it did not realize its own palette), then
  1600. ** the container can realize its palette.
  1601. ** (see ContainerDoc_ForwardPaletteChangedMsg for more info)
  1602. **
  1603. ** (It is a good idea for containers to use the standard
  1604. ** palette even if they do not use colors themselves. this
  1605. ** will allow embedded object to get a good distribution of
  1606. ** colors when they are being drawn by the container)
  1607. **
  1608. */
  1609. LRESULT OleApp_QueryNewPalette(LPOLEAPP lpOleApp)
  1610. {
  1611. #if defined( INPLACE_CNTR )
  1612. LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp;
  1613. if (lpContainerApp && lpContainerApp->m_hWndUIActiveObj) {
  1614. if (SendMessage(lpContainerApp->m_hWndUIActiveObj, WM_QUERYNEWPALETTE,
  1615. (WPARAM)0, (LPARAM)0)) {
  1616. /* Object selected its palette as foreground palette */
  1617. return (LRESULT)1;
  1618. }
  1619. }
  1620. #endif // INPLACE_CNTR
  1621. return wSelectPalette(((LPOUTLINEAPP)lpOleApp)->m_hWndApp,
  1622. lpOleApp->m_hStdPal, FALSE/*fBackground*/);
  1623. }
  1624. #endif // OLE_CNTR
  1625. /* This is just a helper routine */
  1626. LRESULT wSelectPalette(HWND hWnd, HPALETTE hPal, BOOL fBackground)
  1627. {
  1628. HDC hdc;
  1629. HPALETTE hOldPal;
  1630. UINT iPalChg = 0;
  1631. if (hPal == 0)
  1632. return (LRESULT)0;
  1633. hdc = GetDC(hWnd);
  1634. hOldPal = SelectPalette(hdc, hPal, fBackground);
  1635. iPalChg = RealizePalette(hdc);
  1636. SelectPalette(hdc, hOldPal, TRUE /*fBackground*/);
  1637. ReleaseDC(hWnd, hdc);
  1638. if (iPalChg > 0)
  1639. InvalidateRect(hWnd, NULL, TRUE);
  1640. return (LRESULT)1;
  1641. }
  1642. /*************************************************************************
  1643. ** OleApp::IUnknown interface implementation
  1644. *************************************************************************/
  1645. STDMETHODIMP OleApp_Unk_QueryInterface(
  1646. LPUNKNOWN lpThis,
  1647. REFIID riid,
  1648. LPVOID FAR* lplpvObj
  1649. )
  1650. {
  1651. LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp;
  1652. return OleApp_QueryInterface(lpOleApp, riid, lplpvObj);
  1653. }
  1654. STDMETHODIMP_(ULONG) OleApp_Unk_AddRef(LPUNKNOWN lpThis)
  1655. {
  1656. LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp;
  1657. OleDbgAddRefMethod(lpThis, "IUnknown");
  1658. return OleApp_AddRef(lpOleApp);
  1659. }
  1660. STDMETHODIMP_(ULONG) OleApp_Unk_Release (LPUNKNOWN lpThis)
  1661. {
  1662. LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp;
  1663. OleDbgReleaseMethod(lpThis, "IUnknown");
  1664. return OleApp_Release(lpOleApp);
  1665. }
  1666. #if defined( OLE_SERVER )
  1667. /*************************************************************************
  1668. ** ServerDoc Supprt Functions Used by Server versions
  1669. *************************************************************************/
  1670. /* ServerApp_InitInstance
  1671. * ----------------------
  1672. *
  1673. * Initialize the app instance by creating the main frame window and
  1674. * performing app instance specific initializations
  1675. * (eg. initializing interface Vtbls).
  1676. *
  1677. * RETURNS: TRUE if the memory could be allocated, and the server app
  1678. * was properly initialized.
  1679. * FALSE otherwise
  1680. *
  1681. */
  1682. BOOL ServerApp_InitInstance(
  1683. LPSERVERAPP lpServerApp,
  1684. HINSTANCE hInst,
  1685. int nCmdShow
  1686. )
  1687. {
  1688. LPOLEAPP lpOleApp = (LPOLEAPP)lpServerApp;
  1689. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpServerApp;
  1690. /* Setup arrays used by IDataObject::EnumFormatEtc.
  1691. **
  1692. ** OLE2NOTE: The order that the formats are listed for GetData is very
  1693. ** significant. It should be listed in order of highest fidelity
  1694. ** formats to least fidelity formats. A common ordering will be:
  1695. ** 1. private app formats
  1696. ** 2. EmbedSource
  1697. ** 3. lower fidelity interchange formats
  1698. ** 4. pictures (metafile, dib, etc.)
  1699. ** (graphic-related apps offer pictures 1st!)
  1700. ** 5. LinkSource
  1701. */
  1702. /* m_arrDocGetFmts array enumerates the formats that a ServerDoc
  1703. ** DataTransferDoc object can offer (give) through a
  1704. ** IDataObject::GetData call. a ServerDoc DataTransferDoc offers
  1705. ** data formats in the following order:
  1706. ** 1. CF_OUTLINE
  1707. ** 2. CF_EMBEDSOURCE
  1708. ** 3. CF_OBJECTDESCRIPTOR
  1709. ** 4. CF_TEXT
  1710. ** 5. CF_METAFILEPICT
  1711. ** 6. CF_LINKSOURCE *
  1712. ** 7. CF_LINKSRCDESCRIPTOR *
  1713. **
  1714. ** * NOTE: CF_LINKSOURCE and CF_LINKSRCDESCRIPTOR is only
  1715. ** offered if the doc is able to give
  1716. ** a Moniker which references the data. CF_LINKSOURCE is
  1717. ** deliberately listed last in this array of possible formats.
  1718. ** if the doc does not have a Moniker then the last element of
  1719. ** this array is not used. (see SvrDoc_DataObj_EnumFormatEtc).
  1720. **
  1721. ** NOTE: The list of formats that a USER ServerDoc document can
  1722. ** offer is a static list and is registered in the registration
  1723. ** database for the SVROUTL class. The
  1724. ** IDataObject::EnumFormatEtc method returns OLE_S_USEREG in the
  1725. ** case the document is a user docuemt (ie. created via
  1726. ** File.New, File.Open, InsertObject in a container, or
  1727. ** IPersistFile::Load during binding a link source). this tells
  1728. ** OLE to enumerate the formats automatically using the data the
  1729. ** the REGDB.
  1730. */
  1731. lpOleApp->m_arrDocGetFmts[0].cfFormat = lpOutlineApp->m_cfOutline;
  1732. lpOleApp->m_arrDocGetFmts[0].ptd = NULL;
  1733. lpOleApp->m_arrDocGetFmts[0].dwAspect = DVASPECT_CONTENT;
  1734. lpOleApp->m_arrDocGetFmts[0].tymed = TYMED_HGLOBAL;
  1735. lpOleApp->m_arrDocGetFmts[0].lindex = -1;
  1736. lpOleApp->m_arrDocGetFmts[1].cfFormat = lpOleApp->m_cfEmbedSource;
  1737. lpOleApp->m_arrDocGetFmts[1].ptd = NULL;
  1738. lpOleApp->m_arrDocGetFmts[1].dwAspect = DVASPECT_CONTENT;
  1739. lpOleApp->m_arrDocGetFmts[1].tymed = TYMED_ISTORAGE;
  1740. lpOleApp->m_arrDocGetFmts[1].lindex = -1;
  1741. lpOleApp->m_arrDocGetFmts[2].cfFormat = CF_TEXT;
  1742. lpOleApp->m_arrDocGetFmts[2].ptd = NULL;
  1743. lpOleApp->m_arrDocGetFmts[2].dwAspect = DVASPECT_CONTENT;
  1744. lpOleApp->m_arrDocGetFmts[2].tymed = TYMED_HGLOBAL;
  1745. lpOleApp->m_arrDocGetFmts[2].lindex = -1;
  1746. lpOleApp->m_arrDocGetFmts[3].cfFormat = CF_METAFILEPICT;
  1747. lpOleApp->m_arrDocGetFmts[3].ptd = NULL;
  1748. lpOleApp->m_arrDocGetFmts[3].dwAspect = DVASPECT_CONTENT;
  1749. lpOleApp->m_arrDocGetFmts[3].tymed = TYMED_MFPICT;
  1750. lpOleApp->m_arrDocGetFmts[3].lindex = -1;
  1751. lpOleApp->m_arrDocGetFmts[4].cfFormat = lpOleApp->m_cfObjectDescriptor;
  1752. lpOleApp->m_arrDocGetFmts[4].ptd = NULL;
  1753. lpOleApp->m_arrDocGetFmts[4].dwAspect = DVASPECT_CONTENT;
  1754. lpOleApp->m_arrDocGetFmts[4].tymed = TYMED_HGLOBAL;
  1755. lpOleApp->m_arrDocGetFmts[4].lindex = -1;
  1756. lpOleApp->m_arrDocGetFmts[5].cfFormat = lpOleApp->m_cfLinkSource;
  1757. lpOleApp->m_arrDocGetFmts[5].ptd = NULL;
  1758. lpOleApp->m_arrDocGetFmts[5].dwAspect = DVASPECT_CONTENT;
  1759. lpOleApp->m_arrDocGetFmts[5].tymed = TYMED_ISTREAM;
  1760. lpOleApp->m_arrDocGetFmts[5].lindex = -1;
  1761. lpOleApp->m_arrDocGetFmts[6].cfFormat = lpOleApp->m_cfLinkSrcDescriptor;
  1762. lpOleApp->m_arrDocGetFmts[6].ptd = NULL;
  1763. lpOleApp->m_arrDocGetFmts[6].dwAspect = DVASPECT_CONTENT;
  1764. lpOleApp->m_arrDocGetFmts[6].tymed = TYMED_HGLOBAL;
  1765. lpOleApp->m_arrDocGetFmts[6].lindex = -1;
  1766. lpOleApp->m_nDocGetFmts = 7;
  1767. /* m_arrPasteEntries array enumerates the formats that a ServerDoc
  1768. ** object can accept (get) from the clipboard.
  1769. ** The formats are listed in priority order.
  1770. ** ServerDoc accept data formats in the following order:
  1771. ** 1. CF_OUTLINE
  1772. ** 2. CF_TEXT
  1773. */
  1774. // REVIEW: strings should be loaded from string resource
  1775. lpOleApp->m_arrPasteEntries[0].fmtetc.cfFormat =lpOutlineApp->m_cfOutline;
  1776. lpOleApp->m_arrPasteEntries[0].fmtetc.ptd = NULL;
  1777. lpOleApp->m_arrPasteEntries[0].fmtetc.dwAspect = DVASPECT_CONTENT;
  1778. lpOleApp->m_arrPasteEntries[0].fmtetc.tymed = TYMED_HGLOBAL;
  1779. lpOleApp->m_arrPasteEntries[0].fmtetc.lindex = -1;
  1780. lpOleApp->m_arrPasteEntries[0].lpstrFormatName = "Outline Data";
  1781. lpOleApp->m_arrPasteEntries[0].lpstrResultText = "Outline Data";
  1782. lpOleApp->m_arrPasteEntries[0].dwFlags = OLEUIPASTE_PASTEONLY;
  1783. lpOleApp->m_arrPasteEntries[1].fmtetc.cfFormat = CF_TEXT;
  1784. lpOleApp->m_arrPasteEntries[1].fmtetc.ptd = NULL;
  1785. lpOleApp->m_arrPasteEntries[1].fmtetc.dwAspect = DVASPECT_CONTENT;
  1786. lpOleApp->m_arrPasteEntries[1].fmtetc.tymed = TYMED_HGLOBAL;
  1787. lpOleApp->m_arrPasteEntries[1].fmtetc.lindex = -1;
  1788. lpOleApp->m_arrPasteEntries[1].lpstrFormatName = "Text";
  1789. lpOleApp->m_arrPasteEntries[1].lpstrResultText = "text";
  1790. lpOleApp->m_arrPasteEntries[1].dwFlags = OLEUIPASTE_PASTEONLY;
  1791. lpOleApp->m_nPasteEntries = 2;
  1792. /** m_arrLinkTypes array enumerates the link types that a ServerDoc
  1793. ** object can accept from the clipboard. ServerDoc does NOT
  1794. ** accept any type of link from the clipboard. ServerDoc can
  1795. ** only be the source of a link. it can not contain links.
  1796. */
  1797. lpOleApp->m_nLinkTypes = 0;
  1798. #if defined( INPLACE_SVR )
  1799. lpServerApp->m_hAccelBaseApp = NULL;
  1800. lpServerApp->m_hAccelIPSvr = LoadAccelerators(
  1801. hInst,
  1802. "InPlaceSvrOutlAccel"
  1803. );
  1804. lpServerApp->m_lpIPData = NULL;
  1805. lpServerApp->m_hMenuEdit = GetSubMenu (
  1806. lpOutlineApp->m_hMenuApp,
  1807. POS_EDITMENU
  1808. );
  1809. lpServerApp->m_hMenuLine = GetSubMenu (
  1810. lpOutlineApp->m_hMenuApp,
  1811. POS_LINEMENU
  1812. );
  1813. lpServerApp->m_hMenuName = GetSubMenu (
  1814. lpOutlineApp->m_hMenuApp,
  1815. POS_NAMEMENU
  1816. );
  1817. lpServerApp->m_hMenuOptions = GetSubMenu (
  1818. lpOutlineApp->m_hMenuApp,
  1819. POS_OPTIONSMENU
  1820. );
  1821. lpServerApp->m_hMenuDebug = GetSubMenu (
  1822. lpOutlineApp->m_hMenuApp,
  1823. POS_DEBUGMENU
  1824. );
  1825. lpServerApp->m_hMenuHelp = GetSubMenu (
  1826. lpOutlineApp->m_hMenuApp,
  1827. POS_HELPMENU
  1828. );
  1829. #endif // INPLACE_SVR
  1830. return TRUE;
  1831. }
  1832. /* ServerApp_InitVtbls
  1833. * -------------------
  1834. *
  1835. * initialize the methods in all of the interface Vtbl's
  1836. *
  1837. * OLE2NOTE: we only need one copy of each Vtbl. When an object which
  1838. * exposes an interface is instantiated, its lpVtbl is intialized
  1839. * to point to the single copy of the Vtbl.
  1840. *
  1841. */
  1842. BOOL ServerApp_InitVtbls (LPSERVERAPP lpServerApp)
  1843. {
  1844. BOOL fStatus;
  1845. // ServerDoc::IOleObject method table
  1846. OleStdInitVtbl(&g_SvrDoc_OleObjectVtbl, sizeof(IOleObjectVtbl));
  1847. g_SvrDoc_OleObjectVtbl.QueryInterface = SvrDoc_OleObj_QueryInterface;
  1848. g_SvrDoc_OleObjectVtbl.AddRef = SvrDoc_OleObj_AddRef;
  1849. g_SvrDoc_OleObjectVtbl.Release = SvrDoc_OleObj_Release;
  1850. g_SvrDoc_OleObjectVtbl.SetClientSite = SvrDoc_OleObj_SetClientSite;
  1851. g_SvrDoc_OleObjectVtbl.GetClientSite = SvrDoc_OleObj_GetClientSite;
  1852. g_SvrDoc_OleObjectVtbl.SetHostNames = SvrDoc_OleObj_SetHostNames;
  1853. g_SvrDoc_OleObjectVtbl.Close = SvrDoc_OleObj_Close;
  1854. g_SvrDoc_OleObjectVtbl.SetMoniker = SvrDoc_OleObj_SetMoniker;
  1855. g_SvrDoc_OleObjectVtbl.GetMoniker = SvrDoc_OleObj_GetMoniker;
  1856. g_SvrDoc_OleObjectVtbl.InitFromData = SvrDoc_OleObj_InitFromData;
  1857. g_SvrDoc_OleObjectVtbl.GetClipboardData = SvrDoc_OleObj_GetClipboardData;
  1858. g_SvrDoc_OleObjectVtbl.DoVerb = SvrDoc_OleObj_DoVerb;
  1859. g_SvrDoc_OleObjectVtbl.EnumVerbs = SvrDoc_OleObj_EnumVerbs;
  1860. g_SvrDoc_OleObjectVtbl.Update = SvrDoc_OleObj_Update;
  1861. g_SvrDoc_OleObjectVtbl.IsUpToDate = SvrDoc_OleObj_IsUpToDate;
  1862. g_SvrDoc_OleObjectVtbl.GetUserClassID = SvrDoc_OleObj_GetUserClassID;
  1863. g_SvrDoc_OleObjectVtbl.GetUserType = SvrDoc_OleObj_GetUserType;
  1864. g_SvrDoc_OleObjectVtbl.SetExtent = SvrDoc_OleObj_SetExtent;
  1865. g_SvrDoc_OleObjectVtbl.GetExtent = SvrDoc_OleObj_GetExtent;
  1866. g_SvrDoc_OleObjectVtbl.Advise = SvrDoc_OleObj_Advise;
  1867. g_SvrDoc_OleObjectVtbl.Unadvise = SvrDoc_OleObj_Unadvise;
  1868. g_SvrDoc_OleObjectVtbl.EnumAdvise = SvrDoc_OleObj_EnumAdvise;
  1869. g_SvrDoc_OleObjectVtbl.GetMiscStatus = SvrDoc_OleObj_GetMiscStatus;
  1870. g_SvrDoc_OleObjectVtbl.SetColorScheme = SvrDoc_OleObj_SetColorScheme;
  1871. fStatus = OleStdCheckVtbl(
  1872. &g_SvrDoc_OleObjectVtbl,
  1873. sizeof(IOleObjectVtbl),
  1874. "IOleObject"
  1875. );
  1876. if (! fStatus) return FALSE;
  1877. // ServerDoc::IPersistStorage method table
  1878. OleStdInitVtbl(&g_SvrDoc_PersistStorageVtbl, sizeof(IPersistStorageVtbl));
  1879. g_SvrDoc_PersistStorageVtbl.QueryInterface = SvrDoc_PStg_QueryInterface;
  1880. g_SvrDoc_PersistStorageVtbl.AddRef = SvrDoc_PStg_AddRef;
  1881. g_SvrDoc_PersistStorageVtbl.Release = SvrDoc_PStg_Release;
  1882. g_SvrDoc_PersistStorageVtbl.GetClassID = SvrDoc_PStg_GetClassID;
  1883. g_SvrDoc_PersistStorageVtbl.IsDirty = SvrDoc_PStg_IsDirty;
  1884. g_SvrDoc_PersistStorageVtbl.InitNew = SvrDoc_PStg_InitNew;
  1885. g_SvrDoc_PersistStorageVtbl.Load = SvrDoc_PStg_Load;
  1886. g_SvrDoc_PersistStorageVtbl.Save = SvrDoc_PStg_Save;
  1887. g_SvrDoc_PersistStorageVtbl.SaveCompleted = SvrDoc_PStg_SaveCompleted;
  1888. g_SvrDoc_PersistStorageVtbl.HandsOffStorage = SvrDoc_PStg_HandsOffStorage;
  1889. fStatus = OleStdCheckVtbl(
  1890. &g_SvrDoc_PersistStorageVtbl,
  1891. sizeof(IPersistStorageVtbl),
  1892. "IPersistStorage"
  1893. );
  1894. if (! fStatus) return FALSE;
  1895. #if defined( SVR_TREATAS )
  1896. // ServerDoc::IStdMarshalInfo method table
  1897. OleStdInitVtbl(
  1898. &g_SvrDoc_StdMarshalInfoVtbl, sizeof(IStdMarshalInfoVtbl));
  1899. g_SvrDoc_StdMarshalInfoVtbl.QueryInterface =
  1900. SvrDoc_StdMshl_QueryInterface;
  1901. g_SvrDoc_StdMarshalInfoVtbl.AddRef = SvrDoc_StdMshl_AddRef;
  1902. g_SvrDoc_StdMarshalInfoVtbl.Release = SvrDoc_StdMshl_Release;
  1903. g_SvrDoc_StdMarshalInfoVtbl.GetClassForHandler =
  1904. SvrDoc_StdMshl_GetClassForHandler;
  1905. fStatus = OleStdCheckVtbl(
  1906. &g_SvrDoc_StdMarshalInfoVtbl,
  1907. sizeof(IStdMarshalInfoVtbl),
  1908. "IStdMarshalInfo"
  1909. );
  1910. if (! fStatus) return FALSE;
  1911. #endif // SVR_TREATAS
  1912. #if defined( INPLACE_SVR )
  1913. // ServerDoc::IOleInPlaceObject method table
  1914. OleStdInitVtbl(
  1915. &g_SvrDoc_OleInPlaceObjectVtbl,
  1916. sizeof(IOleInPlaceObjectVtbl)
  1917. );
  1918. g_SvrDoc_OleInPlaceObjectVtbl.QueryInterface
  1919. = SvrDoc_IPObj_QueryInterface;
  1920. g_SvrDoc_OleInPlaceObjectVtbl.AddRef
  1921. = SvrDoc_IPObj_AddRef;
  1922. g_SvrDoc_OleInPlaceObjectVtbl.Release
  1923. = SvrDoc_IPObj_Release;
  1924. g_SvrDoc_OleInPlaceObjectVtbl.GetWindow
  1925. = SvrDoc_IPObj_GetWindow;
  1926. g_SvrDoc_OleInPlaceObjectVtbl.ContextSensitiveHelp
  1927. = SvrDoc_IPObj_ContextSensitiveHelp;
  1928. g_SvrDoc_OleInPlaceObjectVtbl.InPlaceDeactivate
  1929. = SvrDoc_IPObj_InPlaceDeactivate;
  1930. g_SvrDoc_OleInPlaceObjectVtbl.UIDeactivate
  1931. = SvrDoc_IPObj_UIDeactivate;
  1932. g_SvrDoc_OleInPlaceObjectVtbl.SetObjectRects
  1933. = SvrDoc_IPObj_SetObjectRects;
  1934. g_SvrDoc_OleInPlaceObjectVtbl.ReactivateAndUndo
  1935. = SvrDoc_IPObj_ReactivateAndUndo;
  1936. fStatus = OleStdCheckVtbl(
  1937. &g_SvrDoc_OleInPlaceObjectVtbl,
  1938. sizeof(IOleInPlaceObjectVtbl),
  1939. "IOleInPlaceObject"
  1940. );
  1941. if (! fStatus) return FALSE;
  1942. // ServerDoc::IOleInPlaceActiveObject method table
  1943. OleStdInitVtbl(
  1944. &g_SvrDoc_OleInPlaceActiveObjectVtbl,
  1945. sizeof(IOleInPlaceActiveObjectVtbl)
  1946. );
  1947. g_SvrDoc_OleInPlaceActiveObjectVtbl.QueryInterface
  1948. = SvrDoc_IPActiveObj_QueryInterface;
  1949. g_SvrDoc_OleInPlaceActiveObjectVtbl.AddRef
  1950. = SvrDoc_IPActiveObj_AddRef;
  1951. g_SvrDoc_OleInPlaceActiveObjectVtbl.Release
  1952. = SvrDoc_IPActiveObj_Release;
  1953. g_SvrDoc_OleInPlaceActiveObjectVtbl.GetWindow
  1954. = SvrDoc_IPActiveObj_GetWindow;
  1955. g_SvrDoc_OleInPlaceActiveObjectVtbl.ContextSensitiveHelp
  1956. = SvrDoc_IPActiveObj_ContextSensitiveHelp;
  1957. g_SvrDoc_OleInPlaceActiveObjectVtbl.TranslateAccelerator
  1958. = SvrDoc_IPActiveObj_TranslateAccelerator;
  1959. g_SvrDoc_OleInPlaceActiveObjectVtbl.OnFrameWindowActivate
  1960. = SvrDoc_IPActiveObj_OnFrameWindowActivate;
  1961. g_SvrDoc_OleInPlaceActiveObjectVtbl.OnDocWindowActivate
  1962. = SvrDoc_IPActiveObj_OnDocWindowActivate;
  1963. g_SvrDoc_OleInPlaceActiveObjectVtbl.ResizeBorder
  1964. = SvrDoc_IPActiveObj_ResizeBorder;
  1965. g_SvrDoc_OleInPlaceActiveObjectVtbl.EnableModeless
  1966. = SvrDoc_IPActiveObj_EnableModeless;
  1967. fStatus = OleStdCheckVtbl(
  1968. &g_SvrDoc_OleInPlaceActiveObjectVtbl,
  1969. sizeof(IOleInPlaceActiveObjectVtbl),
  1970. "IOleInPlaceActiveObject"
  1971. );
  1972. if (! fStatus) return FALSE;
  1973. #endif
  1974. // PseudoObj::IUnknown method table
  1975. OleStdInitVtbl(&g_PseudoObj_UnknownVtbl, sizeof(IUnknownVtbl));
  1976. g_PseudoObj_UnknownVtbl.QueryInterface = PseudoObj_Unk_QueryInterface;
  1977. g_PseudoObj_UnknownVtbl.AddRef = PseudoObj_Unk_AddRef;
  1978. g_PseudoObj_UnknownVtbl.Release = PseudoObj_Unk_Release;
  1979. fStatus = OleStdCheckVtbl(
  1980. &g_PseudoObj_UnknownVtbl,
  1981. sizeof(IUnknownVtbl),
  1982. "IUnknown"
  1983. );
  1984. if (! fStatus) return FALSE;
  1985. // PseudoObj::IOleObject method table
  1986. OleStdInitVtbl(&g_PseudoObj_OleObjectVtbl, sizeof(IOleObjectVtbl));
  1987. g_PseudoObj_OleObjectVtbl.QueryInterface= PseudoObj_OleObj_QueryInterface;
  1988. g_PseudoObj_OleObjectVtbl.AddRef = PseudoObj_OleObj_AddRef;
  1989. g_PseudoObj_OleObjectVtbl.Release = PseudoObj_OleObj_Release;
  1990. g_PseudoObj_OleObjectVtbl.SetClientSite = PseudoObj_OleObj_SetClientSite;
  1991. g_PseudoObj_OleObjectVtbl.GetClientSite = PseudoObj_OleObj_GetClientSite;
  1992. g_PseudoObj_OleObjectVtbl.SetHostNames = PseudoObj_OleObj_SetHostNames;
  1993. g_PseudoObj_OleObjectVtbl.Close = PseudoObj_OleObj_Close;
  1994. g_PseudoObj_OleObjectVtbl.SetMoniker = PseudoObj_OleObj_SetMoniker;
  1995. g_PseudoObj_OleObjectVtbl.GetMoniker = PseudoObj_OleObj_GetMoniker;
  1996. g_PseudoObj_OleObjectVtbl.InitFromData = PseudoObj_OleObj_InitFromData;
  1997. g_PseudoObj_OleObjectVtbl.GetClipboardData =
  1998. PseudoObj_OleObj_GetClipboardData;
  1999. g_PseudoObj_OleObjectVtbl.DoVerb = PseudoObj_OleObj_DoVerb;
  2000. g_PseudoObj_OleObjectVtbl.EnumVerbs = PseudoObj_OleObj_EnumVerbs;
  2001. g_PseudoObj_OleObjectVtbl.Update = PseudoObj_OleObj_Update;
  2002. g_PseudoObj_OleObjectVtbl.IsUpToDate = PseudoObj_OleObj_IsUpToDate;
  2003. g_PseudoObj_OleObjectVtbl.GetUserType = PseudoObj_OleObj_GetUserType;
  2004. g_PseudoObj_OleObjectVtbl.GetUserClassID= PseudoObj_OleObj_GetUserClassID;
  2005. g_PseudoObj_OleObjectVtbl.SetExtent = PseudoObj_OleObj_SetExtent;
  2006. g_PseudoObj_OleObjectVtbl.GetExtent = PseudoObj_OleObj_GetExtent;
  2007. g_PseudoObj_OleObjectVtbl.Advise = PseudoObj_OleObj_Advise;
  2008. g_PseudoObj_OleObjectVtbl.Unadvise = PseudoObj_OleObj_Unadvise;
  2009. g_PseudoObj_OleObjectVtbl.EnumAdvise = PseudoObj_OleObj_EnumAdvise;
  2010. g_PseudoObj_OleObjectVtbl.GetMiscStatus = PseudoObj_OleObj_GetMiscStatus;
  2011. g_PseudoObj_OleObjectVtbl.SetColorScheme= PseudoObj_OleObj_SetColorScheme;
  2012. fStatus = OleStdCheckVtbl(
  2013. &g_PseudoObj_OleObjectVtbl,
  2014. sizeof(IOleObjectVtbl),
  2015. "IOleObject"
  2016. );
  2017. if (! fStatus) return FALSE;
  2018. // ServerDoc::IDataObject method table
  2019. OleStdInitVtbl(&g_PseudoObj_DataObjectVtbl, sizeof(IDataObjectVtbl));
  2020. g_PseudoObj_DataObjectVtbl.QueryInterface =
  2021. PseudoObj_DataObj_QueryInterface;
  2022. g_PseudoObj_DataObjectVtbl.AddRef = PseudoObj_DataObj_AddRef;
  2023. g_PseudoObj_DataObjectVtbl.Release = PseudoObj_DataObj_Release;
  2024. g_PseudoObj_DataObjectVtbl.GetData = PseudoObj_DataObj_GetData;
  2025. g_PseudoObj_DataObjectVtbl.GetDataHere = PseudoObj_DataObj_GetDataHere;
  2026. g_PseudoObj_DataObjectVtbl.QueryGetData = PseudoObj_DataObj_QueryGetData;
  2027. g_PseudoObj_DataObjectVtbl.GetCanonicalFormatEtc =
  2028. PseudoObj_DataObj_GetCanonicalFormatEtc;
  2029. g_PseudoObj_DataObjectVtbl.SetData = PseudoObj_DataObj_SetData;
  2030. g_PseudoObj_DataObjectVtbl.EnumFormatEtc= PseudoObj_DataObj_EnumFormatEtc;
  2031. g_PseudoObj_DataObjectVtbl.DAdvise = PseudoObj_DataObj_DAdvise;
  2032. g_PseudoObj_DataObjectVtbl.DUnadvise = PseudoObj_DataObj_DUnadvise;
  2033. g_PseudoObj_DataObjectVtbl.EnumDAdvise = PseudoObj_DataObj_EnumAdvise;
  2034. fStatus = OleStdCheckVtbl(
  2035. &g_PseudoObj_DataObjectVtbl,
  2036. sizeof(IDataObjectVtbl),
  2037. "IDataObject"
  2038. );
  2039. if (! fStatus) return FALSE;
  2040. return TRUE;
  2041. }
  2042. #endif // OLE_SERVER
  2043. #if defined( OLE_CNTR )
  2044. /*************************************************************************
  2045. ** ContainerDoc Supprt Functions Used by Container versions
  2046. *************************************************************************/
  2047. /* ContainerApp_InitInstance
  2048. * -------------------------
  2049. *
  2050. * Initialize the app instance by creating the main frame window and
  2051. * performing app instance specific initializations
  2052. * (eg. initializing interface Vtbls).
  2053. *
  2054. * RETURNS: TRUE if the memory could be allocated, and the server app
  2055. * was properly initialized.
  2056. * FALSE otherwise
  2057. *
  2058. */
  2059. BOOL ContainerApp_InitInstance(
  2060. LPCONTAINERAPP lpContainerApp,
  2061. HINSTANCE hInst,
  2062. int nCmdShow
  2063. )
  2064. {
  2065. LPOLEAPP lpOleApp = (LPOLEAPP)lpContainerApp;
  2066. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpContainerApp;
  2067. lpContainerApp->m_cfCntrOutl=RegisterClipboardFormat(CONTAINERDOCFORMAT);
  2068. if(! lpContainerApp->m_cfCntrOutl) {
  2069. // REVIEW: should load string from string resource
  2070. OutlineApp_ErrorMessage(lpOutlineApp, "Can't register clipboard format!");
  2071. return FALSE;
  2072. }
  2073. #if defined( INPLACE_CNTR )
  2074. lpContainerApp->m_fPendingUIDeactivate = FALSE;
  2075. lpContainerApp->m_fMustResizeClientArea = FALSE;
  2076. lpContainerApp->m_lpIPActiveObj = NULL;
  2077. lpContainerApp->m_hWndUIActiveObj = NULL;
  2078. lpContainerApp->m_hAccelIPCntr = LoadAccelerators(
  2079. hInst,
  2080. "InPlaceCntrOutlAccel"
  2081. );
  2082. lpContainerApp->m_hMenuFile = GetSubMenu (
  2083. lpOutlineApp->m_hMenuApp,
  2084. POS_FILEMENU
  2085. );
  2086. lpContainerApp->m_hMenuView = GetSubMenu (
  2087. lpOutlineApp->m_hMenuApp,
  2088. POS_VIEWMENU
  2089. );
  2090. lpContainerApp->m_hMenuDebug = GetSubMenu (
  2091. lpOutlineApp->m_hMenuApp,
  2092. POS_DEBUGMENU
  2093. );
  2094. INIT_INTERFACEIMPL(
  2095. &lpContainerApp->m_OleInPlaceFrame,
  2096. &g_CntrApp_OleInPlaceFrameVtbl,
  2097. lpContainerApp
  2098. );
  2099. #endif
  2100. /* Setup arrays used by IDataObject::EnumFormatEtc. This is used to
  2101. ** support copy/paste and drag/drop operations.
  2102. **
  2103. ** OLE2NOTE: The order that the formats are listed for GetData is very
  2104. ** significant. It should be listed in order of highest fidelity
  2105. ** formats to least fidelity formats. A common ordering will be:
  2106. ** 1. private app formats
  2107. ** 2. CF_EMBEDSOURCE or CF_EMBEDOBJECT (as appropriate)
  2108. ** 3. lower fidelity interchange formats
  2109. ** 4. CF_METAFILEPICT
  2110. ** (graphic-related apps might offer picture 1st!)
  2111. ** 5. CF_OBJECTDESCRIPTOR
  2112. ** 6. CF_LINKSOURCE
  2113. ** 6. CF_LINKSRCDESCRIPTOR
  2114. */
  2115. /* m_arrDocGetFmts array enumerates the formats that a ContainerDoc
  2116. ** object can offer (give) through a IDataObject::GetData call
  2117. ** when the selection copied is NOT a single embedded object.
  2118. ** when a single embedded object this list of formats available
  2119. ** is built dynamically depending on the object copied. (see
  2120. ** ContainerDoc_SetupDocGetFmts).
  2121. ** The formats are listed in priority order.
  2122. ** ContainerDoc objects accept data formats in the following order:
  2123. ** 1. CF_CNTROUTL
  2124. ** 2. CF_OUTLINE
  2125. ** 3. CF_TEXT
  2126. ** 4. CF_OBJECTDESCRIPTOR
  2127. **
  2128. ** OLE2NOTE: CF_OBJECTDESCRIPTOR format is used to describe the
  2129. ** data on the clipboard. this information is intended to be
  2130. ** used, for example, to drive the PasteSpecial dialog. it is
  2131. ** useful to render CF_OBJECTDESCRIPTOR format even when the
  2132. ** data on the clipboard does NOT include CF_EMBEDDEDOBJECT
  2133. ** format or CF_EMBEDSOURCE format as when a selection that is
  2134. ** not a single OLE object is copied from the container only
  2135. ** version CNTROUTL. by rendering CF_OBJECTDESCRIPTOR format the
  2136. ** app can indicate a useful string to identifiy the source of
  2137. ** the copy to the user.
  2138. */
  2139. lpOleApp->m_arrDocGetFmts[0].cfFormat = lpContainerApp->m_cfCntrOutl;
  2140. lpOleApp->m_arrDocGetFmts[0].ptd = NULL;
  2141. lpOleApp->m_arrDocGetFmts[0].dwAspect = DVASPECT_CONTENT;
  2142. lpOleApp->m_arrDocGetFmts[0].tymed = TYMED_ISTORAGE;
  2143. lpOleApp->m_arrDocGetFmts[0].lindex = -1;
  2144. lpOleApp->m_arrDocGetFmts[1].cfFormat = lpOutlineApp->m_cfOutline;
  2145. lpOleApp->m_arrDocGetFmts[1].ptd = NULL;
  2146. lpOleApp->m_arrDocGetFmts[1].dwAspect = DVASPECT_CONTENT;
  2147. lpOleApp->m_arrDocGetFmts[1].tymed = TYMED_HGLOBAL;
  2148. lpOleApp->m_arrDocGetFmts[1].lindex = -1;
  2149. lpOleApp->m_arrDocGetFmts[2].cfFormat = CF_TEXT;
  2150. lpOleApp->m_arrDocGetFmts[2].ptd = NULL;
  2151. lpOleApp->m_arrDocGetFmts[2].dwAspect = DVASPECT_CONTENT;
  2152. lpOleApp->m_arrDocGetFmts[2].tymed = TYMED_HGLOBAL;
  2153. lpOleApp->m_arrDocGetFmts[2].lindex = -1;
  2154. lpOleApp->m_arrDocGetFmts[3].cfFormat = lpOleApp->m_cfObjectDescriptor;
  2155. lpOleApp->m_arrDocGetFmts[3].ptd = NULL;
  2156. lpOleApp->m_arrDocGetFmts[3].dwAspect = DVASPECT_CONTENT;
  2157. lpOleApp->m_arrDocGetFmts[3].tymed = TYMED_HGLOBAL;
  2158. lpOleApp->m_arrDocGetFmts[3].lindex = -1;
  2159. lpOleApp->m_nDocGetFmts = 4;
  2160. /* m_arrSingleObjGetFmts array enumerates the formats that a
  2161. ** ContainerDoc object can offer (give) through a
  2162. ** IDataObject::GetData call when the selection copied IS a
  2163. ** single OLE object.
  2164. ** ContainerDoc objects accept data formats in the following order:
  2165. ** 1. CF_CNTROUTL
  2166. ** 2. CF_EMBEDDEDOBJECT
  2167. ** 3. CF_OBJECTDESCRIPTOR
  2168. ** 4. CF_METAFILEPICT (note DVASPECT will vary)
  2169. ** 5. CF_LINKSOURCE *
  2170. ** 6. CF_LINKSRCDESCRIPTOR *
  2171. **
  2172. ** * OLE2NOTE: CF_LINKSOURCE and CF_LINKSRCDESCRIPTOR is only
  2173. ** offered if the OLE object is allowed to be linked to from the
  2174. ** inside (ie. we are allowed to give out a moniker which binds
  2175. ** to the running OLE object), then we want to offer
  2176. ** CF_LINKSOURCE format. if the object is an OLE 2.0 embedded
  2177. ** object then it is allowed to be linked to from the inside. if
  2178. ** the object is either an OleLink or an OLE 1.0 embedding then
  2179. ** it can not be linked to from the inside. if we were a
  2180. ** container/server app then we could offer linking to the
  2181. ** outside of the object (ie. a pseudo object within our
  2182. ** document). we are a container only app that does not support
  2183. ** linking to ranges of its data.
  2184. ** the simplest way to determine if an object can be linked to
  2185. ** on the inside is to call IOleObject::GetMiscStatus and test
  2186. ** to see if the OLEMISC_CANTLINKINSIDE bit is NOT set.
  2187. **
  2188. ** OLE2NOTE: optionally, a container that wants to have a
  2189. ** potentially richer data transfer, can enumerate the data
  2190. ** formats from the OLE object's cache and offer them too. if
  2191. ** the object has a special handler, then it might be able to
  2192. ** render additional data formats.
  2193. */
  2194. lpContainerApp->m_arrSingleObjGetFmts[0].cfFormat =
  2195. lpContainerApp->m_cfCntrOutl;
  2196. lpContainerApp->m_arrSingleObjGetFmts[0].ptd = NULL;
  2197. lpContainerApp->m_arrSingleObjGetFmts[0].dwAspect = DVASPECT_CONTENT;
  2198. lpContainerApp->m_arrSingleObjGetFmts[0].tymed = TYMED_ISTORAGE;
  2199. lpContainerApp->m_arrSingleObjGetFmts[0].lindex = -1;
  2200. lpContainerApp->m_arrSingleObjGetFmts[1].cfFormat =
  2201. lpOleApp->m_cfEmbeddedObject;
  2202. lpContainerApp->m_arrSingleObjGetFmts[1].ptd = NULL;
  2203. lpContainerApp->m_arrSingleObjGetFmts[1].dwAspect = DVASPECT_CONTENT;
  2204. lpContainerApp->m_arrSingleObjGetFmts[1].tymed = TYMED_ISTORAGE;
  2205. lpContainerApp->m_arrSingleObjGetFmts[1].lindex = -1;
  2206. lpContainerApp->m_arrSingleObjGetFmts[2].cfFormat =
  2207. lpOleApp->m_cfObjectDescriptor;
  2208. lpContainerApp->m_arrSingleObjGetFmts[2].ptd = NULL;
  2209. lpContainerApp->m_arrSingleObjGetFmts[2].dwAspect = DVASPECT_CONTENT;
  2210. lpContainerApp->m_arrSingleObjGetFmts[2].tymed = TYMED_HGLOBAL;
  2211. lpContainerApp->m_arrSingleObjGetFmts[2].lindex = -1;
  2212. lpContainerApp->m_arrSingleObjGetFmts[3].cfFormat = CF_METAFILEPICT;
  2213. lpContainerApp->m_arrSingleObjGetFmts[3].ptd = NULL;
  2214. lpContainerApp->m_arrSingleObjGetFmts[3].dwAspect = DVASPECT_CONTENT;
  2215. lpContainerApp->m_arrSingleObjGetFmts[3].tymed = TYMED_MFPICT;
  2216. lpContainerApp->m_arrSingleObjGetFmts[3].lindex = -1;
  2217. lpContainerApp->m_arrSingleObjGetFmts[4].cfFormat =
  2218. lpOleApp->m_cfLinkSource;
  2219. lpContainerApp->m_arrSingleObjGetFmts[4].ptd = NULL;
  2220. lpContainerApp->m_arrSingleObjGetFmts[4].dwAspect = DVASPECT_CONTENT;
  2221. lpContainerApp->m_arrSingleObjGetFmts[4].tymed = TYMED_ISTREAM;
  2222. lpContainerApp->m_arrSingleObjGetFmts[4].lindex = -1;
  2223. lpContainerApp->m_arrSingleObjGetFmts[5].cfFormat =
  2224. lpOleApp->m_cfLinkSrcDescriptor;
  2225. lpContainerApp->m_arrSingleObjGetFmts[5].ptd = NULL;
  2226. lpContainerApp->m_arrSingleObjGetFmts[5].dwAspect = DVASPECT_CONTENT;
  2227. lpContainerApp->m_arrSingleObjGetFmts[5].tymed = TYMED_HGLOBAL;
  2228. lpContainerApp->m_arrSingleObjGetFmts[5].lindex = -1;
  2229. lpContainerApp->m_nSingleObjGetFmts = 6;
  2230. /* NOTE: the Container-Only version of Outline does NOT offer
  2231. ** IDataObject interface from its User documents and the
  2232. ** IDataObject interface available from DataTransferDoc's do NOT
  2233. ** support SetData. IDataObject interface is required by objects
  2234. ** which can be embedded or linked. the Container-only app only
  2235. ** allows linking to its contained objects, NOT the data of the
  2236. ** container itself.
  2237. */
  2238. /* m_arrPasteEntries array enumerates the formats that a ContainerDoc
  2239. ** object can accept from the clipboard. this array is used to
  2240. ** support the PasteSpecial dialog.
  2241. ** The formats are listed in priority order.
  2242. ** ContainerDoc objects accept data formats in the following order:
  2243. ** 1. CF_CNTROUTL
  2244. ** 2. CF_OUTLINE
  2245. ** 3. CF_EMBEDDEDOBJECT
  2246. ** 4. CF_TEXT
  2247. ** 5. CF_METAFILEPICT
  2248. ** 6. CF_DIB
  2249. ** 7. CF_BITMAP
  2250. ** 8. CF_LINKSOURCE
  2251. **
  2252. ** NOTE: specifying CF_EMBEDDEDOBJECT in the PasteEntry array
  2253. ** indicates that the caller is interested in pasting OLE
  2254. ** objects (ie. the caller calls OleCreateFromData). the
  2255. ** OleUIPasteSpecial dialog and OleStdGetPriorityClipboardFormat
  2256. ** call OleQueryCreateFromData to see if an OLE object format is
  2257. ** available. thus, in fact if CF_EMBEDSOURCE or CF_FILENAME are
  2258. ** available from the data source then and OLE object can be
  2259. ** created and this entry will be matched. the caller should
  2260. ** only specify one object type format.
  2261. ** CF_FILENAME format (as generated by copying a file to
  2262. ** the clipboard from the FileManager) is considered an object
  2263. ** format; OleCreatFromData creates an object if the file has an
  2264. ** associated class (see GetClassFile API) or if no class it
  2265. ** creates an OLE 1.0 Package object. this format can also be
  2266. ** paste linked by calling OleCreateLinkFromData.
  2267. */
  2268. // REVIEW: strings should be loaded from string resource
  2269. lpOleApp->m_arrPasteEntries[0].fmtetc.cfFormat =
  2270. lpContainerApp->m_cfCntrOutl;
  2271. lpOleApp->m_arrPasteEntries[0].fmtetc.ptd = NULL;
  2272. lpOleApp->m_arrPasteEntries[0].fmtetc.dwAspect = DVASPECT_CONTENT;
  2273. lpOleApp->m_arrPasteEntries[0].fmtetc.tymed = TYMED_ISTORAGE;
  2274. lpOleApp->m_arrPasteEntries[0].fmtetc.lindex = -1;
  2275. lpOleApp->m_arrPasteEntries[0].lpstrFormatName = "Container Outline Data";
  2276. lpOleApp->m_arrPasteEntries[0].lpstrResultText =
  2277. "Container Outline Data";
  2278. lpOleApp->m_arrPasteEntries[0].dwFlags = OLEUIPASTE_PASTEONLY;
  2279. lpOleApp->m_arrPasteEntries[1].fmtetc.cfFormat =lpOutlineApp->m_cfOutline;
  2280. lpOleApp->m_arrPasteEntries[1].fmtetc.ptd = NULL;
  2281. lpOleApp->m_arrPasteEntries[1].fmtetc.dwAspect = DVASPECT_CONTENT;
  2282. lpOleApp->m_arrPasteEntries[1].fmtetc.tymed = TYMED_HGLOBAL;
  2283. lpOleApp->m_arrPasteEntries[1].fmtetc.lindex = -1;
  2284. lpOleApp->m_arrPasteEntries[1].lpstrFormatName = "Outline Data";
  2285. lpOleApp->m_arrPasteEntries[1].lpstrResultText = "Outline Data";
  2286. lpOleApp->m_arrPasteEntries[1].dwFlags = OLEUIPASTE_PASTEONLY;
  2287. lpOleApp->m_arrPasteEntries[2].fmtetc.cfFormat =
  2288. lpOleApp->m_cfEmbeddedObject;
  2289. lpOleApp->m_arrPasteEntries[2].fmtetc.ptd = NULL;
  2290. lpOleApp->m_arrPasteEntries[2].fmtetc.dwAspect = DVASPECT_CONTENT;
  2291. lpOleApp->m_arrPasteEntries[2].fmtetc.tymed = TYMED_ISTORAGE;
  2292. lpOleApp->m_arrPasteEntries[2].fmtetc.lindex = -1;
  2293. lpOleApp->m_arrPasteEntries[2].lpstrFormatName = "%s";
  2294. lpOleApp->m_arrPasteEntries[2].lpstrResultText = "%s";
  2295. lpOleApp->m_arrPasteEntries[2].dwFlags =
  2296. OLEUIPASTE_PASTE | OLEUIPASTE_ENABLEICON;
  2297. lpOleApp->m_arrPasteEntries[3].fmtetc.cfFormat = CF_TEXT;
  2298. lpOleApp->m_arrPasteEntries[3].fmtetc.ptd = NULL;
  2299. lpOleApp->m_arrPasteEntries[3].fmtetc.dwAspect = DVASPECT_CONTENT;
  2300. lpOleApp->m_arrPasteEntries[3].fmtetc.tymed = TYMED_HGLOBAL;
  2301. lpOleApp->m_arrPasteEntries[3].fmtetc.lindex = -1;
  2302. lpOleApp->m_arrPasteEntries[3].lpstrFormatName = "Text";
  2303. lpOleApp->m_arrPasteEntries[3].lpstrResultText = "text";
  2304. lpOleApp->m_arrPasteEntries[3].dwFlags = OLEUIPASTE_PASTEONLY;
  2305. lpOleApp->m_arrPasteEntries[4].fmtetc.cfFormat = CF_METAFILEPICT;
  2306. lpOleApp->m_arrPasteEntries[4].fmtetc.ptd = NULL;
  2307. lpOleApp->m_arrPasteEntries[4].fmtetc.dwAspect = DVASPECT_CONTENT;
  2308. lpOleApp->m_arrPasteEntries[4].fmtetc.tymed = TYMED_MFPICT;
  2309. lpOleApp->m_arrPasteEntries[4].fmtetc.lindex = -1;
  2310. lpOleApp->m_arrPasteEntries[4].lpstrFormatName = "Picture (Metafile)";
  2311. lpOleApp->m_arrPasteEntries[4].lpstrResultText = "a static picture";
  2312. lpOleApp->m_arrPasteEntries[4].dwFlags = OLEUIPASTE_PASTEONLY;
  2313. lpOleApp->m_arrPasteEntries[5].fmtetc.cfFormat = CF_DIB;
  2314. lpOleApp->m_arrPasteEntries[5].fmtetc.ptd = NULL;
  2315. lpOleApp->m_arrPasteEntries[5].fmtetc.dwAspect = DVASPECT_CONTENT;
  2316. lpOleApp->m_arrPasteEntries[5].fmtetc.tymed = TYMED_HGLOBAL;
  2317. lpOleApp->m_arrPasteEntries[5].fmtetc.lindex = -1;
  2318. lpOleApp->m_arrPasteEntries[5].lpstrFormatName = "Picture (DIB)";
  2319. lpOleApp->m_arrPasteEntries[5].lpstrResultText = "a static picture";
  2320. lpOleApp->m_arrPasteEntries[5].dwFlags = OLEUIPASTE_PASTEONLY;
  2321. lpOleApp->m_arrPasteEntries[6].fmtetc.cfFormat = CF_BITMAP;
  2322. lpOleApp->m_arrPasteEntries[6].fmtetc.ptd = NULL;
  2323. lpOleApp->m_arrPasteEntries[6].fmtetc.dwAspect = DVASPECT_CONTENT;
  2324. lpOleApp->m_arrPasteEntries[6].fmtetc.tymed = TYMED_GDI;
  2325. lpOleApp->m_arrPasteEntries[6].fmtetc.lindex = -1;
  2326. lpOleApp->m_arrPasteEntries[6].lpstrFormatName = "Picture (Bitmap)";
  2327. lpOleApp->m_arrPasteEntries[6].lpstrResultText = "a static picture";
  2328. lpOleApp->m_arrPasteEntries[6].dwFlags = OLEUIPASTE_PASTEONLY;
  2329. lpOleApp->m_arrPasteEntries[7].fmtetc.cfFormat = lpOleApp->m_cfLinkSource;
  2330. lpOleApp->m_arrPasteEntries[7].fmtetc.ptd = NULL;
  2331. lpOleApp->m_arrPasteEntries[7].fmtetc.dwAspect = DVASPECT_CONTENT;
  2332. lpOleApp->m_arrPasteEntries[7].fmtetc.tymed = TYMED_ISTREAM;
  2333. lpOleApp->m_arrPasteEntries[7].fmtetc.lindex = -1;
  2334. lpOleApp->m_arrPasteEntries[7].lpstrFormatName = "%s";
  2335. lpOleApp->m_arrPasteEntries[7].lpstrResultText = "%s";
  2336. lpOleApp->m_arrPasteEntries[7].dwFlags =
  2337. OLEUIPASTE_LINKTYPE1 | OLEUIPASTE_ENABLEICON;
  2338. lpOleApp->m_nPasteEntries = 8;
  2339. /* m_arrLinkTypes array enumerates the link types that a ContainerDoc
  2340. ** object can accept from the clipboard
  2341. */
  2342. lpOleApp->m_arrLinkTypes[0] = lpOleApp->m_cfLinkSource;
  2343. lpOleApp->m_nLinkTypes = 1;
  2344. return TRUE;
  2345. }
  2346. /* ContainerApp_InitVtbls
  2347. ** ----------------------
  2348. **
  2349. ** initialize the interface Vtbl's used to support the OLE 2.0
  2350. ** Container functionality.
  2351. */
  2352. BOOL ContainerApp_InitVtbls(LPCONTAINERAPP lpApp)
  2353. {
  2354. BOOL fStatus;
  2355. // ContainerDoc::IOleUILinkContainer method table
  2356. OleStdInitVtbl(
  2357. &g_CntrDoc_OleUILinkContainerVtbl,
  2358. sizeof(IOleUILinkContainerVtbl)
  2359. );
  2360. g_CntrDoc_OleUILinkContainerVtbl.QueryInterface =
  2361. CntrDoc_LinkCont_QueryInterface;
  2362. g_CntrDoc_OleUILinkContainerVtbl.AddRef = CntrDoc_LinkCont_AddRef;
  2363. g_CntrDoc_OleUILinkContainerVtbl.Release = CntrDoc_LinkCont_Release;
  2364. g_CntrDoc_OleUILinkContainerVtbl.GetNextLink =
  2365. CntrDoc_LinkCont_GetNextLink;
  2366. g_CntrDoc_OleUILinkContainerVtbl.SetLinkUpdateOptions =
  2367. CntrDoc_LinkCont_SetLinkUpdateOptions;
  2368. g_CntrDoc_OleUILinkContainerVtbl.GetLinkUpdateOptions =
  2369. CntrDoc_LinkCont_GetLinkUpdateOptions;
  2370. g_CntrDoc_OleUILinkContainerVtbl.SetLinkSource =
  2371. CntrDoc_LinkCont_SetLinkSource;
  2372. g_CntrDoc_OleUILinkContainerVtbl.GetLinkSource =
  2373. CntrDoc_LinkCont_GetLinkSource;
  2374. g_CntrDoc_OleUILinkContainerVtbl.OpenLinkSource =
  2375. CntrDoc_LinkCont_OpenLinkSource;
  2376. g_CntrDoc_OleUILinkContainerVtbl.UpdateLink =
  2377. CntrDoc_LinkCont_UpdateLink;
  2378. g_CntrDoc_OleUILinkContainerVtbl.CancelLink =
  2379. CntrDoc_LinkCont_CancelLink;
  2380. fStatus = OleStdCheckVtbl(
  2381. &g_CntrDoc_OleUILinkContainerVtbl,
  2382. sizeof(IOleUILinkContainerVtbl),
  2383. "IOleUILinkContainer"
  2384. );
  2385. if (! fStatus) return FALSE;
  2386. #if defined( INPLACE_CNTR )
  2387. // ContainerApp::IOleInPlaceFrame interface method table
  2388. OleStdInitVtbl(
  2389. &g_CntrApp_OleInPlaceFrameVtbl,
  2390. sizeof(g_CntrApp_OleInPlaceFrameVtbl)
  2391. );
  2392. g_CntrApp_OleInPlaceFrameVtbl.QueryInterface
  2393. = CntrApp_IPFrame_QueryInterface;
  2394. g_CntrApp_OleInPlaceFrameVtbl.AddRef
  2395. = CntrApp_IPFrame_AddRef;
  2396. g_CntrApp_OleInPlaceFrameVtbl.Release
  2397. = CntrApp_IPFrame_Release;
  2398. g_CntrApp_OleInPlaceFrameVtbl.GetWindow
  2399. = CntrApp_IPFrame_GetWindow;
  2400. g_CntrApp_OleInPlaceFrameVtbl.ContextSensitiveHelp
  2401. = CntrApp_IPFrame_ContextSensitiveHelp;
  2402. g_CntrApp_OleInPlaceFrameVtbl.GetBorder
  2403. = CntrApp_IPFrame_GetBorder;
  2404. g_CntrApp_OleInPlaceFrameVtbl.RequestBorderSpace
  2405. = CntrApp_IPFrame_RequestBorderSpace;
  2406. g_CntrApp_OleInPlaceFrameVtbl.SetBorderSpace
  2407. = CntrApp_IPFrame_SetBorderSpace;
  2408. g_CntrApp_OleInPlaceFrameVtbl.SetActiveObject
  2409. = CntrApp_IPFrame_SetActiveObject;
  2410. g_CntrApp_OleInPlaceFrameVtbl.InsertMenus
  2411. = CntrApp_IPFrame_InsertMenus;
  2412. g_CntrApp_OleInPlaceFrameVtbl.SetMenu
  2413. = CntrApp_IPFrame_SetMenu;
  2414. g_CntrApp_OleInPlaceFrameVtbl.RemoveMenus
  2415. = CntrApp_IPFrame_RemoveMenus;
  2416. g_CntrApp_OleInPlaceFrameVtbl.SetStatusText
  2417. = CntrApp_IPFrame_SetStatusText;
  2418. g_CntrApp_OleInPlaceFrameVtbl.EnableModeless
  2419. = CntrApp_IPFrame_EnableModeless;
  2420. g_CntrApp_OleInPlaceFrameVtbl.TranslateAccelerator
  2421. = CntrApp_IPFrame_TranslateAccelerator;
  2422. fStatus = OleStdCheckVtbl(
  2423. &g_CntrApp_OleInPlaceFrameVtbl,
  2424. sizeof(g_CntrApp_OleInPlaceFrameVtbl),
  2425. "IOleInPlaceFrame"
  2426. );
  2427. if (! fStatus) return FALSE;
  2428. #endif // INPLACE_CNTR
  2429. // ContainerLine::IUnknown interface method table
  2430. OleStdInitVtbl(
  2431. &g_CntrLine_UnknownVtbl,
  2432. sizeof(g_CntrLine_UnknownVtbl)
  2433. );
  2434. g_CntrLine_UnknownVtbl.QueryInterface = CntrLine_Unk_QueryInterface;
  2435. g_CntrLine_UnknownVtbl.AddRef = CntrLine_Unk_AddRef;
  2436. g_CntrLine_UnknownVtbl.Release = CntrLine_Unk_Release;
  2437. fStatus = OleStdCheckVtbl(
  2438. &g_CntrLine_UnknownVtbl,
  2439. sizeof(g_CntrLine_UnknownVtbl),
  2440. "IUnknown"
  2441. );
  2442. if (! fStatus) return FALSE;
  2443. // ContainerLine::IOleClientSite interface method table
  2444. OleStdInitVtbl(
  2445. &g_CntrLine_OleClientSiteVtbl,
  2446. sizeof(g_CntrLine_OleClientSiteVtbl)
  2447. );
  2448. g_CntrLine_OleClientSiteVtbl.QueryInterface =
  2449. CntrLine_CliSite_QueryInterface;
  2450. g_CntrLine_OleClientSiteVtbl.AddRef = CntrLine_CliSite_AddRef;
  2451. g_CntrLine_OleClientSiteVtbl.Release = CntrLine_CliSite_Release;
  2452. g_CntrLine_OleClientSiteVtbl.SaveObject = CntrLine_CliSite_SaveObject;
  2453. g_CntrLine_OleClientSiteVtbl.GetMoniker = CntrLine_CliSite_GetMoniker;
  2454. g_CntrLine_OleClientSiteVtbl.GetContainer = CntrLine_CliSite_GetContainer;
  2455. g_CntrLine_OleClientSiteVtbl.ShowObject = CntrLine_CliSite_ShowObject;
  2456. g_CntrLine_OleClientSiteVtbl.OnShowWindow = CntrLine_CliSite_OnShowWindow;
  2457. g_CntrLine_OleClientSiteVtbl.RequestNewObjectLayout =
  2458. CntrLine_CliSite_RequestNewObjectLayout;
  2459. fStatus = OleStdCheckVtbl(
  2460. &g_CntrLine_OleClientSiteVtbl,
  2461. sizeof(g_CntrLine_OleClientSiteVtbl),
  2462. "IOleClientSite"
  2463. );
  2464. if (! fStatus) return FALSE;
  2465. // ContainerLine::IAdviseSink interface method table
  2466. OleStdInitVtbl(
  2467. &g_CntrLine_AdviseSinkVtbl,
  2468. sizeof(g_CntrLine_AdviseSinkVtbl)
  2469. );
  2470. g_CntrLine_AdviseSinkVtbl.QueryInterface= CntrLine_AdvSink_QueryInterface;
  2471. g_CntrLine_AdviseSinkVtbl.AddRef = CntrLine_AdvSink_AddRef;
  2472. g_CntrLine_AdviseSinkVtbl.Release = CntrLine_AdvSink_Release;
  2473. g_CntrLine_AdviseSinkVtbl.OnDataChange = CntrLine_AdvSink_OnDataChange;
  2474. g_CntrLine_AdviseSinkVtbl.OnViewChange = CntrLine_AdvSink_OnViewChange;
  2475. g_CntrLine_AdviseSinkVtbl.OnRename = CntrLine_AdvSink_OnRename;
  2476. g_CntrLine_AdviseSinkVtbl.OnSave = CntrLine_AdvSink_OnSave;
  2477. g_CntrLine_AdviseSinkVtbl.OnClose = CntrLine_AdvSink_OnClose;
  2478. fStatus = OleStdCheckVtbl(
  2479. &g_CntrLine_AdviseSinkVtbl,
  2480. sizeof(g_CntrLine_AdviseSinkVtbl),
  2481. "IAdviseSink"
  2482. );
  2483. if (! fStatus) return FALSE;
  2484. #if defined( INPLACE_CNTR )
  2485. // ContainerLine::IOleInPlaceSite interface method table
  2486. OleStdInitVtbl(
  2487. &g_CntrLine_OleInPlaceSiteVtbl,
  2488. sizeof(g_CntrLine_OleInPlaceSiteVtbl)
  2489. );
  2490. g_CntrLine_OleInPlaceSiteVtbl.QueryInterface
  2491. = CntrLine_IPSite_QueryInterface;
  2492. g_CntrLine_OleInPlaceSiteVtbl.AddRef
  2493. = CntrLine_IPSite_AddRef;
  2494. g_CntrLine_OleInPlaceSiteVtbl.Release
  2495. = CntrLine_IPSite_Release;
  2496. g_CntrLine_OleInPlaceSiteVtbl.GetWindow
  2497. = CntrLine_IPSite_GetWindow;
  2498. g_CntrLine_OleInPlaceSiteVtbl.ContextSensitiveHelp
  2499. = CntrLine_IPSite_ContextSensitiveHelp;
  2500. g_CntrLine_OleInPlaceSiteVtbl.CanInPlaceActivate
  2501. = CntrLine_IPSite_CanInPlaceActivate;
  2502. g_CntrLine_OleInPlaceSiteVtbl.OnInPlaceActivate
  2503. = CntrLine_IPSite_OnInPlaceActivate;
  2504. g_CntrLine_OleInPlaceSiteVtbl.OnUIActivate
  2505. = CntrLine_IPSite_OnUIActivate;
  2506. g_CntrLine_OleInPlaceSiteVtbl.GetWindowContext
  2507. = CntrLine_IPSite_GetWindowContext;
  2508. g_CntrLine_OleInPlaceSiteVtbl.Scroll
  2509. = CntrLine_IPSite_Scroll;
  2510. g_CntrLine_OleInPlaceSiteVtbl.OnUIDeactivate
  2511. = CntrLine_IPSite_OnUIDeactivate;
  2512. g_CntrLine_OleInPlaceSiteVtbl.OnInPlaceDeactivate
  2513. = CntrLine_IPSite_OnInPlaceDeactivate;
  2514. g_CntrLine_OleInPlaceSiteVtbl.DiscardUndoState
  2515. = CntrLine_IPSite_DiscardUndoState;
  2516. g_CntrLine_OleInPlaceSiteVtbl.DeactivateAndUndo
  2517. = CntrLine_IPSite_DeactivateAndUndo;
  2518. g_CntrLine_OleInPlaceSiteVtbl.OnPosRectChange
  2519. = CntrLine_IPSite_OnPosRectChange;
  2520. fStatus = OleStdCheckVtbl(
  2521. &g_CntrLine_OleInPlaceSiteVtbl,
  2522. sizeof(g_CntrLine_OleInPlaceSiteVtbl),
  2523. "IOleInPlaceSite"
  2524. );
  2525. if (! fStatus) return FALSE;
  2526. #endif // INPLACE_CNTR
  2527. return TRUE;
  2528. }
  2529. #endif // OLE_CNTR