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

Windows编程

开发平台:

Visual C++

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