summaryrefslogtreecommitdiffstats
path: root/private/oleutest/letest/outline/oleapp.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/oleutest/letest/outline/oleapp.c')
-rw-r--r--private/oleutest/letest/outline/oleapp.c2989
1 files changed, 2989 insertions, 0 deletions
diff --git a/private/oleutest/letest/outline/oleapp.c b/private/oleutest/letest/outline/oleapp.c
new file mode 100644
index 000000000..0f355307b
--- /dev/null
+++ b/private/oleutest/letest/outline/oleapp.c
@@ -0,0 +1,2989 @@
+/*************************************************************************
+**
+** OLE 2 Sample Code
+**
+** oleapp.c
+**
+** This file contains functions and methods that are common to
+** server and the client version of the app. This includes the class
+** factory methods and all OleApp functions.
+**
+** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
+**
+*************************************************************************/
+
+#include "outline.h"
+#include <ole2ver.h>
+
+OLEDBGDATA
+
+extern LPOUTLINEAPP g_lpApp;
+
+extern IUnknownVtbl g_OleApp_UnknownVtbl;
+
+extern IUnknownVtbl g_OleDoc_UnknownVtbl;
+extern IPersistFileVtbl g_OleDoc_PersistFileVtbl;
+extern IOleItemContainerVtbl g_OleDoc_OleItemContainerVtbl;
+extern IExternalConnectionVtbl g_OleDoc_ExternalConnectionVtbl;
+extern IDataObjectVtbl g_OleDoc_DataObjectVtbl;
+
+#if defined( USE_DRAGDROP )
+extern IDropTargetVtbl g_OleDoc_DropTargetVtbl;
+extern IDropSourceVtbl g_OleDoc_DropSourceVtbl;
+#endif // USE_DRAGDROP
+
+#if defined( OLE_SERVER )
+extern IOleObjectVtbl g_SvrDoc_OleObjectVtbl;
+extern IPersistStorageVtbl g_SvrDoc_PersistStorageVtbl;
+
+#if defined( SVR_TREATAS )
+extern IStdMarshalInfoVtbl g_SvrDoc_StdMarshalInfoVtbl;
+#endif // SVR_TREATAS
+
+extern IUnknownVtbl g_PseudoObj_UnknownVtbl;
+extern IOleObjectVtbl g_PseudoObj_OleObjectVtbl;
+extern IDataObjectVtbl g_PseudoObj_DataObjectVtbl;
+
+#if defined( INPLACE_SVR )
+extern IOleInPlaceObjectVtbl g_SvrDoc_OleInPlaceObjectVtbl;
+extern IOleInPlaceActiveObjectVtbl g_SvrDoc_OleInPlaceActiveObjectVtbl;
+#endif // INPLACE_SVR
+
+#endif // OLE_SERVER
+
+#if defined( OLE_CNTR )
+
+extern IOleUILinkContainerVtbl g_CntrDoc_OleUILinkContainerVtbl;
+extern IUnknownVtbl g_CntrLine_UnknownVtbl;
+extern IOleClientSiteVtbl g_CntrLine_OleClientSiteVtbl;
+extern IAdviseSinkVtbl g_CntrLine_AdviseSinkVtbl;
+
+#if defined( INPLACE_CNTR )
+extern IOleInPlaceSiteVtbl g_CntrLine_OleInPlaceSiteVtbl;
+extern IOleInPlaceFrameVtbl g_CntrApp_OleInPlaceFrameVtbl;
+extern BOOL g_fInsideOutContainer;
+#endif // INPLACE_CNTR
+
+#endif // OLE_CNTR
+
+// REVIEW: these are NOT useful end-user messages
+static char ErrMsgCreateCF[] = "Can't create Class Factory!";
+static char ErrMsgRegCF[] = "Can't register Class Factory!";
+static char ErrMsgRegMF[] = "Can't register Message Filter!";
+
+extern UINT g_uMsgHelp;
+
+
+/* OleApp_InitInstance
+ * -------------------
+ *
+ * Initialize the app instance by creating the main frame window and
+ * performing app instance specific initializations
+ * (eg. initializing interface Vtbls).
+ *
+ * RETURNS: TRUE if the memory could be allocated, and the server app
+ * was properly initialized.
+ * FALSE otherwise
+ *
+ */
+BOOL OleApp_InitInstance(LPOLEAPP lpOleApp, HINSTANCE hInst, int nCmdShow)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+ HRESULT hrErr;
+ DWORD dwBuildVersion = OleBuildVersion();
+ LPMALLOC lpMalloc = NULL;
+
+ OLEDBG_BEGIN3("OleApp_InitInstance\r\n")
+
+ lpOleApp->m_fOleInitialized = FALSE;
+
+ /* OLE2NOTE: check if the build version of the OLE2 DLL's match
+ ** what our application is expecting.
+ */
+ if (HIWORD(dwBuildVersion) != rmm || LOWORD(dwBuildVersion) < rup) {
+ OleDbgAssertSz(0, "ERROR: OLE 2.0 DLL's are NOT compatible!");
+
+#if !defined( _DEBUG )
+ return FALSE; // Wrong version of DLL's
+#endif
+ }
+
+#if defined( _DEBUG )
+ /* OLE2NOTE: Use a special debug allocator to help track down
+ ** memory leaks.
+ */
+ OleStdCreateDbAlloc(0, &lpMalloc);
+#endif
+ /* OLE2NOTE: the OLE libraries must be properly initialized before
+ ** making any calls. OleInitialize automatically calls
+ ** CoInitialize. we will use the default task memory allocator
+ ** therefore we pass NULL to OleInitialize.
+ */
+ OLEDBG_BEGIN2("OleInitialize called\r\n")
+ hrErr = OleInitialize(lpMalloc);
+
+ if (FAILED(hrErr))
+ {
+ // Replacing the allocator may not be legal - try initializing
+ // without overriding the allocator
+ hrErr = OleInitialize(NULL);
+ }
+
+ OLEDBG_END2
+
+#if defined( _DEBUG )
+ /* OLE2NOTE: release the special debug allocator so that only OLE is
+ ** holding on to it. later when OleUninitialize is called, then
+ ** the debug allocator object will be destroyed. when the debug
+ ** allocator object is destoyed, it will report (to the Output
+ ** Debug Terminal) whether there are any memory leaks.
+ */
+ if (lpMalloc) lpMalloc->lpVtbl->Release(lpMalloc);
+#endif
+
+ if (hrErr != NOERROR) {
+ OutlineApp_ErrorMessage(lpOutlineApp,"OLE initialization failed!");
+ goto error;
+ }
+
+ /*****************************************************************
+ ** OLE2NOTE: we must remember the fact that OleInitialize has
+ ** been call successfully. the very last thing an app must
+ ** be do is properly shut down OLE by calling
+ ** OleUninitialize. This call MUST be guarded! it is only
+ ** allowable to call OleUninitialize if OleInitialize has
+ ** been called SUCCESSFULLY.
+ *****************************************************************/
+
+ lpOleApp->m_fOleInitialized = TRUE;
+
+ // Initialize the OLE 2.0 interface method tables.
+ if (! OleApp_InitVtbls(lpOleApp))
+ goto error;
+
+ // Register OLE 2.0 clipboard formats.
+ lpOleApp->m_cfEmbedSource = RegisterClipboardFormat(CF_EMBEDSOURCE);
+ lpOleApp->m_cfEmbeddedObject = RegisterClipboardFormat(
+ CF_EMBEDDEDOBJECT
+ );
+ lpOleApp->m_cfLinkSource = RegisterClipboardFormat(CF_LINKSOURCE);
+ lpOleApp->m_cfFileName = RegisterClipboardFormat(CF_FILENAME);
+ lpOleApp->m_cfObjectDescriptor =
+ RegisterClipboardFormat(CF_OBJECTDESCRIPTOR);
+ lpOleApp->m_cfLinkSrcDescriptor =
+ RegisterClipboardFormat(CF_LINKSRCDESCRIPTOR);
+
+ lpOleApp->m_cRef = 0;
+ lpOleApp->m_cDoc = 0;
+ lpOleApp->m_fUserCtrl = FALSE;
+ lpOleApp->m_dwRegClassFac = 0;
+ lpOleApp->m_lpClassFactory = NULL;
+ lpOleApp->m_cModalDlgActive = 0;
+
+ INIT_INTERFACEIMPL(
+ &lpOleApp->m_Unknown,
+ &g_OleApp_UnknownVtbl,
+ lpOleApp
+ );
+
+#if defined( USE_DRAGDROP )
+
+ // delay before dragging should start, in milliseconds
+ lpOleApp->m_nDragDelay = GetProfileInt(
+ "windows",
+ "DragDelay",
+ DD_DEFDRAGDELAY
+ );
+
+ // minimum distance (radius) before drag should start, in pixels
+ lpOleApp->m_nDragMinDist = GetProfileInt(
+ "windows",
+ "DragMinDist",
+ DD_DEFDRAGMINDIST
+ );
+
+ // delay before scrolling, in milliseconds
+ lpOleApp->m_nScrollDelay = GetProfileInt(
+ "windows",
+ "DragScrollDelay",
+ DD_DEFSCROLLDELAY
+ );
+
+ // inset-width of the hot zone, in pixels
+ lpOleApp->m_nScrollInset = GetProfileInt(
+ "windows",
+ "DragScrollInset",
+ DD_DEFSCROLLINSET
+ );
+
+ // scroll interval, in milliseconds
+ lpOleApp->m_nScrollInterval = GetProfileInt(
+ "windows",
+ "DragScrollInterval",
+ DD_DEFSCROLLINTERVAL
+ );
+
+#if defined( IF_SPECIAL_DD_CURSORS_NEEDED )
+ // This would be used if the app wanted to have custom drag/drop cursors
+ lpOleApp->m_hcursorDragNone = LoadCursor ( hInst, "DragNoneCur" );
+ lpOleApp->m_hcursorDragCopy = LoadCursor ( hInst, "DragCopyCur" );
+ lpOleApp->m_hcursorDragMove = LoadCursor ( hInst, "DragMoveCur" );
+ lpOleApp->m_hcursorDragLink = LoadCursor ( hInst, "DragLinkCur" );
+#endif // IF_SPECIAL_DD_CURSORS_NEEDED
+
+#endif // USE_DRAGDROP
+
+ lpOleApp->m_lpMsgFilter = NULL;
+
+#if defined( USE_MSGFILTER )
+ /* OLE2NOTE: Register our message filter upon app startup. the
+ ** message filter is used to handle concurrency.
+ ** we will use a standard implementation of IMessageFilter that
+ ** is included as part of the OLE2UI library.
+ */
+ lpOleApp->m_lpMsgFilter = NULL;
+ if (! OleApp_RegisterMessageFilter(lpOleApp))
+ goto error;
+
+ /* OLE2NOTE: because our app is initially INVISIBLE, we must
+ ** DISABLE the busy dialog. we should NOT put up any dialogs if
+ ** our app is invisible. when our app window is made visible,
+ ** then the busy dialog will be enabled.
+ */
+ OleStdMsgFilter_EnableBusyDialog(lpOleApp->m_lpMsgFilter, FALSE);
+#endif // USE_MSGFILTER
+
+#if defined( OLE_SERVER )
+ /* OLE2NOTE: perform initialization specific for an OLE server */
+ if (! ServerApp_InitInstance((LPSERVERAPP)lpOutlineApp, hInst, nCmdShow))
+ goto error;
+#endif
+#if defined( OLE_CNTR )
+ /* OLE2NOTE: perform initialization specific for an OLE container */
+
+ // Register help message
+ g_uMsgHelp = RegisterWindowMessage(SZOLEUI_MSG_HELP);
+
+ if (! ContainerApp_InitInstance((LPCONTAINERAPP)lpOutlineApp, hInst, nCmdShow))
+ goto error;
+#endif
+
+#if defined( OLE_CNTR )
+ lpOleApp->m_hStdPal = OleStdCreateStandardPalette();
+#endif
+
+ OLEDBG_END3
+ return TRUE;
+
+error:
+ OLEDBG_END3
+ return FALSE;
+}
+
+
+/*
+ * OleApp_TerminateApplication
+ * ---------------------------
+ * Perform proper OLE application cleanup before shutting down
+ */
+void OleApp_TerminateApplication(LPOLEAPP lpOleApp)
+{
+ OLEDBG_BEGIN3("OleApp_TerminateApplication\r\n")
+
+ /* OLE2NOTE: perform a clean shut down for OLE. at this point our
+ ** App refcnt should be 0, or else we should never have reached
+ ** this point!
+ */
+ OleDbgAssertSz(lpOleApp->m_cRef == 0, "App NOT shut down properly");
+
+ if(lpOleApp->m_fOleInitialized) {
+ OLEDBG_BEGIN2("OleUninitialize called\r\n")
+ OleUninitialize();
+ OLEDBG_END2
+ }
+ OLEDBG_END3
+}
+
+
+/* OleApp_ParseCmdLine
+ * -------------------
+ *
+ * Parse the command line for any execution flags/arguments.
+ * OLE2NOTE: check if "-Embedding" switch is given.
+ */
+BOOL OleApp_ParseCmdLine(LPOLEAPP lpOleApp, LPSTR lpszCmdLine, int nCmdShow)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+ char szFileName[256]; /* buffer for filename in command line */
+ BOOL fStatus = TRUE;
+ BOOL fEmbedding = FALSE;
+
+ OLEDBG_BEGIN3("OleApp_ParseCmdLine\r\n")
+
+ szFileName[0] = '\0';
+ ParseCmdLine(lpszCmdLine, &fEmbedding, (LPSTR)szFileName);
+
+#if defined( MDI_VERSION )
+ /* OLE2NOTE: an MDI app would ALWAYS register its ClassFactory. it
+ ** can handle multiple objects at the same time, while an SDI
+ ** application can only handle a single embedded or file-based
+ ** object at a time.
+ */
+ fStatus = OleApp_RegisterClassFactory(lpOleApp);
+#endif
+
+ if(fEmbedding) {
+
+ if (szFileName[0] == '\0') {
+
+ /*****************************************************************
+ ** App was launched with /Embedding.
+ ** We must register our ClassFactory with OLE, remain hidden
+ ** (the app window is initially created not visible), and
+ ** wait for OLE to call IClassFactory::CreateInstance
+ ** method. We do not automatically create a document as we
+ ** do when the app is launched by the user from the
+ ** FileManager. We must NOT make our app window visible
+ ** until told to do so by our container.
+ **
+ ** OLE2NOTE: Because we are an SDI app, we only register our
+ ** ClassFactory if we are launched with the /Embedding
+ ** flag WITHOUT a filename. an MDI app would ALWAYS
+ ** register its ClassFactory. it can handle multiple
+ ** objects at the same time, while an SDI application
+ ** can only handle a single embedded or file-based
+ ** object at a time.
+ *****************************************************************/
+
+#if defined( SDI_VERSION )
+ fStatus = OleApp_RegisterClassFactory(lpOleApp);
+#endif
+ } else {
+
+ /*****************************************************************
+ ** App was launched with /Embedding <Filename>.
+ ** We must create a document and load the file and
+ ** register it in the RunningObjectTable BEFORE we
+ ** enter our GetMessage loop (ie. before we yield).
+ ** One way to perform these tasks is to call the same
+ ** interface methods that OLE 2.0 calls for linking to a
+ ** file:
+ ** IClassFactory::CreateInstance
+ ** IPersistFile::Load
+ **
+ ** We must NOT make our app window visible until told to
+ ** do so by our container. An application will be
+ ** launched in this manner by an OLE 1.0 application
+ ** link situation (eg. double clicking a linked object
+ ** or OleCreateLinkFromFile called).
+ **
+ ** OLE2NOTE: Because we are an SDI app, we should NOT
+ ** register our ClassFactory when we are launched with the
+ ** /Embedding <Filename> flag. our SDI instance can only
+ ** handle a single embedded or file-based object.
+ ** an MDI app WOULD register its ClassFactory at all
+ ** times because it can handle multiple objects.
+ *****************************************************************/
+
+ // allocate a new document object
+ lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
+ if (! lpOutlineApp->m_lpDoc) {
+ OLEDBG_END3
+ return FALSE;
+ }
+
+ /* OLE2NOTE: initially the Doc object is created with a 0 ref
+ ** count. in order to have a stable Doc object during the
+ ** process of initializing the new Doc instance,
+ ** we intially AddRef the Doc ref cnt and later
+ ** Release it. This initial AddRef is artificial; it is simply
+ ** done to guarantee that a harmless QueryInterface followed by
+ ** a Release does not inadvertantly force our object to destroy
+ ** itself prematurely.
+ */
+ OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ /* OLE2NOTE: OutlineDoc_LoadFromFile will register our document
+ ** in the RunningObjectTable. this registration will
+ ** AddRef our document. therefore our document will not
+ ** be destroyed when we release the artificial AddRef
+ */
+ fStatus = OutlineDoc_LoadFromFile(
+ lpOutlineApp->m_lpDoc, (LPSTR)szFileName);
+
+ OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel AddRef
+
+ OLEDBG_END3
+ return fStatus;
+ }
+ } else {
+
+ /*****************************************************************
+ ** App was launched by the user (without /Embedding) and
+ ** therefore is marked to be under user control.
+ ** In this case, because we are an SDI app, we do NOT
+ ** register our ClassFactory with OLE. This app instance can
+ ** only manage one document at a time (either a user
+ ** document or an embedded object document). An MDI app
+ ** would register its ClassFactory here.
+ **
+ ** We must create a document for the user (either
+ ** initialized from a file given on the command line or
+ ** initialized as an untitled document. We must also make
+ ** our app window visible to the user.
+ *****************************************************************/
+
+ // allocate a new document object
+ lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
+ if (! lpOutlineApp->m_lpDoc) goto error;
+
+ /* OLE2NOTE: initially the Doc object is created with a 0 ref
+ ** count. in order to have a stable Doc object during the
+ ** process of initializing the new Doc instance,
+ ** we intially AddRef the Doc ref cnt and later
+ ** Release it. This initial AddRef is artificial; it is simply
+ ** done to guarantee that a harmless QueryInterface followed by
+ ** a Release does not inadvertantly force our object to destroy
+ ** itself prematurely.
+ */
+ OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ if(*szFileName) {
+ // initialize the document from the specified file
+ if (! OutlineDoc_LoadFromFile(lpOutlineApp->m_lpDoc, szFileName))
+ goto error;
+ } else {
+ // set the doc to an (Untitled) doc.
+ if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc))
+ goto error;
+ }
+
+ // position and size the new doc window
+ OutlineApp_ResizeWindows(lpOutlineApp);
+ OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc); // calls OleDoc_Lock
+ OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);// rel AddRef above
+
+ // show main app window
+ ShowWindow(lpOutlineApp->m_hWndApp, nCmdShow);
+ UpdateWindow(lpOutlineApp->m_hWndApp);
+
+#if defined( OLE_CNTR )
+ ContainerDoc_UpdateLinks((LPCONTAINERDOC)lpOutlineApp->m_lpDoc);
+#endif
+
+ }
+
+ OLEDBG_END3
+ return fStatus;
+
+error:
+ // REVIEW: should load string from string resource
+ OutlineApp_ErrorMessage(
+ lpOutlineApp,
+ "Could not create document--Out of Memory"
+ );
+ if (lpOutlineApp->m_lpDoc) // rel artificial AddRef above
+ OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ OLEDBG_END3
+ return FALSE;
+}
+
+
+/* OleApp_CloseAllDocsAndExitCommand
+ * ---------------------------------
+ *
+ * Close all active documents and exit the app.
+ * Because this is an SDI, there is only one document
+ * If the doc was modified, prompt the user if he wants to save it.
+ *
+ * Returns:
+ * TRUE if the app is successfully closed
+ * FALSE if failed or aborted
+ *
+ * OLE2NOTE: in the OLE version, we can NOT directly
+ * destroy the App object. we can only take all
+ * necessary actions to ensure that our object receives
+ * all of its Releases from clients holding onto
+ * pointers (eg. closing all docs and flushing the
+ * clipboard) and then we must hide our window and wait
+ * actually for our refcnt to reach 0. when it reaches 0,
+ * our destructor (OutlineApp_Destroy) will be called.
+ * each document addref's the app object in order to
+ * guarentee that the app does not shut down while the doc
+ * is still open. closing all docs, will release these
+ * refcnt's. if there are now more open documents AND the
+ * app is not under the control of the user (ie. launched by
+ * OLE) then the app will now shut down. the OleApp_Release
+ * function executes this shut down procedure. after closing
+ * all docs, then releasing the user refcnt will force the
+ * app to shut down.
+ */
+BOOL OleApp_CloseAllDocsAndExitCommand(
+ LPOLEAPP lpOleApp,
+ BOOL fForceEndSession
+)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+ DWORD dwSaveOption = (fForceEndSession ?
+ OLECLOSE_NOSAVE : OLECLOSE_PROMPTSAVE);
+
+ /* OLE2NOTE: in order to have a stable App object during the
+ ** process of closing, we intially AddRef the App ref cnt and
+ ** later Release it. This initial AddRef is artificial; it is
+ ** simply done to guarantee that our App object does not
+ ** destroy itself until the end of this routine.
+ */
+ OleApp_AddRef(lpOleApp);
+
+ /* Because this is an SDI app, there is only one document.
+ ** Close the doc. if it is successfully closed and the app will
+ ** not automatically exit, then also exit the app.
+ ** if this were an MDI app, we would loop through and close all
+ ** open MDI child documents.
+ */
+
+#if defined( OLE_SERVER )
+ if (!fForceEndSession &&
+ lpOutlineApp->m_lpDoc->m_docInitType == DOCTYPE_EMBEDDED)
+ dwSaveOption = OLECLOSE_SAVEIFDIRTY;
+#endif
+
+ if (! OutlineDoc_Close(lpOutlineApp->m_lpDoc, dwSaveOption)) {
+ OleApp_Release(lpOleApp);
+ return FALSE; // User Aborted shutdown
+ }
+#if defined( _DEBUG )
+ OleDbgAssertSz(
+ lpOutlineApp->m_lpDoc==NULL,
+ "Closed doc NOT properly destroyed"
+ );
+#endif
+
+#if defined( OLE_CNTR )
+ /* if we currently have data on the clipboard then we must tell
+ ** the clipboard to release our clipboard data object
+ ** (document)
+ */
+ if (lpOutlineApp->m_lpClipboardDoc)
+ OleApp_FlushClipboard(lpOleApp);
+#endif
+
+ OleApp_HideWindow(lpOleApp);
+
+ /* OLE2NOTE: this call forces all external connections to our
+ ** object to close down and therefore guarantees that we receive
+ ** all releases associated with those external connections.
+ */
+ OLEDBG_BEGIN2("CoDisconnectObject(lpApp) called\r\n")
+ CoDisconnectObject((LPUNKNOWN)&lpOleApp->m_Unknown, 0);
+ OLEDBG_END2
+
+ OleApp_Release(lpOleApp); // release artificial AddRef above
+
+ return TRUE;
+}
+
+
+/* OleApp_ShowWindow
+ * -----------------
+ *
+ * Show the window of the app to the user.
+ * make sure app window is visible and bring the app to the top.
+ * IF fGiveUserCtrl == TRUE
+ * THEN give the user the control over the life-time of the app.
+ */
+void OleApp_ShowWindow(LPOLEAPP lpOleApp, BOOL fGiveUserCtrl)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+
+ OLEDBG_BEGIN3("OleApp_ShowWindow\r\n")
+
+ /* OLE2NOTE: while the application is visible and under user
+ ** control, we do NOT want it to be prematurely destroyed when
+ ** the user closes a document. thus we must inform OLE to hold
+ ** an external lock on our application on behalf of the user.
+ ** this arranges that OLE holds at least 1 reference to our
+ ** application that will NOT be released until we release this
+ ** external lock. later, when the application window is hidden, we
+ ** will release this external lock.
+ */
+ if (fGiveUserCtrl && ! lpOleApp->m_fUserCtrl) {
+ lpOleApp->m_fUserCtrl = TRUE;
+ OleApp_Lock(lpOleApp, TRUE /* fLock */, 0 /* not applicable */);
+ }
+
+ // we must show our App window and force it to have input focus
+ ShowWindow(lpOutlineApp->m_hWndApp, SW_SHOWNORMAL);
+ SetFocus(lpOutlineApp->m_hWndApp);
+
+ /* OLE2NOTE: because our app is now visible, we can enable the busy
+ ** dialog. we should NOT put up any dialogs if our app is
+ ** invisible.
+ */
+ OleApp_EnableBusyDialogs(lpOleApp, TRUE, TRUE);
+
+ OLEDBG_END3
+}
+
+
+/* OleApp_HideWindow
+ * -----------------
+ *
+ * Hide the window of the app from the user.
+ * take away the control of the app by the user.
+ */
+void OleApp_HideWindow(LPOLEAPP lpOleApp)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+
+ OLEDBG_BEGIN3("OleApp_HideWindow\r\n")
+
+ /* OLE2NOTE: the application is now being hidden, so we must release
+ ** the external lock that was made on behalf of the user.
+ ** if this is that last external lock on our application, thus
+ ** enabling our application to complete its shutdown operation.
+ */
+ if (lpOleApp->m_fUserCtrl) {
+ lpOleApp->m_fUserCtrl = FALSE;
+ OleApp_Lock(lpOleApp, FALSE /*fLock*/, TRUE /*fLastUnlockReleases*/);
+ }
+
+ ShowWindow(lpOutlineApp->m_hWndApp, SW_HIDE);
+
+ /* OLE2NOTE: because our app is now INVISIBLE, we must DISABLE the busy
+ ** dialog. we should NOT put up any dialogs if our app is
+ ** invisible.
+ */
+ OleApp_EnableBusyDialogs(lpOleApp, FALSE, FALSE);
+ OLEDBG_END3
+}
+
+
+/* OleApp_Lock
+** -----------
+** Lock/Unlock the App object. if the last lock is unlocked and
+** fLastUnlockReleases == TRUE, then the app object will shut down
+** (ie. it will recieve its final release and its refcnt will go to 0).
+*/
+HRESULT OleApp_Lock(LPOLEAPP lpOleApp, BOOL fLock, BOOL fLastUnlockReleases)
+{
+ HRESULT hrErr;
+
+#if defined( _DEBUG )
+ if (fLock) {
+ OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,TRUE) called\r\n")
+ } else {
+ if (fLastUnlockReleases)
+ OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,FALSE,TRUE) called\r\n")
+ else
+ OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,FALSE,FALSE) called\r\n")
+ }
+#endif // _DEBUG
+
+ OleApp_AddRef(lpOleApp); // artificial AddRef to make object stable
+
+ hrErr = CoLockObjectExternal(
+ (LPUNKNOWN)&lpOleApp->m_Unknown, fLock, fLastUnlockReleases);
+
+ OleApp_Release(lpOleApp); // release artificial AddRef above
+
+ OLEDBG_END2
+ return hrErr;
+}
+
+
+/* OleApp_Destroy
+ * --------------
+ *
+ * Free all OLE related resources that had been allocated for the app.
+ */
+void OleApp_Destroy(LPOLEAPP lpOleApp)
+{
+ // OLE2NOTE: Revoke our message filter upon app shutdown.
+ OleApp_RevokeMessageFilter(lpOleApp);
+
+ // OLE2NOTE: Revoke our ClassFactory upon app shutdown.
+ OleApp_RevokeClassFactory(lpOleApp);
+
+#if defined( IF_SPECIAL_DD_CURSORS_NEEDED )
+ // This would be used if the app wanted to have custom drag/drop cursors
+ DestroyCursor(lpOleApp->m_hcursorDragNone);
+ DestroyCursor(lpOleApp->m_hcursorDragCopy);
+ DestroyCursor(lpOleApp->m_hcursorDragLink);
+ DestroyCursor(lpOleApp->m_hcursorDragMove);
+#endif // IF_SPECIAL_DD_CURSORS_NEEDED
+
+#if defined( OLE_CNTR )
+ if (lpOleApp->m_hStdPal) {
+ DeleteObject(lpOleApp->m_hStdPal);
+ lpOleApp->m_hStdPal = NULL;
+ }
+#endif
+}
+
+
+/* OleApp_DocLockApp
+** -----------------
+** Add a lock on the App on behalf of the Doc. the App may not close
+** while the Doc exists.
+**
+** when a document is first created, it calls this method to
+** guarantee that the application stays alive (OleDoc_Init).
+** when a document is destroyed, it calls
+** OleApp_DocUnlockApp to release this hold on the app.
+*/
+void OleApp_DocLockApp(LPOLEAPP lpOleApp)
+{
+ ULONG cDoc;
+
+ OLEDBG_BEGIN3("OleApp_DocLockApp\r\n")
+
+ cDoc = ++lpOleApp->m_cDoc;
+
+ OleDbgOutRefCnt3("OleApp_DocLockApp: cDoc++\r\n", lpOleApp, cDoc);
+
+ OleApp_Lock(lpOleApp, TRUE /* fLock */, 0 /* not applicable */);
+
+ OLEDBG_END3
+ return;
+}
+
+
+/* OleApp_DocUnlockApp
+** -------------------
+** Forget all references to a closed document.
+** Release the lock on the App on behalf of the Doc. if this was the
+** last lock on the app, then it will shutdown.
+*/
+void OleApp_DocUnlockApp(LPOLEAPP lpOleApp, LPOUTLINEDOC lpOutlineDoc)
+{
+ ULONG cDoc;
+
+ OLEDBG_BEGIN3("OleApp_DocUnlockApp\r\n")
+
+ /* OLE2NOTE: when there are no open documents and the app is not
+ ** under the control of the user then revoke our ClassFactory to
+ ** enable the app to shut down.
+ */
+ cDoc = --lpOleApp->m_cDoc;
+
+#if defined( _DEBUG )
+ OleDbgAssertSz (
+ lpOleApp->m_cDoc >= 0, "DocUnlockApp called with cDoc == 0");
+
+ OleDbgOutRefCnt3(
+ "OleApp_DocUnlockApp: cDoc--\r\n", lpOleApp, cDoc);
+#endif
+
+ OleApp_Lock(lpOleApp, FALSE /* fLock */, TRUE /* fLastUnlockReleases */);
+
+ OLEDBG_END3
+ return;
+}
+
+
+/* OleApp_HideIfNoReasonToStayVisible
+** ----------------------------------
+**
+** if there are no more documents visible to the user and the app
+** itself is not under user control, then it has no reason to stay
+** visible. we thus should hide the app. we can not directly destroy
+** the app, because it may be validly being used programatically by
+** another client application and should remain running. the app
+** should simply be hidden from the user.
+*/
+void OleApp_HideIfNoReasonToStayVisible(LPOLEAPP lpOleApp)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+ LPOUTLINEDOC lpOutlineDoc;
+
+ OLEDBG_BEGIN3("OleApp_HideIfNoReasonToStayVisible\r\n")
+
+ if (lpOleApp->m_fUserCtrl) {
+ OLEDBG_END3
+ return; // remain visible; user in control of app
+ }
+
+ /* Because this is an SDI app, there is only one user document.
+ ** check if it is visible to the user. an MDI app would loop over
+ ** all open MDI child documents to see if any are visible.
+ */
+ lpOutlineDoc = (LPOUTLINEDOC)lpOutlineApp->m_lpDoc;
+ if (lpOutlineDoc && IsWindowVisible(lpOutlineDoc->m_hWndDoc))
+ return; // remain visible; the doc is visible to the user
+
+ // if we reached here, the app should be hidden
+ OleApp_HideWindow(lpOleApp);
+
+ OLEDBG_END3
+}
+
+
+/* OleApp_AddRef
+** -------------
+**
+** increment the ref count of the App object.
+**
+** Returns the new ref count on the object
+*/
+ULONG OleApp_AddRef(LPOLEAPP lpOleApp)
+{
+ ++lpOleApp->m_cRef;
+
+#if defined( _DEBUG )
+ OleDbgOutRefCnt4(
+ "OleApp_AddRef: cRef++\r\n",
+ lpOleApp,
+ lpOleApp->m_cRef
+ );
+#endif
+ return lpOleApp->m_cRef;
+}
+
+
+/* OleApp_Release
+** --------------
+**
+** decrement the ref count of the App object.
+** if the ref count goes to 0, then the app object is destroyed.
+**
+** Returns the remaining ref count on the object
+*/
+ULONG OleApp_Release (LPOLEAPP lpOleApp)
+{
+ ULONG cRef;
+
+ cRef = --lpOleApp->m_cRef;
+
+#if defined( _DEBUG )
+ OleDbgAssertSz (lpOleApp->m_cRef >= 0, "Release called with cRef == 0");
+
+ OleDbgOutRefCnt4(
+ "OleApp_AddRef: cRef--\r\n", lpOleApp, cRef);
+#endif // _DEBUG
+ /*********************************************************************
+ ** OLE2NOTE: when the ClassFactory refcnt == 0, then destroy it. **
+ ** otherwise the ClassFactory is still in use. **
+ *********************************************************************/
+
+ if(cRef == 0)
+ OutlineApp_Destroy((LPOUTLINEAPP)lpOleApp);
+
+ return cRef;
+}
+
+
+
+/* OleApp_QueryInterface
+** ---------------------
+**
+** Retrieve a pointer to an interface on the app object.
+**
+** OLE2NOTE: this function will AddRef the ref cnt of the object.
+**
+** Returns NOERROR if interface is successfully retrieved.
+** E_NOINTERFACE if the interface is not supported
+*/
+HRESULT OleApp_QueryInterface (
+ LPOLEAPP lpOleApp,
+ REFIID riid,
+ LPVOID FAR* lplpvObj
+)
+{
+ SCODE sc;
+
+ /* OLE2NOTE: we must make sure to set all out ptr parameters to NULL. */
+ *lplpvObj = NULL;
+
+ if (IsEqualIID(riid, &IID_IUnknown)) {
+ OleDbgOut4("OleApp_QueryInterface: IUnknown* RETURNED\r\n");
+
+ *lplpvObj = (LPVOID) &lpOleApp->m_Unknown;
+ OleApp_AddRef(lpOleApp);
+ sc = S_OK;
+ }
+ else {
+ sc = E_NOINTERFACE;
+ }
+
+ OleDbgQueryInterfaceMethod(*lplpvObj);
+ return ResultFromScode(sc);
+}
+
+
+/* OleApp_RejectInComingCalls
+** -------------------------
+** Reject/Handle in coming OLE (LRPC) calls.
+**
+** OLE2NOTE: if the app is in a state when it can NOT handle in
+** coming OLE method calls from an external process (eg. the app has
+** an application modal dialog up), then it should call
+** OleApp_RejectInComingCalls(TRUE). in this state the
+** IMessageFilter::HandleInComingCall method will return
+** SERVERCALL_RETRYLATER. this tells the caller to try again in a
+** little while. normally the calling app will put up a dialog (see
+** OleUIBusy dialog) in this situation informing the user of the
+** situation. the user then is normally given the option to
+** "Switch To..." the busy application, retry, or cancel the
+** operation. when the app is ready to continue processing such
+** calls, it should call OleApp_RejectInComingCalls(FALSE). in this
+** state, SERVERCALL_ISHANDLED is returned by
+** IMessageFilter::HandleInComingCall.
+*/
+void OleApp_RejectInComingCalls(LPOLEAPP lpOleApp, BOOL fReject)
+{
+#if defined( _DEBUG )
+ if (fReject)
+ OleDbgOut3("OleApp_RejectInComingCalls(TRUE)\r\n");
+ else
+ OleDbgOut3("OleApp_RejectInComingCalls(FALSE)\r\n");
+#endif // _DEBUG
+
+ OleDbgAssert(lpOleApp->m_lpMsgFilter != NULL);
+ if (! lpOleApp->m_lpMsgFilter)
+ return;
+
+ OleStdMsgFilter_SetInComingCallStatus(
+ lpOleApp->m_lpMsgFilter,
+ (fReject ? SERVERCALL_RETRYLATER : SERVERCALL_ISHANDLED)
+ );
+}
+
+
+/* OleApp_DisableBusyDialogs
+** -------------------------
+** Disable the Busy and NotResponding dialogs.
+**
+** Returns previous enable state so that it can be restored by
+** calling OleApp_ReEnableBusyDialogs.
+*/
+void OleApp_DisableBusyDialogs(
+ LPOLEAPP lpOleApp,
+ BOOL FAR* lpfPrevBusyEnable,
+ BOOL FAR* lpfPrevNREnable
+)
+{
+ if (lpOleApp->m_lpMsgFilter) {
+ *lpfPrevNREnable = OleStdMsgFilter_EnableNotRespondingDialog(
+ lpOleApp->m_lpMsgFilter, FALSE);
+ *lpfPrevBusyEnable = OleStdMsgFilter_EnableBusyDialog(
+ lpOleApp->m_lpMsgFilter, FALSE);
+ }
+}
+
+
+/* OleApp_EnableBusyDialogs
+** ------------------------
+** Set the enable state of the Busy and NotResponding dialogs.
+**
+** This function is typically used after a call to
+** OleApp_DisableBusyDialogs in order to restore the previous enable
+** state of the dialogs.
+*/
+void OleApp_EnableBusyDialogs(
+ LPOLEAPP lpOleApp,
+ BOOL fPrevBusyEnable,
+ BOOL fPrevNREnable
+)
+{
+ if (lpOleApp->m_lpMsgFilter) {
+ OleStdMsgFilter_EnableNotRespondingDialog(
+ lpOleApp->m_lpMsgFilter, fPrevNREnable);
+ OleStdMsgFilter_EnableBusyDialog(
+ lpOleApp->m_lpMsgFilter, fPrevBusyEnable);
+ }
+}
+
+
+/* OleApp_PreModalDialog
+** ---------------------
+** Keep track that a modal dialog is about to be brought up.
+**
+** while a modal dialog is up we need to take special actions:
+** 1. we do NOT want to initialize our tool bar buttons on
+** WM_ACTIVATEAPP. the tool bar is not accessible.
+** 2. we want to reject new top-level, incoming LRPC calls
+** (return SERVERCALL_RETRYLATER from IMessageFilter::
+** HandleInComingCall).
+** 3. (IN-PLACE SERVER) tell our in-place container to disable
+** modeless dialogs by calling IOleInPlaceFrame::
+** EnableModeless(FALSE).
+** 4. (IN-PLACE CONTAINER) tell our UIActive in-place object to
+** disable modeless dialogs by calling IOleInPlaceActiveObject::
+** EnableModeless(FALSE).
+*/
+void OleApp_PreModalDialog(LPOLEAPP lpOleApp, LPOLEDOC lpOleDoc)
+{
+ if (lpOleApp->m_cModalDlgActive == 0) {
+ // top-level modal dialog is being brought up
+
+#if defined( USE_FRAMETOOLS )
+ LPFRAMETOOLS lptb;
+
+ if (lpOleDoc)
+ lptb = ((LPOUTLINEDOC)lpOleDoc)->m_lpFrameTools;
+ else
+ lptb = OutlineApp_GetFrameTools((LPOUTLINEAPP)lpOleApp);
+ if (lptb)
+ FrameTools_EnableWindow(lptb, FALSE);
+#endif // USE_FRAMETOOLS
+
+ OleApp_RejectInComingCalls(lpOleApp, TRUE);
+
+#if defined( INPLACE_SVR )
+ {
+ LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
+
+ /* if the document bringing up the modal dialog is
+ ** currently a UIActive in-place object, then tell the
+ ** top-level in-place frame to disable its modeless
+ ** dialogs.
+ */
+ if (lpServerDoc && lpServerDoc->m_fUIActive &&
+ lpServerDoc->m_lpIPData &&
+ lpServerDoc->m_lpIPData->lpFrame) {
+ OLEDBG_BEGIN2("IOleInPlaceFrame::EnableModless(FALSE) called\r\n");
+ lpServerDoc->m_lpIPData->lpFrame->lpVtbl->EnableModeless(
+ lpServerDoc->m_lpIPData->lpFrame, FALSE);
+ OLEDBG_END2
+ }
+ }
+#endif // INPLACE_SVR
+#if defined( INPLACE_CNTR )
+ {
+ LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp;
+
+ /* if the document bringing up the modal dialog is an
+ ** in-place container that has a UIActive object, then
+ ** tell the UIActive object to disable its modeless
+ ** dialogs.
+ */
+ if (lpContainerApp->m_lpIPActiveObj) {
+ OLEDBG_BEGIN2("IOleInPlaceActiveObject::EnableModless(FALSE) called\r\n");
+ lpContainerApp->m_lpIPActiveObj->lpVtbl->EnableModeless(
+ lpContainerApp->m_lpIPActiveObj, FALSE);
+ OLEDBG_END2
+ }
+ }
+#endif // INPLACE_CNTR
+ }
+
+ lpOleApp->m_cModalDlgActive++;
+}
+
+
+/* OleApp_PostModalDialog
+** ----------------------
+** Keep track that a modal dialog is being brought down. this call
+** balances the OleApp_PreModalDialog call.
+*/
+void OleApp_PostModalDialog(LPOLEAPP lpOleApp, LPOLEDOC lpOleDoc)
+{
+ lpOleApp->m_cModalDlgActive--;
+
+ if (lpOleApp->m_cModalDlgActive == 0) {
+ // last modal dialog is being brought down
+
+#if defined( USE_FRAMETOOLS )
+ LPFRAMETOOLS lptb;
+
+ if (lpOleDoc)
+ lptb = ((LPOUTLINEDOC)lpOleDoc)->m_lpFrameTools;
+ else
+ lptb = OutlineApp_GetFrameTools((LPOUTLINEAPP)lpOleApp);
+ if (lptb) {
+ FrameTools_EnableWindow(lptb, TRUE);
+ FrameTools_UpdateButtons(lptb, (LPOUTLINEDOC)lpOleDoc);
+ }
+#endif // USE_FRAMETOOLS
+
+ OleApp_RejectInComingCalls(lpOleApp, FALSE);
+
+#if defined( INPLACE_SVR )
+ {
+ LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
+
+ /* if the document bringing down the modal dialog is
+ ** currently a UIActive in-place object, then tell the
+ ** top-level in-place frame it can re-enable its
+ ** modeless dialogs.
+ */
+ if (lpServerDoc && lpServerDoc->m_fUIActive &&
+ lpServerDoc->m_lpIPData &&
+ lpServerDoc->m_lpIPData->lpFrame) {
+ OLEDBG_BEGIN2("IOleInPlaceFrame::EnableModless(TRUE) called\r\n");
+ lpServerDoc->m_lpIPData->lpFrame->lpVtbl->EnableModeless(
+ lpServerDoc->m_lpIPData->lpFrame, TRUE);
+ OLEDBG_END2
+ }
+ }
+#endif // INPLACE_SVR
+#if defined( INPLACE_CNTR )
+ {
+ LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp;
+
+ /* if the document bringing down the modal dialog is an
+ ** in-place container that has a UIActive object, then
+ ** tell the UIActive object it can re-enable its
+ ** modeless dialogs.
+ */
+ if (lpContainerApp->m_lpIPActiveObj) {
+ OLEDBG_BEGIN2("IOleInPlaceActiveObject::EnableModless(TRUE) called\r\n");
+ lpContainerApp->m_lpIPActiveObj->lpVtbl->EnableModeless(
+ lpContainerApp->m_lpIPActiveObj, TRUE);
+ OLEDBG_END2
+ }
+ }
+#endif // INPLACE_CNTR
+ }
+}
+
+
+/* OleApp_InitVtbls
+ * ----------------
+ *
+ * initialize the methods in all of the interface Vtbl's
+ *
+ * OLE2NOTE: we only need one copy of each Vtbl. When an object which
+ * exposes an interface is instantiated, its lpVtbl is intialized
+ * to point to the single copy of the Vtbl.
+ *
+ */
+BOOL OleApp_InitVtbls (LPOLEAPP lpOleApp)
+{
+ BOOL fStatus;
+
+ // OleApp::IUnknown method table
+ OleStdInitVtbl(&g_OleApp_UnknownVtbl, sizeof(IUnknownVtbl));
+ g_OleApp_UnknownVtbl.QueryInterface = OleApp_Unk_QueryInterface;
+ g_OleApp_UnknownVtbl.AddRef = OleApp_Unk_AddRef;
+ g_OleApp_UnknownVtbl.Release = OleApp_Unk_Release;
+ fStatus = OleStdCheckVtbl(
+ &g_OleApp_UnknownVtbl,
+ sizeof(IUnknownVtbl),
+ "IUnknown"
+ );
+ if (! fStatus) return FALSE;
+
+ // OleDoc::IUnknown method table
+ OleStdInitVtbl(&g_OleDoc_UnknownVtbl, sizeof(IUnknownVtbl));
+ g_OleDoc_UnknownVtbl.QueryInterface = OleDoc_Unk_QueryInterface;
+ g_OleDoc_UnknownVtbl.AddRef = OleDoc_Unk_AddRef;
+ g_OleDoc_UnknownVtbl.Release = OleDoc_Unk_Release;
+ fStatus = OleStdCheckVtbl(
+ &g_OleDoc_UnknownVtbl,
+ sizeof(IUnknownVtbl),
+ "IUnknown"
+ );
+ if (! fStatus) return FALSE;
+
+ // OleDoc::IPersistFile method table
+ OleStdInitVtbl(&g_OleDoc_PersistFileVtbl, sizeof(IPersistFileVtbl));
+ g_OleDoc_PersistFileVtbl.QueryInterface = OleDoc_PFile_QueryInterface;
+ g_OleDoc_PersistFileVtbl.AddRef = OleDoc_PFile_AddRef;
+ g_OleDoc_PersistFileVtbl.Release = OleDoc_PFile_Release;
+ g_OleDoc_PersistFileVtbl.GetClassID = OleDoc_PFile_GetClassID;
+ g_OleDoc_PersistFileVtbl.IsDirty = OleDoc_PFile_IsDirty;
+ g_OleDoc_PersistFileVtbl.Load = OleDoc_PFile_Load;
+ g_OleDoc_PersistFileVtbl.Save = OleDoc_PFile_Save;
+ g_OleDoc_PersistFileVtbl.SaveCompleted = OleDoc_PFile_SaveCompleted;
+ g_OleDoc_PersistFileVtbl.GetCurFile = OleDoc_PFile_GetCurFile;
+ fStatus = OleStdCheckVtbl(
+ &g_OleDoc_PersistFileVtbl,
+ sizeof(IPersistFileVtbl),
+ "IPersistFile"
+ );
+ if (! fStatus) return FALSE;
+
+ // OleDoc::IOleItemContainer method table
+ OleStdInitVtbl(&g_OleDoc_OleItemContainerVtbl, sizeof(IOleItemContainerVtbl));
+ g_OleDoc_OleItemContainerVtbl.QueryInterface =
+ OleDoc_ItemCont_QueryInterface;
+ g_OleDoc_OleItemContainerVtbl.AddRef = OleDoc_ItemCont_AddRef;
+ g_OleDoc_OleItemContainerVtbl.Release = OleDoc_ItemCont_Release;
+ g_OleDoc_OleItemContainerVtbl.ParseDisplayName =
+ OleDoc_ItemCont_ParseDisplayName;
+ g_OleDoc_OleItemContainerVtbl.EnumObjects= OleDoc_ItemCont_EnumObjects;
+ g_OleDoc_OleItemContainerVtbl.LockContainer =
+ OleDoc_ItemCont_LockContainer;
+ g_OleDoc_OleItemContainerVtbl.GetObject = OleDoc_ItemCont_GetObject;
+ g_OleDoc_OleItemContainerVtbl.GetObjectStorage =
+ OleDoc_ItemCont_GetObjectStorage;
+ g_OleDoc_OleItemContainerVtbl.IsRunning = OleDoc_ItemCont_IsRunning;
+ fStatus = OleStdCheckVtbl(
+ &g_OleDoc_OleItemContainerVtbl,
+ sizeof(IOleItemContainerVtbl),
+ "IOleItemContainer"
+ );
+ if (! fStatus) return FALSE;
+
+ // OleDoc::IExternalConnection method table
+ OleStdInitVtbl(
+ &g_OleDoc_ExternalConnectionVtbl,sizeof(IExternalConnectionVtbl));
+ g_OleDoc_ExternalConnectionVtbl.QueryInterface =
+ OleDoc_ExtConn_QueryInterface;
+ g_OleDoc_ExternalConnectionVtbl.AddRef = OleDoc_ExtConn_AddRef;
+ g_OleDoc_ExternalConnectionVtbl.Release = OleDoc_ExtConn_Release;
+ g_OleDoc_ExternalConnectionVtbl.AddConnection =
+ OleDoc_ExtConn_AddConnection;
+ g_OleDoc_ExternalConnectionVtbl.ReleaseConnection =
+ OleDoc_ExtConn_ReleaseConnection;
+ fStatus = OleStdCheckVtbl(
+ &g_OleDoc_ExternalConnectionVtbl,
+ sizeof(IExternalConnectionVtbl),
+ "IExternalConnection"
+ );
+ if (! fStatus) return FALSE;
+
+ // OleDoc::IDataObject method table
+ OleStdInitVtbl(&g_OleDoc_DataObjectVtbl, sizeof(IDataObjectVtbl));
+ g_OleDoc_DataObjectVtbl.QueryInterface = OleDoc_DataObj_QueryInterface;
+ g_OleDoc_DataObjectVtbl.AddRef = OleDoc_DataObj_AddRef;
+ g_OleDoc_DataObjectVtbl.Release = OleDoc_DataObj_Release;
+ g_OleDoc_DataObjectVtbl.GetData = OleDoc_DataObj_GetData;
+ g_OleDoc_DataObjectVtbl.GetDataHere = OleDoc_DataObj_GetDataHere;
+ g_OleDoc_DataObjectVtbl.QueryGetData = OleDoc_DataObj_QueryGetData;
+ g_OleDoc_DataObjectVtbl.GetCanonicalFormatEtc =
+ OleDoc_DataObj_GetCanonicalFormatEtc;
+ g_OleDoc_DataObjectVtbl.SetData = OleDoc_DataObj_SetData;
+ g_OleDoc_DataObjectVtbl.EnumFormatEtc = OleDoc_DataObj_EnumFormatEtc;
+ g_OleDoc_DataObjectVtbl.DAdvise = OleDoc_DataObj_DAdvise;
+ g_OleDoc_DataObjectVtbl.DUnadvise = OleDoc_DataObj_DUnadvise;
+ g_OleDoc_DataObjectVtbl.EnumDAdvise = OleDoc_DataObj_EnumDAdvise;
+
+ fStatus = OleStdCheckVtbl(
+ &g_OleDoc_DataObjectVtbl,
+ sizeof(IDataObjectVtbl),
+ "IDataObject"
+ );
+ if (! fStatus) return FALSE;
+
+#if defined( USE_DRAGDROP )
+
+ // OleDoc::IDropTarget method table
+ OleStdInitVtbl(&g_OleDoc_DropTargetVtbl, sizeof(IDropTargetVtbl));
+ g_OleDoc_DropTargetVtbl.QueryInterface= OleDoc_DropTarget_QueryInterface;
+ g_OleDoc_DropTargetVtbl.AddRef = OleDoc_DropTarget_AddRef;
+ g_OleDoc_DropTargetVtbl.Release = OleDoc_DropTarget_Release;
+
+ g_OleDoc_DropTargetVtbl.DragEnter = OleDoc_DropTarget_DragEnter;
+ g_OleDoc_DropTargetVtbl.DragOver = OleDoc_DropTarget_DragOver;
+ g_OleDoc_DropTargetVtbl.DragLeave = OleDoc_DropTarget_DragLeave;
+ g_OleDoc_DropTargetVtbl.Drop = OleDoc_DropTarget_Drop;
+
+ fStatus = OleStdCheckVtbl(
+ &g_OleDoc_DropTargetVtbl,
+ sizeof(IDropTargetVtbl),
+ "IDropTarget"
+ );
+ if (! fStatus)
+ return FALSE;
+
+ // OleDoc::IDropSource method table
+ OleStdInitVtbl(&g_OleDoc_DropSourceVtbl, sizeof(IDropSourceVtbl));
+ g_OleDoc_DropSourceVtbl.QueryInterface =
+ OleDoc_DropSource_QueryInterface;
+ g_OleDoc_DropSourceVtbl.AddRef = OleDoc_DropSource_AddRef;
+ g_OleDoc_DropSourceVtbl.Release = OleDoc_DropSource_Release;
+
+ g_OleDoc_DropSourceVtbl.QueryContinueDrag =
+ OleDoc_DropSource_QueryContinueDrag;
+ g_OleDoc_DropSourceVtbl.GiveFeedback = OleDoc_DropSource_GiveFeedback;
+
+ fStatus = OleStdCheckVtbl(
+ &g_OleDoc_DropSourceVtbl,
+ sizeof(IDropSourceVtbl),
+ "IDropSource"
+ );
+ if (! fStatus) return FALSE;
+#endif // USE_DRAGDROP
+
+#if defined( OLE_SERVER )
+
+ // Initialize the server specific interface method tables.
+ if (! ServerApp_InitVtbls((LPSERVERAPP)lpOleApp))
+ return FALSE;
+#endif
+#if defined( OLE_CNTR )
+
+ // Initialize the container specific interface method tables.
+ if (! ContainerApp_InitVtbls((LPCONTAINERAPP)lpOleApp))
+ return FALSE;
+#endif
+ return TRUE;
+};
+
+
+
+/* OleApp_InitMenu
+ * ---------------
+ *
+ * Enable or Disable menu items depending on the state of
+ * the appliation.
+ * The OLE versions of the Outline sample app add a PasteSpecial command.
+ * Also, the container version add InsertObject and ObjectVerb menu items.
+ */
+void OleApp_InitMenu(
+ LPOLEAPP lpOleApp,
+ LPOLEDOC lpOleDoc,
+ HMENU hMenu
+)
+{
+ BOOL bMsgFilterInstalled = FALSE;
+ BOOL bRejecting = FALSE;
+
+ if (!lpOleApp || !hMenu)
+ return;
+
+ OLEDBG_BEGIN3("OleApp_InitMenu\r\n")
+
+ /*
+ ** Enable/disable menu items for Message Filter
+ */
+ bMsgFilterInstalled = (lpOleApp->m_lpMsgFilter != NULL);
+ bRejecting = bMsgFilterInstalled &&
+ OleStdMsgFilter_GetInComingCallStatus(lpOleApp->m_lpMsgFilter) != SERVERCALL_ISHANDLED;
+
+ CheckMenuItem(hMenu,
+ IDM_D_INSTALLMSGFILTER,
+ bMsgFilterInstalled ? MF_CHECKED : MF_UNCHECKED);
+
+ EnableMenuItem(hMenu,
+ IDM_D_REJECTINCOMING,
+ bMsgFilterInstalled ? MF_ENABLED : MF_GRAYED);
+
+ CheckMenuItem(hMenu,
+ IDM_D_REJECTINCOMING,
+ bRejecting ? MF_CHECKED : MF_UNCHECKED);
+
+#if defined( OLE_CNTR )
+ {
+ LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOleDoc;
+ BOOL fShowObject;
+
+ fShowObject = ContainerDoc_GetShowObjectFlag(lpContainerDoc);
+ CheckMenuItem(
+ hMenu,
+ IDM_O_SHOWOBJECT,
+ (fShowObject ? MF_CHECKED : MF_UNCHECKED)
+ );
+
+#if defined( INPLACE_CNTR ) && defined( _DEBUG )
+ CheckMenuItem(
+ hMenu,
+ IDM_D_INSIDEOUT,
+ g_fInsideOutContainer ? MF_CHECKED:MF_UNCHECKED);
+#endif // INPLACE_CNTR && _DEBUG
+
+ }
+#endif // OLE_CNTR
+
+ OLEDBG_END3
+}
+
+
+
+/* OleApp_UpdateEditMenu
+ * ---------------------
+ *
+ * Purpose:
+ * Update the Edit menuitems of the App according to the state of
+ * OutlineDoc
+ *
+ * Parameter:
+ * lpOutlineDoc pointer to the document
+ * hMenuEdit edit menu handle
+ */
+void OleApp_UpdateEditMenu(
+ LPOLEAPP lpOleApp,
+ LPOUTLINEDOC lpOutlineDoc,
+ HMENU hMenuEdit
+)
+{
+ int nFmtEtc;
+ UINT uEnablePaste = MF_GRAYED;
+ UINT uEnablePasteLink = MF_GRAYED;
+ LPDATAOBJECT lpClipboardDataObj;
+ LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
+ HRESULT hrErr;
+ BOOL fPrevEnable1;
+ BOOL fPrevEnable2;
+
+ if (!lpOleApp || !lpOutlineDoc || !hMenuEdit)
+ return;
+
+ if (!OleDoc_GetUpdateEditMenuFlag(lpOleDoc))
+ /* OLE2NOTE: if the flag is not set, we don't have to update
+ ** the edit menu again. This blocks repetitive updating when
+ ** the user move the mouse across Edit menu while holding
+ ** down the button
+ */
+ return;
+
+ OLEDBG_BEGIN3("OleApp_InitEditMenu\r\n")
+
+ /* OLE2NOTE: we do not want to ever give the busy dialog when we
+ ** are trying to put up our menus. eg. even if the source of
+ ** data on the clipboard is busy, we do not want put up the busy
+ ** dialog. thus we will disable the dialog and at the end
+ ** re-enable it.
+ */
+ OleApp_DisableBusyDialogs(lpOleApp, &fPrevEnable1, &fPrevEnable2);
+
+ // check if there is data on the clipboard that we can paste/paste link
+
+ OLEDBG_BEGIN2("OleGetClipboard called\r\n")
+ hrErr = OleGetClipboard((LPDATAOBJECT FAR*)&lpClipboardDataObj);
+ OLEDBG_END2
+
+ if (hrErr == NOERROR) {
+ nFmtEtc = OleStdGetPriorityClipboardFormat(
+ lpClipboardDataObj,
+ lpOleApp->m_arrPasteEntries,
+ lpOleApp->m_nPasteEntries
+ );
+
+ if (nFmtEtc >= 0)
+ uEnablePaste = MF_ENABLED; // there IS a format we like
+
+ OLEDBG_BEGIN2("OleQueryLinkFromData called\r\n")
+ hrErr = OleQueryLinkFromData(lpClipboardDataObj);
+ OLEDBG_END2
+
+ if(hrErr == NOERROR)
+ uEnablePasteLink = MF_ENABLED;
+
+ OleStdRelease((LPUNKNOWN)lpClipboardDataObj);
+ }
+
+ EnableMenuItem(hMenuEdit, IDM_E_PASTE, uEnablePaste);
+ EnableMenuItem(hMenuEdit, IDM_E_PASTESPECIAL, uEnablePaste);
+
+
+#if defined( OLE_CNTR )
+ if (ContainerDoc_GetNextLink((LPCONTAINERDOC)lpOutlineDoc, NULL))
+ EnableMenuItem(hMenuEdit, IDM_E_EDITLINKS, MF_ENABLED);
+ else
+ EnableMenuItem(hMenuEdit, IDM_E_EDITLINKS, MF_GRAYED);
+
+
+ {
+ LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp;
+ HMENU hMenuVerb = NULL;
+ LPOLEOBJECT lpOleObj = NULL;
+ LPCONTAINERLINE lpContainerLine = NULL;
+ BOOL fSelIsOleObject;
+
+ EnableMenuItem(hMenuEdit, IDM_E_PASTELINK, uEnablePasteLink);
+
+ /* check if selection is a single line that contains an OleObject */
+
+ fSelIsOleObject = ContainerDoc_IsSelAnOleObject(
+ (LPCONTAINERDOC)lpOutlineDoc,
+ &IID_IOleObject,
+ (LPUNKNOWN FAR*)&lpOleObj,
+ NULL, /* we don't need the line index */
+ (LPCONTAINERLINE FAR*)&lpContainerLine
+ );
+
+ if (hMenuEdit != NULL) {
+
+ /* If the current line is an ContainerLine, add the object
+ ** verb sub menu to the Edit menu. if the line is not an
+ ** ContainerLine, (lpOleObj==NULL) then disable the
+ ** Edit.Object command. this helper API takes care of
+ ** building the verb menu as appropriate.
+ */
+ OleUIAddVerbMenu(
+ (LPOLEOBJECT)lpOleObj,
+ (lpContainerLine ? lpContainerLine->m_lpszShortType:NULL),
+ hMenuEdit,
+ POS_OBJECT,
+ IDM_E_OBJECTVERBMIN,
+ 0, // no uIDVerbMax enforced
+ TRUE, // Add Convert menu item
+ IDM_E_CONVERTVERB, // ID for Convert menu item
+ (HMENU FAR*) &hMenuVerb
+ );
+
+#if defined( USE_STATUSBAR_LATER )
+ /* setup status messages for the object verb menu */
+ if (hMenuVerb) {
+ // REVIEW: this string should come from a string resource.
+ // REVIEW: this doesn't work for dynamically created menus
+ AssignPopupMessage(
+ hMenuVerb,
+ "Open, edit or interact with an object"
+ );
+ }
+#endif // USE_STATUSBAR_LATER
+ }
+
+ if (lpOleObj)
+ OleStdRelease((LPUNKNOWN)lpOleObj);
+ }
+
+#endif // OLE_CNTR
+
+ // re-enable the Busy/NotResponding dialogs
+ OleApp_EnableBusyDialogs(lpOleApp, fPrevEnable1, fPrevEnable2);
+
+ OleDoc_SetUpdateEditMenuFlag(lpOleDoc, FALSE);
+
+ OLEDBG_END3
+}
+
+
+/* OleApp_RegisterClassFactory
+ * ---------------------------
+ *
+ * Register our app's ClassFactory with OLE.
+ *
+ */
+BOOL OleApp_RegisterClassFactory(LPOLEAPP lpOleApp)
+{
+ HRESULT hrErr;
+
+ if (lpOleApp->m_lpClassFactory)
+ return TRUE; // already registered
+
+ OLEDBG_BEGIN3("OleApp_RegisterClassFactory\r\n")
+
+ /******************************************************************
+ ** An SDI app must register its ClassFactory if it is launched
+ ** for embedding (/Embedding command line option specified).
+ ** An MDI app must register its ClassFactory in all cases,
+ ******************************************************************/
+
+ lpOleApp->m_lpClassFactory = AppClassFactory_Create();
+ if (! lpOleApp->m_lpClassFactory) {
+ OutlineApp_ErrorMessage(g_lpApp, ErrMsgCreateCF);
+ goto error;
+ }
+
+ OLEDBG_BEGIN2("CoRegisterClassObject called\r\n")
+ hrErr = CoRegisterClassObject(
+ &CLSID_APP,
+ (LPUNKNOWN)lpOleApp->m_lpClassFactory,
+ CLSCTX_LOCAL_SERVER,
+ REGCLS_SINGLEUSE,
+ &lpOleApp->m_dwRegClassFac
+ );
+ OLEDBG_END2
+
+ if(hrErr != NOERROR) {
+ OleDbgOutHResult("CoRegisterClassObject returned", hrErr);
+ OutlineApp_ErrorMessage(g_lpApp, ErrMsgRegCF);
+ goto error;
+ }
+
+ OLEDBG_END3
+ return TRUE;
+
+error:
+
+ if (lpOleApp->m_lpClassFactory) {
+ OleStdRelease((LPUNKNOWN)lpOleApp->m_lpClassFactory);
+ lpOleApp->m_lpClassFactory = NULL;
+ }
+ OLEDBG_END3
+ return FALSE;
+}
+
+
+/* OleApp_RevokeClassFactory
+ * -------------------------
+ *
+ * Revoke our app's ClassFactory.
+ *
+ */
+void OleApp_RevokeClassFactory(LPOLEAPP lpOleApp)
+{
+ HRESULT hrErr;
+
+ if (lpOleApp->m_lpClassFactory) {
+
+ OLEDBG_BEGIN2("CoRevokeClassObject called\r\n")
+ hrErr = CoRevokeClassObject(lpOleApp->m_dwRegClassFac);
+ OLEDBG_END2
+
+#if defined( _DEBUG )
+ if (hrErr != NOERROR) {
+ OleDbgOutHResult("CoRevokeClassObject returned", hrErr);
+ }
+#endif
+
+ // we just release here; other folks may still have
+ // a pointer to our class factory, so we can't
+ // do any checks on the reference count.
+ OleStdRelease((LPUNKNOWN)lpOleApp->m_lpClassFactory);
+ lpOleApp->m_lpClassFactory = NULL;
+ }
+}
+
+
+#if defined( USE_MSGFILTER )
+
+/* OleApp_RegisterMessageFilter
+ * ----------------------------
+ * Register our IMessageFilter*. the message filter is used to handle
+ * concurrency. we will use a standard implementation of IMessageFilter
+ * that is included as part of the OLE2UI library.
+ */
+BOOL OleApp_RegisterMessageFilter(LPOLEAPP lpOleApp)
+{
+ HRESULT hrErr;
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+
+ if (lpOleApp->m_lpMsgFilter == NULL) {
+ // Register our message filter.
+ lpOleApp->m_lpfnMsgPending = (MSGPENDINGPROC)MessagePendingProc;
+ lpOleApp->m_lpMsgFilter = OleStdMsgFilter_Create(
+ g_lpApp->m_hWndApp,
+ (LPSTR)APPNAME,
+ lpOleApp->m_lpfnMsgPending,
+ NULL /* Busy dialog callback hook function */
+ );
+
+ OLEDBG_BEGIN2("CoRegisterMessageFilter called\r\n")
+ hrErr = CoRegisterMessageFilter(
+ lpOleApp->m_lpMsgFilter,
+ NULL /* don't need previous message filter */
+ );
+ OLEDBG_END2
+
+ if(hrErr != NOERROR) {
+ OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgRegMF);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+/* OleApp_RevokeMessageFilter
+ * --------------------------
+ * Revoke our IMessageFilter*. the message filter is used to handle
+ * concurrency. we will use a standard implementation of IMessageFilter
+ * that is included as part of the OLE2UI library.
+ */
+void OleApp_RevokeMessageFilter(LPOLEAPP lpOleApp)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
+
+ if (lpOleApp->m_lpMsgFilter != NULL) {
+ // Revoke our message filter
+ OLEDBG_BEGIN2("CoRegisterMessageFilter(NULL) called\r\n")
+ CoRegisterMessageFilter(NULL, NULL);
+ OLEDBG_END2
+
+ if (lpOleApp->m_lpfnMsgPending) {
+ lpOleApp->m_lpfnMsgPending = NULL;
+ }
+
+ OleStdVerifyRelease(
+ (LPUNKNOWN)lpOleApp->m_lpMsgFilter,
+ "Release MessageFilter FAILED!"
+ );
+ lpOleApp->m_lpMsgFilter = NULL;
+ }
+}
+
+
+/* MessagePendingProc
+ * ------------------
+ *
+ * Callback function for the IMessageFilter::MessagePending procedure. This
+ * function is called when a message is received by our application while
+ * we are waiting for an OLE call to complete. We are essentially
+ * blocked at this point, waiting for a response from the other OLE application.
+ * We should not process any messages which might cause another OLE call
+ * to become blocked, or any other call which might cause re-entrancy problems.
+ *
+ * For this application, only process WM_PAINT messages. A more sophisticated
+ * application might allow certain menu messages and menu items to be processed
+ * also.
+ *
+ * RETURNS: TRUE if we processed the message, FALSE if we did not.
+ */
+
+BOOL FAR PASCAL EXPORT MessagePendingProc(MSG FAR *lpMsg)
+{
+ // Our application is only handling WM_PAINT messages when we are blocked
+ switch (lpMsg->message) {
+ case WM_PAINT:
+ OleDbgOut2("WM_PAINT dispatched while blocked\r\n");
+
+ DispatchMessage(lpMsg);
+ break;
+ }
+
+ return FALSE; // return PENDINGMSG_WAITDEFPROCESS from MessagePending
+}
+#endif // USE_MSGFILTER
+
+
+/* OleApp_FlushClipboard
+ * ---------------------
+ *
+ * Force the Windows clipboard to release our clipboard DataObject.
+ */
+void OleApp_FlushClipboard(LPOLEAPP lpOleApp)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+ LPOLEDOC lpClipboardDoc = (LPOLEDOC)lpOutlineApp->m_lpClipboardDoc;
+ OLEDBG_BEGIN3("OleApp_FlushClipboard\r\n")
+
+ /* OLE2NOTE: if for some reason our clipboard data transfer
+ ** document is still held on to by an external client, we want
+ ** to forceably break all external connections.
+ */
+ OLEDBG_BEGIN2("CoDisconnectObject called\r\n")
+ CoDisconnectObject((LPUNKNOWN)&lpClipboardDoc->m_Unknown, 0);
+ OLEDBG_END2
+
+ OLEDBG_BEGIN2("OleFlushClipboard called\r\n")
+ OleFlushClipboard();
+ OLEDBG_END2
+
+ lpOutlineApp->m_lpClipboardDoc = NULL;
+
+ OLEDBG_END3
+}
+
+
+/* OleApp_NewCommand
+ * -----------------
+ *
+ * Start a new untitled document (File.New command).
+ */
+void OleApp_NewCommand(LPOLEAPP lpOleApp)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+ LPOUTLINEDOC lpOutlineDoc = lpOutlineApp->m_lpDoc;
+
+ if (! OutlineDoc_Close(lpOutlineDoc, OLECLOSE_PROMPTSAVE))
+ return;
+
+ OleDbgAssertSz(lpOutlineApp->m_lpDoc==NULL,"Closed doc NOT properly destroyed");
+ lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
+ if (! lpOutlineApp->m_lpDoc) goto error;
+
+ /* OLE2NOTE: initially the Doc object is created with a 0 ref
+ ** count. in order to have a stable Doc object during the
+ ** process of initializing the new Doc instance,
+ ** we intially AddRef the Doc ref cnt and later
+ ** Release it. This initial AddRef is artificial; it is simply
+ ** done to guarantee that a harmless QueryInterface followed by
+ ** a Release does not inadvertantly force our object to destroy
+ ** itself prematurely.
+ */
+ OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ // set the doc to an (Untitled) doc.
+ if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc))
+ goto error;
+
+ // position and size the new doc window
+ OutlineApp_ResizeWindows(lpOutlineApp);
+ OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc); // calls OleDoc_Lock
+
+ OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel artificial AddRef
+
+ return;
+
+error:
+ // REVIEW: should load string from string resource
+ OutlineApp_ErrorMessage(lpOutlineApp, "Could not create new document");
+
+ if (lpOutlineApp->m_lpDoc) {
+ // releasing the artificial AddRef above will destroy the document
+ OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);
+ lpOutlineApp->m_lpDoc = NULL;
+ }
+
+ return;
+}
+
+
+/* OleApp_OpenCommand
+ * ------------------
+ *
+ * Load a document from file (File.Open command).
+ */
+void OleApp_OpenCommand(LPOLEAPP lpOleApp)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp;
+ LPOUTLINEDOC lpOutlineDoc = lpOutlineApp->m_lpDoc;
+ OPENFILENAME ofn;
+ char szFilter[]=APPFILENAMEFILTER;
+ char szFileName[256];
+ UINT i;
+ DWORD dwSaveOption = OLECLOSE_PROMPTSAVE;
+ BOOL fStatus = TRUE;
+
+ if (! OutlineDoc_CheckSaveChanges(lpOutlineDoc, &dwSaveOption))
+ return; // abort opening new doc
+
+ for(i=0; szFilter[i]; i++)
+ if(szFilter[i]=='|') szFilter[i]='\0';
+
+ _fmemset((LPOPENFILENAME)&ofn,0,sizeof(OPENFILENAME));
+
+ szFileName[0]='\0';
+
+ ofn.lStructSize=sizeof(OPENFILENAME);
+ ofn.hwndOwner=lpOutlineApp->m_hWndApp;
+ ofn.lpstrFilter=(LPSTR)szFilter;
+ ofn.lpstrFile=(LPSTR)szFileName;
+ ofn.nMaxFile=sizeof(szFileName);
+ ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+ ofn.lpstrDefExt=DEFEXTENSION;
+
+ OleApp_PreModalDialog(lpOleApp, (LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ fStatus = GetOpenFileName((LPOPENFILENAME)&ofn);
+
+ OleApp_PostModalDialog(lpOleApp, (LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ if(! fStatus)
+ return; // user canceled file open dialog
+
+ OutlineDoc_Close(lpOutlineDoc, OLECLOSE_NOSAVE);
+ OleDbgAssertSz(lpOutlineApp->m_lpDoc==NULL,"Closed doc NOT properly destroyed");
+
+ lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
+ if (! lpOutlineApp->m_lpDoc) goto error;
+
+ /* OLE2NOTE: initially the Doc object is created with a 0 ref
+ ** count. in order to have a stable Doc object during the
+ ** process of initializing the new Doc instance,
+ ** we intially AddRef the Doc ref cnt and later
+ ** Release it. This initial AddRef is artificial; it is simply
+ ** done to guarantee that a harmless QueryInterface followed by
+ ** a Release does not inadvertantly force our object to destroy
+ ** itself prematurely.
+ */
+ OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ fStatus=OutlineDoc_LoadFromFile(lpOutlineApp->m_lpDoc, (LPSTR)szFileName);
+
+ if (! fStatus) {
+ // loading the doc failed; create an untitled instead
+
+ // releasing the artificial AddRef above will destroy the document
+ OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
+ if (! lpOutlineApp->m_lpDoc) goto error;
+ OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc);
+
+ if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc))
+ goto error;
+ }
+
+ // position and size the new doc window
+ OutlineApp_ResizeWindows(lpOutlineApp);
+ OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc);
+
+#if defined( OLE_CNTR )
+ UpdateWindow(lpOutlineApp->m_hWndApp);
+ ContainerDoc_UpdateLinks((LPCONTAINERDOC)lpOutlineApp->m_lpDoc);
+#endif
+
+ OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel artificial AddRef
+
+ return;
+
+error:
+ // REVIEW: should load string from string resource
+ OutlineApp_ErrorMessage(lpOutlineApp, "Could not create new document");
+
+ if (lpOutlineApp->m_lpDoc) {
+ // releasing the artificial AddRef above will destroy the document
+ OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);
+ lpOutlineApp->m_lpDoc = NULL;
+ }
+
+ return;
+}
+
+
+
+#if defined( OLE_CNTR )
+
+/* OLE2NOTE: forward the WM_QUERYNEWPALETTE message (via
+** SendMessage) to UIActive in-place object if there is one.
+** this gives the UIActive object the opportunity to select
+** and realize its color palette as the FOREGROUND palette.
+** this is optional for in-place containers. if a container
+** prefers to force its color palette as the foreground
+** palette then it should NOT forward the this message. or
+** the container can give the UIActive object priority; if
+** the UIActive object returns 0 from the WM_QUERYNEWPALETTE
+** message (ie. it did not realize its own palette), then
+** the container can realize its palette.
+** (see ContainerDoc_ForwardPaletteChangedMsg for more info)
+**
+** (It is a good idea for containers to use the standard
+** palette even if they do not use colors themselves. this
+** will allow embedded object to get a good distribution of
+** colors when they are being drawn by the container)
+**
+*/
+
+LRESULT OleApp_QueryNewPalette(LPOLEAPP lpOleApp)
+{
+#if defined( INPLACE_CNTR )
+ LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp;
+
+ if (lpContainerApp && lpContainerApp->m_hWndUIActiveObj) {
+ if (SendMessage(lpContainerApp->m_hWndUIActiveObj, WM_QUERYNEWPALETTE,
+ (WPARAM)0, (LPARAM)0)) {
+ /* Object selected its palette as foreground palette */
+ return (LRESULT)1;
+ }
+ }
+#endif // INPLACE_CNTR
+
+
+ return wSelectPalette(((LPOUTLINEAPP)lpOleApp)->m_hWndApp,
+ lpOleApp->m_hStdPal, FALSE/*fBackground*/);
+}
+
+#endif // OLE_CNTR
+
+
+
+/* This is just a helper routine */
+
+LRESULT wSelectPalette(HWND hWnd, HPALETTE hPal, BOOL fBackground)
+{
+ HDC hdc;
+ HPALETTE hOldPal;
+ UINT iPalChg = 0;
+
+ if (hPal == 0)
+ return (LRESULT)0;
+
+ hdc = GetDC(hWnd);
+ hOldPal = SelectPalette(hdc, hPal, fBackground);
+ iPalChg = RealizePalette(hdc);
+ SelectPalette(hdc, hOldPal, TRUE /*fBackground*/);
+ ReleaseDC(hWnd, hdc);
+
+ if (iPalChg > 0)
+ InvalidateRect(hWnd, NULL, TRUE);
+
+ return (LRESULT)1;
+}
+
+
+
+
+/*************************************************************************
+** OleApp::IUnknown interface implementation
+*************************************************************************/
+
+STDMETHODIMP OleApp_Unk_QueryInterface(
+ LPUNKNOWN lpThis,
+ REFIID riid,
+ LPVOID FAR* lplpvObj
+)
+{
+ LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp;
+
+ return OleApp_QueryInterface(lpOleApp, riid, lplpvObj);
+}
+
+
+STDMETHODIMP_(ULONG) OleApp_Unk_AddRef(LPUNKNOWN lpThis)
+{
+ LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp;
+
+ OleDbgAddRefMethod(lpThis, "IUnknown");
+
+ return OleApp_AddRef(lpOleApp);
+}
+
+
+STDMETHODIMP_(ULONG) OleApp_Unk_Release (LPUNKNOWN lpThis)
+{
+ LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp;
+
+ OleDbgReleaseMethod(lpThis, "IUnknown");
+
+ return OleApp_Release(lpOleApp);
+}
+
+
+
+
+#if defined( OLE_SERVER )
+
+/*************************************************************************
+** ServerDoc Supprt Functions Used by Server versions
+*************************************************************************/
+
+/* ServerApp_InitInstance
+ * ----------------------
+ *
+ * Initialize the app instance by creating the main frame window and
+ * performing app instance specific initializations
+ * (eg. initializing interface Vtbls).
+ *
+ * RETURNS: TRUE if the memory could be allocated, and the server app
+ * was properly initialized.
+ * FALSE otherwise
+ *
+ */
+
+BOOL ServerApp_InitInstance(
+ LPSERVERAPP lpServerApp,
+ HINSTANCE hInst,
+ int nCmdShow
+)
+{
+ LPOLEAPP lpOleApp = (LPOLEAPP)lpServerApp;
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpServerApp;
+
+ /* Setup arrays used by IDataObject::EnumFormatEtc.
+ **
+ ** OLE2NOTE: The order that the formats are listed for GetData is very
+ ** significant. It should be listed in order of highest fidelity
+ ** formats to least fidelity formats. A common ordering will be:
+ ** 1. private app formats
+ ** 2. EmbedSource
+ ** 3. lower fidelity interchange formats
+ ** 4. pictures (metafile, dib, etc.)
+ ** (graphic-related apps offer pictures 1st!)
+ ** 5. LinkSource
+ */
+
+ /* m_arrDocGetFmts array enumerates the formats that a ServerDoc
+ ** DataTransferDoc object can offer (give) through a
+ ** IDataObject::GetData call. a ServerDoc DataTransferDoc offers
+ ** data formats in the following order:
+ ** 1. CF_OUTLINE
+ ** 2. CF_EMBEDSOURCE
+ ** 3. CF_OBJECTDESCRIPTOR
+ ** 4. CF_TEXT
+ ** 5. CF_METAFILEPICT
+ ** 6. CF_LINKSOURCE *
+ ** 7. CF_LINKSRCDESCRIPTOR *
+ **
+ ** * NOTE: CF_LINKSOURCE and CF_LINKSRCDESCRIPTOR is only
+ ** offered if the doc is able to give
+ ** a Moniker which references the data. CF_LINKSOURCE is
+ ** deliberately listed last in this array of possible formats.
+ ** if the doc does not have a Moniker then the last element of
+ ** this array is not used. (see SvrDoc_DataObj_EnumFormatEtc).
+ **
+ ** NOTE: The list of formats that a USER ServerDoc document can
+ ** offer is a static list and is registered in the registration
+ ** database for the SVROUTL class. The
+ ** IDataObject::EnumFormatEtc method returns OLE_S_USEREG in the
+ ** case the document is a user docuemt (ie. created via
+ ** File.New, File.Open, InsertObject in a container, or
+ ** IPersistFile::Load during binding a link source). this tells
+ ** OLE to enumerate the formats automatically using the data the
+ ** the REGDB.
+ */
+
+ lpOleApp->m_arrDocGetFmts[0].cfFormat = lpOutlineApp->m_cfOutline;
+ lpOleApp->m_arrDocGetFmts[0].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[0].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[0].tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrDocGetFmts[0].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[1].cfFormat = lpOleApp->m_cfEmbedSource;
+ lpOleApp->m_arrDocGetFmts[1].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[1].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[1].tymed = TYMED_ISTORAGE;
+ lpOleApp->m_arrDocGetFmts[1].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[2].cfFormat = CF_TEXT;
+ lpOleApp->m_arrDocGetFmts[2].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[2].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[2].tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrDocGetFmts[2].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[3].cfFormat = CF_METAFILEPICT;
+ lpOleApp->m_arrDocGetFmts[3].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[3].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[3].tymed = TYMED_MFPICT;
+ lpOleApp->m_arrDocGetFmts[3].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[4].cfFormat = lpOleApp->m_cfObjectDescriptor;
+ lpOleApp->m_arrDocGetFmts[4].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[4].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[4].tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrDocGetFmts[4].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[5].cfFormat = lpOleApp->m_cfLinkSource;
+ lpOleApp->m_arrDocGetFmts[5].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[5].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[5].tymed = TYMED_ISTREAM;
+ lpOleApp->m_arrDocGetFmts[5].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[6].cfFormat = lpOleApp->m_cfLinkSrcDescriptor;
+ lpOleApp->m_arrDocGetFmts[6].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[6].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[6].tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrDocGetFmts[6].lindex = -1;
+
+ lpOleApp->m_nDocGetFmts = 7;
+
+ /* m_arrPasteEntries array enumerates the formats that a ServerDoc
+ ** object can accept (get) from the clipboard.
+ ** The formats are listed in priority order.
+ ** ServerDoc accept data formats in the following order:
+ ** 1. CF_OUTLINE
+ ** 2. CF_TEXT
+ */
+ // REVIEW: strings should be loaded from string resource
+ lpOleApp->m_arrPasteEntries[0].fmtetc.cfFormat =lpOutlineApp->m_cfOutline;
+ lpOleApp->m_arrPasteEntries[0].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[0].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[0].fmtetc.tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrPasteEntries[0].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[0].lpstrFormatName = "Outline Data";
+ lpOleApp->m_arrPasteEntries[0].lpstrResultText = "Outline Data";
+ lpOleApp->m_arrPasteEntries[0].dwFlags = OLEUIPASTE_PASTEONLY;
+
+ lpOleApp->m_arrPasteEntries[1].fmtetc.cfFormat = CF_TEXT;
+ lpOleApp->m_arrPasteEntries[1].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[1].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[1].fmtetc.tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrPasteEntries[1].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[1].lpstrFormatName = "Text";
+ lpOleApp->m_arrPasteEntries[1].lpstrResultText = "text";
+ lpOleApp->m_arrPasteEntries[1].dwFlags = OLEUIPASTE_PASTEONLY;
+
+ lpOleApp->m_nPasteEntries = 2;
+
+ /** m_arrLinkTypes array enumerates the link types that a ServerDoc
+ ** object can accept from the clipboard. ServerDoc does NOT
+ ** accept any type of link from the clipboard. ServerDoc can
+ ** only be the source of a link. it can not contain links.
+ */
+
+ lpOleApp->m_nLinkTypes = 0;
+
+#if defined( INPLACE_SVR )
+
+ lpServerApp->m_hAccelBaseApp = NULL;
+ lpServerApp->m_hAccelIPSvr = LoadAccelerators(
+ hInst,
+ "InPlaceSvrOutlAccel"
+ );
+
+ lpServerApp->m_lpIPData = NULL;
+
+ lpServerApp->m_hMenuEdit = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_EDITMENU
+ );
+ lpServerApp->m_hMenuLine = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_LINEMENU
+ );
+ lpServerApp->m_hMenuName = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_NAMEMENU
+ );
+ lpServerApp->m_hMenuOptions = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_OPTIONSMENU
+ );
+ lpServerApp->m_hMenuDebug = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_DEBUGMENU
+ );
+ lpServerApp->m_hMenuHelp = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_HELPMENU
+ );
+
+#endif // INPLACE_SVR
+
+ return TRUE;
+}
+
+
+/* ServerApp_InitVtbls
+ * -------------------
+ *
+ * initialize the methods in all of the interface Vtbl's
+ *
+ * OLE2NOTE: we only need one copy of each Vtbl. When an object which
+ * exposes an interface is instantiated, its lpVtbl is intialized
+ * to point to the single copy of the Vtbl.
+ *
+ */
+BOOL ServerApp_InitVtbls (LPSERVERAPP lpServerApp)
+{
+ BOOL fStatus;
+
+ // ServerDoc::IOleObject method table
+ OleStdInitVtbl(&g_SvrDoc_OleObjectVtbl, sizeof(IOleObjectVtbl));
+ g_SvrDoc_OleObjectVtbl.QueryInterface = SvrDoc_OleObj_QueryInterface;
+ g_SvrDoc_OleObjectVtbl.AddRef = SvrDoc_OleObj_AddRef;
+ g_SvrDoc_OleObjectVtbl.Release = SvrDoc_OleObj_Release;
+ g_SvrDoc_OleObjectVtbl.SetClientSite = SvrDoc_OleObj_SetClientSite;
+ g_SvrDoc_OleObjectVtbl.GetClientSite = SvrDoc_OleObj_GetClientSite;
+ g_SvrDoc_OleObjectVtbl.SetHostNames = SvrDoc_OleObj_SetHostNames;
+ g_SvrDoc_OleObjectVtbl.Close = SvrDoc_OleObj_Close;
+ g_SvrDoc_OleObjectVtbl.SetMoniker = SvrDoc_OleObj_SetMoniker;
+ g_SvrDoc_OleObjectVtbl.GetMoniker = SvrDoc_OleObj_GetMoniker;
+ g_SvrDoc_OleObjectVtbl.InitFromData = SvrDoc_OleObj_InitFromData;
+ g_SvrDoc_OleObjectVtbl.GetClipboardData = SvrDoc_OleObj_GetClipboardData;
+ g_SvrDoc_OleObjectVtbl.DoVerb = SvrDoc_OleObj_DoVerb;
+ g_SvrDoc_OleObjectVtbl.EnumVerbs = SvrDoc_OleObj_EnumVerbs;
+ g_SvrDoc_OleObjectVtbl.Update = SvrDoc_OleObj_Update;
+ g_SvrDoc_OleObjectVtbl.IsUpToDate = SvrDoc_OleObj_IsUpToDate;
+ g_SvrDoc_OleObjectVtbl.GetUserClassID = SvrDoc_OleObj_GetUserClassID;
+ g_SvrDoc_OleObjectVtbl.GetUserType = SvrDoc_OleObj_GetUserType;
+ g_SvrDoc_OleObjectVtbl.SetExtent = SvrDoc_OleObj_SetExtent;
+ g_SvrDoc_OleObjectVtbl.GetExtent = SvrDoc_OleObj_GetExtent;
+ g_SvrDoc_OleObjectVtbl.Advise = SvrDoc_OleObj_Advise;
+ g_SvrDoc_OleObjectVtbl.Unadvise = SvrDoc_OleObj_Unadvise;
+ g_SvrDoc_OleObjectVtbl.EnumAdvise = SvrDoc_OleObj_EnumAdvise;
+ g_SvrDoc_OleObjectVtbl.GetMiscStatus = SvrDoc_OleObj_GetMiscStatus;
+ g_SvrDoc_OleObjectVtbl.SetColorScheme = SvrDoc_OleObj_SetColorScheme;
+ fStatus = OleStdCheckVtbl(
+ &g_SvrDoc_OleObjectVtbl,
+ sizeof(IOleObjectVtbl),
+ "IOleObject"
+ );
+ if (! fStatus) return FALSE;
+
+ // ServerDoc::IPersistStorage method table
+ OleStdInitVtbl(&g_SvrDoc_PersistStorageVtbl, sizeof(IPersistStorageVtbl));
+ g_SvrDoc_PersistStorageVtbl.QueryInterface = SvrDoc_PStg_QueryInterface;
+ g_SvrDoc_PersistStorageVtbl.AddRef = SvrDoc_PStg_AddRef;
+ g_SvrDoc_PersistStorageVtbl.Release = SvrDoc_PStg_Release;
+ g_SvrDoc_PersistStorageVtbl.GetClassID = SvrDoc_PStg_GetClassID;
+ g_SvrDoc_PersistStorageVtbl.IsDirty = SvrDoc_PStg_IsDirty;
+ g_SvrDoc_PersistStorageVtbl.InitNew = SvrDoc_PStg_InitNew;
+ g_SvrDoc_PersistStorageVtbl.Load = SvrDoc_PStg_Load;
+ g_SvrDoc_PersistStorageVtbl.Save = SvrDoc_PStg_Save;
+ g_SvrDoc_PersistStorageVtbl.SaveCompleted = SvrDoc_PStg_SaveCompleted;
+ g_SvrDoc_PersistStorageVtbl.HandsOffStorage = SvrDoc_PStg_HandsOffStorage;
+ fStatus = OleStdCheckVtbl(
+ &g_SvrDoc_PersistStorageVtbl,
+ sizeof(IPersistStorageVtbl),
+ "IPersistStorage"
+ );
+ if (! fStatus) return FALSE;
+
+#if defined( SVR_TREATAS )
+ // ServerDoc::IStdMarshalInfo method table
+ OleStdInitVtbl(
+ &g_SvrDoc_StdMarshalInfoVtbl, sizeof(IStdMarshalInfoVtbl));
+ g_SvrDoc_StdMarshalInfoVtbl.QueryInterface =
+ SvrDoc_StdMshl_QueryInterface;
+ g_SvrDoc_StdMarshalInfoVtbl.AddRef = SvrDoc_StdMshl_AddRef;
+ g_SvrDoc_StdMarshalInfoVtbl.Release = SvrDoc_StdMshl_Release;
+ g_SvrDoc_StdMarshalInfoVtbl.GetClassForHandler =
+ SvrDoc_StdMshl_GetClassForHandler;
+ fStatus = OleStdCheckVtbl(
+ &g_SvrDoc_StdMarshalInfoVtbl,
+ sizeof(IStdMarshalInfoVtbl),
+ "IStdMarshalInfo"
+ );
+ if (! fStatus) return FALSE;
+#endif // SVR_TREATAS
+
+#if defined( INPLACE_SVR )
+ // ServerDoc::IOleInPlaceObject method table
+ OleStdInitVtbl(
+ &g_SvrDoc_OleInPlaceObjectVtbl,
+ sizeof(IOleInPlaceObjectVtbl)
+ );
+ g_SvrDoc_OleInPlaceObjectVtbl.QueryInterface
+ = SvrDoc_IPObj_QueryInterface;
+ g_SvrDoc_OleInPlaceObjectVtbl.AddRef
+ = SvrDoc_IPObj_AddRef;
+ g_SvrDoc_OleInPlaceObjectVtbl.Release
+ = SvrDoc_IPObj_Release;
+ g_SvrDoc_OleInPlaceObjectVtbl.GetWindow
+ = SvrDoc_IPObj_GetWindow;
+ g_SvrDoc_OleInPlaceObjectVtbl.ContextSensitiveHelp
+ = SvrDoc_IPObj_ContextSensitiveHelp;
+ g_SvrDoc_OleInPlaceObjectVtbl.InPlaceDeactivate
+ = SvrDoc_IPObj_InPlaceDeactivate;
+ g_SvrDoc_OleInPlaceObjectVtbl.UIDeactivate
+ = SvrDoc_IPObj_UIDeactivate;
+ g_SvrDoc_OleInPlaceObjectVtbl.SetObjectRects
+ = SvrDoc_IPObj_SetObjectRects;
+ g_SvrDoc_OleInPlaceObjectVtbl.ReactivateAndUndo
+ = SvrDoc_IPObj_ReactivateAndUndo;
+ fStatus = OleStdCheckVtbl(
+ &g_SvrDoc_OleInPlaceObjectVtbl,
+ sizeof(IOleInPlaceObjectVtbl),
+ "IOleInPlaceObject"
+ );
+ if (! fStatus) return FALSE;
+
+ // ServerDoc::IOleInPlaceActiveObject method table
+ OleStdInitVtbl(
+ &g_SvrDoc_OleInPlaceActiveObjectVtbl,
+ sizeof(IOleInPlaceActiveObjectVtbl)
+ );
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.QueryInterface
+ = SvrDoc_IPActiveObj_QueryInterface;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.AddRef
+ = SvrDoc_IPActiveObj_AddRef;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.Release
+ = SvrDoc_IPActiveObj_Release;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.GetWindow
+ = SvrDoc_IPActiveObj_GetWindow;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.ContextSensitiveHelp
+ = SvrDoc_IPActiveObj_ContextSensitiveHelp;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.TranslateAccelerator
+ = SvrDoc_IPActiveObj_TranslateAccelerator;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.OnFrameWindowActivate
+ = SvrDoc_IPActiveObj_OnFrameWindowActivate;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.OnDocWindowActivate
+ = SvrDoc_IPActiveObj_OnDocWindowActivate;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.ResizeBorder
+ = SvrDoc_IPActiveObj_ResizeBorder;
+ g_SvrDoc_OleInPlaceActiveObjectVtbl.EnableModeless
+ = SvrDoc_IPActiveObj_EnableModeless;
+ fStatus = OleStdCheckVtbl(
+ &g_SvrDoc_OleInPlaceActiveObjectVtbl,
+ sizeof(IOleInPlaceActiveObjectVtbl),
+ "IOleInPlaceActiveObject"
+ );
+ if (! fStatus) return FALSE;
+
+#endif
+
+
+ // PseudoObj::IUnknown method table
+ OleStdInitVtbl(&g_PseudoObj_UnknownVtbl, sizeof(IUnknownVtbl));
+ g_PseudoObj_UnknownVtbl.QueryInterface = PseudoObj_Unk_QueryInterface;
+ g_PseudoObj_UnknownVtbl.AddRef = PseudoObj_Unk_AddRef;
+ g_PseudoObj_UnknownVtbl.Release = PseudoObj_Unk_Release;
+ fStatus = OleStdCheckVtbl(
+ &g_PseudoObj_UnknownVtbl,
+ sizeof(IUnknownVtbl),
+ "IUnknown"
+ );
+ if (! fStatus) return FALSE;
+
+ // PseudoObj::IOleObject method table
+ OleStdInitVtbl(&g_PseudoObj_OleObjectVtbl, sizeof(IOleObjectVtbl));
+ g_PseudoObj_OleObjectVtbl.QueryInterface= PseudoObj_OleObj_QueryInterface;
+ g_PseudoObj_OleObjectVtbl.AddRef = PseudoObj_OleObj_AddRef;
+ g_PseudoObj_OleObjectVtbl.Release = PseudoObj_OleObj_Release;
+ g_PseudoObj_OleObjectVtbl.SetClientSite = PseudoObj_OleObj_SetClientSite;
+ g_PseudoObj_OleObjectVtbl.GetClientSite = PseudoObj_OleObj_GetClientSite;
+ g_PseudoObj_OleObjectVtbl.SetHostNames = PseudoObj_OleObj_SetHostNames;
+ g_PseudoObj_OleObjectVtbl.Close = PseudoObj_OleObj_Close;
+ g_PseudoObj_OleObjectVtbl.SetMoniker = PseudoObj_OleObj_SetMoniker;
+ g_PseudoObj_OleObjectVtbl.GetMoniker = PseudoObj_OleObj_GetMoniker;
+ g_PseudoObj_OleObjectVtbl.InitFromData = PseudoObj_OleObj_InitFromData;
+ g_PseudoObj_OleObjectVtbl.GetClipboardData =
+ PseudoObj_OleObj_GetClipboardData;
+ g_PseudoObj_OleObjectVtbl.DoVerb = PseudoObj_OleObj_DoVerb;
+ g_PseudoObj_OleObjectVtbl.EnumVerbs = PseudoObj_OleObj_EnumVerbs;
+ g_PseudoObj_OleObjectVtbl.Update = PseudoObj_OleObj_Update;
+ g_PseudoObj_OleObjectVtbl.IsUpToDate = PseudoObj_OleObj_IsUpToDate;
+ g_PseudoObj_OleObjectVtbl.GetUserType = PseudoObj_OleObj_GetUserType;
+ g_PseudoObj_OleObjectVtbl.GetUserClassID= PseudoObj_OleObj_GetUserClassID;
+ g_PseudoObj_OleObjectVtbl.SetExtent = PseudoObj_OleObj_SetExtent;
+ g_PseudoObj_OleObjectVtbl.GetExtent = PseudoObj_OleObj_GetExtent;
+ g_PseudoObj_OleObjectVtbl.Advise = PseudoObj_OleObj_Advise;
+ g_PseudoObj_OleObjectVtbl.Unadvise = PseudoObj_OleObj_Unadvise;
+ g_PseudoObj_OleObjectVtbl.EnumAdvise = PseudoObj_OleObj_EnumAdvise;
+ g_PseudoObj_OleObjectVtbl.GetMiscStatus = PseudoObj_OleObj_GetMiscStatus;
+ g_PseudoObj_OleObjectVtbl.SetColorScheme= PseudoObj_OleObj_SetColorScheme;
+ fStatus = OleStdCheckVtbl(
+ &g_PseudoObj_OleObjectVtbl,
+ sizeof(IOleObjectVtbl),
+ "IOleObject"
+ );
+ if (! fStatus) return FALSE;
+
+ // ServerDoc::IDataObject method table
+ OleStdInitVtbl(&g_PseudoObj_DataObjectVtbl, sizeof(IDataObjectVtbl));
+ g_PseudoObj_DataObjectVtbl.QueryInterface =
+ PseudoObj_DataObj_QueryInterface;
+ g_PseudoObj_DataObjectVtbl.AddRef = PseudoObj_DataObj_AddRef;
+ g_PseudoObj_DataObjectVtbl.Release = PseudoObj_DataObj_Release;
+ g_PseudoObj_DataObjectVtbl.GetData = PseudoObj_DataObj_GetData;
+ g_PseudoObj_DataObjectVtbl.GetDataHere = PseudoObj_DataObj_GetDataHere;
+ g_PseudoObj_DataObjectVtbl.QueryGetData = PseudoObj_DataObj_QueryGetData;
+ g_PseudoObj_DataObjectVtbl.GetCanonicalFormatEtc =
+ PseudoObj_DataObj_GetCanonicalFormatEtc;
+ g_PseudoObj_DataObjectVtbl.SetData = PseudoObj_DataObj_SetData;
+ g_PseudoObj_DataObjectVtbl.EnumFormatEtc= PseudoObj_DataObj_EnumFormatEtc;
+ g_PseudoObj_DataObjectVtbl.DAdvise = PseudoObj_DataObj_DAdvise;
+ g_PseudoObj_DataObjectVtbl.DUnadvise = PseudoObj_DataObj_DUnadvise;
+ g_PseudoObj_DataObjectVtbl.EnumDAdvise = PseudoObj_DataObj_EnumAdvise;
+
+ fStatus = OleStdCheckVtbl(
+ &g_PseudoObj_DataObjectVtbl,
+ sizeof(IDataObjectVtbl),
+ "IDataObject"
+ );
+ if (! fStatus) return FALSE;
+
+ return TRUE;
+}
+
+#endif // OLE_SERVER
+
+
+
+#if defined( OLE_CNTR )
+
+/*************************************************************************
+** ContainerDoc Supprt Functions Used by Container versions
+*************************************************************************/
+
+
+/* ContainerApp_InitInstance
+ * -------------------------
+ *
+ * Initialize the app instance by creating the main frame window and
+ * performing app instance specific initializations
+ * (eg. initializing interface Vtbls).
+ *
+ * RETURNS: TRUE if the memory could be allocated, and the server app
+ * was properly initialized.
+ * FALSE otherwise
+ *
+ */
+
+BOOL ContainerApp_InitInstance(
+ LPCONTAINERAPP lpContainerApp,
+ HINSTANCE hInst,
+ int nCmdShow
+)
+{
+ LPOLEAPP lpOleApp = (LPOLEAPP)lpContainerApp;
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpContainerApp;
+
+ lpContainerApp->m_cfCntrOutl=RegisterClipboardFormat(CONTAINERDOCFORMAT);
+ if(! lpContainerApp->m_cfCntrOutl) {
+ // REVIEW: should load string from string resource
+ OutlineApp_ErrorMessage(lpOutlineApp, "Can't register clipboard format!");
+ return FALSE;
+ }
+
+#if defined( INPLACE_CNTR )
+
+ lpContainerApp->m_fPendingUIDeactivate = FALSE;
+ lpContainerApp->m_fMustResizeClientArea = FALSE;
+ lpContainerApp->m_lpIPActiveObj = NULL;
+ lpContainerApp->m_hWndUIActiveObj = NULL;
+ lpContainerApp->m_hAccelIPCntr = LoadAccelerators(
+ hInst,
+ "InPlaceCntrOutlAccel"
+ );
+ lpContainerApp->m_hMenuFile = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_FILEMENU
+ );
+ lpContainerApp->m_hMenuView = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_VIEWMENU
+ );
+ lpContainerApp->m_hMenuDebug = GetSubMenu (
+ lpOutlineApp->m_hMenuApp,
+ POS_DEBUGMENU
+ );
+
+ INIT_INTERFACEIMPL(
+ &lpContainerApp->m_OleInPlaceFrame,
+ &g_CntrApp_OleInPlaceFrameVtbl,
+ lpContainerApp
+ );
+
+#endif
+
+ /* Setup arrays used by IDataObject::EnumFormatEtc. This is used to
+ ** support copy/paste and drag/drop operations.
+ **
+ ** OLE2NOTE: The order that the formats are listed for GetData is very
+ ** significant. It should be listed in order of highest fidelity
+ ** formats to least fidelity formats. A common ordering will be:
+ ** 1. private app formats
+ ** 2. CF_EMBEDSOURCE or CF_EMBEDOBJECT (as appropriate)
+ ** 3. lower fidelity interchange formats
+ ** 4. CF_METAFILEPICT
+ ** (graphic-related apps might offer picture 1st!)
+ ** 5. CF_OBJECTDESCRIPTOR
+ ** 6. CF_LINKSOURCE
+ ** 6. CF_LINKSRCDESCRIPTOR
+ */
+
+ /* m_arrDocGetFmts array enumerates the formats that a ContainerDoc
+ ** object can offer (give) through a IDataObject::GetData call
+ ** when the selection copied is NOT a single embedded object.
+ ** when a single embedded object this list of formats available
+ ** is built dynamically depending on the object copied. (see
+ ** ContainerDoc_SetupDocGetFmts).
+ ** The formats are listed in priority order.
+ ** ContainerDoc objects accept data formats in the following order:
+ ** 1. CF_CNTROUTL
+ ** 2. CF_OUTLINE
+ ** 3. CF_TEXT
+ ** 4. CF_OBJECTDESCRIPTOR
+ **
+ ** OLE2NOTE: CF_OBJECTDESCRIPTOR format is used to describe the
+ ** data on the clipboard. this information is intended to be
+ ** used, for example, to drive the PasteSpecial dialog. it is
+ ** useful to render CF_OBJECTDESCRIPTOR format even when the
+ ** data on the clipboard does NOT include CF_EMBEDDEDOBJECT
+ ** format or CF_EMBEDSOURCE format as when a selection that is
+ ** not a single OLE object is copied from the container only
+ ** version CNTROUTL. by rendering CF_OBJECTDESCRIPTOR format the
+ ** app can indicate a useful string to identifiy the source of
+ ** the copy to the user.
+ */
+
+ lpOleApp->m_arrDocGetFmts[0].cfFormat = lpContainerApp->m_cfCntrOutl;
+ lpOleApp->m_arrDocGetFmts[0].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[0].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[0].tymed = TYMED_ISTORAGE;
+ lpOleApp->m_arrDocGetFmts[0].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[1].cfFormat = lpOutlineApp->m_cfOutline;
+ lpOleApp->m_arrDocGetFmts[1].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[1].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[1].tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrDocGetFmts[1].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[2].cfFormat = CF_TEXT;
+ lpOleApp->m_arrDocGetFmts[2].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[2].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[2].tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrDocGetFmts[2].lindex = -1;
+
+ lpOleApp->m_arrDocGetFmts[3].cfFormat = lpOleApp->m_cfObjectDescriptor;
+ lpOleApp->m_arrDocGetFmts[3].ptd = NULL;
+ lpOleApp->m_arrDocGetFmts[3].dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrDocGetFmts[3].tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrDocGetFmts[3].lindex = -1;
+
+ lpOleApp->m_nDocGetFmts = 4;
+
+ /* m_arrSingleObjGetFmts array enumerates the formats that a
+ ** ContainerDoc object can offer (give) through a
+ ** IDataObject::GetData call when the selection copied IS a
+ ** single OLE object.
+ ** ContainerDoc objects accept data formats in the following order:
+ ** 1. CF_CNTROUTL
+ ** 2. CF_EMBEDDEDOBJECT
+ ** 3. CF_OBJECTDESCRIPTOR
+ ** 4. CF_METAFILEPICT (note DVASPECT will vary)
+ ** 5. CF_LINKSOURCE *
+ ** 6. CF_LINKSRCDESCRIPTOR *
+ **
+ ** * OLE2NOTE: CF_LINKSOURCE and CF_LINKSRCDESCRIPTOR is only
+ ** offered if the OLE object is allowed to be linked to from the
+ ** inside (ie. we are allowed to give out a moniker which binds
+ ** to the running OLE object), then we want to offer
+ ** CF_LINKSOURCE format. if the object is an OLE 2.0 embedded
+ ** object then it is allowed to be linked to from the inside. if
+ ** the object is either an OleLink or an OLE 1.0 embedding then
+ ** it can not be linked to from the inside. if we were a
+ ** container/server app then we could offer linking to the
+ ** outside of the object (ie. a pseudo object within our
+ ** document). we are a container only app that does not support
+ ** linking to ranges of its data.
+ ** the simplest way to determine if an object can be linked to
+ ** on the inside is to call IOleObject::GetMiscStatus and test
+ ** to see if the OLEMISC_CANTLINKINSIDE bit is NOT set.
+ **
+ ** OLE2NOTE: optionally, a container that wants to have a
+ ** potentially richer data transfer, can enumerate the data
+ ** formats from the OLE object's cache and offer them too. if
+ ** the object has a special handler, then it might be able to
+ ** render additional data formats.
+ */
+ lpContainerApp->m_arrSingleObjGetFmts[0].cfFormat =
+ lpContainerApp->m_cfCntrOutl;
+ lpContainerApp->m_arrSingleObjGetFmts[0].ptd = NULL;
+ lpContainerApp->m_arrSingleObjGetFmts[0].dwAspect = DVASPECT_CONTENT;
+ lpContainerApp->m_arrSingleObjGetFmts[0].tymed = TYMED_ISTORAGE;
+ lpContainerApp->m_arrSingleObjGetFmts[0].lindex = -1;
+
+ lpContainerApp->m_arrSingleObjGetFmts[1].cfFormat =
+ lpOleApp->m_cfEmbeddedObject;
+ lpContainerApp->m_arrSingleObjGetFmts[1].ptd = NULL;
+ lpContainerApp->m_arrSingleObjGetFmts[1].dwAspect = DVASPECT_CONTENT;
+ lpContainerApp->m_arrSingleObjGetFmts[1].tymed = TYMED_ISTORAGE;
+ lpContainerApp->m_arrSingleObjGetFmts[1].lindex = -1;
+
+ lpContainerApp->m_arrSingleObjGetFmts[2].cfFormat =
+ lpOleApp->m_cfObjectDescriptor;
+ lpContainerApp->m_arrSingleObjGetFmts[2].ptd = NULL;
+ lpContainerApp->m_arrSingleObjGetFmts[2].dwAspect = DVASPECT_CONTENT;
+ lpContainerApp->m_arrSingleObjGetFmts[2].tymed = TYMED_HGLOBAL;
+ lpContainerApp->m_arrSingleObjGetFmts[2].lindex = -1;
+
+ lpContainerApp->m_arrSingleObjGetFmts[3].cfFormat = CF_METAFILEPICT;
+ lpContainerApp->m_arrSingleObjGetFmts[3].ptd = NULL;
+ lpContainerApp->m_arrSingleObjGetFmts[3].dwAspect = DVASPECT_CONTENT;
+ lpContainerApp->m_arrSingleObjGetFmts[3].tymed = TYMED_MFPICT;
+ lpContainerApp->m_arrSingleObjGetFmts[3].lindex = -1;
+
+ lpContainerApp->m_arrSingleObjGetFmts[4].cfFormat =
+ lpOleApp->m_cfLinkSource;
+ lpContainerApp->m_arrSingleObjGetFmts[4].ptd = NULL;
+ lpContainerApp->m_arrSingleObjGetFmts[4].dwAspect = DVASPECT_CONTENT;
+ lpContainerApp->m_arrSingleObjGetFmts[4].tymed = TYMED_ISTREAM;
+ lpContainerApp->m_arrSingleObjGetFmts[4].lindex = -1;
+
+ lpContainerApp->m_arrSingleObjGetFmts[5].cfFormat =
+ lpOleApp->m_cfLinkSrcDescriptor;
+ lpContainerApp->m_arrSingleObjGetFmts[5].ptd = NULL;
+ lpContainerApp->m_arrSingleObjGetFmts[5].dwAspect = DVASPECT_CONTENT;
+ lpContainerApp->m_arrSingleObjGetFmts[5].tymed = TYMED_HGLOBAL;
+ lpContainerApp->m_arrSingleObjGetFmts[5].lindex = -1;
+
+ lpContainerApp->m_nSingleObjGetFmts = 6;
+
+ /* NOTE: the Container-Only version of Outline does NOT offer
+ ** IDataObject interface from its User documents and the
+ ** IDataObject interface available from DataTransferDoc's do NOT
+ ** support SetData. IDataObject interface is required by objects
+ ** which can be embedded or linked. the Container-only app only
+ ** allows linking to its contained objects, NOT the data of the
+ ** container itself.
+ */
+
+ /* m_arrPasteEntries array enumerates the formats that a ContainerDoc
+ ** object can accept from the clipboard. this array is used to
+ ** support the PasteSpecial dialog.
+ ** The formats are listed in priority order.
+ ** ContainerDoc objects accept data formats in the following order:
+ ** 1. CF_CNTROUTL
+ ** 2. CF_OUTLINE
+ ** 3. CF_EMBEDDEDOBJECT
+ ** 4. CF_TEXT
+ ** 5. CF_METAFILEPICT
+ ** 6. CF_DIB
+ ** 7. CF_BITMAP
+ ** 8. CF_LINKSOURCE
+ **
+ ** NOTE: specifying CF_EMBEDDEDOBJECT in the PasteEntry array
+ ** indicates that the caller is interested in pasting OLE
+ ** objects (ie. the caller calls OleCreateFromData). the
+ ** OleUIPasteSpecial dialog and OleStdGetPriorityClipboardFormat
+ ** call OleQueryCreateFromData to see if an OLE object format is
+ ** available. thus, in fact if CF_EMBEDSOURCE or CF_FILENAME are
+ ** available from the data source then and OLE object can be
+ ** created and this entry will be matched. the caller should
+ ** only specify one object type format.
+ ** CF_FILENAME format (as generated by copying a file to
+ ** the clipboard from the FileManager) is considered an object
+ ** format; OleCreatFromData creates an object if the file has an
+ ** associated class (see GetClassFile API) or if no class it
+ ** creates an OLE 1.0 Package object. this format can also be
+ ** paste linked by calling OleCreateLinkFromData.
+ */
+ // REVIEW: strings should be loaded from string resource
+
+ lpOleApp->m_arrPasteEntries[0].fmtetc.cfFormat =
+ lpContainerApp->m_cfCntrOutl;
+ lpOleApp->m_arrPasteEntries[0].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[0].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[0].fmtetc.tymed = TYMED_ISTORAGE;
+ lpOleApp->m_arrPasteEntries[0].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[0].lpstrFormatName = "Container Outline Data";
+ lpOleApp->m_arrPasteEntries[0].lpstrResultText =
+ "Container Outline Data";
+ lpOleApp->m_arrPasteEntries[0].dwFlags = OLEUIPASTE_PASTEONLY;
+
+ lpOleApp->m_arrPasteEntries[1].fmtetc.cfFormat =lpOutlineApp->m_cfOutline;
+ lpOleApp->m_arrPasteEntries[1].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[1].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[1].fmtetc.tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrPasteEntries[1].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[1].lpstrFormatName = "Outline Data";
+ lpOleApp->m_arrPasteEntries[1].lpstrResultText = "Outline Data";
+ lpOleApp->m_arrPasteEntries[1].dwFlags = OLEUIPASTE_PASTEONLY;
+
+ lpOleApp->m_arrPasteEntries[2].fmtetc.cfFormat =
+ lpOleApp->m_cfEmbeddedObject;
+ lpOleApp->m_arrPasteEntries[2].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[2].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[2].fmtetc.tymed = TYMED_ISTORAGE;
+ lpOleApp->m_arrPasteEntries[2].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[2].lpstrFormatName = "%s";
+ lpOleApp->m_arrPasteEntries[2].lpstrResultText = "%s";
+ lpOleApp->m_arrPasteEntries[2].dwFlags =
+ OLEUIPASTE_PASTE | OLEUIPASTE_ENABLEICON;
+
+ lpOleApp->m_arrPasteEntries[3].fmtetc.cfFormat = CF_TEXT;
+ lpOleApp->m_arrPasteEntries[3].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[3].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[3].fmtetc.tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrPasteEntries[3].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[3].lpstrFormatName = "Text";
+ lpOleApp->m_arrPasteEntries[3].lpstrResultText = "text";
+ lpOleApp->m_arrPasteEntries[3].dwFlags = OLEUIPASTE_PASTEONLY;
+
+ lpOleApp->m_arrPasteEntries[4].fmtetc.cfFormat = CF_METAFILEPICT;
+ lpOleApp->m_arrPasteEntries[4].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[4].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[4].fmtetc.tymed = TYMED_MFPICT;
+ lpOleApp->m_arrPasteEntries[4].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[4].lpstrFormatName = "Picture (Metafile)";
+ lpOleApp->m_arrPasteEntries[4].lpstrResultText = "a static picture";
+ lpOleApp->m_arrPasteEntries[4].dwFlags = OLEUIPASTE_PASTEONLY;
+
+ lpOleApp->m_arrPasteEntries[5].fmtetc.cfFormat = CF_DIB;
+ lpOleApp->m_arrPasteEntries[5].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[5].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[5].fmtetc.tymed = TYMED_HGLOBAL;
+ lpOleApp->m_arrPasteEntries[5].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[5].lpstrFormatName = "Picture (DIB)";
+ lpOleApp->m_arrPasteEntries[5].lpstrResultText = "a static picture";
+ lpOleApp->m_arrPasteEntries[5].dwFlags = OLEUIPASTE_PASTEONLY;
+
+ lpOleApp->m_arrPasteEntries[6].fmtetc.cfFormat = CF_BITMAP;
+ lpOleApp->m_arrPasteEntries[6].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[6].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[6].fmtetc.tymed = TYMED_GDI;
+ lpOleApp->m_arrPasteEntries[6].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[6].lpstrFormatName = "Picture (Bitmap)";
+ lpOleApp->m_arrPasteEntries[6].lpstrResultText = "a static picture";
+ lpOleApp->m_arrPasteEntries[6].dwFlags = OLEUIPASTE_PASTEONLY;
+
+ lpOleApp->m_arrPasteEntries[7].fmtetc.cfFormat = lpOleApp->m_cfLinkSource;
+ lpOleApp->m_arrPasteEntries[7].fmtetc.ptd = NULL;
+ lpOleApp->m_arrPasteEntries[7].fmtetc.dwAspect = DVASPECT_CONTENT;
+ lpOleApp->m_arrPasteEntries[7].fmtetc.tymed = TYMED_ISTREAM;
+ lpOleApp->m_arrPasteEntries[7].fmtetc.lindex = -1;
+ lpOleApp->m_arrPasteEntries[7].lpstrFormatName = "%s";
+ lpOleApp->m_arrPasteEntries[7].lpstrResultText = "%s";
+ lpOleApp->m_arrPasteEntries[7].dwFlags =
+ OLEUIPASTE_LINKTYPE1 | OLEUIPASTE_ENABLEICON;
+
+ lpOleApp->m_nPasteEntries = 8;
+
+ /* m_arrLinkTypes array enumerates the link types that a ContainerDoc
+ ** object can accept from the clipboard
+ */
+
+ lpOleApp->m_arrLinkTypes[0] = lpOleApp->m_cfLinkSource;
+ lpOleApp->m_nLinkTypes = 1;
+
+ return TRUE;
+}
+
+
+/* ContainerApp_InitVtbls
+** ----------------------
+**
+** initialize the interface Vtbl's used to support the OLE 2.0
+** Container functionality.
+*/
+
+BOOL ContainerApp_InitVtbls(LPCONTAINERAPP lpApp)
+{
+ BOOL fStatus;
+
+ // ContainerDoc::IOleUILinkContainer method table
+ OleStdInitVtbl(
+ &g_CntrDoc_OleUILinkContainerVtbl,
+ sizeof(IOleUILinkContainerVtbl)
+ );
+ g_CntrDoc_OleUILinkContainerVtbl.QueryInterface =
+ CntrDoc_LinkCont_QueryInterface;
+ g_CntrDoc_OleUILinkContainerVtbl.AddRef = CntrDoc_LinkCont_AddRef;
+ g_CntrDoc_OleUILinkContainerVtbl.Release = CntrDoc_LinkCont_Release;
+ g_CntrDoc_OleUILinkContainerVtbl.GetNextLink =
+ CntrDoc_LinkCont_GetNextLink;
+ g_CntrDoc_OleUILinkContainerVtbl.SetLinkUpdateOptions =
+ CntrDoc_LinkCont_SetLinkUpdateOptions;
+ g_CntrDoc_OleUILinkContainerVtbl.GetLinkUpdateOptions =
+ CntrDoc_LinkCont_GetLinkUpdateOptions;
+ g_CntrDoc_OleUILinkContainerVtbl.SetLinkSource =
+ CntrDoc_LinkCont_SetLinkSource;
+ g_CntrDoc_OleUILinkContainerVtbl.GetLinkSource =
+ CntrDoc_LinkCont_GetLinkSource;
+ g_CntrDoc_OleUILinkContainerVtbl.OpenLinkSource =
+ CntrDoc_LinkCont_OpenLinkSource;
+ g_CntrDoc_OleUILinkContainerVtbl.UpdateLink =
+ CntrDoc_LinkCont_UpdateLink;
+ g_CntrDoc_OleUILinkContainerVtbl.CancelLink =
+ CntrDoc_LinkCont_CancelLink;
+ fStatus = OleStdCheckVtbl(
+ &g_CntrDoc_OleUILinkContainerVtbl,
+ sizeof(IOleUILinkContainerVtbl),
+ "IOleUILinkContainer"
+ );
+ if (! fStatus) return FALSE;
+
+#if defined( INPLACE_CNTR )
+
+ // ContainerApp::IOleInPlaceFrame interface method table
+ OleStdInitVtbl(
+ &g_CntrApp_OleInPlaceFrameVtbl,
+ sizeof(g_CntrApp_OleInPlaceFrameVtbl)
+ );
+
+ g_CntrApp_OleInPlaceFrameVtbl.QueryInterface
+ = CntrApp_IPFrame_QueryInterface;
+ g_CntrApp_OleInPlaceFrameVtbl.AddRef
+ = CntrApp_IPFrame_AddRef;
+ g_CntrApp_OleInPlaceFrameVtbl.Release
+ = CntrApp_IPFrame_Release;
+ g_CntrApp_OleInPlaceFrameVtbl.GetWindow
+ = CntrApp_IPFrame_GetWindow;
+ g_CntrApp_OleInPlaceFrameVtbl.ContextSensitiveHelp
+ = CntrApp_IPFrame_ContextSensitiveHelp;
+
+ g_CntrApp_OleInPlaceFrameVtbl.GetBorder
+ = CntrApp_IPFrame_GetBorder;
+ g_CntrApp_OleInPlaceFrameVtbl.RequestBorderSpace
+ = CntrApp_IPFrame_RequestBorderSpace;
+ g_CntrApp_OleInPlaceFrameVtbl.SetBorderSpace
+ = CntrApp_IPFrame_SetBorderSpace;
+ g_CntrApp_OleInPlaceFrameVtbl.SetActiveObject
+ = CntrApp_IPFrame_SetActiveObject;
+ g_CntrApp_OleInPlaceFrameVtbl.InsertMenus
+ = CntrApp_IPFrame_InsertMenus;
+ g_CntrApp_OleInPlaceFrameVtbl.SetMenu
+ = CntrApp_IPFrame_SetMenu;
+ g_CntrApp_OleInPlaceFrameVtbl.RemoveMenus
+ = CntrApp_IPFrame_RemoveMenus;
+ g_CntrApp_OleInPlaceFrameVtbl.SetStatusText
+ = CntrApp_IPFrame_SetStatusText;
+ g_CntrApp_OleInPlaceFrameVtbl.EnableModeless
+ = CntrApp_IPFrame_EnableModeless;
+ g_CntrApp_OleInPlaceFrameVtbl.TranslateAccelerator
+ = CntrApp_IPFrame_TranslateAccelerator;
+
+ fStatus = OleStdCheckVtbl(
+ &g_CntrApp_OleInPlaceFrameVtbl,
+ sizeof(g_CntrApp_OleInPlaceFrameVtbl),
+ "IOleInPlaceFrame"
+ );
+ if (! fStatus) return FALSE;
+
+#endif // INPLACE_CNTR
+
+
+ // ContainerLine::IUnknown interface method table
+ OleStdInitVtbl(
+ &g_CntrLine_UnknownVtbl,
+ sizeof(g_CntrLine_UnknownVtbl)
+ );
+ g_CntrLine_UnknownVtbl.QueryInterface = CntrLine_Unk_QueryInterface;
+ g_CntrLine_UnknownVtbl.AddRef = CntrLine_Unk_AddRef;
+ g_CntrLine_UnknownVtbl.Release = CntrLine_Unk_Release;
+ fStatus = OleStdCheckVtbl(
+ &g_CntrLine_UnknownVtbl,
+ sizeof(g_CntrLine_UnknownVtbl),
+ "IUnknown"
+ );
+ if (! fStatus) return FALSE;
+
+ // ContainerLine::IOleClientSite interface method table
+ OleStdInitVtbl(
+ &g_CntrLine_OleClientSiteVtbl,
+ sizeof(g_CntrLine_OleClientSiteVtbl)
+ );
+ g_CntrLine_OleClientSiteVtbl.QueryInterface =
+ CntrLine_CliSite_QueryInterface;
+ g_CntrLine_OleClientSiteVtbl.AddRef = CntrLine_CliSite_AddRef;
+ g_CntrLine_OleClientSiteVtbl.Release = CntrLine_CliSite_Release;
+ g_CntrLine_OleClientSiteVtbl.SaveObject = CntrLine_CliSite_SaveObject;
+ g_CntrLine_OleClientSiteVtbl.GetMoniker = CntrLine_CliSite_GetMoniker;
+ g_CntrLine_OleClientSiteVtbl.GetContainer = CntrLine_CliSite_GetContainer;
+ g_CntrLine_OleClientSiteVtbl.ShowObject = CntrLine_CliSite_ShowObject;
+ g_CntrLine_OleClientSiteVtbl.OnShowWindow = CntrLine_CliSite_OnShowWindow;
+ g_CntrLine_OleClientSiteVtbl.RequestNewObjectLayout =
+ CntrLine_CliSite_RequestNewObjectLayout;
+ fStatus = OleStdCheckVtbl(
+ &g_CntrLine_OleClientSiteVtbl,
+ sizeof(g_CntrLine_OleClientSiteVtbl),
+ "IOleClientSite"
+ );
+ if (! fStatus) return FALSE;
+
+ // ContainerLine::IAdviseSink interface method table
+ OleStdInitVtbl(
+ &g_CntrLine_AdviseSinkVtbl,
+ sizeof(g_CntrLine_AdviseSinkVtbl)
+ );
+ g_CntrLine_AdviseSinkVtbl.QueryInterface= CntrLine_AdvSink_QueryInterface;
+ g_CntrLine_AdviseSinkVtbl.AddRef = CntrLine_AdvSink_AddRef;
+ g_CntrLine_AdviseSinkVtbl.Release = CntrLine_AdvSink_Release;
+ g_CntrLine_AdviseSinkVtbl.OnDataChange = CntrLine_AdvSink_OnDataChange;
+ g_CntrLine_AdviseSinkVtbl.OnViewChange = CntrLine_AdvSink_OnViewChange;
+ g_CntrLine_AdviseSinkVtbl.OnRename = CntrLine_AdvSink_OnRename;
+ g_CntrLine_AdviseSinkVtbl.OnSave = CntrLine_AdvSink_OnSave;
+ g_CntrLine_AdviseSinkVtbl.OnClose = CntrLine_AdvSink_OnClose;
+ fStatus = OleStdCheckVtbl(
+ &g_CntrLine_AdviseSinkVtbl,
+ sizeof(g_CntrLine_AdviseSinkVtbl),
+ "IAdviseSink"
+ );
+ if (! fStatus) return FALSE;
+
+
+#if defined( INPLACE_CNTR )
+
+ // ContainerLine::IOleInPlaceSite interface method table
+ OleStdInitVtbl(
+ &g_CntrLine_OleInPlaceSiteVtbl,
+ sizeof(g_CntrLine_OleInPlaceSiteVtbl)
+ );
+
+ g_CntrLine_OleInPlaceSiteVtbl.QueryInterface
+ = CntrLine_IPSite_QueryInterface;
+ g_CntrLine_OleInPlaceSiteVtbl.AddRef
+ = CntrLine_IPSite_AddRef;
+ g_CntrLine_OleInPlaceSiteVtbl.Release
+ = CntrLine_IPSite_Release;
+ g_CntrLine_OleInPlaceSiteVtbl.GetWindow
+ = CntrLine_IPSite_GetWindow;
+ g_CntrLine_OleInPlaceSiteVtbl.ContextSensitiveHelp
+ = CntrLine_IPSite_ContextSensitiveHelp;
+ g_CntrLine_OleInPlaceSiteVtbl.CanInPlaceActivate
+ = CntrLine_IPSite_CanInPlaceActivate;
+ g_CntrLine_OleInPlaceSiteVtbl.OnInPlaceActivate
+ = CntrLine_IPSite_OnInPlaceActivate;
+ g_CntrLine_OleInPlaceSiteVtbl.OnUIActivate
+ = CntrLine_IPSite_OnUIActivate;
+ g_CntrLine_OleInPlaceSiteVtbl.GetWindowContext
+ = CntrLine_IPSite_GetWindowContext;
+ g_CntrLine_OleInPlaceSiteVtbl.Scroll
+ = CntrLine_IPSite_Scroll;
+ g_CntrLine_OleInPlaceSiteVtbl.OnUIDeactivate
+ = CntrLine_IPSite_OnUIDeactivate;
+
+ g_CntrLine_OleInPlaceSiteVtbl.OnInPlaceDeactivate
+ = CntrLine_IPSite_OnInPlaceDeactivate;
+ g_CntrLine_OleInPlaceSiteVtbl.DiscardUndoState
+ = CntrLine_IPSite_DiscardUndoState;
+ g_CntrLine_OleInPlaceSiteVtbl.DeactivateAndUndo
+ = CntrLine_IPSite_DeactivateAndUndo;
+ g_CntrLine_OleInPlaceSiteVtbl.OnPosRectChange
+ = CntrLine_IPSite_OnPosRectChange;
+
+ fStatus = OleStdCheckVtbl(
+ &g_CntrLine_OleInPlaceSiteVtbl,
+ sizeof(g_CntrLine_OleInPlaceSiteVtbl),
+ "IOleInPlaceSite"
+ );
+ if (! fStatus) return FALSE;
+
+#endif // INPLACE_CNTR
+
+ return TRUE;
+}
+
+
+#endif // OLE_CNTR