Annotation of mstools/ole20/samples/outline/svrbase.c, revision 1.1.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.