Annotation of mstools/ole20/samples/outline/oledoc.c, revision 1.1

1.1     ! root        1: /*************************************************************************
        !             2: **
        !             3: **    OLE 2 Server Sample Code
        !             4: **
        !             5: **    oledoc.c
        !             6: **
        !             7: **    This file contains general OleDoc methods and related support
        !             8: **    functions. OleDoc implementation is used by both the Container
        !             9: **    versions and the Server (Object) versions of the Outline Sample.
        !            10: **    
        !            11: **    This file includes general support for the following:
        !            12: **    1. show/hide doc window
        !            13: **    2. QueryInterface, AddRef, Release
        !            14: **    3. document locking (calls CoLockObjectExternal)
        !            15: **    4. document shutdown (Close, Destroy)
        !            16: **    5. clipboard support
        !            17: **    
        !            18: **    OleDoc Object
        !            19: **      exposed interfaces:
        !            20: **          IUnknown
        !            21: **          IPersistFile
        !            22: **          IOleItemContainer
        !            23: **          IDataObject
        !            24: **    
        !            25: **    (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
        !            26: **
        !            27: *************************************************************************/
        !            28: 
        !            29: 
        !            30: #include "outline.h"
        !            31: 
        !            32: OLEDBGDATA
        !            33: 
        !            34: extern LPOUTLINEAPP             g_lpApp;
        !            35: 
        !            36: extern IUnknownVtbl             g_OleDoc_UnknownVtbl;
        !            37: extern IPersistFileVtbl         g_OleDoc_PersistFileVtbl;
        !            38: extern IOleItemContainerVtbl    g_OleDoc_OleItemContainerVtbl;
        !            39: extern IDataObjectVtbl          g_OleDoc_DataObjectVtbl;
        !            40: 
        !            41: #if defined( USE_DRAGDROP )
        !            42: extern IDropTargetVtbl          g_OleDoc_DropTargetVtbl;
        !            43: extern IDropSourceVtbl          g_OleDoc_DropSourceVtbl;
        !            44: #endif  // USE_DRAGDROP
        !            45: 
        !            46: #if defined( INPLACE_CNTR )
        !            47: extern BOOL g_fInsideOutContainer;
        !            48: #endif 
        !            49: 
        !            50: 
        !            51: /* OleDoc_Init
        !            52:  * -----------
        !            53:  *
        !            54:  *  Initialize the fields of a new OleDoc object. The object is initially
        !            55:  *  not associated with a file or an (Untitled) document. This function sets
        !            56:  *  the docInitType to DOCTYPE_UNKNOWN. After calling this function the
        !            57:  *  caller should call:
        !            58:  *      1.) Doc_InitNewFile to set the OleDoc to (Untitled)
        !            59:  *      2.) Doc_LoadFromFile to associate the OleDoc with a file.
        !            60:  *  This function creates a new window for the document.
        !            61:  *
        !            62:  *  NOTE: the window is initially created with a NIL size. it must be
        !            63:  *        sized and positioned by the caller. also the document is initially
        !            64:  *        created invisible. the caller must call OutlineDoc_ShowWindow
        !            65:  *        after sizing it to make the document window visible.
        !            66:  */
        !            67: BOOL OleDoc_Init(LPOLEDOC lpOleDoc, BOOL fDataTransferDoc)
        !            68: {
        !            69:     LPOLEAPP   lpOleApp = (LPOLEAPP)g_lpApp;
        !            70:     LPLINELIST lpLL     = (LPLINELIST)&((LPOUTLINEDOC)lpOleDoc)->m_LineList;
        !            71: 
        !            72:     lpOleDoc->m_cRef                        = 0;
        !            73:     lpOleDoc->m_cLock                       = 0;
        !            74: 
        !            75:     lpOleDoc->m_dwRegROT                    = 0;
        !            76:     lpOleDoc->m_lpFileMoniker               = NULL;
        !            77:     lpOleDoc->m_fLinkSourceAvail            = FALSE;
        !            78:     lpOleDoc->m_lpSrcDocOfCopy              = NULL;
        !            79:     lpOleDoc->m_fObjIsClosing               = FALSE;
        !            80:     lpOleDoc->m_fObjIsDestroying            = FALSE;
        !            81:     lpOleDoc->m_fUpdateEditMenu             = FALSE;
        !            82: 
        !            83: #if defined( USE_DRAGDROP )
        !            84:     lpOleDoc->m_dwTimeEnterScrollArea       = 0;
        !            85:     lpOleDoc->m_lastdwScrollDir             = SCROLLDIR_NULL;
        !            86:     lpOleDoc->m_fRegDragDrop                = FALSE;
        !            87:     lpOleDoc->m_fLocalDrag                  = FALSE;
        !            88:     lpOleDoc->m_fCanDropCopy                = FALSE;
        !            89:     lpOleDoc->m_fCanDropLink                = FALSE;
        !            90:     lpOleDoc->m_fLocalDrop                  = FALSE;
        !            91:     lpOleDoc->m_fDragLeave                  = FALSE;
        !            92:     lpOleDoc->m_fPendingDrag                = FALSE;
        !            93: #endif
        !            94: 
        !            95:     INIT_INTERFACEIMPL(
        !            96:             &lpOleDoc->m_Unknown,
        !            97:             &g_OleDoc_UnknownVtbl,
        !            98:             lpOleDoc
        !            99:     );
        !           100: 
        !           101:     INIT_INTERFACEIMPL(
        !           102:             &lpOleDoc->m_PersistFile,
        !           103:             &g_OleDoc_PersistFileVtbl,
        !           104:             lpOleDoc
        !           105:     );
        !           106: 
        !           107:     INIT_INTERFACEIMPL(
        !           108:             &lpOleDoc->m_OleItemContainer,
        !           109:             &g_OleDoc_OleItemContainerVtbl,
        !           110:             lpOleDoc
        !           111:     );
        !           112: 
        !           113:     INIT_INTERFACEIMPL(
        !           114:             &lpOleDoc->m_DataObject,
        !           115:             &g_OleDoc_DataObjectVtbl,
        !           116:             lpOleDoc
        !           117:     );
        !           118: 
        !           119: #if defined( USE_DRAGDROP )
        !           120:     INIT_INTERFACEIMPL(
        !           121:             &lpOleDoc->m_DropSource,
        !           122:             &g_OleDoc_DropSourceVtbl,
        !           123:             lpOleDoc
        !           124:     );
        !           125: 
        !           126:     INIT_INTERFACEIMPL(
        !           127:             &lpOleDoc->m_DropTarget,
        !           128:             &g_OleDoc_DropTargetVtbl,
        !           129:             lpOleDoc
        !           130:     );
        !           131: #endif  // USE_DRAGDROP
        !           132: 
        !           133:     /*
        !           134:     ** OLE2NOTE: each user level document addref's the app object in
        !           135:     **    order to guarentee that the app does not shut down while the
        !           136:     **    doc is still open.
        !           137:     */
        !           138: 
        !           139:     // OLE2NOTE: data transfer documents should not hold the app alive
        !           140:     if (! fDataTransferDoc)
        !           141:         OleApp_DocLockApp(lpOleApp);
        !           142: 
        !           143: #if defined( OLE_SERVER )
        !           144: 
        !           145:     /* OLE2NOTE: perform initialization specific for an OLE server */
        !           146:     if (! ServerDoc_Init((LPSERVERDOC)lpOleDoc, fDataTransferDoc))
        !           147:         return FALSE;
        !           148: 
        !           149: #elif defined( OLE_CNTR )
        !           150: 
        !           151:     /* OLE2NOTE: perform initialization specific for an OLE container */
        !           152:     if (! ContainerDoc_Init((LPCONTAINERDOC)lpOleDoc, fDataTransferDoc))
        !           153:         return FALSE;
        !           154: 
        !           155: #endif
        !           156: 
        !           157:     return TRUE;
        !           158: }
        !           159: 
        !           160: 
        !           161: 
        !           162: /* OleDoc_InitNewFile
        !           163:  * ------------------
        !           164:  *
        !           165:  *  Initialize the document to be a new (Untitled) document.
        !           166:  *  This function sets the docInitType to DOCTYPE_NEW.
        !           167:  *
        !           168:  *  OLE2NOTE: if this is a visible user document then generate a unique
        !           169:  *  untitled name that we can use to register in the RunningObjectTable.
        !           170:  *  We need a unique name so that clients can link to data in this document
        !           171:  *  even when the document is in the un-saved (untitled) state. it would be
        !           172:  *  ambiguous to register two documents titled "Outline1" in the ROT. we
        !           173:  *  thus generate the lowest numbered document that is not already
        !           174:  *  registered in the ROT.
        !           175:  */
        !           176: BOOL OleDoc_InitNewFile(LPOLEDOC lpOleDoc)
        !           177: {
        !           178:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpOleDoc;
        !           179: 
        !           180:     static UINT uUnique = 1;
        !           181: 
        !           182:     OleDbgAssert(lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN);
        !           183: 
        !           184: #if defined( OLE_CNTR )
        !           185:     {
        !           186:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOleDoc;
        !           187: 
        !           188:         OleDbgAssertSz(lpContainerDoc->m_lpStg == NULL,
        !           189:                 "Setting to untitled with current file open"
        !           190:         );
        !           191: 
        !           192:         /* Create a temp, (delete-on-release) file base storage
        !           193:         **  for the untitled document.
        !           194:         */
        !           195:         lpContainerDoc->m_lpStg = OleStdCreateRootStorage(
        !           196:                 NULL,
        !           197:                 STGM_SHARE_EXCLUSIVE
        !           198:         );
        !           199:         if (! lpContainerDoc->m_lpStg) return FALSE;
        !           200:     }
        !           201: #endif
        !           202: 
        !           203:     lpOutlineDoc->m_docInitType = DOCTYPE_NEW;
        !           204: 
        !           205:     if (! lpOutlineDoc->m_fDataTransferDoc) {
        !           206:         /* OLE2NOTE: choose a unique name for a Moniker so that
        !           207:         **    potential clients can link to our new, untitled document.
        !           208:         **    if links are established (and currently are connected),
        !           209:         **    then they will be notified that we have been renamed when
        !           210:         **    this document is saved to a file.
        !           211:         */
        !           212: 
        !           213:         lpOleDoc->m_fLinkSourceAvail = TRUE;
        !           214: 
        !           215:         // REVIEW: should load UNTITLED string from string resource
        !           216:         OleStdCreateTempFileMoniker(
        !           217:                 UNTITLED,
        !           218:                 (UINT FAR*)&uUnique,
        !           219:                 lpOutlineDoc->m_szFileName,
        !           220:                 &lpOleDoc->m_lpFileMoniker
        !           221:         );
        !           222: 
        !           223:         OLEDBG_BEGIN3("OleStdRegisterAsRunning called\r\n")
        !           224:         OleStdRegisterAsRunning(
        !           225:                 (LPUNKNOWN)&lpOleDoc->m_PersistFile,
        !           226:                 (LPMONIKER)lpOleDoc->m_lpFileMoniker,
        !           227:                 &lpOleDoc->m_dwRegROT
        !           228:         );
        !           229:         OLEDBG_END3
        !           230: 
        !           231:         lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
        !           232:         OutlineDoc_SetTitle(lpOutlineDoc);
        !           233:     } else {
        !           234:         lstrcpy(lpOutlineDoc->m_szFileName, UNTITLED);
        !           235:         lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
        !           236:     }
        !           237: 
        !           238:     return TRUE;
        !           239: }
        !           240: 
        !           241: 
        !           242: /* OleDoc_ShowWindow
        !           243:  * -----------------
        !           244:  *
        !           245:  *      Show the window of the document to the user.
        !           246:  *      make sure app window is visible and bring the document to the top.
        !           247:  *      if the document is a file-based document or a new untitled
        !           248:  *      document, give the user the control over the life-time of the doc.
        !           249:  */
        !           250: void OleDoc_ShowWindow(LPOLEDOC lpOleDoc)
        !           251: {
        !           252:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           253:     LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
        !           254:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpOleDoc;
        !           255:     LPLINELIST lpLL     = (LPLINELIST)&((LPOUTLINEDOC)lpOleDoc)->m_LineList;
        !           256: #if defined( OLE_SERVER )
        !           257:     LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
        !           258: #endif // OLE_SERVER
        !           259: 
        !           260:     OLEDBG_BEGIN3("OleDoc_ShowWindow\r\n")
        !           261: 
        !           262:     /* OLE2NOTE: while the document is visible, we do NOT want it to be
        !           263:     **    prematurely destroyed when a linking client disconnects. thus
        !           264:     **    we must inform OLE to hold an external lock on our document.
        !           265:     **    this arranges that OLE holds at least 1 reference to our
        !           266:     **    document that will NOT be released until we release this
        !           267:     **    external lock. later, when the document window is hidden, we
        !           268:     **    will release this external lock.
        !           269:     */
        !           270:     if (! IsWindowVisible(lpOutlineDoc->m_hWndDoc)) 
        !           271:         OleDoc_Lock(lpOleDoc, TRUE /* fLock */, 0 /* not applicable */);
        !           272: 
        !           273: #if defined( USE_DRAGDROP )
        !           274:     /* OLE2NOTE: since our window is now being made visible, we will
        !           275:     **    register our window as a potential drop target. when the
        !           276:     **    window is hidden there is no reason to be registered as a
        !           277:     **    drop target.
        !           278:     */
        !           279:     if (! lpOleDoc->m_fRegDragDrop) {
        !           280:         OLEDBG_BEGIN2("RegisterDragDrop called\r\n")
        !           281:         RegisterDragDrop(
        !           282:                 LineList_GetWindow(lpLL),
        !           283:                 (LPDROPTARGET)&lpOleDoc->m_DropTarget
        !           284:         );
        !           285:         OLEDBG_END2
        !           286:         lpOleDoc->m_fRegDragDrop = TRUE;
        !           287:     }
        !           288: #endif  // USE_DRAGDROP
        !           289: 
        !           290: #if defined( USE_FRAMETOOLS )
        !           291:     {
        !           292:         /* OLE2NOTE: we need to enable our frame level tools
        !           293:         */
        !           294:         FrameTools_Enable(lpOutlineDoc->m_lpFrameTools, TRUE);
        !           295:     }
        !           296: #endif // USE_FRAMETOOLS
        !           297: 
        !           298: #if defined( OLE_SERVER )
        !           299: 
        !           300:     if (lpOutlineDoc->m_docInitType == DOCTYPE_EMBEDDED &&
        !           301:             lpServerDoc->m_lpOleClientSite != NULL) {
        !           302: 
        !           303:         /* OLE2NOTE: we must also ask our container to show itself if
        !           304:         **    it is not already visible and to scroll us into view. we
        !           305:         **    must make sure to call this BEFORE showing our server's
        !           306:         **    window and taking focus. we do not want our container's
        !           307:         **    window to end up on top.
        !           308:         */
        !           309:         OLEDBG_BEGIN2("IOleClientSite::ShowObject called\r\n");
        !           310:         lpServerDoc->m_lpOleClientSite->lpVtbl->ShowObject(
        !           311:                 lpServerDoc->m_lpOleClientSite
        !           312:         );
        !           313:         OLEDBG_END2
        !           314: 
        !           315:         /* OLE2NOTE: if we are an embedded object and we are not
        !           316:         **    in-place active in our containers window, we must inform our
        !           317:         **    embedding container that our window is opening.
        !           318:         **    the container must now hatch our object.
        !           319:         */
        !           320: 
        !           321: #if defined( INPLACE_SVR )
        !           322:         if (! lpServerDoc->m_fInPlaceActive)
        !           323: #endif
        !           324:         {
        !           325:             OLEDBG_BEGIN2("IOleClientSite::OnShowWindow(TRUE) called\r\n");
        !           326:             lpServerDoc->m_lpOleClientSite->lpVtbl->OnShowWindow(
        !           327:                     lpServerDoc->m_lpOleClientSite,
        !           328:                     TRUE
        !           329:             );
        !           330:             OLEDBG_END2
        !           331:         }
        !           332: 
        !           333:         /* OLE2NOTE: the life-time of our document is controlled by our
        !           334:         **    client and NOT by the user. we are not an independent
        !           335:         **    file-level object. we simply want to show our window here.
        !           336:         **
        !           337:         **    if we are not in-place active (ie. we are opening
        !           338:         **    our own window), we must make sure our main app window is
        !           339:         **    visible. we do not, however, want to give the user
        !           340:         **    control of the App window; we do not want OleApp_ShowWindow
        !           341:         **    to call OleApp_Lock on behalf of the user.
        !           342:         */
        !           343:         if (! IsWindowVisible(lpOutlineApp->m_hWndApp) || 
        !           344:                 IsIconic(lpOutlineApp->m_hWndApp)) {
        !           345: #if defined( INPLACE_SVR )
        !           346:             if (! ((LPSERVERDOC)lpOleDoc)->m_fInPlaceActive)
        !           347: #endif
        !           348:                 OleApp_ShowWindow(lpOleApp, FALSE /* fGiveUserCtrl */);
        !           349:             SetFocus(lpOutlineDoc->m_hWndDoc);
        !           350:         }
        !           351:         
        !           352:     } else
        !           353: #endif  // OLE_SERVER
        !           354: 
        !           355:     {    // DOCTYPE_NEW || DOCTYPE_FROMFILE
        !           356: 
        !           357:         // we must make sure our app window is visible
        !           358:         OleApp_ShowWindow(lpOleApp, TRUE /* fGiveUserCtrl */);
        !           359:     }
        !           360: 
        !           361:     // make document window visible and make sure it is not minimized
        !           362:     ShowWindow(lpOutlineDoc->m_hWndDoc, SW_SHOWNORMAL);
        !           363:     SetFocus(lpOutlineDoc->m_hWndDoc);
        !           364: 
        !           365:     OLEDBG_END3
        !           366: }
        !           367: 
        !           368: 
        !           369: /* OleDoc_HideWindow
        !           370:  * -----------------
        !           371:  *
        !           372:  *      Hide the window of the document from the user.
        !           373:  *      take away the control of the document by the user.
        !           374:  */
        !           375: void OleDoc_HideWindow(LPOLEDOC lpOleDoc, BOOL fShutdown)
        !           376: {
        !           377:     LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
        !           378:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpOleDoc;
        !           379:     LPLINELIST lpLL     = (LPLINELIST)&((LPOUTLINEDOC)lpOleDoc)->m_LineList;
        !           380: 
        !           381:     if (! IsWindowVisible(lpOutlineDoc->m_hWndDoc))
        !           382:         return;     // already visible
        !           383: 
        !           384:     OLEDBG_BEGIN3("OleDoc_HideWindow\r\n")
        !           385: 
        !           386: #if defined( USE_DRAGDROP )
        !           387:     // The document's window is being hidden, revoke it as a DropTarget
        !           388:     if (lpOleDoc->m_fRegDragDrop) {
        !           389:         OLEDBG_BEGIN2("RevokeDragDrop called\r\n");
        !           390:         RevokeDragDrop(LineList_GetWindow(lpLL));
        !           391:         OLEDBG_END2
        !           392: 
        !           393:         lpOleDoc->m_fRegDragDrop = FALSE ;
        !           394:     }
        !           395: #endif  // USE_DRAGDROP
        !           396: 
        !           397:     /* OLE2NOTE: the document is now being hidden, so we must release
        !           398:     **    the external lock made when the document was made visible.
        !           399:     **    if this is a shutdown situation (fShutdown==TRUE), then OLE
        !           400:     **    is instructed to release our document. if this is that last
        !           401:     **    external lock on our document, thus enabling our document to
        !           402:     **    complete its shutdown operation. If This is not a shutdown
        !           403:     **    situation (eg. in-place server hiding its window when
        !           404:     **    UIDeactivating or IOleObject::DoVerb(OLEVERB_HIDE) is called),
        !           405:     **    then OLE is told to NOT immediately release the document.
        !           406:     **    this leaves the document in an unstable state where the next
        !           407:     **    Lock/Unlock sequence will shut the document down (eg. a
        !           408:     **    linking client connecting and disconnecting).
        !           409:     */
        !           410:     if (fShutdown && IsWindowVisible(lpOutlineDoc->m_hWndDoc)) 
        !           411:         OleDoc_Lock(lpOleDoc, FALSE /* fLock */, fShutdown);
        !           412: 
        !           413:     ShowWindow(((LPOUTLINEDOC)lpOleDoc)->m_hWndDoc, SW_HIDE);
        !           414: 
        !           415: #if defined( OLE_SERVER )
        !           416:     {
        !           417:         LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
        !           418: 
        !           419:         /* OLE2NOTE: if we are an embedded object and we are not
        !           420:         **    in-place active, we must inform our
        !           421:         **    embedding container that our window is hiding (closing
        !           422:         **    from the user's perspective). the container must now
        !           423:         **    un-hatch our object.
        !           424:         */
        !           425:         if (lpServerDoc->m_lpOleClientSite != NULL
        !           426: #if defined( INPLACE_SVR )
        !           427:             && !lpServerDoc->m_fInPlaceVisible
        !           428: #endif
        !           429:         ) {
        !           430:             OLEDBG_BEGIN2("IOleClientSite::OnShowWindow(FALSE) called\r\n");
        !           431:             lpServerDoc->m_lpOleClientSite->lpVtbl->OnShowWindow(
        !           432:                     lpServerDoc->m_lpOleClientSite,
        !           433:                     FALSE
        !           434:             );
        !           435:             OLEDBG_END2
        !           436:         }
        !           437:     }
        !           438: #endif
        !           439: 
        !           440:     /* OLE2NOTE: if there are no more documents visible to the user.
        !           441:     **    and the app itself is not under user control, then
        !           442:     **    it has no reason to stay visible. we thus should hide the
        !           443:     **    app. we can not directly destroy the app, because it may be
        !           444:     **    validly being used programatically by another client
        !           445:     **    application and should remain running. it should simply be
        !           446:     **    hidded from the user.
        !           447:     */
        !           448:     OleApp_HideIfNoReasonToStayVisible(lpOleApp);
        !           449:     OLEDBG_END3
        !           450: }
        !           451: 
        !           452: 
        !           453: /* OleDoc_Lock
        !           454: ** -----------
        !           455: **    Lock/Unlock the Doc object. if the last lock is unlocked and
        !           456: **    fLastUnlockReleases == TRUE, then the Doc object will shut down
        !           457: **    (ie. it will recieve its final release and its refcnt will go to 0).
        !           458: */
        !           459: HRESULT OleDoc_Lock(LPOLEDOC lpOleDoc, BOOL fLock, BOOL fLastUnlockReleases)
        !           460: {
        !           461:     HRESULT hrErr;
        !           462: 
        !           463: #if defined( _DEBUG )
        !           464:     if (fLock) {
        !           465:         OLEDBG_BEGIN2("CoLockObjectExternal(lpDoc,TRUE) called\r\n")
        !           466:     } else {
        !           467:         if (fLastUnlockReleases) 
        !           468:             OLEDBG_BEGIN2("CoLockObjectExternal(lpDoc,FALSE,TRUE) called\r\n")
        !           469:         else
        !           470:             OLEDBG_BEGIN2("CoLockObjectExternal(lpDoc,FALSE,FALSE) called\r\n")
        !           471:     }
        !           472: #endif  // _DEBUG
        !           473: 
        !           474:     OleDoc_AddRef(lpOleDoc);       // artificial AddRef to make object stable
        !           475: 
        !           476:     hrErr = CoLockObjectExternal(
        !           477:             (LPUNKNOWN)&lpOleDoc->m_Unknown, fLock, fLastUnlockReleases);
        !           478: 
        !           479:     OleDoc_Release(lpOleDoc);       // release artificial AddRef above
        !           480: 
        !           481:     OLEDBG_END2
        !           482:     return hrErr;
        !           483: }
        !           484: 
        !           485: 
        !           486: /* OleDoc_AddRef
        !           487: ** -------------
        !           488: **
        !           489: **  increment the ref count of the document object.
        !           490: **
        !           491: **    Returns the new ref count on the object
        !           492: */
        !           493: ULONG OleDoc_AddRef(LPOLEDOC lpOleDoc)
        !           494: {
        !           495:     ++lpOleDoc->m_cRef;
        !           496: 
        !           497:     OleDbgOutRefCnt4(
        !           498:             "OleDoc_AddRef: cRef++\r\n",
        !           499:             lpOleDoc,
        !           500:             lpOleDoc->m_cRef
        !           501:     );
        !           502: 
        !           503:     return lpOleDoc->m_cRef;
        !           504: }
        !           505: 
        !           506: 
        !           507: /* OleDoc_Release
        !           508: ** --------------
        !           509: **
        !           510: **  decrement the ref count of the document object.
        !           511: **    if the ref count goes to 0, then the document is destroyed.
        !           512: **
        !           513: **    Returns the remaining ref count on the object
        !           514: */
        !           515: ULONG OleDoc_Release (LPOLEDOC lpOleDoc)
        !           516: {
        !           517:     ULONG cRef;
        !           518:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           519:     LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
        !           520: 
        !           521:     OleDbgAssertSz (lpOleDoc->m_cRef > 0, "Release called with cRef == 0");
        !           522: 
        !           523:     /*********************************************************************
        !           524:     ** OLE2NOTE: when the obj refcnt == 0, then destroy the object.     **
        !           525:     **     otherwise the object is still in use.                        **
        !           526:     *********************************************************************/
        !           527: 
        !           528:     cRef = --lpOleDoc->m_cRef;
        !           529: 
        !           530:     OleDbgOutRefCnt4(
        !           531:             "OleDoc_Release: cRef--\r\n", lpOleDoc, cRef);
        !           532: 
        !           533:     if (cRef == 0)
        !           534:         OutlineDoc_Destroy((LPOUTLINEDOC)lpOleDoc);
        !           535: 
        !           536:     return cRef;
        !           537: }
        !           538: 
        !           539: 
        !           540: /* OleDoc_QueryInterface
        !           541: ** ---------------------
        !           542: **
        !           543: ** Retrieve a pointer to an interface on the document object.
        !           544: **
        !           545: **    OLE2NOTE: this function will AddRef the ref cnt of the object.
        !           546: **
        !           547: **    Returns S_OK if interface is successfully retrieved.
        !           548: **            S_FALSE if the interface is not supported
        !           549: */
        !           550: HRESULT OleDoc_QueryInterface(
        !           551:         LPOLEDOC          lpOleDoc,
        !           552:         REFIID            riid,
        !           553:         LPVOID FAR*       lplpvObj
        !           554: )
        !           555: {
        !           556:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpOleDoc;
        !           557:     SCODE sc = E_NOINTERFACE;
        !           558: 
        !           559:     /* OLE2NOTE: we must make sure to set all out ptr parameters to NULL. */
        !           560:     *lplpvObj = NULL;
        !           561: 
        !           562:     if (IsEqualIID(riid, &IID_IUnknown)) {
        !           563:         OleDbgOut4("OleDoc_QueryInterface: IUnknown* RETURNED\r\n");
        !           564: 
        !           565:         *lplpvObj = (LPVOID) &lpOleDoc->m_Unknown;
        !           566:         OleDoc_AddRef(lpOleDoc);
        !           567:         sc = S_OK;
        !           568:     }
        !           569:     else if(lpOutlineDoc->m_fDataTransferDoc
        !           570:             && IsEqualIID(riid, &IID_IDataObject)) {
        !           571:         OleDbgOut4("OleDoc_QueryInterface: IDataObject* RETURNED\r\n");
        !           572: 
        !           573:         *lplpvObj = (LPVOID) &lpOleDoc->m_DataObject;
        !           574:         OleDoc_AddRef(lpOleDoc);
        !           575:         sc = S_OK;
        !           576:     }
        !           577: 
        !           578: #if defined( USE_DRAGDROP )
        !           579: 
        !           580:     /* DropSource is only needed on a DataTransferDoc */
        !           581:     else if(lpOutlineDoc->m_fDataTransferDoc
        !           582:             && IsEqualIID(riid, &IID_IDropSource)) {
        !           583: 
        !           584:         OleDbgOut4("OleDoc_QueryInterface: IDropSource* RETURNED\r\n");
        !           585: 
        !           586:         *lplpvObj = (LPVOID) &lpOleDoc->m_DropSource;
        !           587:         OleDoc_AddRef(lpOleDoc);
        !           588:         sc = S_OK;
        !           589:     }
        !           590: #endif
        !           591: 
        !           592:     /* OLE2NOTE: if this document is a DataTransferDocument used to
        !           593:     **    support a clipboard or drag/drop operation, then it should
        !           594:     **    only expose IUnknown, IDataObject, and IDropSource
        !           595:     **    interfaces. if the document is a normal user document, then
        !           596:     **    we will also continue to consider our other interfaces.
        !           597:     */
        !           598:     if (lpOutlineDoc->m_fDataTransferDoc)
        !           599:         goto done;
        !           600: 
        !           601:     if(IsEqualIID(riid, &IID_IPersist) || IsEqualIID(riid, &IID_IPersistFile)) {
        !           602:         OleDbgOut4("OleDoc_QueryInterface: IPersistFile* RETURNED\r\n");
        !           603: 
        !           604:         *lplpvObj = (LPVOID) &lpOleDoc->m_PersistFile;
        !           605:         OleDoc_AddRef(lpOleDoc);
        !           606:         sc = S_OK;
        !           607:     }
        !           608:     else if(IsEqualIID(riid, &IID_IOleItemContainer) ||
        !           609:             IsEqualIID(riid, &IID_IOleContainer) ||
        !           610:             IsEqualIID(riid, &IID_IParseDisplayName) ) {
        !           611:         OleDbgOut4("OleDoc_QueryInterface: IOleItemContainer* RETURNED\r\n");
        !           612: 
        !           613:         *lplpvObj = (LPVOID) &lpOleDoc->m_OleItemContainer;
        !           614:         OleDoc_AddRef(lpOleDoc);
        !           615:         sc = S_OK;
        !           616:     }
        !           617: 
        !           618: #if defined( USE_DRAGDROP )
        !           619: 
        !           620:     else if(IsEqualIID(riid, &IID_IDropTarget)) {
        !           621:         OleDbgOut4("OleDoc_QueryInterface: IDropTarget* RETURNED\r\n");
        !           622: 
        !           623:         *lplpvObj = (LPVOID) &lpOleDoc->m_DropTarget;
        !           624:         OleDoc_AddRef(lpOleDoc);
        !           625:         sc = S_OK;
        !           626:     }
        !           627: #endif
        !           628: 
        !           629: #if defined( OLE_CNTR ) && defined ( IID_IOleUILinkContainer )
        !           630: 
        !           631:     else if (IsEqualIID(riid, &IID_IOleUILinkContainer)) {
        !           632:         OleDbgOut4("OleDoc_QueryInterface: IOleUILinkContainer* RETURNED\r\n");
        !           633: 
        !           634:         *lplpvObj=(LPVOID)&((LPCONTAINERERDOC)lpOleDoc)->m_OleUILinkContainer;
        !           635:         OleDoc_AddRef(lpOleDoc);
        !           636:         sc = S_OK;
        !           637:     }
        !           638: #endif
        !           639: 
        !           640: #if defined( OLE_SERVER )
        !           641: 
        !           642:     /* OLE2NOTE: if OLE server version, than also offer the server
        !           643:     **    specific interfaces: IOleObject and IPersistStorage.
        !           644:     */
        !           645:     else if (IsEqualIID(riid, &IID_IOleObject)) {
        !           646:         OleDbgOut4("OleDoc_QueryInterface: IOleObject* RETURNED\r\n");
        !           647: 
        !           648:         *lplpvObj = (LPVOID) &((LPSERVERDOC)lpOleDoc)->m_OleObject;
        !           649:         OleDoc_AddRef(lpOleDoc);
        !           650:         sc = S_OK;
        !           651:     }
        !           652:     else if(IsEqualIID(riid, &IID_IPersistStorage)) {
        !           653:         OleDbgOut4("OleDoc_QueryInterface: IPersistStorage* RETURNED\r\n");
        !           654: 
        !           655:         *lplpvObj = (LPVOID) &((LPSERVERDOC)lpOleDoc)->m_PersistStorage;
        !           656:         OleDoc_AddRef(lpOleDoc);
        !           657:         sc = S_OK;
        !           658:     }
        !           659:     else if(IsEqualIID(riid, &IID_IDataObject)) {
        !           660:         OleDbgOut4("OleDoc_QueryInterface: IDataObject* RETURNED\r\n");
        !           661: 
        !           662:         *lplpvObj = (LPVOID) &lpOleDoc->m_DataObject;
        !           663:         OleDoc_AddRef(lpOleDoc);
        !           664:         sc = S_OK;
        !           665:     }
        !           666: 
        !           667: #if defined( SVR_TREATAS )
        !           668:     else if(IsEqualIID(riid, &IID_IStdMarshalInfo)) {
        !           669:         OleDbgOut4("OleDoc_QueryInterface: IStdMarshalInfo* RETURNED\r\n");
        !           670: 
        !           671:         *lplpvObj = (LPVOID) &((LPSERVERDOC)lpOleDoc)->m_StdMarshalInfo;
        !           672:         OleDoc_AddRef(lpOleDoc);
        !           673:         sc = S_OK;
        !           674:     }
        !           675: #endif  // SVR_TREATAS
        !           676: 
        !           677: #if defined( INPLACE_SVR )
        !           678:     else if (IsEqualIID(riid, &IID_IOleWindow) ||
        !           679:              IsEqualIID(riid, &IID_IOleInPlaceObject)) {
        !           680:         OleDbgOut4("OleDoc_QueryInterface: IOleInPlaceObject* RETURNED\r\n");
        !           681: 
        !           682:         *lplpvObj = (LPVOID) &((LPSERVERDOC)lpOleDoc)->m_OleInPlaceObject;
        !           683:         OleDoc_AddRef(lpOleDoc);
        !           684:         sc = S_OK;
        !           685:     }
        !           686: #endif // INPLACE_SVR
        !           687: #endif // OLE_SERVER
        !           688: 
        !           689: done:
        !           690:     OleDbgQueryInterfaceMethod(*lplpvObj);
        !           691: 
        !           692:     return ResultFromScode(sc);
        !           693: }
        !           694: 
        !           695: 
        !           696: /* OleDoc_Close
        !           697:  * ------------
        !           698:  *
        !           699:  *  Close the document.
        !           700:  *      This functions performs the actions that are in common to all
        !           701:  *      document types which derive from OleDoc (eg. ContainerDoc and
        !           702:  *      ServerDoc) which are required to close a document.
        !           703:  *
        !           704:  *  Returns:
        !           705:  *      FALSE -- user canceled the closing of the doc.
        !           706:  *      TRUE -- the doc was successfully closed
        !           707:  */
        !           708: 
        !           709: BOOL OleDoc_Close(LPOLEDOC lpOleDoc, DWORD dwSaveOption)
        !           710: {
        !           711:     LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
        !           712:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           713:     LPOLEDOC lpClipboardDoc;
        !           714:     LPLINELIST lpLL     = (LPLINELIST)&((LPOUTLINEDOC)lpOleDoc)->m_LineList;
        !           715: 
        !           716:     if (! lpOleDoc)
        !           717:         return TRUE;    // active doc's are already destroyed
        !           718: 
        !           719:     if (lpOleDoc->m_fObjIsClosing)
        !           720:         return TRUE;    // Closing is already in progress
        !           721: 
        !           722:     OLEDBG_BEGIN3("OleDoc_Close\r\n")
        !           723: 
        !           724:     if (! OutlineDoc_CheckSaveChanges((LPOUTLINEDOC)lpOleDoc, dwSaveOption)) {
        !           725:         OLEDBG_END3
        !           726:         return FALSE;           // cancel closing the doc
        !           727:     }
        !           728: 
        !           729:     lpOleDoc->m_fObjIsClosing = TRUE;   // guard against recursive call
        !           730: 
        !           731:     /* OLE2NOTE: in order to have a stable app and doc during the
        !           732:     **    process of closing, we intially AddRef the App and Doc ref
        !           733:     **    cnts and later Release them. These initial AddRefs are
        !           734:     **    artificial; they simply guarantee that these objects do not
        !           735:     **    get destroyed until the end of this routine.
        !           736:     */
        !           737:     OleApp_AddRef(lpOleApp);
        !           738:     OleDoc_AddRef(lpOleDoc);
        !           739: 
        !           740: #if defined( OLE_CNTR )
        !           741:     {
        !           742:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOleDoc;
        !           743: 
        !           744:         /* OLE2NOTE: force all OLE objects to close. this forces all
        !           745:         **    OLE object to transition from running to loaded. we can
        !           746:         **    NOT exit if any embeddings are still running.
        !           747:         **    if an object can't be closed then we will abort closing
        !           748:         **    our document.
        !           749:         */
        !           750:         if (! ContainerDoc_CloseAllOleObjects(lpContainerDoc)) {
        !           751:             OleDoc_Release(lpOleDoc);       // release artificial AddRef above
        !           752:             OleApp_Release(lpOleApp);       // release artificial AddRef above
        !           753:             lpOleDoc->m_fObjIsClosing = FALSE; // guard against recursive call
        !           754: 
        !           755:             OLEDBG_END3
        !           756:             return FALSE;
        !           757:         }
        !           758:     }
        !           759: #endif
        !           760: 
        !           761: #if defined( INPLACE_SVR )
        !           762:     /* OLE2NOTE: if the server is currently in-place active we must
        !           763:     **    deactivate it now before closing
        !           764:     */
        !           765:     ServerDoc_DoInPlaceDeactivate((LPSERVERDOC)lpOleDoc); 
        !           766: #endif
        !           767: 
        !           768:     /* OLE2NOTE: if this document is the source of data for the 
        !           769:     **    clipboard, then flush the clipboard. it is important to flush
        !           770:     **    the clipboard BEFORE calling sending any notifications to
        !           771:     **    clients (eg. IOleClientSite::OnShowWindow(FALSE)) which could
        !           772:     **    give them a chance to run and try to get our clipboard data 
        !           773:     **    object that we want to destroy. (eg. our app tries to
        !           774:     **    update the paste button of the toolbar when
        !           775:     **    WM_ACTIVATEAPP is received.) 
        !           776:     */
        !           777:     lpClipboardDoc = (LPOLEDOC)lpOutlineApp->m_lpClipboardDoc;
        !           778:     if (lpClipboardDoc && 
        !           779:         lpClipboardDoc->m_lpSrcDocOfCopy == lpOleDoc) {
        !           780:         OleApp_FlushClipboard(lpOleApp);
        !           781:     }
        !           782: 
        !           783:     /* OLE2NOTE: Revoke the object from the Running Object Table. it is
        !           784:     **    best if the object is revoke prior to calling
        !           785:     **    COLockObjectExternal(FALSE,TRUE) which is called when the
        !           786:     **    document window is hidden from the user.
        !           787:     */
        !           788:     OLEDBG_BEGIN3("OleStdRevokeAsRunning called\r\n")
        !           789:     OleStdRevokeAsRunning(&lpOleDoc->m_dwRegROT);
        !           790:     OLEDBG_END3
        !           791: 
        !           792:     /* OLE2NOTE: if the user is in control of the document, the user
        !           793:     **    accounts for one refcnt on the document. Closing the
        !           794:     **    document is achieved by releasing the object on behalf of
        !           795:     **    the user. if the document is not referenced by any other
        !           796:     **    clients, then the document will also be destroyed. if it
        !           797:     **    is referenced by other clients, then it will remain until
        !           798:     **    they release it. it is important to hide the window and call
        !           799:     **    IOleClientSite::OnShowWindow(FALSE) BEFORE sending OnClose
        !           800:     **    notification.
        !           801:     */
        !           802:     OleDoc_HideWindow(lpOleDoc, TRUE);
        !           803: 
        !           804: #if defined( OLE_SERVER )
        !           805:     {
        !           806:         LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
        !           807:         LPSERVERNAMETABLE lpServerNameTable =
        !           808:             (LPSERVERNAMETABLE)((LPOUTLINEDOC)lpOleDoc)->m_lpNameTable;
        !           809: 
        !           810:         /* OLE2NOTE: force all pseudo objects to close. this informs all
        !           811:         **    linking clients of pseudo objects to release their PseudoObj.
        !           812:         */
        !           813:         ServerNameTable_CloseAllPseudoObjs(lpServerNameTable);
        !           814: 
        !           815:         /* OLE2NOTE: send last OnDataChange notification to clients
        !           816:         **    that have registered for data notifications when object
        !           817:         **    stops running (ADVF_DATAONSTOP), if the data in our
        !           818:         **    object has ever changed. it is best to only send this
        !           819:         **    notification if necessary.
        !           820:         */
        !           821:         if (lpServerDoc->m_fSendDataOnStop 
        !           822:                 && lpServerDoc->m_lpDataAdviseHldr) {
        !           823:             ServerDoc_SendAdvise(
        !           824:                     (LPSERVERDOC)lpOleDoc,
        !           825:                     OLE_ONDATACHANGE,
        !           826:                     NULL,   /* lpmkDoc -- not relevant here */
        !           827:                     ADVF_DATAONSTOP
        !           828:             );
        !           829: 
        !           830:             /* OLE2NOTE: we just sent the last data notification that we
        !           831:             **    need to send; release our DataAdviseHolder. we SHOULD be
        !           832:             **    the only one using it.
        !           833:             */
        !           834: 
        !           835:             OleStdVerifyRelease(
        !           836:                     (LPUNKNOWN)lpServerDoc->m_lpDataAdviseHldr,
        !           837:                     "DataAdviseHldr not released properly"
        !           838:             );
        !           839:             lpServerDoc->m_lpDataAdviseHldr = NULL;
        !           840:         }
        !           841: 
        !           842:         // OLE2NOTE: inform all of our linking clients that we are closing.
        !           843: 
        !           844: 
        !           845:         if (lpServerDoc->m_lpOleAdviseHldr) {
        !           846:             ServerDoc_SendAdvise(
        !           847:                     (LPSERVERDOC)lpOleDoc,
        !           848:                     OLE_ONCLOSE,
        !           849:                     NULL,   /* lpmkDoc -- not relevant here */
        !           850:                     0       /* advf -- not relevant here */
        !           851:             );
        !           852: 
        !           853:             /* OLE2NOTE: OnClose is the last notification that we need to
        !           854:             **    send; release our OleAdviseHolder. we SHOULD be the only
        !           855:             **    one using it. this will make our destructor realize that
        !           856:             **    OnClose notification has already been sent.
        !           857:             */
        !           858:             OleStdVerifyRelease(
        !           859:                     (LPUNKNOWN)lpServerDoc->m_lpOleAdviseHldr,
        !           860:                     "OleAdviseHldr not released properly"
        !           861:             );
        !           862:             lpServerDoc->m_lpOleAdviseHldr = NULL;
        !           863:         }
        !           864: 
        !           865:         /* release our Container's ClientSite. */
        !           866:         if(lpServerDoc->m_lpOleClientSite) {
        !           867:             OleStdRelease((LPUNKNOWN)lpServerDoc->m_lpOleClientSite);
        !           868:             lpServerDoc->m_lpOleClientSite = NULL;
        !           869:         }
        !           870:     }
        !           871: #endif
        !           872: 
        !           873:     /* OLE2NOTE: this call forces all external connections to our
        !           874:     **    object to close down and therefore guarantees that we receive
        !           875:     **    all releases associated with those external connections.
        !           876:     */
        !           877:     OLEDBG_BEGIN2("CoDisconnectObject(lpDoc) called\r\n")
        !           878:     CoDisconnectObject((LPUNKNOWN)&lpOleDoc->m_Unknown, 0);
        !           879:     OLEDBG_END2
        !           880: 
        !           881:     OleDoc_Release(lpOleDoc);       // release artificial AddRef above
        !           882:     OleApp_Release(lpOleApp);       // release artificial AddRef above
        !           883: 
        !           884:     OLEDBG_END3
        !           885:     return TRUE;
        !           886: }
        !           887: 
        !           888: 
        !           889: /* OleDoc_Destroy
        !           890:  * --------------
        !           891:  *  
        !           892:  *  Free all OLE related resources that had been allocated for a document.  
        !           893:  */
        !           894: void OleDoc_Destroy(LPOLEDOC lpOleDoc)
        !           895: {
        !           896:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           897:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpOleDoc;
        !           898: 
        !           899:     if (lpOleDoc->m_fObjIsDestroying) 
        !           900:         return;     // Doc destruction is already in progress
        !           901:     
        !           902:     lpOleDoc->m_fObjIsDestroying = TRUE;    // guard against recursive call
        !           903: 
        !           904:     /* OLE2NOTE: if the document destructor is called directly because
        !           905:     **    the object's refcnt went to 0 (ie. without OleDoc_Close first
        !           906:     **    being called), then we need to make sure that the document is
        !           907:     **    properly closed before destroying the object. this scenario
        !           908:     **    could arise during a silent-update of a link. calling
        !           909:     **    OleDoc_Close here guarantees that the clipboard will be
        !           910:     **    properly flushed, the doc's moniker will be properly revoked,
        !           911:     **    the document will be saved if necessary, etc.
        !           912:     */
        !           913:     if (!lpOutlineDoc->m_fDataTransferDoc && !lpOleDoc->m_fObjIsClosing)
        !           914:         OleDoc_Close(lpOleDoc, OLECLOSE_SAVEIFDIRTY);
        !           915: 
        !           916: #if defined( OLE_SERVER )
        !           917:     {
        !           918:         LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
        !           919:         /* OLE2NOTE: perform processing specific for an OLE server */
        !           920: 
        !           921: #if defined( SVR_TREATAS )
        !           922:         if (lpServerDoc->m_lpszTreatAsType) {
        !           923:             OleStdFreeString(lpServerDoc->m_lpszTreatAsType, NULL);
        !           924:             lpServerDoc->m_lpszTreatAsType = NULL;
        !           925:         }
        !           926: #endif // SVR_TREATAS
        !           927: 
        !           928: #if defined( INPLACE_SVR )
        !           929:         if (IsWindow(lpServerDoc->m_hWndHatch))
        !           930:             DestroyWindow(lpServerDoc->m_hWndHatch);
        !           931: #endif  // INPLACE_SVR
        !           932:     }
        !           933: #endif  // OLE_SERVER
        !           934: 
        !           935: 
        !           936: #if defined( OLE_CNTR )
        !           937:     {
        !           938:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOleDoc;
        !           939:         /* OLE2NOTE: perform processing specific for an OLE container */
        !           940: 
        !           941:         if (lpContainerDoc->m_lpStg) {
        !           942:             /* release our doc storage. */
        !           943:             OleStdRelease((LPUNKNOWN)lpContainerDoc->m_lpStg);
        !           944:             lpContainerDoc->m_lpStg = NULL;
        !           945:         }
        !           946:     }
        !           947: #endif  // OLE_CNTR
        !           948: 
        !           949:     if (lpOleDoc->m_lpFileMoniker) {
        !           950:         OleStdRelease((LPUNKNOWN)lpOleDoc->m_lpFileMoniker);
        !           951:         lpOleDoc->m_lpFileMoniker = NULL;
        !           952:     }
        !           953: 
        !           954:     /*****************************************************************
        !           955:     ** OLE2NOTE: each document addref's the app object in order to  **
        !           956:     **    guarentee that the app does not shut down while the doc   **
        !           957:     **    is still open. since this doc is now destroyed, we will   **
        !           958:     **    release this refcnt now. if there are now more open       **
        !           959:     **    documents AND the app is not under the control of the     **
        !           960:     **    user (ie. launched by OLE) then the app will revoke its   **
        !           961:     **    ClassFactory. if there are no more references to the      **
        !           962:     **    ClassFactory after it is revoked, then the app will shut  **
        !           963:     **    down. this whole procedure is triggered by calling        **
        !           964:     **    OutlineApp_DocUnlockApp.                                  **
        !           965:     *****************************************************************/
        !           966: 
        !           967:     OutlineApp_DocUnlockApp(lpOutlineApp, lpOutlineDoc);
        !           968: }
        !           969: 
        !           970: 
        !           971: /* OleDoc_SetUpdateEditMenuFlag
        !           972:  * ----------------------------
        !           973:  *
        !           974:  *  Purpose:
        !           975:  *      Set/clear the UpdateEditMenuFlag in OleDoc.
        !           976:  *
        !           977:  *  Parameters:
        !           978:  *      fUpdate     new value of the flag
        !           979:  *
        !           980:  *  Returns:
        !           981:  */
        !           982: void OleDoc_SetUpdateEditMenuFlag(LPOLEDOC lpOleDoc, BOOL fUpdate)
        !           983: {
        !           984:     if (!lpOleDoc)
        !           985:         return;
        !           986: 
        !           987:     lpOleDoc->m_fUpdateEditMenu = fUpdate;
        !           988: }
        !           989: 
        !           990: 
        !           991: /* OleDoc_GetUpdateEditMenuFlag
        !           992:  * ----------------------------
        !           993:  *
        !           994:  *  Purpose:
        !           995:  *      Get the value of the UpdateEditMenuFlag in OleDoc
        !           996:  *
        !           997:  *  Parameters:
        !           998:  *
        !           999:  *  Returns:
        !          1000:  *      value of the flag
        !          1001:  */
        !          1002: BOOL OleDoc_GetUpdateEditMenuFlag(LPOLEDOC lpOleDoc)
        !          1003: {
        !          1004:     if (!lpOleDoc)
        !          1005:         return FALSE;
        !          1006: 
        !          1007:     return lpOleDoc->m_fUpdateEditMenu;
        !          1008: }
        !          1009: 
        !          1010: 
        !          1011: 
        !          1012: /*************************************************************************
        !          1013: ** OleDoc::IUnknown interface implementation
        !          1014: *************************************************************************/
        !          1015: 
        !          1016: STDMETHODIMP OleDoc_Unk_QueryInterface(
        !          1017:         LPUNKNOWN           lpThis,
        !          1018:         REFIID              riid,
        !          1019:         LPVOID FAR*         lplpvObj
        !          1020: )
        !          1021: {
        !          1022:     LPOLEDOC lpOleDoc = ((struct CDocUnknownImpl FAR*)lpThis)->lpOleDoc;
        !          1023: 
        !          1024:     return OleDoc_QueryInterface(lpOleDoc, riid, lplpvObj);
        !          1025: }
        !          1026: 
        !          1027: 
        !          1028: STDMETHODIMP_(ULONG) OleDoc_Unk_AddRef(LPUNKNOWN lpThis)
        !          1029: {
        !          1030:     LPOLEDOC lpOleDoc = ((struct CDocUnknownImpl FAR*)lpThis)->lpOleDoc;
        !          1031: 
        !          1032:     OleDbgAddRefMethod(lpThis, "IUnknown");
        !          1033: 
        !          1034:     return OleDoc_AddRef(lpOleDoc);
        !          1035: }
        !          1036: 
        !          1037: 
        !          1038: STDMETHODIMP_(ULONG) OleDoc_Unk_Release (LPUNKNOWN lpThis)
        !          1039: {
        !          1040:     LPOLEDOC lpOleDoc = ((struct CDocUnknownImpl FAR*)lpThis)->lpOleDoc;
        !          1041: 
        !          1042:     OleDbgReleaseMethod(lpThis, "IUnknown");
        !          1043: 
        !          1044:     return OleDoc_Release(lpOleDoc);
        !          1045: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.