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

1.1     ! root        1: /*************************************************************************
        !             2: ** 
        !             3: **    OLE 2 Server Sample Code
        !             4: **    
        !             5: **    svrbase.c
        !             6: **    
        !             7: **    This file contains all interfaces, methods and related support
        !             8: **    functions for the basic OLE Object (Server) application. The
        !             9: **    basic OLE Object application supports embedding an object and
        !            10: **    linking to a file-based or embedded object as a whole. The basic
        !            11: **    Object application includes the following implementation objects:
        !            12: **    
        !            13: **    ClassFactory (aka. ClassObject) Object    (see file classfac.c)
        !            14: **      exposed interfaces:
        !            15: **          IClassFactory interface
        !            16: **    
        !            17: **    ServerDoc Object
        !            18: **      exposed interfaces:
        !            19: **          IUnknown
        !            20: **          IOleObject interface
        !            21: **          IPersistStorage interface
        !            22: **          IDataObject interface
        !            23: **    
        !            24: **    ServerApp Object
        !            25: **      exposed interfaces:
        !            26: **          IUnknown
        !            27: **    
        !            28: **    (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
        !            29: **
        !            30: *************************************************************************/
        !            31: 
        !            32: 
        !            33: #include "outline.h"
        !            34: #include <regdb.h>
        !            35: #include <enumfetc.h>
        !            36: #include <geticon.h>
        !            37: 
        !            38: OLEDBGDATA
        !            39: 
        !            40: extern LPOUTLINEAPP             g_lpApp;
        !            41: extern IOleObjectVtbl           g_SvrDoc_OleObjectVtbl;
        !            42: extern IPersistStorageVtbl      g_SvrDoc_PersistStorageVtbl;
        !            43: 
        !            44: #if defined( INPLACE_SVR )
        !            45: extern IOleInPlaceObjectVtbl        g_SvrDoc_OleInPlaceObjectVtbl;
        !            46: extern IOleInPlaceActiveObjectVtbl  g_SvrDoc_OleInPlaceActiveObjectVtbl;
        !            47: #endif  // INPLACE_SVR
        !            48: 
        !            49: #if defined( SVR_TREATAS )
        !            50: extern IStdMarshalInfoVtbl             g_SvrDoc_StdMarshalInfoVtbl;
        !            51: #endif // SVR_TREATAS
        !            52: 
        !            53: 
        !            54: // REVIEW: should use string resource for messages
        !            55: extern char ErrMsgSaving[];
        !            56: extern char ErrMsgFormatNotSupported[];
        !            57: static char ErrMsgPSSaveFail[] = "PSSave failed";
        !            58: extern char g_szUpdateCntrDoc[] = "&Update %s";
        !            59: extern char g_szExitNReturnToCntrDoc[] = "E&xit && Return to %s";
        !            60: 
        !            61: 
        !            62: /*************************************************************************
        !            63: ** ServerDoc::IOleObject interface implementation
        !            64: *************************************************************************/
        !            65: 
        !            66: // IOleObject::QueryInterface method
        !            67: 
        !            68: STDMETHODIMP SvrDoc_OleObj_QueryInterface(
        !            69:         LPOLEOBJECT             lpThis,
        !            70:         REFIID                  riid,
        !            71:         LPVOID FAR*             lplpvObj
        !            72: )
        !            73: {
        !            74:     LPSERVERDOC lpServerDoc =
        !            75:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !            76: 
        !            77:     return OleDoc_QueryInterface((LPOLEDOC)lpServerDoc, riid, lplpvObj);
        !            78: }
        !            79: 
        !            80: 
        !            81: // IOleObject::AddRef method
        !            82: 
        !            83: STDMETHODIMP_(ULONG) SvrDoc_OleObj_AddRef(LPOLEOBJECT lpThis)
        !            84: {
        !            85:     LPSERVERDOC lpServerDoc =
        !            86:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !            87: 
        !            88:     OleDbgAddRefMethod(lpThis, "IOleObject");
        !            89: 
        !            90:     return OleDoc_AddRef((LPOLEDOC)lpServerDoc);
        !            91: }
        !            92: 
        !            93: 
        !            94: // IOleObject::Release method
        !            95: 
        !            96: STDMETHODIMP_(ULONG) SvrDoc_OleObj_Release(LPOLEOBJECT lpThis)
        !            97: {
        !            98:     LPSERVERDOC lpServerDoc =
        !            99:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           100:     
        !           101:     OleDbgReleaseMethod(lpThis, "IOleObject");
        !           102: 
        !           103:     return OleDoc_Release((LPOLEDOC)lpServerDoc);
        !           104: }
        !           105: 
        !           106: 
        !           107: // IOleObject::SetClientSite method
        !           108: 
        !           109: STDMETHODIMP SvrDoc_OleObj_SetClientSite(
        !           110:         LPOLEOBJECT             lpThis,
        !           111:         LPOLECLIENTSITE         lpclientSite
        !           112: )
        !           113: {
        !           114:     LPSERVERDOC lpServerDoc =
        !           115:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           116:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !           117: 
        !           118:     OLEDBG_BEGIN2("SvrDoc_OleObj_SetClientSite\r\n")
        !           119: 
        !           120:     // SetClientSite is only valid to call on an embedded object
        !           121:     if (lpOutlineDoc->m_docInitType != DOCTYPE_EMBEDDED) {
        !           122:         OleDbgAssert(lpOutlineDoc->m_docInitType == DOCTYPE_EMBEDDED);
        !           123:         OLEDBG_END2
        !           124:         return ResultFromScode(E_UNEXPECTED);
        !           125:     }
        !           126: 
        !           127:     /* if we currently have a client site ptr, then release it. */
        !           128:     if (lpServerDoc->m_lpOleClientSite) 
        !           129:         OleStdRelease((LPUNKNOWN)lpServerDoc->m_lpOleClientSite);
        !           130:     
        !           131:     lpServerDoc->m_lpOleClientSite = (LPOLECLIENTSITE) lpclientSite;
        !           132:     // OLE2NOTE: to be able to hold onto clientSite pointer, we must AddRef it
        !           133:     if (lpclientSite)
        !           134:         lpclientSite->lpVtbl->AddRef(lpclientSite); 
        !           135:     
        !           136:     OLEDBG_END2
        !           137:     return NOERROR;
        !           138: }
        !           139: 
        !           140: 
        !           141: // IOleObject::GetClientSite method
        !           142: 
        !           143: STDMETHODIMP SvrDoc_OleObj_GetClientSite(
        !           144:         LPOLEOBJECT             lpThis,
        !           145:         LPOLECLIENTSITE FAR*    lplpClientSite
        !           146: )
        !           147: {
        !           148:     LPSERVERDOC lpServerDoc =
        !           149:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           150: 
        !           151:     OleDbgOut2("SvrDoc_OleObj_GetClientSite\r\n");
        !           152: 
        !           153:        /* OLE2NOTE: we MUST AddRef this interface pointer to give the
        !           154:        **    caller a personal copy of the pointer
        !           155:        */
        !           156:        lpServerDoc->m_lpOleClientSite->lpVtbl->AddRef(
        !           157:                        lpServerDoc->m_lpOleClientSite
        !           158:        );
        !           159:     *lplpClientSite = lpServerDoc->m_lpOleClientSite;
        !           160:     
        !           161:     return NOERROR;
        !           162: 
        !           163: }
        !           164: 
        !           165: 
        !           166: // IOleObject::SetHostNames method
        !           167: 
        !           168: STDMETHODIMP SvrDoc_OleObj_SetHostNames(
        !           169:         LPOLEOBJECT             lpThis,
        !           170:         LPCSTR                  szContainerApp,
        !           171:         LPCSTR                  szContainerObj
        !           172: )
        !           173: {
        !           174:     LPSERVERDOC lpServerDoc =
        !           175:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           176:     LPOUTLINEDOC    lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !           177: 
        !           178:     OleDbgOut2("SvrDoc_OleObj_SetHostNames\r\n");
        !           179: 
        !           180:     lstrcpy((LPSTR)lpServerDoc->m_szContainerApp, szContainerApp);
        !           181:     lstrcpy((LPSTR)lpServerDoc->m_szContainerObj, szContainerObj);
        !           182: 
        !           183:     /* The Window title for an embedded object is constructed as
        !           184:     **    follows: 
        !           185:     **      <server app name> - <obj short type> in <cont. doc name>
        !           186:     **    
        !           187:     **    here we construct the current document title portion of the
        !           188:     **    name which follows the '-'. OutlineDoc_SetTitle prepends the
        !           189:     **    "<server app name> - " to the document title.
        !           190:     */
        !           191:     // REVIEW: this string should be loaded from string resource
        !           192:     wsprintf(lpOutlineDoc->m_szFileName, "%s in %s", 
        !           193:             (LPSTR)SHORTUSERTYPENAME, (LPSTR)lpServerDoc->m_szContainerObj);
        !           194: 
        !           195:     lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
        !           196:     OutlineDoc_SetTitle(lpOutlineDoc);
        !           197:     
        !           198:     /* OLE2NOTE: update the application menus correctly for an embedded
        !           199:     **    object. the changes include:
        !           200:     **      1 Remove File/New and File/Open (SDI ONLY)
        !           201:     **      2 Change File/Save As.. to File/Save Copy As.. 
        !           202:     **      3 Change File menu so it contains "Update" instead of "Save" 
        !           203:     **      4 Change File/Exit to File/Exit & Return to <client doc>" 
        !           204:     */
        !           205:     ServerDoc_UpdateMenu(lpServerDoc);
        !           206: 
        !           207:     return NOERROR;
        !           208: }
        !           209: 
        !           210: 
        !           211: // IOleObject::Close method
        !           212: 
        !           213: STDMETHODIMP SvrDoc_OleObj_Close(
        !           214:         LPOLEOBJECT             lpThis,
        !           215:         DWORD                   dwSaveOption
        !           216: )
        !           217: {
        !           218:     LPSERVERDOC lpServerDoc =
        !           219:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           220:     BOOL fStatus;
        !           221: 
        !           222:     OLEDBG_BEGIN2("SvrDoc_OleObj_Close\r\n")
        !           223: 
        !           224:     // REVIEW: dwSaveOption not yet supported
        !           225: 
        !           226:     /* OLE2NOTE: the OLE 2.0 user model is that embedded objects should
        !           227:     **    always be saved when closed WITHOUT any prompting to the
        !           228:     **    user. this is the recommendation irregardless of whether the
        !           229:     **    object is activated in-place or open in its own window.
        !           230:     **    this is a CHANGE from the OLE 1.0 user model where it
        !           231:     **    was the guideline that servers always prompt to save changes.
        !           232:     **    thus OLE 2.0 compound document oriented container's should
        !           233:     **    always pass dwSaveOption==OLECLOSE_SAVEIFDIRTY. it is
        !           234:     **    possible that for programmatic uses a container may want to
        !           235:     **    specify a different dwSaveOption. the implementation of
        !           236:     **    various save options can be tricky, particularly considering
        !           237:     **    cases involving in-place activation. the following would be
        !           238:     **    reasonable behavior:
        !           239:     **
        !           240:     **      (1) OLECLOSE_SAVEIFDIRTY: if dirty, save. close.
        !           241:     **      (2) OLECLOSE_NOSAVE: close.
        !           242:     **      (3) OLECLOSE_PROMPTSAVE:
        !           243:     **        (a) object visible, but not in-place:
        !           244:     **               if not dirty, close.
        !           245:     **               switch(prompt)
        !           246:     **                  case IDYES: save. close.
        !           247:     **                  case IDNO: close.
        !           248:     **                  case IDCANCEL: return OLE_E_PROMPTSAVECANCELLED
        !           249:     **        (b) object invisible (includes UIDeactivated object)
        !           250:     **               if dirty, save. close.
        !           251:     **               NOTE: NO PROMPT. it is not appropriate to prompt
        !           252:     **                     if the object is not visible.
        !           253:     **        (c) object is in-place active:
        !           254:     **               if dirty, save. close.
        !           255:     **               NOTE: NO PROMPT. it is not appropriate to prompt
        !           256:     **                     if the object is active in-place.
        !           257:     */
        !           258: 
        !           259:     fStatus = OutlineDoc_Close((LPOUTLINEDOC)lpServerDoc, dwSaveOption);
        !           260:     OleDbgAssertSz(fStatus == TRUE, "SvrDoc_OleObj_Close failed\r\n");
        !           261: 
        !           262:     OLEDBG_END2
        !           263:     return (fStatus ? NOERROR : ResultFromScode(E_FAIL));
        !           264: }
        !           265: 
        !           266: 
        !           267: // IOleObject::SetMoniker method
        !           268: 
        !           269: STDMETHODIMP SvrDoc_OleObj_SetMoniker(
        !           270:         LPOLEOBJECT             lpThis, 
        !           271:         DWORD                   dwWhichMoniker, 
        !           272:         LPMONIKER               lpmk
        !           273: )
        !           274: {
        !           275:     LPSERVERDOC lpServerDoc =
        !           276:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           277:     LPOLEDOC lpOleDoc = (LPOLEDOC)lpServerDoc;
        !           278:     LPMONIKER lpmkFull;
        !           279:     HRESULT hrErr;
        !           280:     SCODE sc;
        !           281: 
        !           282:     OLEDBG_BEGIN2("SvrDoc_OleObj_SetMoniker\r\n")
        !           283: 
        !           284:     /* only our container should call IOleObject::SetMoniker. if we
        !           285:     **    don't have a ClientSite assigned then ignore this attempt to
        !           286:     **    set our moniker.
        !           287:     */
        !           288:     if (lpServerDoc->m_lpOleClientSite == NULL) {
        !           289:         sc = E_FAIL;
        !           290:         goto error;
        !           291:     }
        !           292: 
        !           293:     /* retrieve our full, absolute moniker from our container. the
        !           294:     **    moniker passed to the current method is either the relative
        !           295:     **    moniker of the object or the moniker of our container. we
        !           296:     **    require the full moniker in order to register as running.
        !           297:     */
        !           298:     hrErr = lpServerDoc->m_lpOleClientSite->lpVtbl->GetMoniker(
        !           299:             lpServerDoc->m_lpOleClientSite,
        !           300:             OLEGETMONIKER_ONLYIFTHERE, 
        !           301:             OLEWHICHMK_OBJFULL,
        !           302:             &lpmkFull
        !           303:     );
        !           304:     if (hrErr != NOERROR) {
        !           305:         sc = GetScode(hrErr);
        !           306:         goto error;
        !           307:     }
        !           308: 
        !           309:     /* Register the document as running with the new moniker and
        !           310:     **      notify any clients that our moniker has changed. 
        !           311:     */
        !           312:     OleDoc_DocRenamedUpdate(lpOleDoc, lpmkFull);
        !           313: 
        !           314:     if (lpmkFull) 
        !           315:         OleStdRelease((LPUNKNOWN)lpmkFull);
        !           316:                 
        !           317:     OLEDBG_END2
        !           318:     return NOERROR;
        !           319: 
        !           320: error:
        !           321:     OLEDBG_END2
        !           322:     return ResultFromScode(sc);
        !           323: }
        !           324: 
        !           325: 
        !           326: // IOleObject::GetMoniker method
        !           327: 
        !           328: STDMETHODIMP SvrDoc_OleObj_GetMoniker(
        !           329:         LPOLEOBJECT             lpThis, 
        !           330:         DWORD                   dwAssign,
        !           331:         DWORD                   dwWhichMoniker, 
        !           332:         LPMONIKER FAR*          lplpmk
        !           333: )
        !           334: {
        !           335:     LPSERVERDOC lpServerDoc =
        !           336:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           337:     HRESULT hrErr;
        !           338:     SCODE sc;
        !           339: 
        !           340:     OLEDBG_BEGIN2("SvrDoc_OleObj_GetMoniker\r\n")
        !           341: 
        !           342:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !           343:     *lplpmk = NULL;
        !           344:     
        !           345:     if (lpServerDoc->m_lpOleClientSite != NULL) {
        !           346:         OleDbgAssert(((LPOUTLINEDOC)lpServerDoc)->m_docInitType==DOCTYPE_EMBEDDED);
        !           347: 
        !           348:         /* document is an embedded object. retrieve our moniker from
        !           349:         **    our container.
        !           350:         */
        !           351:         OLEDBG_BEGIN2("IOleClientSite::GetMoniker called\r\n")
        !           352:         hrErr = lpServerDoc->m_lpOleClientSite->lpVtbl->GetMoniker(
        !           353:                 lpServerDoc->m_lpOleClientSite,
        !           354:                 dwAssign, 
        !           355:                 dwWhichMoniker,
        !           356:                 lplpmk
        !           357:         );
        !           358:         OLEDBG_END2
        !           359: 
        !           360:     } else if (((LPOUTLINEDOC)lpServerDoc)->m_docInitType == DOCTYPE_FROMFILE) {
        !           361: 
        !           362:         // document is a file-based document => return a FileMoniker
        !           363:         hrErr = CreateFileMoniker(
        !           364:                 ((LPOUTLINEDOC)lpServerDoc)->m_szFileName, 
        !           365:                 lplpmk
        !           366:         );
        !           367: 
        !           368:     } else {
        !           369:         // document is either New or not yet fully initialized => no moniker
        !           370:         sc = E_FAIL;
        !           371:         goto error;
        !           372:     }
        !           373: 
        !           374:     OLEDBG_END2
        !           375:     return hrErr;
        !           376: 
        !           377: error:
        !           378:     OLEDBG_END2
        !           379:     return ResultFromScode(sc);
        !           380: }
        !           381: 
        !           382: 
        !           383: // IOleObject::InitFromData method
        !           384: 
        !           385: STDMETHODIMP SvrDoc_OleObj_InitFromData(
        !           386:         LPOLEOBJECT             lpThis,
        !           387:         LPDATAOBJECT            lpDataObject,
        !           388:         BOOL                    fCreation,
        !           389:         DWORD                   reserved
        !           390: )
        !           391: {
        !           392:     LPSERVERDOC lpServerDoc =
        !           393:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           394: 
        !           395:     OLEDBG_BEGIN2("SvrDoc_OleObj_InitFromData\r\n")
        !           396: 
        !           397:     // REVIEW: NOT YET IMPLEMENTED
        !           398: 
        !           399:     OLEDBG_END2
        !           400:     return ResultFromScode(E_NOTIMPL);
        !           401: }
        !           402: 
        !           403: 
        !           404: // IOleObject::GetClipboardData method
        !           405: 
        !           406: STDMETHODIMP SvrDoc_OleObj_GetClipboardData(
        !           407:         LPOLEOBJECT             lpThis,
        !           408:         DWORD                   reserved,
        !           409:         LPDATAOBJECT FAR*       lplpDataObject
        !           410: )
        !           411: {
        !           412:     LPSERVERDOC lpServerDoc =
        !           413:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           414: 
        !           415:     OLEDBG_BEGIN2("SvrDoc_OleObj_GetClipboardData\r\n")
        !           416: 
        !           417:     // REVIEW: NOT YET IMPLEMENTED
        !           418: 
        !           419:     OLEDBG_END2
        !           420:     return ResultFromScode(E_NOTIMPL);
        !           421: }
        !           422: 
        !           423: 
        !           424: // IOleObject::DoVerb method
        !           425: 
        !           426: STDMETHODIMP SvrDoc_OleObj_DoVerb(
        !           427:         LPOLEOBJECT             lpThis,
        !           428:         LONG                    lVerb,
        !           429:         LPMSG                   lpmsg,
        !           430:         LPOLECLIENTSITE         lpActiveSite,
        !           431:                LONG                                    lindex,
        !           432:                HWND                                    hwndParent,
        !           433:                LPCRECT                                 lprcPosRect
        !           434: )
        !           435: {
        !           436:     LPSERVERDOC lpServerDoc =
        !           437:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           438:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !           439:        SCODE sc = S_OK;
        !           440: 
        !           441:     OLEDBG_BEGIN2("SvrDoc_OleObj_DoVerb\r\n")
        !           442:     
        !           443:     switch (lVerb) {
        !           444: 
        !           445:                default:
        !           446:                        /* OLE2NOTE: when an unknown verb number is given, the
        !           447:             **    server must take careful action:
        !           448:             **    1. if it is one of the specially defined OLEIVERB
        !           449:             **    (negative numbered) verbs, the app should return an
        !           450:             **    error (E_NOTIMPL) and perform no action.
        !           451:             **    
        !           452:             **    2. if the verb is a application specific verb
        !           453:             **    (positive numbered verb), then the app should
        !           454:                        **    return the special scode (OLEOBJ_S_INVALIDVERB). BUT,
        !           455:                        **    we should still perform our normal primary verb action.
        !           456:                        */
        !           457:                        if (lVerb < 0) {
        !           458:                 OLEDBG_END2
        !           459:                                return ResultFromScode(E_NOTIMPL);
        !           460:             } else {
        !           461:                 sc = OLEOBJ_S_INVALIDVERB;
        !           462:             }
        !           463:                        
        !           464:                        // deliberatly fall through to Primary Verb
        !           465: 
        !           466:         case 0:
        !           467:         case OLEIVERB_SHOW:
        !           468: 
        !           469: #if defined( INPLACE_SVR )                        
        !           470:             /* OLE2NOTE: if our window is already open (visible) then
        !           471:             **    we should simply surface the open window. if not,
        !           472:             **    then we can do our primary action of in-place 
        !           473:             **    activation.
        !           474:             */
        !           475:             if ( lpServerDoc->m_lpOleClientSite 
        !           476:                     && ! (IsWindowVisible(lpOutlineDoc->m_hWndDoc) &&
        !           477:                             ! lpServerDoc->m_fInPlaceActive) ) {
        !           478:                 ServerDoc_DoInPlaceActivate(
        !           479:                         lpServerDoc, lVerb, lpmsg, lpActiveSite);
        !           480:             }
        !           481: #endif // INPLACE_SVR         
        !           482: 
        !           483:             OutlineDoc_ShowWindow(lpOutlineDoc);
        !           484:             break;
        !           485: 
        !           486:         case 1:
        !           487:         case OLEIVERB_OPEN:
        !           488: #if defined( INPLACE_SVR )
        !           489:                        ServerDoc_DoInPlaceDeactivate(lpServerDoc);
        !           490: #endif // INPLACE_SVR
        !           491:             OutlineDoc_ShowWindow(lpOutlineDoc);
        !           492:             break;
        !           493: 
        !           494: 
        !           495:         case OLEIVERB_HIDE:
        !           496: #if defined( INPLACE_SVR )
        !           497:                        if (lpServerDoc->m_fInPlaceActive) {
        !           498: 
        !           499:                 SvrDoc_IPObj_UIDeactivate(
        !           500:                         (LPOLEINPLACEOBJECT)&lpServerDoc->m_OleInPlaceObject);
        !           501: 
        !           502: #if defined( SVR_INSIDEOUT )
        !           503:                 /* OLE2NOTE: an inside-out style in-place server will
        !           504:                 **    NOT hide its window in UIDeactive (an outside-in
        !           505:                 **    style object will hide its window in
        !           506:                 **    UIDeactivate). thus we need to explicitly hide
        !           507:                 **    our window now.
        !           508:                 */
        !           509:                                ServerDoc_DoInPlaceHide(lpServerDoc);
        !           510: #endif // INSIEDOUT
        !           511: 
        !           512:             } else {
        !           513:                                OleDoc_HideWindow((LPOLEDOC)lpServerDoc, FALSE /*fShutdown*/);
        !           514:             }
        !           515: #endif // INPLACE_SVR
        !           516:             break;
        !           517: 
        !           518: #if defined( INPLACE_SVR )                     
        !           519:                case OLEIVERB_UIACTIVATE:
        !           520: 
        !           521: #if defined( SVR_INSIDEOUT )
        !           522:         /* OLE2NOTE: only an inside-out style object supports
        !           523:         **    INPLACEACTIVATE verb 
        !           524:         */
        !           525:                case OLEIVERB_INPLACEACTIVATE:
        !           526: #endif // INSIEDOUT
        !           527:             /* OLE2NOTE: if our window is already open (visible) then
        !           528:             **    we can NOT activate in-place.
        !           529:             */
        !           530:             if (IsWindowVisible(lpOutlineDoc->m_hWndDoc) &&
        !           531:                         ! lpServerDoc->m_fInPlaceActive ) {
        !           532:                 sc = OLE_E_NOT_INPLACEACTIVE;
        !           533:             } else {
        !           534:                 sc = GetScode( ServerDoc_DoInPlaceActivate(
        !           535:                         lpServerDoc, lVerb, lpmsg, lpActiveSite) );
        !           536:                 if (SUCCEEDED(sc)) 
        !           537:                     OutlineDoc_ShowWindow(lpOutlineDoc);
        !           538:             }
        !           539:             break;
        !           540: #endif  // INPLACE_SVR
        !           541:     }
        !           542:     
        !           543:     OLEDBG_END2
        !           544:        return ResultFromScode(sc);
        !           545: }
        !           546: 
        !           547: 
        !           548: // IOleObject::EnumVerbs method
        !           549: 
        !           550: STDMETHODIMP SvrDoc_OleObj_EnumVerbs(
        !           551:         LPOLEOBJECT             lpThis,
        !           552:         LPENUMOLEVERB FAR*      lplpenumOleVerb 
        !           553: )
        !           554: {
        !           555:     OleDbgOut2("SvrDoc_OleObj_EnumVerbs\r\n");
        !           556: 
        !           557:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !           558:     *lplpenumOleVerb = NULL;
        !           559: 
        !           560:     // Tell OLE to enumerate our verbs using the REGDB
        !           561:     return ResultFromScode(OLE_S_USEREG);
        !           562: }
        !           563: 
        !           564: 
        !           565: // IOleObject::Update method
        !           566: 
        !           567: STDMETHODIMP SvrDoc_OleObj_Update(LPOLEOBJECT lpThis)
        !           568: {
        !           569:     OleDbgOut2("SvrDoc_OleObj_Update\r\n");
        !           570: 
        !           571:     /* OLE2NOTE: a server-only app is always "up-to-date". 
        !           572:     **    a container-app which contains links where the link source
        !           573:     **    has changed since the last update of the link would be
        !           574:     **    considered "out-of-date". the "Update" method instructs the
        !           575:     **    object to get an update from any out-of-date links.
        !           576:     */
        !           577: 
        !           578:     return NOERROR;
        !           579: }
        !           580: 
        !           581: 
        !           582: // IOleObject::IsUpToDate method
        !           583: 
        !           584: STDMETHODIMP SvrDoc_OleObj_IsUpToDate(LPOLEOBJECT lpThis)
        !           585: {
        !           586:     OleDbgOut2("SvrDoc_OleObj_IsUpToDate\r\n");
        !           587: 
        !           588:     /* OLE2NOTE: a server-only app is always "up-to-date". 
        !           589:     **    a container-app which contains links where the link source
        !           590:     **    has changed since the last update of the link would be
        !           591:     **    considered "out-of-date".
        !           592:     */
        !           593:     return NOERROR;
        !           594: }
        !           595: 
        !           596: 
        !           597: // IOleObject::GetUserClassID method
        !           598: 
        !           599: STDMETHODIMP SvrDoc_OleObj_GetUserClassID(
        !           600:         LPOLEOBJECT             lpThis, 
        !           601:         LPCLSID                 lpClassID
        !           602: )
        !           603: {
        !           604:     LPSERVERDOC lpServerDoc =
        !           605:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           606: 
        !           607:     OleDbgOut2("SvrDoc_OleObj_GetClassID\r\n");
        !           608: 
        !           609:        /* OLE2NOTE: we must be carefull to return the correct CLSID here.
        !           610:        **    if we are currently preforming a "TreatAs (aka. ActivateAs)"
        !           611:        **    operation then we need to return the class of the object
        !           612:        **    written in the storage of the object. otherwise we would
        !           613:        **    return our own class id. 
        !           614:        */
        !           615:        return ServerDoc_GetClassID(lpServerDoc, lpClassID);
        !           616: }
        !           617: 
        !           618: 
        !           619: // IOleObject::GetUserType method
        !           620: 
        !           621: STDMETHODIMP SvrDoc_OleObj_GetUserType(
        !           622:         LPOLEOBJECT             lpThis,
        !           623:         DWORD                   dwFormOfType, 
        !           624:         LPSTR FAR*              lpszUserType
        !           625: )
        !           626: {
        !           627:     OleDbgOut2("SvrDoc_OleObj_GetUserType\r\n");
        !           628: 
        !           629:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !           630:     *lpszUserType = NULL;
        !           631: 
        !           632:     // Tell OLE to enumerate our verbs using the REGDB
        !           633:     return ResultFromScode(OLE_S_USEREG);
        !           634: 
        !           635: #if defined( LATER )
        !           636:     LPSERVERDOC lpServerDoc =
        !           637:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           638: 
        !           639:        /* OLE2NOTE: we must be carefull to return the correct UserType here.
        !           640:        **    if we are currently preforming a "TreatAs (aka. ActivateAs)"
        !           641:        **    operation then we need to return the UserType of the object
        !           642:        **    written in the storage of the object. otherwise we would
        !           643:        **    return our own UserType.
        !           644:        */
        !           645:        return ServerDoc_GetUserType(lpServerDoc, dwFormOfType, lpszUserType);
        !           646: #endif
        !           647: }
        !           648: 
        !           649: 
        !           650: // IOleObject::SetExtent method
        !           651: 
        !           652: STDMETHODIMP SvrDoc_OleObj_SetExtent(
        !           653:         LPOLEOBJECT             lpThis,
        !           654:         DWORD                   dwDrawAspect,
        !           655:         LPSIZEL                 lplgrc
        !           656: )
        !           657: {
        !           658:     OleDbgOut2("SvrDoc_OleObj_SetExtent\r\n");
        !           659: 
        !           660:     /* SVROUTL does NOT allow the object's size to be set by its
        !           661:     **    container. the size of the ServerDoc object is determined by
        !           662:     **    the data contained within the document.
        !           663:     */
        !           664:     return ResultFromScode(S_FALSE);
        !           665: }
        !           666: 
        !           667: 
        !           668: // IOleObject::GetExtent method
        !           669: 
        !           670: STDMETHODIMP SvrDoc_OleObj_GetExtent(
        !           671:         LPOLEOBJECT             lpThis,
        !           672:         DWORD                   dwDrawAspect,
        !           673:         LPSIZEL                 lpsizel
        !           674: )
        !           675: {
        !           676:     LPOLEDOC lpOleDoc =
        !           677:             (LPOLEDOC)((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           678: 
        !           679:     OleDbgOut2("SvrDoc_OleObj_GetExtent\r\n");
        !           680: 
        !           681:        if (dwDrawAspect == DVASPECT_CONTENT
        !           682:                        || dwDrawAspect == DVASPECT_THUMBNAIL
        !           683:                        || dwDrawAspect == DVASPECT_DOCPRINT) 
        !           684:     {
        !           685:                OleDoc_GetExtent(lpOleDoc, lpsizel);
        !           686:                return NOERROR;
        !           687:     }
        !           688: 
        !           689: #if defined( LATER )
        !           690: 
        !           691:     else if (dwDrawAspect == DVASPECT_THUMBNAIL) 
        !           692:     {
        !           693:         /* as our thumbnail we will render only the first page of the 
        !           694:         **    document. calculate extents of our thumbnail rendering.
        !           695:         **    
        !           696:         ** OLE2NOTE: thumbnails are most often used by applications in
        !           697:         **    FindFile or FileOpen type dialogs to give the user a
        !           698:         **    quick view of the contents of the file or object.
        !           699:         */
        !           700:                OleDoc_GetThumbnailExtent(lpOleDoc, lpsizel);
        !           701:                return NOERROR;
        !           702:     }
        !           703: #endif
        !           704: 
        !           705:        else 
        !           706:     {
        !           707:                return ResultFromScode(E_INVALIDARG);
        !           708:        }
        !           709: }
        !           710: 
        !           711: 
        !           712: // IOleObject::Advise method
        !           713: 
        !           714: STDMETHODIMP SvrDoc_OleObj_Advise(
        !           715:         LPOLEOBJECT             lpThis, 
        !           716:         LPADVISESINK            lpAdvSink, 
        !           717:         LPDWORD                 lpdwConnection
        !           718: )
        !           719: {
        !           720:     LPSERVERDOC lpServerDoc =
        !           721:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           722:     HRESULT hrErr;
        !           723:     SCODE   sc;
        !           724: 
        !           725:     OLEDBG_BEGIN2("SvrDoc_OleObj_Advise\r\n");
        !           726: 
        !           727:     if (lpServerDoc->m_lpOleAdviseHldr == NULL && 
        !           728:         CreateOleAdviseHolder(&lpServerDoc->m_lpOleAdviseHldr) != NOERROR) {
        !           729:         sc = E_OUTOFMEMORY;
        !           730:         goto error;
        !           731:     }
        !           732: 
        !           733:     OLEDBG_BEGIN2("IOleAdviseHolder::Advise called\r\n")
        !           734:     hrErr = lpServerDoc->m_lpOleAdviseHldr->lpVtbl->Advise(
        !           735:             lpServerDoc->m_lpOleAdviseHldr, 
        !           736:             lpAdvSink, 
        !           737:             lpdwConnection
        !           738:     );
        !           739:     OLEDBG_END2
        !           740: 
        !           741:     OLEDBG_END2
        !           742:     return hrErr;
        !           743: 
        !           744: error:
        !           745:     OLEDBG_END2
        !           746:     return ResultFromScode(sc);
        !           747: }
        !           748: 
        !           749: 
        !           750: // IOleObject::Unadvise method
        !           751: 
        !           752: STDMETHODIMP SvrDoc_OleObj_Unadvise(LPOLEOBJECT lpThis, DWORD dwConnection)
        !           753: {
        !           754:     LPSERVERDOC lpServerDoc =
        !           755:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           756:     HRESULT hrErr;
        !           757:     SCODE   sc;
        !           758: 
        !           759:     OLEDBG_BEGIN2("SvrDoc_OleObj_Unadvise\r\n");
        !           760: 
        !           761:     if (lpServerDoc->m_lpOleAdviseHldr == NULL) {
        !           762:         sc = E_FAIL;
        !           763:         goto error;
        !           764:     }
        !           765: 
        !           766:     OLEDBG_BEGIN2("IOleAdviseHolder::Unadvise called\r\n")
        !           767:     hrErr = lpServerDoc->m_lpOleAdviseHldr->lpVtbl->Unadvise(
        !           768:             lpServerDoc->m_lpOleAdviseHldr, 
        !           769:             dwConnection
        !           770:     );
        !           771:     OLEDBG_END2
        !           772: 
        !           773:     OLEDBG_END2
        !           774:     return hrErr;
        !           775: 
        !           776: error:
        !           777:     OLEDBG_END2
        !           778:     return ResultFromScode(sc);
        !           779: }
        !           780: 
        !           781: 
        !           782: // IOleObject::EnumAdvise method
        !           783: 
        !           784: STDMETHODIMP SvrDoc_OleObj_EnumAdvise(
        !           785:         LPOLEOBJECT             lpThis, 
        !           786:         LPENUMSTATDATA FAR*     lplpenumAdvise
        !           787: )
        !           788: {
        !           789:     LPSERVERDOC lpServerDoc =
        !           790:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           791:     HRESULT hrErr;
        !           792:     SCODE   sc;
        !           793: 
        !           794:     OLEDBG_BEGIN2("SvrDoc_OleObj_EnumAdvise\r\n");
        !           795: 
        !           796:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !           797:     *lplpenumAdvise = NULL;
        !           798: 
        !           799:     if (lpServerDoc->m_lpOleAdviseHldr == NULL) {
        !           800:         sc = E_FAIL;
        !           801:         goto error;
        !           802:     }
        !           803: 
        !           804:     OLEDBG_BEGIN2("IOleAdviseHolder::EnumAdvise called\r\n")
        !           805:     hrErr = lpServerDoc->m_lpOleAdviseHldr->lpVtbl->EnumAdvise(
        !           806:             lpServerDoc->m_lpOleAdviseHldr, 
        !           807:             lplpenumAdvise
        !           808:     );
        !           809:     OLEDBG_END2
        !           810: 
        !           811:     OLEDBG_END2
        !           812:     return hrErr;
        !           813: 
        !           814: error:
        !           815:     OLEDBG_END2
        !           816:     return ResultFromScode(sc);
        !           817: }
        !           818: 
        !           819: 
        !           820: // IOleObject::GetMiscStatus method
        !           821: 
        !           822: STDMETHODIMP SvrDoc_OleObj_GetMiscStatus(
        !           823:         LPOLEOBJECT             lpThis,
        !           824:         DWORD                   dwAspect,
        !           825:         DWORD FAR*              lpdwStatus
        !           826: )
        !           827: {
        !           828:        LPSERVERDOC lpServerDoc =
        !           829:             ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
        !           830:        LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !           831: 
        !           832:     OleDbgOut2("SvrDoc_OleObj_GetMiscStatus\r\n");
        !           833: 
        !           834:        *lpdwStatus = 0;
        !           835: 
        !           836:     /* OLE2NOTE: check if the data copied is compatible to be
        !           837:     **    linked by an OLE 1.0 container. it is compatible if
        !           838:     **    either the data is an untitled document, a file, or a
        !           839:     **    selection of data within a file. if the data is part of
        !           840:     **    an embedded object, then it is NOT compatible to be
        !           841:     **    linked by an OLE 1.0 container. if it is compatible then
        !           842:     **    we must include OLEMISC_CANLINKBYOLE1 as part of the
        !           843:     **    dwStatus flags transfered via CF_OBJECTDESCRIPTOR or
        !           844:     **    CF_LINKSRCDESCRIPTOR.
        !           845:     */
        !           846:        if (lpOutlineDoc->m_docInitType == DOCTYPE_NEW || 
        !           847:                lpOutlineDoc->m_docInitType == DOCTYPE_FROMFILE) 
        !           848:                *lpdwStatus |= OLEMISC_CANLINKBYOLE1;
        !           849: 
        !           850: #if defined( INPLACE_SVR )     
        !           851:        if (dwAspect == DVASPECT_CONTENT)
        !           852:                *lpdwStatus |= (OLEMISC_INSIDEOUT | OLEMISC_ACTIVATEWHENVISIBLE);
        !           853: #endif  // INPLACE_SVR
        !           854: 
        !           855:        return NOERROR;
        !           856: }
        !           857: 
        !           858: 
        !           859: // IOleObject::SetColorScheme method
        !           860: 
        !           861: STDMETHODIMP SvrDoc_OleObj_SetColorScheme(
        !           862:         LPOLEOBJECT             lpThis,
        !           863:         LPLOGPALETTE            lpLogpal
        !           864: )
        !           865: {
        !           866:     OleDbgOut2("SvrDoc_OleObj_SetColorScheme\r\n");
        !           867: 
        !           868:     // REVIEW: NOT YET IMPLEMENTED
        !           869: 
        !           870:     return ResultFromScode(E_NOTIMPL);
        !           871: }
        !           872: 
        !           873: 
        !           874: /*************************************************************************
        !           875: ** ServerDoc::IPersistStorage interface implementation
        !           876: *************************************************************************/
        !           877: 
        !           878: // IPersistStorage::QueryInterface method
        !           879: 
        !           880: STDMETHODIMP SvrDoc_PStg_QueryInterface(
        !           881:         LPPERSISTSTORAGE        lpThis,
        !           882:         REFIID                  riid,
        !           883:         LPVOID FAR*             lplpvObj
        !           884: )
        !           885: {
        !           886:     LPSERVERDOC lpServerDoc =
        !           887:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !           888: 
        !           889:     return OleDoc_QueryInterface((LPOLEDOC)lpServerDoc, riid, lplpvObj);
        !           890: }
        !           891: 
        !           892: 
        !           893: // IPersistStorage::AddRef method
        !           894: 
        !           895: STDMETHODIMP_(ULONG) SvrDoc_PStg_AddRef(LPPERSISTSTORAGE lpThis)
        !           896: {
        !           897:     LPSERVERDOC lpServerDoc = 
        !           898:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !           899:     
        !           900:     OleDbgAddRefMethod(lpThis, "IPersistStorage");
        !           901: 
        !           902:     return OleDoc_AddRef((LPOLEDOC)lpServerDoc);
        !           903: }
        !           904: 
        !           905: 
        !           906: // IPersistStorage::Release method
        !           907: 
        !           908: STDMETHODIMP_(ULONG) SvrDoc_PStg_Release(LPPERSISTSTORAGE lpThis)
        !           909: {
        !           910:     LPSERVERDOC lpServerDoc = 
        !           911:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !           912:     
        !           913:     OleDbgReleaseMethod(lpThis, "IPersistStorage");
        !           914: 
        !           915:     return OleDoc_Release((LPOLEDOC)lpServerDoc);
        !           916: }
        !           917: 
        !           918: 
        !           919: // IPersistStorage::GetClassID method
        !           920: 
        !           921: STDMETHODIMP SvrDoc_PStg_GetClassID(
        !           922:         LPPERSISTSTORAGE        lpThis, 
        !           923:         LPCLSID                 lpClassID
        !           924: )
        !           925: {
        !           926:     LPSERVERDOC lpServerDoc = 
        !           927:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !           928: 
        !           929:     OleDbgOut2("SvrDoc_PStg_GetClassID\r\n");
        !           930: 
        !           931:        /* OLE2NOTE: we must be carefull to return the correct CLSID here.
        !           932:        **    if we are currently preforming a "TreatAs (aka. ActivateAs)"
        !           933:        **    operation then we need to return the class of the object
        !           934:        **    written in the storage of the object. otherwise we would
        !           935:        **    return our own class id. 
        !           936:        */
        !           937:        return ServerDoc_GetClassID(lpServerDoc, lpClassID);
        !           938: }
        !           939: 
        !           940: 
        !           941: // IPersistStorage::IsDirty method
        !           942: 
        !           943: STDMETHODIMP  SvrDoc_PStg_IsDirty(LPPERSISTSTORAGE  lpThis)
        !           944: {
        !           945:     LPSERVERDOC lpServerDoc = 
        !           946:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !           947: 
        !           948:     OleDbgOut2("SvrDoc_PStg_IsDirty\r\n");
        !           949: 
        !           950:     if (OutlineDoc_IsModified((LPOUTLINEDOC)lpServerDoc))
        !           951:         return NOERROR;
        !           952:     else 
        !           953:         return ResultFromScode(S_FALSE);
        !           954: }
        !           955: 
        !           956: 
        !           957: 
        !           958: // IPersistStorage::InitNew method
        !           959: 
        !           960: STDMETHODIMP SvrDoc_PStg_InitNew(
        !           961:         LPPERSISTSTORAGE        lpThis, 
        !           962:         LPSTORAGE               lpStg
        !           963: )
        !           964: {
        !           965:     LPSERVERDOC lpServerDoc = 
        !           966:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !           967:     SCODE sc;
        !           968: 
        !           969:     OLEDBG_BEGIN2("SvrDoc_PStg_InitNew\r\n")
        !           970: 
        !           971: #if defined( SVR_TREATAS )
        !           972:        {
        !           973:                LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           974:                CLSID           clsid;
        !           975:                CLIPFORMAT      cfFmt;
        !           976:                LPSTR           lpszType;
        !           977: 
        !           978:                /* OLE2NOTE: if the Server is capable of supporting "TreatAs"
        !           979:                **    (aka. ActivateAs), it must read the class that is written
        !           980:                **    into the storage. if this class is NOT the app's own
        !           981:                **    class ID, then this is a TreatAs operation. the server
        !           982:                **    then must faithfully pretend to be the class that is
        !           983:                **    written into the storage. it must also faithfully write
        !           984:                **    the data back to the storage in the SAME format as is
        !           985:                **    written in the storage.
        !           986:                **    
        !           987:                **    SVROUTL and ISVROTL can emulate each other. they have the
        !           988:                **    simplification that they both read/write the identical
        !           989:                **    format. thus for these apps no actual conversion of the
        !           990:                **    native bits is actually required.
        !           991:                */
        !           992:                lpServerDoc->m_clsidTreatAs = CLSID_NULL;
        !           993:                if (OleStdGetTreatAsFmtUserType(&CLSID_APP, lpStg, &clsid,
        !           994:                                                        (CLIPFORMAT FAR*)&cfFmt, (LPSTR FAR*)&lpszType)) {
        !           995:                                                        
        !           996:                        if (cfFmt == lpOutlineApp->m_cfOutline) {
        !           997:                                // We should perform TreatAs operation
        !           998:                                if (lpServerDoc->m_lpszTreatAsType) 
        !           999:                                        OleStdFreeString(lpServerDoc->m_lpszTreatAsType, NULL);
        !          1000: 
        !          1001:                                lpServerDoc->m_clsidTreatAs = clsid;
        !          1002:                                ((LPOUTLINEDOC)lpServerDoc)->m_cfSaveFormat = cfFmt; 
        !          1003:                                lpServerDoc->m_lpszTreatAsType = lpszType;
        !          1004: 
        !          1005:                                OleDbgOut3("SvrDoc_PStg_InitNew: TreateAs ==> '");
        !          1006:                                OleDbgOutNoPrefix3(lpServerDoc->m_lpszTreatAsType);
        !          1007:                                OleDbgOutNoPrefix3("'\r\n");
        !          1008:                        } else {
        !          1009:                                // ERROR: we ONLY support TreatAs for CF_OUTLINE format
        !          1010:                                OleDbgOut("SvrDoc_PStg_InitNew: INVALID TreatAs Format\r\n");
        !          1011:                                OleStdFreeString(lpszType, NULL);
        !          1012:                        }
        !          1013:                }
        !          1014:        }
        !          1015: #endif // SVR_TREATAS
        !          1016: 
        !          1017:     // set the doc to a new embedded object.
        !          1018:     if (! ServerDoc_InitNewEmbed(lpServerDoc)) {
        !          1019:         sc = E_FAIL;
        !          1020:         goto error;
        !          1021:     }
        !          1022: 
        !          1023:        lpServerDoc->m_dwStorageMode = STGMODE_NORMAL;
        !          1024: 
        !          1025:     OLEDBG_END2
        !          1026:     return NOERROR;
        !          1027: 
        !          1028: error:
        !          1029:     OLEDBG_END2
        !          1030:     return ResultFromScode(sc);
        !          1031: }
        !          1032: 
        !          1033: 
        !          1034: // IPersistStorage::Load method
        !          1035: 
        !          1036: STDMETHODIMP SvrDoc_PStg_Load(
        !          1037:         LPPERSISTSTORAGE        lpThis, 
        !          1038:         LPSTORAGE               lpStg
        !          1039: )
        !          1040: {
        !          1041:     LPSERVERDOC lpServerDoc = 
        !          1042:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !          1043:        LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1044:     SCODE sc;
        !          1045: 
        !          1046:     OLEDBG_BEGIN2("SvrDoc_PStg_Load\r\n")
        !          1047: 
        !          1048:     if (OutlineDoc_LoadFromStg((LPOUTLINEDOC)lpServerDoc, lpStg)) {
        !          1049: 
        !          1050:         ((LPOUTLINEDOC)lpServerDoc)->m_docInitType = DOCTYPE_EMBEDDED;
        !          1051: 
        !          1052:                lpServerDoc->m_dwStorageMode = STGMODE_NORMAL;
        !          1053: 
        !          1054:                /* OLE2NOTE: we need to check if the ConvertStg bit is on. if
        !          1055:                **    so, we need to clear the ConvertStg bit and mark the
        !          1056:         **    document as dirty so as to force a save when the document
        !          1057:         **    is closed. the actual conversion of the bits should be
        !          1058:         **    performed when the data is loaded from the IStorage*. in
        !          1059:         **    our case any conversion of data formats would be done in
        !          1060:         **    OutlineDoc_LoadFromStg function. in reality both SVROUTL
        !          1061:         **    and ISVROTL read and write the same format so no actual
        !          1062:         **    conversion of data bits is necessary.
        !          1063:                */
        !          1064:                if (GetConvertStg(lpStg) == NOERROR) {
        !          1065:             SetConvertStg(lpStg, FALSE);
        !          1066: 
        !          1067:                        OleDbgOut3("SvrDoc_PStg_Load: ConvertStg==TRUE\r\n");
        !          1068:                        OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
        !          1069:                }
        !          1070: 
        !          1071:     } else {
        !          1072:         sc = E_FAIL;
        !          1073:         goto error;
        !          1074:     }
        !          1075: 
        !          1076:     OLEDBG_END2
        !          1077:     return NOERROR;
        !          1078: 
        !          1079: error:
        !          1080:     OLEDBG_END2
        !          1081:     return ResultFromScode(sc);
        !          1082: }
        !          1083: 
        !          1084: 
        !          1085: // IPersistStorage::Save method
        !          1086: 
        !          1087: STDMETHODIMP SvrDoc_PStg_Save(
        !          1088:         LPPERSISTSTORAGE        lpThis,
        !          1089:         LPSTORAGE               lpStg,
        !          1090:         BOOL                    fSameAsLoad
        !          1091: )
        !          1092: {
        !          1093:     LPSERVERDOC lpServerDoc = 
        !          1094:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !          1095:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1096:     BOOL fStatus;
        !          1097:     SCODE sc;
        !          1098: 
        !          1099:     OLEDBG_BEGIN2("SvrDoc_PStg_Save\r\n")
        !          1100: 
        !          1101:     fStatus = OutlineDoc_SaveSelToStg(
        !          1102:             (LPOUTLINEDOC)lpServerDoc, 
        !          1103:             NULL, 
        !          1104:             lpOutlineDoc->m_cfSaveFormat,
        !          1105:             lpStg, 
        !          1106:             FALSE
        !          1107:     );
        !          1108: 
        !          1109:     lpServerDoc->m_fSaveWithSameAsLoad = fSameAsLoad;
        !          1110: 
        !          1111:     if (! fStatus) {
        !          1112:         OutlineApp_ErrorMessage(g_lpApp, ErrMsgPSSaveFail);
        !          1113:         sc = E_FAIL;
        !          1114:         goto error;
        !          1115:     }
        !          1116: 
        !          1117:        lpServerDoc->m_dwStorageMode = STGMODE_NOSCRIBBLE;
        !          1118:     OLEDBG_END2
        !          1119:     return NOERROR;
        !          1120: 
        !          1121: error:
        !          1122:     OLEDBG_END2
        !          1123:     return ResultFromScode(sc);
        !          1124: }
        !          1125: 
        !          1126: 
        !          1127: 
        !          1128: // IPersistStorage::SaveCompleted method
        !          1129: 
        !          1130: STDMETHODIMP SvrDoc_PStg_SaveCompleted(
        !          1131:         LPPERSISTSTORAGE        lpThis, 
        !          1132:         LPSTORAGE               lpStgNew
        !          1133: )
        !          1134: {
        !          1135:     LPSERVERDOC lpServerDoc = 
        !          1136:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !          1137:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1138: 
        !          1139:     OLEDBG_BEGIN2("SvrDoc_PStg_SaveCompleted\r\n")
        !          1140: 
        !          1141:        /* OLE2NOTE: because we are a pure server that loads all data into
        !          1142:        **    memory, we do not hold on to our storage. thus we do not have
        !          1143:        **    to remember the storage passed into SaveCompleted.
        !          1144:        **    a container/server application must hold on to its storage
        !          1145:        **    however. any application that holds onto its storage must now
        !          1146:        **    remember the storage if one is passed in. in addition a
        !          1147:        **    container/server application would have to call SaveCompleted
        !          1148:        **    for each of its contained compound document objects. if a new
        !          1149:        **    storage was given, then the container/server would have to
        !          1150:        **    open the corresponding new sub-storage for each compound
        !          1151:        **    document object and pass as an argument in the SaveCompleted
        !          1152:        **    call. 
        !          1153:        */
        !          1154: 
        !          1155:        lpServerDoc->m_dwStorageMode = STGMODE_NORMAL;
        !          1156: 
        !          1157:     /* OLE2NOTE: it is only legal to perform a Save or SaveAs operation 
        !          1158:     **    on an embedded object. if the document is a file-based document
        !          1159:     **    then we can not be changed to a IStorage-base object.
        !          1160:     **    
        !          1161:     **      fSameAsLoad   lpStgNew     Type of Save     Send OnSave
        !          1162:     **    ---------------------------------------------------------
        !          1163:     **         TRUE        NULL        SAVE             YES
        !          1164:     **         TRUE        ! NULL      SAVE *           YES
        !          1165:     **         FALSE       ! NULL      SAVE AS          YES
        !          1166:     **         FALSE       NULL        SAVE COPY AS     NO
        !          1167:     **    
        !          1168:     **    * this is a strange case that is possible. it is inefficient
        !          1169:     **    for the caller; it would be better to pass lpStgNew==NULL for
        !          1170:     **    the Save operation.
        !          1171:     */
        !          1172:     if ( ((lpServerDoc->m_fSaveWithSameAsLoad && lpStgNew==NULL) || lpStgNew)
        !          1173:             && (lpOutlineDoc->m_docInitType != DOCTYPE_EMBEDDED) ) {
        !          1174:         OLEDBG_END2
        !          1175:         return ResultFromScode(E_INVALIDARG);
        !          1176:     }
        !          1177: 
        !          1178:     /* OLE2NOTE: inform any linking clients that the document has been
        !          1179:     **    saved. in addition, any currently active pseudo objects
        !          1180:     **    should also inform their clients. we should only broadcast an
        !          1181:     **    OnSave notification if a Save or SaveAs operation was
        !          1182:     **    performed. we do NOT want to send the notification if a
        !          1183:     **    SaveCopyAs operation was performed.
        !          1184:     */
        !          1185:     if ((lpServerDoc->m_fSaveWithSameAsLoad && lpStgNew==NULL) || lpStgNew) {
        !          1186: 
        !          1187:         // Clear dirty flag upon save or saveAs
        !          1188:         OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
        !          1189: 
        !          1190:         ServerDoc_SendAdvise (
        !          1191:                 lpServerDoc, 
        !          1192:                 OLE_ONSAVE, 
        !          1193:                 NULL,  /* lpmkDoc -- not relevant here */
        !          1194:                 0      /* advf -- not relevant here */
        !          1195:         );
        !          1196:     }
        !          1197:     OLEDBG_END2
        !          1198:     return NOERROR;
        !          1199: }
        !          1200: 
        !          1201: 
        !          1202: // IPersistStorage::HandsOffStorage method
        !          1203: 
        !          1204: STDMETHODIMP SvrDoc_PStg_HandsOffStorage(LPPERSISTSTORAGE lpThis)
        !          1205: {
        !          1206:     LPSERVERDOC lpServerDoc = 
        !          1207:             ((struct CDocPersistStorageImpl FAR*)lpThis)->lpServerDoc;
        !          1208: 
        !          1209:     OLEDBG_BEGIN2("SvrDoc_PStg_HandsOffStorage\r\n")
        !          1210: 
        !          1211:        /* OLE2NOTE: because we are a pure server that loads all data into
        !          1212:        **    memory, we do not hold on to our storage. thus we do not have
        !          1213:        **    a storage to release (ie. to enter HandsOff Mode). 
        !          1214:        **    a container/server application must hold on to its storage
        !          1215:        **    however. any application that holds onto its storage must now
        !          1216:        **    release its storage. when SaveCompleted is called, then a new
        !          1217:        **    storage will be given.
        !          1218:        */
        !          1219: 
        !          1220:        lpServerDoc->m_dwStorageMode = STGMODE_HANDSOFF;
        !          1221:     
        !          1222:     OLEDBG_END2
        !          1223:     return NOERROR;
        !          1224: }
        !          1225: 
        !          1226: 
        !          1227: 
        !          1228: #if defined( SVR_TREATAS )
        !          1229: 
        !          1230: /*************************************************************************
        !          1231: ** ServerDoc::IStdMarshalInfo interface implementation
        !          1232: *************************************************************************/
        !          1233: 
        !          1234: // IStdMarshalInfo::QueryInterface method
        !          1235: 
        !          1236: STDMETHODIMP SvrDoc_StdMshl_QueryInterface(
        !          1237:         LPSTDMARSHALINFO        lpThis,
        !          1238:         REFIID                  riid,
        !          1239:         LPVOID FAR*             lplpvObj
        !          1240: )
        !          1241: {
        !          1242:     LPSERVERDOC lpServerDoc =
        !          1243:             ((struct CDocStdMarshalInfoImpl FAR*)lpThis)->lpServerDoc;
        !          1244: 
        !          1245:     return OleDoc_QueryInterface((LPOLEDOC)lpServerDoc, riid, lplpvObj);
        !          1246: }
        !          1247: 
        !          1248: 
        !          1249: // IStdMarshalInfo::AddRef method
        !          1250: 
        !          1251: STDMETHODIMP_(ULONG) SvrDoc_StdMshl_AddRef(LPSTDMARSHALINFO lpThis)
        !          1252: {
        !          1253:     LPSERVERDOC lpServerDoc = 
        !          1254:             ((struct CDocStdMarshalInfoImpl FAR*)lpThis)->lpServerDoc;
        !          1255:     
        !          1256:     OleDbgAddRefMethod(lpThis, "IStdMarshalInfo");
        !          1257: 
        !          1258:     return OleDoc_AddRef((LPOLEDOC)lpServerDoc);
        !          1259: }
        !          1260: 
        !          1261: 
        !          1262: // IStdMarshalInfo::Release method
        !          1263: 
        !          1264: STDMETHODIMP_(ULONG) SvrDoc_StdMshl_Release(LPSTDMARSHALINFO lpThis)
        !          1265: {
        !          1266:     LPSERVERDOC lpServerDoc = 
        !          1267:             ((struct CDocStdMarshalInfoImpl FAR*)lpThis)->lpServerDoc;
        !          1268:     
        !          1269:     OleDbgReleaseMethod(lpThis, "IStdMarshalInfo");
        !          1270: 
        !          1271:     return OleDoc_Release((LPOLEDOC)lpServerDoc);
        !          1272: }
        !          1273: 
        !          1274: 
        !          1275: // IStdMarshalInfo::GetClassForHandler
        !          1276: 
        !          1277: STDMETHODIMP SvrDoc_StdMshl_GetClassForHandler(
        !          1278:         LPSTDMARSHALINFO        lpThis, 
        !          1279:                DWORD                                   dwDestContext, 
        !          1280:                LPVOID                                  pvDestContext, 
        !          1281:         LPCLSID                 lpClassID
        !          1282: )
        !          1283: {
        !          1284:     LPSERVERDOC lpServerDoc = 
        !          1285:             ((struct CDocStdMarshalInfoImpl FAR*)lpThis)->lpServerDoc;
        !          1286: 
        !          1287:     OleDbgOut2("SvrDoc_StdMshl_GetClassForHandler\r\n");
        !          1288: 
        !          1289:        // OLE2NOTE: we only handle LOCAL marshal context.
        !          1290:        if (dwDestContext != MSHCTX_LOCAL || pvDestContext != NULL) 
        !          1291:                return ResultFromScode(E_INVALIDARG);
        !          1292: 
        !          1293:        /* OLE2NOTE: we must return our REAL clsid, NOT the clsid that we
        !          1294:        **    are pretending to be if a "TreatAs" is in effect.
        !          1295:        */
        !          1296:     *lpClassID = CLSID_APP; 
        !          1297:     return NOERROR;
        !          1298: }
        !          1299: #endif // SVR_TREATAS
        !          1300: 
        !          1301: 
        !          1302: 
        !          1303: /*************************************************************************
        !          1304: ** ServerDoc Support Functions
        !          1305: *************************************************************************/
        !          1306: 
        !          1307: 
        !          1308: /* ServerDoc_Init
        !          1309:  * --------------
        !          1310:  *
        !          1311:  *  Initialize the fields of a new ServerDoc object. The object is initially
        !          1312:  *  not associated with a file or an (Untitled) document. This function sets
        !          1313:  *  the docInitType to DOCTYPE_UNKNOWN. After calling this function the 
        !          1314:  *  caller should call:
        !          1315:  *      1.) OutlineDoc_InitNewFile to set the ServerDoc to (Untitled)
        !          1316:  *      2.) OutlineDoc_LoadFromFile to associate the ServerDoc with a file.
        !          1317:  *  This function creates a new window for the document.
        !          1318:  *  
        !          1319:  *  NOTE: the window is initially created with a NIL size. it must be
        !          1320:  *        sized and positioned by the caller. also the document is initially
        !          1321:  *        created invisible. the caller must call OutlineDoc_ShowWindow 
        !          1322:  *        after sizing it to make the document window visible.
        !          1323:  */
        !          1324: BOOL ServerDoc_Init(LPSERVERDOC lpServerDoc, BOOL fDataTransferDoc)
        !          1325: {
        !          1326:     lpServerDoc->m_cPseudoObj                   = 0;
        !          1327:     lpServerDoc->m_lpOleClientSite              = NULL;
        !          1328:     lpServerDoc->m_lpOleAdviseHldr              = NULL;
        !          1329:     lpServerDoc->m_lpDataAdviseHldr             = NULL;
        !          1330:        
        !          1331:        // initialy doc does not have any storage
        !          1332:        lpServerDoc->m_dwStorageMode                            = STGMODE_HANDSOFF;
        !          1333:     lpServerDoc->m_fSaveWithSameAsLoad          = FALSE;
        !          1334:     lpServerDoc->m_szContainerApp[0]            = '\0';
        !          1335:     lpServerDoc->m_szContainerObj[0]            = '\0';
        !          1336:     lpServerDoc->m_nNextRangeNo                 = 0L;
        !          1337:     lpServerDoc->m_lrSrcSelOfCopy.m_nStartLine  = -1;
        !          1338:     lpServerDoc->m_lrSrcSelOfCopy.m_nEndLine    = -1;
        !          1339:     lpServerDoc->m_fDataChanged                 = FALSE;
        !          1340:     lpServerDoc->m_fSizeChanged                 = FALSE;
        !          1341:     lpServerDoc->m_fSendDataOnStop              = FALSE;
        !          1342: 
        !          1343: #if defined( SVR_TREATAS )
        !          1344:        lpServerDoc->m_clsidTreatAs                                     = CLSID_NULL;           
        !          1345:        lpServerDoc->m_lpszTreatAsType                          = NULL;
        !          1346: #endif // SVR_TREATAS
        !          1347: 
        !          1348: #if defined( INPLACE_SVR )
        !          1349:        lpServerDoc->m_hWndHatch                                        = 
        !          1350:                        CreateHatchWindow(
        !          1351:                                        OutlineApp_GetWindow(g_lpApp),
        !          1352:                                        OutlineApp_GetInstance(g_lpApp)
        !          1353:                        );
        !          1354:        if (!lpServerDoc->m_hWndHatch)
        !          1355:                return FALSE;
        !          1356: 
        !          1357:     lpServerDoc->m_fInPlaceActive               = FALSE;
        !          1358:     lpServerDoc->m_fInPlaceVisible                             = FALSE;        
        !          1359:     lpServerDoc->m_fUIActive                    = FALSE;
        !          1360:     lpServerDoc->m_lpIPData                     = NULL; 
        !          1361: 
        !          1362:     INIT_INTERFACEIMPL(
        !          1363:             &lpServerDoc->m_OleInPlaceObject,
        !          1364:             &g_SvrDoc_OleInPlaceObjectVtbl,
        !          1365:             lpServerDoc
        !          1366:     );
        !          1367:     INIT_INTERFACEIMPL(
        !          1368:             &lpServerDoc->m_OleInPlaceActiveObject,
        !          1369:             &g_SvrDoc_OleInPlaceActiveObjectVtbl,
        !          1370:             lpServerDoc
        !          1371:     );
        !          1372: #endif // INPLACE_SVR
        !          1373: 
        !          1374:     INIT_INTERFACEIMPL(
        !          1375:             &lpServerDoc->m_OleObject,
        !          1376:             &g_SvrDoc_OleObjectVtbl,
        !          1377:             lpServerDoc
        !          1378:        );
        !          1379: 
        !          1380:     INIT_INTERFACEIMPL(
        !          1381:             &lpServerDoc->m_PersistStorage,
        !          1382:             &g_SvrDoc_PersistStorageVtbl,
        !          1383:             lpServerDoc
        !          1384:     );
        !          1385: 
        !          1386: #if defined( SVR_TREATAS )
        !          1387: 
        !          1388:     INIT_INTERFACEIMPL(
        !          1389:             &lpServerDoc->m_StdMarshalInfo,
        !          1390:             &g_SvrDoc_StdMarshalInfoVtbl,
        !          1391:             lpServerDoc
        !          1392:     );
        !          1393: #endif // SVR_TREATAS
        !          1394:     return TRUE;
        !          1395: }
        !          1396: 
        !          1397: 
        !          1398: /* ServerDoc_InitNewEmbed
        !          1399:  * ----------------------
        !          1400:  *
        !          1401:  *  Initialize the ServerDoc object to be a new embedded object document.
        !          1402:  *  This function sets the docInitType to DOCTYPE_EMBED.
        !          1403:  */
        !          1404: BOOL ServerDoc_InitNewEmbed(LPSERVERDOC lpServerDoc)
        !          1405: {
        !          1406:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1407:     
        !          1408:     OleDbgAssert(lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN);
        !          1409: 
        !          1410:     lpOutlineDoc->m_docInitType = DOCTYPE_EMBEDDED;
        !          1411: 
        !          1412:     /* The Window title for an embedded object is constructed as
        !          1413:     **    follows: 
        !          1414:     **      <server app name> - <obj short type> in <cont. doc name>
        !          1415:     **    
        !          1416:     **    here we construct the current document title portion of the
        !          1417:     **    name which follows the '-'. OutlineDoc_SetTitle prepends the
        !          1418:     **    "<server app name> - " to the document title.
        !          1419:     */
        !          1420:     // REVIEW: this string should be loaded from string resource
        !          1421:     wsprintf(lpOutlineDoc->m_szFileName, "%s in %s", 
        !          1422:         (LPSTR)SHORTUSERTYPENAME, 
        !          1423:         (LPSTR)DEFCONTAINERNAME);
        !          1424:     lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
        !          1425: 
        !          1426:     
        !          1427:     /* OLE2NOTE: an embedding should be marked as initially dirty so
        !          1428:     **    that on close we always call IOleClientSite::SaveObject.
        !          1429:     */
        !          1430:     OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
        !          1431: 
        !          1432:     OutlineDoc_SetTitle(lpOutlineDoc);
        !          1433: 
        !          1434:     return TRUE;
        !          1435: }
        !          1436: 
        !          1437: 
        !          1438: /* ServerDoc_SendAdvise
        !          1439:  * --------------------
        !          1440:  *
        !          1441:  * This function sends an advise notification on behalf of a specific 
        !          1442:  *  doc object to all its clients.
        !          1443:  */
        !          1444: void ServerDoc_SendAdvise(
        !          1445:         LPSERVERDOC     lpServerDoc, 
        !          1446:         WORD            wAdvise, 
        !          1447:         LPMONIKER       lpmkDoc,
        !          1448:                DWORD                   dwAdvf
        !          1449: )
        !          1450: {
        !          1451:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1452:     LPOLEDOC lpOleDoc = (LPOLEDOC)lpServerDoc;
        !          1453: 
        !          1454:     switch (wAdvise) {
        !          1455: 
        !          1456:         case OLE_ONDATACHANGE:
        !          1457: 
        !          1458:             // inform clients that the data of the object has changed
        !          1459: 
        !          1460:             if (lpOutlineDoc->m_nDisableDraw == 0) {
        !          1461:                 /* drawing is currently enabled. inform clients that
        !          1462:                 **    the data of the object has changed 
        !          1463:                 */
        !          1464: 
        !          1465:                 lpServerDoc->m_fDataChanged = FALSE;
        !          1466: 
        !          1467:                 if (lpServerDoc->m_lpDataAdviseHldr) {
        !          1468:                     OLEDBG_BEGIN2(
        !          1469:                         "IDataAdviseHolder::SendOnDataChange called\r\n"
        !          1470:                     );
        !          1471:                     lpServerDoc->m_lpDataAdviseHldr->lpVtbl->SendOnDataChange(
        !          1472:                             lpServerDoc->m_lpDataAdviseHldr, 
        !          1473:                             (LPDATAOBJECT)&lpOleDoc->m_DataObject, 
        !          1474:                             0, 
        !          1475:                             dwAdvf
        !          1476:                     );
        !          1477:                     OLEDBG_END2
        !          1478:                         
        !          1479:                     /* OLE2NOTE: we must note the time of last change
        !          1480:                     **    for our object in the RunningObjectTable.
        !          1481:                     **    this is used as the basis to answer
        !          1482:                     **    IOleObject::IsUpToDate.
        !          1483:                     */
        !          1484:                     OleStdNoteObjectChangeTime(lpOleDoc->m_dwRegROT);
        !          1485:                 }
        !          1486: 
        !          1487: #if defined( INPLACE_SVR )
        !          1488:                                /* OLE2NOTE: if the ServerDoc is currently in-place UI active,
        !          1489:                                **    then is it important to renegotiate the size for the
        !          1490:                                **    in-place document window BEFORE sending OnDataChange
        !          1491:                                **    (which will cause the window to repaint).
        !          1492:                                */
        !          1493:                                if (lpServerDoc->m_fSizeChanged) {
        !          1494:                                        lpServerDoc->m_fSizeChanged = FALSE;
        !          1495:                                        if (lpServerDoc->m_fInPlaceActive) 
        !          1496:                                                ServerDoc_UpdateInPlaceWindowOnExtentChange(lpServerDoc);
        !          1497:                                }
        !          1498: #endif              
        !          1499:                 
        !          1500:                 /* OLE2NOTE: we do NOT need to tell our pseudo objects to
        !          1501:                 **    broadcast OnDataChange notification because
        !          1502:                 **    they will do it automatically when an editing
        !          1503:                 **    change in the document affects a PseudoObj.
        !          1504:                 **    (see OutlineNameTable_AddLineUpdate,
        !          1505:                 **         OutlineNameTable_DeleteLineUpdate,
        !          1506:                 **    and  ServerNameTable_EditLineUpdate)
        !          1507:                 */
        !          1508: 
        !          1509:             } else {
        !          1510:                 /* drawing is currently disabled. do not send
        !          1511:                 **    notifications or call 
        !          1512:                                **    IOleInPlaceObject::OnPosRectChange until drawing
        !          1513:                                **    is re-enabled.  
        !          1514:                 */
        !          1515:             }
        !          1516:             break;
        !          1517: 
        !          1518:         case OLE_ONCLOSE:
        !          1519: 
        !          1520:             // inform clients that the document is shutting down
        !          1521: 
        !          1522:             if (lpServerDoc->m_lpOleAdviseHldr) {
        !          1523:                 OLEDBG_BEGIN2("IOleAdviseHolder::SendOnClose called\r\n");
        !          1524:                 lpServerDoc->m_lpOleAdviseHldr->lpVtbl->SendOnClose(
        !          1525:                         lpServerDoc->m_lpOleAdviseHldr
        !          1526:                 );
        !          1527:                 OLEDBG_END2
        !          1528:             }
        !          1529: 
        !          1530:             /* OLE2NOTE: we do NOT need to tell our pseudo objects to
        !          1531:             **    broadcast OnClose notification because they will do
        !          1532:             **    it automatically when the pseudo object is closed.
        !          1533:             **    (see PseudoObj_Close)
        !          1534:             */
        !          1535: 
        !          1536:             break;
        !          1537: 
        !          1538:         case OLE_ONSAVE:
        !          1539: 
        !          1540:             // inform clients that the object has been saved
        !          1541: 
        !          1542:             OLEDBG_BEGIN3("ServerDoc_SendAdvise ONSAVE\r\n");
        !          1543: 
        !          1544:             if (lpServerDoc->m_lpOleAdviseHldr) {
        !          1545:                 OLEDBG_BEGIN2("IOleAdviseHolder::SendOnSave called\r\n");
        !          1546:                 lpServerDoc->m_lpOleAdviseHldr->lpVtbl->SendOnSave(
        !          1547:                         lpServerDoc->m_lpOleAdviseHldr
        !          1548:                 );
        !          1549:                 OLEDBG_END2
        !          1550:             }
        !          1551: 
        !          1552:             /* OLE2NOTE: inform any clients of pseudo objects
        !          1553:             **    within our document, that our document has been
        !          1554:             **    saved.  
        !          1555:             */
        !          1556:             ServerNameTable_InformAllPseudoObjectsDocSaved(
        !          1557:                     (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
        !          1558:                     lpmkDoc
        !          1559:             );
        !          1560: 
        !          1561: 
        !          1562:             if (lpOutlineDoc->m_docInitType == DOCTYPE_FROMFILE) {
        !          1563:                 /* OLE2NOTE: we must note the time this File-Based
        !          1564:                 **    object has been saved in the RunningObjectTable.
        !          1565:                 **    These change times are used as the basis for
        !          1566:                 **    IOleObject::IsUpToDate.  It is important to set
        !          1567:                 **    the time of the file-based object following a
        !          1568:                 **    save operation to exactly the time of the saved
        !          1569:                 **    file. this helps IOleObject::IsUpToDate to give
        !          1570:                 **    the correct answer after a file has been saved.
        !          1571:                 */
        !          1572:                 OleStdNoteFileChangeTime(
        !          1573:                         lpOutlineDoc->m_szFileName, lpOleDoc->m_dwRegROT);
        !          1574:             }
        !          1575:             OLEDBG_END3
        !          1576:             break;
        !          1577: 
        !          1578:         case OLE_ONRENAME:
        !          1579: 
        !          1580:             // inform clients that the object's name has changed
        !          1581: 
        !          1582:             OLEDBG_BEGIN3("ServerDoc_SendAdvise ONRENAME\r\n");
        !          1583: 
        !          1584:             if (lpmkDoc && lpServerDoc->m_lpOleAdviseHldr) {
        !          1585:                 OLEDBG_BEGIN2("IOleAdviseHolder::SendOnRename called\r\n");
        !          1586:                 lpServerDoc->m_lpOleAdviseHldr->lpVtbl->SendOnRename(
        !          1587:                         lpServerDoc->m_lpOleAdviseHldr,
        !          1588:                         lpmkDoc
        !          1589:                 );
        !          1590:                 OLEDBG_END2
        !          1591:             }
        !          1592: 
        !          1593:             /* OLE2NOTE: inform any clients of pseudo objects
        !          1594:             **    within our document, that our document's
        !          1595:             **    Moniker has changed.  
        !          1596:             */
        !          1597:             ServerNameTable_InformAllPseudoObjectsDocRenamed(
        !          1598:                     (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable, lpmkDoc);
        !          1599: 
        !          1600:             OLEDBG_END3
        !          1601:             break;
        !          1602:     }
        !          1603: }
        !          1604: 
        !          1605: 
        !          1606: /* ServerDoc_GetClassID
        !          1607: ** --------------------
        !          1608: **    Return the class ID corresponding to the bits in the storage.
        !          1609: **    normally this will be our application's given CLSID. but if a
        !          1610: **    "TreateAs (aka. ActivateAs)" operation is taking place, then our
        !          1611: **    application needs to pretend to be the class of the object that
        !          1612: **    we are emulating. this is also the class that will be written
        !          1613: **    into the storage.
        !          1614: */
        !          1615: HRESULT ServerDoc_GetClassID(LPSERVERDOC lpServerDoc, LPCLSID lpclsid)
        !          1616: {
        !          1617: #if defined( SVR_TREATAS )
        !          1618:        if (! IsEqualCLSID(&lpServerDoc->m_clsidTreatAs, &CLSID_NULL))
        !          1619:                *lpclsid = lpServerDoc->m_clsidTreatAs;
        !          1620:        else 
        !          1621: #endif // SVR_TREATAS
        !          1622:                *lpclsid = CLSID_APP;
        !          1623:        
        !          1624:        return NOERROR;
        !          1625: }
        !          1626: 
        !          1627: 
        !          1628: #if defined( LATER )
        !          1629: 
        !          1630: /* ServerDoc_GetUserType
        !          1631: ** ---------------------
        !          1632: **    Return the UserType corresponding to the bits in the storage.
        !          1633: **    normally this will be our application's given UserType. but if a
        !          1634: **    "TreateAs (aka. ActivateAs)" operation is taking place, then our
        !          1635: **    application needs to pretend to be the UserType of the object that
        !          1636: **    we are emulating. this is also the class that will be written
        !          1637: **    into the storage.
        !          1638: */
        !          1639: HRESULT ServerDoc_GetUserType(LPSERVERDOC lpServerDoc, LPCLSID lpclsid)
        !          1640: {
        !          1641:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !          1642:     *lpszUserType = NULL;
        !          1643: 
        !          1644: #if defined( SVR_TREATAS )
        !          1645:        if (lpServerDoc->m_clsidTreatAs != CLSID_NULL) 
        !          1646:                return OleStdGetUserType(&lpServerDoc->m_clsidTreatAs);
        !          1647:        else 
        !          1648: #endif // SVR_TREATAS
        !          1649:                return OleStdGetUserType(&CLSID_APP);
        !          1650: }
        !          1651: 
        !          1652: #endif // LATER
        !          1653: 
        !          1654: 
        !          1655: /* ServerDoc_UpdateMenu
        !          1656:  * --------------------
        !          1657:  *
        !          1658:  *  Update menu for embedding mode. the changes include:
        !          1659:  *      1 Remove File/New and File/Open (SDI ONLY)
        !          1660:  *      2 Change File/Save As.. to File/Save Copy As.. 
        !          1661:  *      3 Change File menu so it contains "Update" instead of "Save" 
        !          1662:  *      4 Change File/Exit to File/Exit & Return to <client doc>" 
        !          1663:  */
        !          1664: void ServerDoc_UpdateMenu(LPSERVERDOC lpServerDoc)
        !          1665: {
        !          1666:     char    str[256];
        !          1667:     HWND    hWndMain;
        !          1668:     HMENU   hMenu;
        !          1669:     
        !          1670:     OleDbgOut2("ServerDoc_UpdateMenu\r\n");
        !          1671: 
        !          1672:     hWndMain=g_lpApp->m_hWndApp;
        !          1673:     hMenu=GetMenu(hWndMain);
        !          1674: 
        !          1675: #if defined( SDI_VERSION )
        !          1676:     /* SDI ONLY: Remove File/New and File/Open */
        !          1677:     DeleteMenu(hMenu, IDM_F_NEW, MF_BYCOMMAND);
        !          1678:     DeleteMenu(hMenu, IDM_F_OPEN, MF_BYCOMMAND);
        !          1679: #endif
        !          1680:     
        !          1681:     // Change File.Save As.. to File.Save Copy As.. */
        !          1682:     ModifyMenu(hMenu,IDM_F_SAVEAS, MF_STRING, IDM_F_SAVEAS, "Save Copy As..");
        !          1683: 
        !          1684:     // Change File.Save to "&Update <container doc>"
        !          1685:     wsprintf(str, g_szUpdateCntrDoc, lpServerDoc->m_szContainerObj);
        !          1686:     ModifyMenu(hMenu, IDM_F_SAVE, MF_STRING, IDM_F_SAVE, str);
        !          1687:     
        !          1688:     // Change File/Exit to File/Exit & Return to <container doc>" */
        !          1689:     wsprintf(str, g_szExitNReturnToCntrDoc, lpServerDoc->m_szContainerObj);
        !          1690:     ModifyMenu(hMenu, IDM_F_EXIT, MF_STRING, IDM_F_EXIT, str);
        !          1691:     
        !          1692:     DrawMenuBar(hWndMain);
        !          1693: }
        !          1694: 
        !          1695: #if defined( MDI_VERSION )
        !          1696: 
        !          1697: // NOTE: ServerDoc_RestoreMenu is actually redundant because the 
        !          1698: //          app is dying when the function is called.  (In SDI, the 
        !          1699: //          app will terminate when the ref counter of the server doc 
        !          1700: //          is zero). However, it is important for MDI.
        !          1701: 
        !          1702: /* ServerDoc_RestoreMenu
        !          1703:  * ---------------------
        !          1704:  *
        !          1705:  *      Reset the menu to non-embedding mode
        !          1706:  */
        !          1707: void ServerDoc_RestoreMenu(LPSERVERDOC lpServerDoc)
        !          1708: {
        !          1709:     LPOUTLINEAPP       lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          1710:     HWND                       hWndMain;
        !          1711:     HMENU                      hMenu;
        !          1712:     
        !          1713:     OleDbgOut2("ServerDoc_RestoreMenu\r\n");
        !          1714: 
        !          1715:     hWndMain = lpOutlineApp->m_hWndApp;
        !          1716:     hMenu = GetMenu(hWndMain);
        !          1717: 
        !          1718:     /* Add back File/New, File/Open.. and File/Save */
        !          1719:     InsertMenu(hMenu, IDM_F_SAVEAS, MF_BYCOMMAND | MF_ENABLED | MF_STRING, 
        !          1720:         IDM_F_NEW, "&New");
        !          1721:     InsertMenu(hMenu, IDM_F_SAVEAS, MF_BYCOMMAND | MF_ENABLED | MF_STRING, 
        !          1722:         IDM_F_OPEN, "&Open...");
        !          1723: 
        !          1724:     /* Change File menu so it contains "Save As..." instead of */
        !          1725:     /* "Save Copy As..." */
        !          1726:     ModifyMenu(hMenu, IDM_F_SAVEAS, MF_STRING, IDM_F_SAVEAS, "Save &As..");
        !          1727: 
        !          1728:     /* Change File menu so it contains "Save" instead of "Update" */
        !          1729:     ModifyMenu(hMenu, IDM_F_SAVE, MF_STRING, IDM_F_SAVE, "&Save");
        !          1730:         
        !          1731:     /* Change File menu so it contains "Exit" */
        !          1732:     /* instead of just "Exit & Return to <client doc>" */
        !          1733:     ModifyMenu(hMenu, IDM_F_EXIT, MF_STRING, IDM_F_EXIT, "E&xit");
        !          1734:     
        !          1735:     DrawMenuBar (hWndMain);
        !          1736: }
        !          1737: 
        !          1738: #endif  // MDI_VERSION

unix.superglobalmegacorp.com

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