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

1.1     ! root        1: /*************************************************************************
        !             2: ** 
        !             3: **    OLE 2 Server Sample Code
        !             4: **    
        !             5: **    svrpsobj.c
        !             6: **    
        !             7: **    This file contains all PseudoObj methods and related support
        !             8: **    functions.
        !             9: **    
        !            10: **    (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
        !            11: **
        !            12: *************************************************************************/
        !            13: 
        !            14: 
        !            15: #include "outline.h"
        !            16: #include <geticon.h>
        !            17: 
        !            18: OLEDBGDATA
        !            19: 
        !            20: extern LPOUTLINEAPP             g_lpApp;
        !            21: extern IUnknownVtbl             g_PseudoObj_UnknownVtbl;
        !            22: extern IOleObjectVtbl           g_PseudoObj_OleObjectVtbl;
        !            23: extern IDataObjectVtbl          g_PseudoObj_DataObjectVtbl;
        !            24:     
        !            25: 
        !            26: /* PseudoObj_Init
        !            27: ** --------------
        !            28: **  Initialize fields in a newly constructed PseudoObj.
        !            29: **  NOTE: ref cnt of PseudoObj initialized to 0
        !            30: */
        !            31: void PseudoObj_Init(
        !            32:         LPPSEUDOOBJ             lpPseudoObj, 
        !            33:         LPSERVERNAME            lpServerName, 
        !            34:         LPSERVERDOC             lpServerDoc
        !            35: )
        !            36: {
        !            37:     OleDbgOut2("++PseudoObj Created\r\n");
        !            38: 
        !            39:     lpPseudoObj->m_cRef             = 0;
        !            40:     lpPseudoObj->m_lpName           = lpServerName;
        !            41:     lpPseudoObj->m_lpDoc            = lpServerDoc;
        !            42:     lpPseudoObj->m_lpOleAdviseHldr  = NULL;
        !            43:     lpPseudoObj->m_lpDataAdviseHldr = NULL;
        !            44:     lpPseudoObj->m_fObjIsClosing       = FALSE;
        !            45: 
        !            46:     INIT_INTERFACEIMPL(
        !            47:             &lpPseudoObj->m_Unknown,
        !            48:             &g_PseudoObj_UnknownVtbl,
        !            49:             lpPseudoObj
        !            50:     );
        !            51: 
        !            52:     INIT_INTERFACEIMPL(
        !            53:             &lpPseudoObj->m_OleObject,
        !            54:             &g_PseudoObj_OleObjectVtbl,
        !            55:             lpPseudoObj
        !            56:     );
        !            57: 
        !            58:     INIT_INTERFACEIMPL(
        !            59:             &lpPseudoObj->m_DataObject,
        !            60:             &g_PseudoObj_DataObjectVtbl,
        !            61:             lpPseudoObj
        !            62:     );
        !            63: 
        !            64:     /* OLE2NOTE: Increment the refcnt of the Doc on behalf of the
        !            65:     **    PseudoObj. the Document should not shut down unless all
        !            66:     **    pseudo objects are closed. when a pseudo object is destroyed,
        !            67:     **    it calls ServerDoc_PseudoObjUnlockDoc to release this hold on
        !            68:     **    the document. 
        !            69:     */
        !            70:     ServerDoc_PseudoObjLockDoc(lpServerDoc);
        !            71: }
        !            72: 
        !            73: 
        !            74: 
        !            75: /* PseudoObj_AddRef
        !            76: ** ----------------
        !            77: **    
        !            78: **  increment the ref count of the PseudoObj object.
        !            79: **    
        !            80: **    Returns the new ref count on the object
        !            81: */
        !            82: ULONG PseudoObj_AddRef(LPPSEUDOOBJ lpPseudoObj)
        !            83: {
        !            84:     ++lpPseudoObj->m_cRef;
        !            85: 
        !            86:     OleDbgOutRefCnt4(
        !            87:             "PseudoObj_AddRef: cRef++\r\n",
        !            88:             lpPseudoObj,
        !            89:             lpPseudoObj->m_cRef
        !            90:     );
        !            91:     return lpPseudoObj->m_cRef;
        !            92: }
        !            93: 
        !            94: 
        !            95: /* PseudoObj_Release
        !            96: ** -----------------
        !            97: **    
        !            98: **  decrement the ref count of the PseudoObj object. 
        !            99: **    if the ref count goes to 0, then the PseudoObj is destroyed.
        !           100: **    
        !           101: **    Returns the remaining ref count on the object
        !           102: */
        !           103: ULONG PseudoObj_Release(LPPSEUDOOBJ lpPseudoObj)
        !           104: {
        !           105:     ULONG cRef;
        !           106:     
        !           107:     OleDbgAssertSz(lpPseudoObj->m_cRef > 0,"Release called with cRef == 0");
        !           108: 
        !           109:     /*********************************************************************
        !           110:     ** OLE2NOTE: when the obj refcnt == 0, then destroy the object.     **
        !           111:     **     otherwise the object is still in use.                        **
        !           112:     *********************************************************************/
        !           113: 
        !           114:     cRef = --lpPseudoObj->m_cRef;
        !           115: 
        !           116:     OleDbgOutRefCnt4(
        !           117:             "PseudoObj_Release: cRef--\r\n", lpPseudoObj,cRef);
        !           118: 
        !           119:     if (cRef == 0) 
        !           120:         PseudoObj_Destroy(lpPseudoObj);
        !           121: 
        !           122:     return cRef;
        !           123: }
        !           124: 
        !           125: 
        !           126: /* PseudoObj_QueryInterface
        !           127: ** ------------------------
        !           128: **
        !           129: ** Retrieve a pointer to an interface on the PseudoObj object.
        !           130: **    
        !           131: **    Returns S_OK if interface is successfully retrieved.
        !           132: **            E_NOINTERFACE if the interface is not supported
        !           133: */
        !           134: HRESULT PseudoObj_QueryInterface(
        !           135:         LPPSEUDOOBJ         lpPseudoObj, 
        !           136:         REFIID              riid, 
        !           137:         LPVOID FAR*         lplpvObj
        !           138: )
        !           139: {
        !           140:     SCODE sc = E_NOINTERFACE;
        !           141: 
        !           142:     /* OLE2NOTE: we must make sure to set all out ptr parameters to NULL. */
        !           143:     *lplpvObj = NULL;
        !           144: 
        !           145:     if (IsEqualIID(riid, &IID_IUnknown)) {
        !           146:         OleDbgOut4("PseudoObj_QueryInterface: IUnknown* RETURNED\r\n");
        !           147: 
        !           148:         *lplpvObj = (LPVOID) &lpPseudoObj->m_Unknown;
        !           149:         PseudoObj_AddRef(lpPseudoObj);
        !           150:         sc = S_OK;
        !           151:     } 
        !           152:     else if (IsEqualIID(riid, &IID_IOleObject)) {
        !           153:         OleDbgOut4("PseudoObj_QueryInterface: IOleObject* RETURNED\r\n");
        !           154: 
        !           155:         *lplpvObj = (LPVOID) &lpPseudoObj->m_OleObject;
        !           156:         PseudoObj_AddRef(lpPseudoObj);
        !           157:         sc = S_OK;
        !           158:     }
        !           159:     else if (IsEqualIID(riid, &IID_IDataObject)) {
        !           160:         OleDbgOut4("PseudoObj_QueryInterface: IDataObject* RETURNED\r\n");
        !           161: 
        !           162:         *lplpvObj = (LPVOID) &lpPseudoObj->m_DataObject;
        !           163:         PseudoObj_AddRef(lpPseudoObj);
        !           164:         sc = S_OK;
        !           165:     }
        !           166: 
        !           167:     OleDbgQueryInterfaceMethod(*lplpvObj);
        !           168: 
        !           169:     return ResultFromScode(sc);
        !           170: }
        !           171: 
        !           172: 
        !           173: /* PseudoObj_Close
        !           174:  * ---------------
        !           175:  *
        !           176:  *  Close the pseudo object. Force all external connections to close
        !           177:  *      down. This causes link clients to release this PseudoObj. when
        !           178:  *      the refcount actually reaches 0, then the PseudoObj will be
        !           179:  *      destroyed.
        !           180:  *
        !           181:  *  Returns:
        !           182:  *      FALSE -- user canceled the closing of the doc.
        !           183:  *      TRUE -- the doc was successfully closed
        !           184:  */
        !           185: 
        !           186: BOOL PseudoObj_Close(LPPSEUDOOBJ lpPseudoObj)
        !           187: {
        !           188:     LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpPseudoObj->m_lpDoc;
        !           189:     LPSERVERNAME lpServerName = (LPSERVERNAME)lpPseudoObj->m_lpName;
        !           190:     LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
        !           191:     LPOLEDOC lpOleDoc = (LPOLEDOC)lpServerDoc;
        !           192:     BOOL fStatus;
        !           193: 
        !           194:     if (lpPseudoObj->m_fObjIsClosing) 
        !           195:         return TRUE;    // Closing is already in progress
        !           196: 
        !           197:     lpPseudoObj->m_fObjIsClosing = TRUE;   // guard against recursive call
        !           198: 
        !           199:     OLEDBG_BEGIN3("PseudoObj_Close\r\n")
        !           200: 
        !           201:     /* OLE2NOTE: in order to have a stable App, Doc, AND pseudo object
        !           202:     **    during the process of closing, we intially AddRef the App,
        !           203:     **    Doc, and PseudoObj ref counts and later Release them. These
        !           204:     **    initial AddRefs are artificial; they are simply done to
        !           205:     **    guarantee that these objects do not get destroyed until the
        !           206:     **    end of this routine. 
        !           207:     */
        !           208:     OleApp_AddRef(lpOleApp);
        !           209:     OleDoc_AddRef(lpOleDoc);
        !           210:     PseudoObj_AddRef(lpPseudoObj);
        !           211: 
        !           212:        if (lpPseudoObj->m_lpDataAdviseHldr) {
        !           213:                /* OLE2NOTE: send last OnDataChange notification to clients
        !           214:                **    that have registered for data notifications when object
        !           215:                **    stops running (ADVF_DATAONSTOP)
        !           216:                */
        !           217:                PseudoObj_SendAdvise(
        !           218:                                lpPseudoObj, 
        !           219:                                OLE_ONDATACHANGE, 
        !           220:                                NULL,   /* lpmkObj -- not relevant here */
        !           221:                                ADVF_DATAONSTOP
        !           222:                );
        !           223: 
        !           224:                /* OLE2NOTE: we just sent the last data notification that we
        !           225:                **    need to send; release our DataAdviseHolder. we SHOULD be
        !           226:                **    the only one using it.
        !           227:                */
        !           228:                OleStdVerifyRelease(
        !           229:                                (LPUNKNOWN)lpPseudoObj->m_lpDataAdviseHldr, 
        !           230:                                "DataAdviseHldr not released properly"
        !           231:                );
        !           232:                lpPseudoObj->m_lpDataAdviseHldr = NULL;
        !           233:        }
        !           234: 
        !           235:        if (lpPseudoObj->m_lpOleAdviseHldr) {
        !           236:                // OLE2NOTE: inform all of our linking clients that we are closing.
        !           237:                PseudoObj_SendAdvise(
        !           238:                                lpPseudoObj,
        !           239:                                OLE_ONCLOSE, 
        !           240:                                NULL,   /* lpmkObj -- not relevant here */
        !           241:                                0       /* advf -- not relevant here */
        !           242:                );
        !           243: 
        !           244:                /* OLE2NOTE: OnClose is the last notification that we need to
        !           245:                **    send; release our OleAdviseHolder. we SHOULD be the only
        !           246:                **    one using it. this will make our destructor realize that
        !           247:                **    OnClose notification has already been sent.
        !           248:                */
        !           249:                OleStdVerifyRelease(
        !           250:                                (LPUNKNOWN)lpPseudoObj->m_lpOleAdviseHldr, 
        !           251:                                "OleAdviseHldr not released properly"
        !           252:                );
        !           253:                lpPseudoObj->m_lpOleAdviseHldr = NULL;
        !           254:        }
        !           255: 
        !           256:     /* OLE2NOTE: this call forces all external connections to our
        !           257:     **    object to close down and therefore guarantees that we receive
        !           258:     **    all releases associated with those external connections.
        !           259:     */
        !           260:     OLEDBG_BEGIN2("CoDisconnectObject called\r\n")
        !           261:     CoDisconnectObject((LPUNKNOWN)&lpPseudoObj->m_Unknown, 0);
        !           262:     OLEDBG_END2
        !           263:         
        !           264:     PseudoObj_Release(lpPseudoObj);     // release artificial AddRef above
        !           265:     OleDoc_Release(lpOleDoc);                  // release artificial AddRef above
        !           266:     OleApp_Release(lpOleApp);                  // release artificial AddRef above
        !           267: 
        !           268:     OLEDBG_END3
        !           269:     return fStatus;
        !           270: }
        !           271: 
        !           272: 
        !           273: /* PseudoObj_Destroy
        !           274: ** -----------------
        !           275: **    Destroy (Free) the memory used by a PseudoObj structure. 
        !           276: **    This function is called when the ref count of the PseudoObj goes
        !           277: **    to zero. the ref cnt goes to zero after PseudoObj_Delete forces
        !           278: **    the OleObject to unload and release its pointers to the
        !           279: **    PseudoObj IOleClientSite and IAdviseSink interfaces. 
        !           280: */
        !           281: 
        !           282: void PseudoObj_Destroy(LPPSEUDOOBJ lpPseudoObj)
        !           283: {
        !           284:     LPSERVERDOC lpServerDoc = lpPseudoObj->m_lpDoc;
        !           285:     LPOLEAPP   lpOleApp = (LPOLEAPP)g_lpApp;
        !           286:     LPOLEDOC   lpOleDoc = (LPOLEDOC)lpServerDoc;
        !           287: 
        !           288:     OLEDBG_BEGIN3("PseudoObj_Destroy\r\n")
        !           289: 
        !           290:     /* OLE2NOTE: in order to have a stable App, Doc, AND pseudo object
        !           291:     **    during the process of closing, we intially AddRef the App,
        !           292:     **    Doc ref counts and later Release them. These
        !           293:     **    initial AddRefs are artificial; they are simply done to
        !           294:     **    guarantee that these objects do not get destroyed until the
        !           295:     **    end of this routine. 
        !           296:     */
        !           297:     OleApp_AddRef(lpOleApp);
        !           298:     OleDoc_AddRef(lpOleDoc);
        !           299: 
        !           300:     /******************************************************************
        !           301:     ** OLE2NOTE: we no longer need the advise and enum holder objects, 
        !           302:     **    so release them.
        !           303:     ******************************************************************/
        !           304: 
        !           305:     if (lpPseudoObj->m_lpDataAdviseHldr) {
        !           306:         /* release DataAdviseHldr; we SHOULD be the only one using it. */
        !           307:         OleStdVerifyRelease(
        !           308:                 (LPUNKNOWN)lpPseudoObj->m_lpDataAdviseHldr, 
        !           309:                 "DataAdviseHldr not released properly"
        !           310:             );
        !           311:         lpPseudoObj->m_lpDataAdviseHldr = NULL;
        !           312:     }
        !           313: 
        !           314:     if (lpPseudoObj->m_lpOleAdviseHldr) {
        !           315:         /* release OleAdviseHldr; we SHOULD be the only one using it. */
        !           316:         OleStdVerifyRelease(
        !           317:                 (LPUNKNOWN)lpPseudoObj->m_lpOleAdviseHldr, 
        !           318:                 "OleAdviseHldr not released properly"
        !           319:             );
        !           320:         lpPseudoObj->m_lpOleAdviseHldr = NULL;
        !           321:     }
        !           322: 
        !           323:        /* forget the pointer to destroyed PseudoObj in NameTable */
        !           324:        if (lpPseudoObj->m_lpName) 
        !           325:                lpPseudoObj->m_lpName->m_lpPseudoObj = NULL;
        !           326: 
        !           327:     /* OLE2NOTE: release the lock on the Doc held on behalf of the
        !           328:     **    PseudoObj. the Document should not shut down unless all
        !           329:     **    pseudo objects are closed. when a pseudo object is first
        !           330:     **    created, it calls ServerDoc_PseudoObjLockDoc to guarantee 
        !           331:     **    that the document stays alive (called from PseudoObj_Init). 
        !           332:     */
        !           333:     ServerDoc_PseudoObjUnlockDoc(lpServerDoc, lpPseudoObj);
        !           334: 
        !           335:     Delete(lpPseudoObj);        // Free the memory for the structure itself
        !           336: 
        !           337:     OleDoc_Release(lpOleDoc);       // release artificial AddRef above
        !           338:     OleApp_Release(lpOleApp);       // release artificial AddRef above
        !           339: 
        !           340:     OLEDBG_END3
        !           341: }
        !           342: 
        !           343: 
        !           344: /* PseudoObj_GetSel
        !           345: ** ----------------
        !           346: **    Return the line range for the pseudo object
        !           347: */
        !           348: void PseudoObj_GetSel(LPPSEUDOOBJ lpPseudoObj, LPLINERANGE lplrSel)
        !           349: {
        !           350:     LPOUTLINENAME lpOutlineName = (LPOUTLINENAME)lpPseudoObj->m_lpName;
        !           351:     lplrSel->m_nStartLine = lpOutlineName->m_nStartLine;
        !           352:     lplrSel->m_nEndLine = lpOutlineName->m_nEndLine;
        !           353: }
        !           354: 
        !           355: 
        !           356: /* PseudoObj_GetExtent
        !           357:  * -------------------
        !           358:  *
        !           359:  *      Get the extent (width, height) of the entire document.
        !           360:  */
        !           361: void PseudoObj_GetExtent(LPPSEUDOOBJ lpPseudoObj, LPSIZEL lpsizel)
        !           362: {
        !           363:     LPOLEDOC lpOleDoc = (LPOLEDOC)lpPseudoObj->m_lpDoc;
        !           364:     LPLINELIST lpLL = (LPLINELIST)&((LPOUTLINEDOC)lpOleDoc)->m_LineList;
        !           365:     LINERANGE lrSel;
        !           366:     
        !           367:     PseudoObj_GetSel(lpPseudoObj, (LPLINERANGE)&lrSel);
        !           368: 
        !           369:     LineList_CalcSelExtentInHimetric(lpLL, (LPLINERANGE)&lrSel, lpsizel);
        !           370: }
        !           371: 
        !           372: 
        !           373: /* PseudoObj_SendAdvise
        !           374:  * --------------------
        !           375:  *
        !           376:  * This function sends an advise notification on behalf of a specific 
        !           377:  *  doc object to all its clients.
        !           378:  */
        !           379: void PseudoObj_SendAdvise(
        !           380:         LPPSEUDOOBJ lpPseudoObj, 
        !           381:         WORD        wAdvise, 
        !           382:         LPMONIKER   lpmkObj,
        !           383:                DWORD           dwAdvf
        !           384: )
        !           385: {
        !           386:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpPseudoObj->m_lpDoc;
        !           387: 
        !           388:     switch (wAdvise) {
        !           389: 
        !           390:         case OLE_ONDATACHANGE:
        !           391: 
        !           392:             // inform clients that the data of the object has changed
        !           393: 
        !           394:             if (lpOutlineDoc->m_nDisableDraw == 0) {
        !           395:                 /* drawing is currently enabled. inform clients that
        !           396:                 **    the data of the object has changed 
        !           397:                 */
        !           398: 
        !           399:                 lpPseudoObj->m_fDataChanged = FALSE;
        !           400:                 if (lpPseudoObj->m_lpDataAdviseHldr) {
        !           401: 
        !           402:                     OLEDBG_BEGIN2(
        !           403:                         "IDataAdviseHolder::SendOnDataChange called\r\n"
        !           404:                     );
        !           405:                     lpPseudoObj->m_lpDataAdviseHldr->lpVtbl->SendOnDataChange(
        !           406:                             lpPseudoObj->m_lpDataAdviseHldr, 
        !           407:                             (LPDATAOBJECT)&lpPseudoObj->m_DataObject, 
        !           408:                             0, 
        !           409:                             dwAdvf
        !           410:                     );
        !           411:                     OLEDBG_END2
        !           412:                 }
        !           413: 
        !           414:             } else {
        !           415:                 /* drawing is currently disabled. do not send
        !           416:                 **    notifications until drawing is re-enabled.
        !           417:                 */
        !           418:                 lpPseudoObj->m_fDataChanged = TRUE;
        !           419:             }
        !           420:             break;
        !           421: 
        !           422:         case OLE_ONCLOSE:
        !           423: 
        !           424:             // inform clients that the object is shutting down
        !           425: 
        !           426:             if (lpPseudoObj->m_lpOleAdviseHldr) {
        !           427: 
        !           428:                 OLEDBG_BEGIN2("IOleAdviseHolder::SendOnClose called\r\n");
        !           429:                 lpPseudoObj->m_lpOleAdviseHldr->lpVtbl->SendOnClose(
        !           430:                         lpPseudoObj->m_lpOleAdviseHldr
        !           431:                 );
        !           432:                 OLEDBG_END2
        !           433:             }
        !           434:             break;
        !           435: 
        !           436:         case OLE_ONSAVE:
        !           437: 
        !           438:             // inform clients that the object has been saved
        !           439: 
        !           440:             if (lpPseudoObj->m_lpOleAdviseHldr) {
        !           441: 
        !           442:                 OLEDBG_BEGIN2("IOleAdviseHolder::SendOnClose called\r\n");
        !           443:                 lpPseudoObj->m_lpOleAdviseHldr->lpVtbl->SendOnSave(
        !           444:                         lpPseudoObj->m_lpOleAdviseHldr
        !           445:                 );
        !           446:                 OLEDBG_END2
        !           447:             }
        !           448:             break;
        !           449: 
        !           450:         case OLE_ONRENAME:
        !           451: 
        !           452:             // inform clients that the object's name has changed
        !           453:             if (lpmkObj && lpPseudoObj->m_lpOleAdviseHldr) {
        !           454: 
        !           455:                 OLEDBG_BEGIN2("IOleAdviseHolder::SendOnRename called\r\n");
        !           456:                 if (lpPseudoObj->m_lpOleAdviseHldr) 
        !           457:                     lpPseudoObj->m_lpOleAdviseHldr->lpVtbl->SendOnRename(
        !           458:                             lpPseudoObj->m_lpOleAdviseHldr,
        !           459:                             lpmkObj
        !           460:                     );
        !           461:                 OLEDBG_END2
        !           462:             }
        !           463:             break;
        !           464:     }
        !           465: }
        !           466: 
        !           467: 
        !           468: /* PseudoObj_GetFullMoniker
        !           469:  * ------------------------
        !           470:  *
        !           471:  * Returns the Full, absolute Moniker which identifies this pseudo object.
        !           472:  */
        !           473: LPMONIKER PseudoObj_GetFullMoniker(LPPSEUDOOBJ lpPseudoObj, LPMONIKER lpmkDoc)
        !           474: {
        !           475:     LPOUTLINENAME lpOutlineName = (LPOUTLINENAME)lpPseudoObj->m_lpName;
        !           476:     LPMONIKER lpmkItem = NULL;
        !           477:     LPMONIKER lpmkPseudoObj = NULL;
        !           478: 
        !           479:     if (lpmkDoc != NULL) {
        !           480:         CreateItemMoniker(OLESTDDELIM,lpOutlineName->m_szName,&lpmkItem);
        !           481: 
        !           482:         /* OLE2NOTE: create an absolute moniker which identifies the
        !           483:         **    pseudo object. this moniker is created as a composite of
        !           484:         **    the absolute moniker for the entire document appended
        !           485:         **    with an item moniker which identifies the selection of
        !           486:         **    the pseudo object relative to the document.
        !           487:         */
        !           488:         CreateGenericComposite(lpmkDoc, lpmkItem, &lpmkPseudoObj);
        !           489: 
        !           490:         if (lpmkItem) 
        !           491:             OleStdRelease((LPUNKNOWN)lpmkItem);
        !           492: 
        !           493:         return lpmkPseudoObj;
        !           494:     } else {
        !           495:         return NULL;
        !           496:     }
        !           497: }
        !           498: 
        !           499: 
        !           500: /*************************************************************************
        !           501: ** PseudoObj::IUnknown interface implementation
        !           502: *************************************************************************/
        !           503: 
        !           504: STDMETHODIMP PseudoObj_Unk_QueryInterface(
        !           505:         LPUNKNOWN         lpThis,
        !           506:         REFIID            riid,
        !           507:         LPVOID FAR*       lplpvObj
        !           508: )
        !           509: {
        !           510:     LPPSEUDOOBJ lpPseudoObj = 
        !           511:             ((struct CPseudoObjUnknownImpl FAR*)lpThis)->lpPseudoObj;
        !           512: 
        !           513:     return PseudoObj_QueryInterface(lpPseudoObj, riid, lplpvObj);
        !           514: }
        !           515: 
        !           516: 
        !           517: STDMETHODIMP_(ULONG) PseudoObj_Unk_AddRef(LPUNKNOWN lpThis)
        !           518: {
        !           519:     LPPSEUDOOBJ lpPseudoObj = 
        !           520:             ((struct CPseudoObjUnknownImpl FAR*)lpThis)->lpPseudoObj;
        !           521: 
        !           522:     OleDbgAddRefMethod(lpThis, "IUnknown");
        !           523: 
        !           524:     return PseudoObj_AddRef(lpPseudoObj);
        !           525: }
        !           526: 
        !           527: 
        !           528: STDMETHODIMP_(ULONG) PseudoObj_Unk_Release (LPUNKNOWN lpThis)
        !           529: {
        !           530:     LPPSEUDOOBJ lpPseudoObj = 
        !           531:             ((struct CPseudoObjUnknownImpl FAR*)lpThis)->lpPseudoObj;
        !           532: 
        !           533:     OleDbgReleaseMethod(lpThis, "IUnknown");
        !           534: 
        !           535:     return PseudoObj_Release(lpPseudoObj);
        !           536: }
        !           537: 
        !           538: 
        !           539: /*************************************************************************
        !           540: ** PseudoObj::IOleObject interface implementation
        !           541: *************************************************************************/
        !           542: 
        !           543: STDMETHODIMP PseudoObj_OleObj_QueryInterface(
        !           544:         LPOLEOBJECT     lpThis,
        !           545:         REFIID          riid,
        !           546:         LPVOID FAR*     lplpvObj
        !           547: )
        !           548: {
        !           549:     LPPSEUDOOBJ lpPseudoObj =
        !           550:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           551: 
        !           552:     return PseudoObj_QueryInterface(lpPseudoObj, riid, lplpvObj);
        !           553: }
        !           554: 
        !           555: 
        !           556: STDMETHODIMP_(ULONG) PseudoObj_OleObj_AddRef(LPOLEOBJECT lpThis)
        !           557: {
        !           558:     LPPSEUDOOBJ lpPseudoObj =
        !           559:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           560: 
        !           561:     OleDbgAddRefMethod(lpThis, "IOleObject");
        !           562: 
        !           563:     return PseudoObj_AddRef((LPPSEUDOOBJ)lpPseudoObj);
        !           564: }
        !           565: 
        !           566: 
        !           567: STDMETHODIMP_(ULONG) PseudoObj_OleObj_Release(LPOLEOBJECT lpThis)
        !           568: {
        !           569:     LPPSEUDOOBJ lpPseudoObj =
        !           570:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           571:     
        !           572:     OleDbgReleaseMethod(lpThis, "IOleObject");
        !           573: 
        !           574:     return PseudoObj_Release((LPPSEUDOOBJ)lpPseudoObj);
        !           575: }
        !           576: 
        !           577: 
        !           578: STDMETHODIMP PseudoObj_OleObj_SetClientSite(
        !           579:         LPOLEOBJECT         lpThis,
        !           580:         LPOLECLIENTSITE     lpClientSite
        !           581: )
        !           582: {
        !           583:     OleDbgOut2("PseudoObj_OleObj_SetClientSite\r\n");
        !           584: 
        !           585:     // OLE2NOTE: a pseudo object does NOT support SetExtent
        !           586: 
        !           587:     return ResultFromScode(E_FAIL);
        !           588: }
        !           589: 
        !           590: 
        !           591: STDMETHODIMP PseudoObj_OleObj_GetClientSite(
        !           592:         LPOLEOBJECT             lpThis,
        !           593:         LPOLECLIENTSITE FAR*    lplpClientSite
        !           594: )
        !           595: {
        !           596:     OleDbgOut2("PseudoObj_OleObj_GetClientSite\r\n");
        !           597: 
        !           598:     *lplpClientSite = NULL;
        !           599: 
        !           600:     // OLE2NOTE: a pseudo object does NOT support SetExtent
        !           601: 
        !           602:     return ResultFromScode(E_FAIL);
        !           603: }
        !           604: 
        !           605: 
        !           606: 
        !           607: STDMETHODIMP PseudoObj_OleObj_SetHostNames(
        !           608:         LPOLEOBJECT             lpThis,
        !           609:         LPCSTR                  szContainerApp,
        !           610:         LPCSTR                  szContainerObj
        !           611: )
        !           612: {
        !           613:     OleDbgOut2("PseudoObj_OleObj_SetHostNames\r\n");
        !           614: 
        !           615:     // OLE2NOTE: a pseudo object does NOT support SetExtent
        !           616: 
        !           617:     return ResultFromScode(E_FAIL);
        !           618: }
        !           619: 
        !           620: 
        !           621: STDMETHODIMP PseudoObj_OleObj_Close(
        !           622:         LPOLEOBJECT             lpThis,
        !           623:         DWORD                   dwSaveOption
        !           624: )
        !           625: {
        !           626:     LPPSEUDOOBJ lpPseudoObj =
        !           627:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           628:     BOOL fStatus;
        !           629: 
        !           630:     OLEDBG_BEGIN2("PseudoObj_OleObj_Close\r\n")
        !           631: 
        !           632:     /* OLE2NOTE: a pseudo object's implementation of IOleObject::Close
        !           633:     **    should ignore the dwSaveOption parameter. it is NOT
        !           634:     **    applicable to pseudo objects.
        !           635:     */
        !           636: 
        !           637:     fStatus = PseudoObj_Close(lpPseudoObj);
        !           638:     OleDbgAssertSz(fStatus == TRUE, "PseudoObj_OleObj_Close failed\r\n");
        !           639: 
        !           640:     OLEDBG_END2
        !           641:     return NOERROR;
        !           642: }
        !           643: 
        !           644: 
        !           645: STDMETHODIMP PseudoObj_OleObj_SetMoniker(
        !           646:         LPOLEOBJECT lpThis, 
        !           647:         DWORD       dwWhichMoniker, 
        !           648:         LPMONIKER   lpmk
        !           649: )
        !           650: {
        !           651:     OleDbgOut2("PseudoObj_OleObj_SetMoniker\r\n");
        !           652: 
        !           653:     // OLE2NOTE: a pseudo object does NOT support SetMoniker
        !           654: 
        !           655:     return ResultFromScode(E_FAIL);
        !           656: }
        !           657: 
        !           658: 
        !           659: STDMETHODIMP PseudoObj_OleObj_GetMoniker(
        !           660:         LPOLEOBJECT     lpThis, 
        !           661:         DWORD           dwAssign,
        !           662:         DWORD           dwWhichMoniker, 
        !           663:         LPMONIKER FAR*  lplpmk
        !           664: )
        !           665: {
        !           666:     LPPSEUDOOBJ lpPseudoObj =
        !           667:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           668:     LPOLEDOC lpOleDoc = (LPOLEDOC)lpPseudoObj->m_lpDoc;
        !           669:     LPMONIKER lpmkDoc;
        !           670: 
        !           671:     OLEDBG_BEGIN2("PseudoObj_OleObj_GetMoniker\r\n")
        !           672:     
        !           673:     lpmkDoc = OleDoc_GetFullMoniker(lpOleDoc, GETMONIKER_ONLYIFTHERE);
        !           674:     *lplpmk = PseudoObj_GetFullMoniker(lpPseudoObj, lpmkDoc);
        !           675: 
        !           676:     OLEDBG_END2
        !           677: 
        !           678:     if (*lplpmk != NULL) 
        !           679:         return NOERROR;
        !           680:     else 
        !           681:         return ResultFromScode(E_FAIL);
        !           682: }
        !           683: 
        !           684: 
        !           685: STDMETHODIMP PseudoObj_OleObj_InitFromData(
        !           686:         LPOLEOBJECT             lpThis,
        !           687:         LPDATAOBJECT            lpDataObject,
        !           688:         BOOL                    fCreation,
        !           689:         DWORD                   reserved
        !           690: )
        !           691: {
        !           692:     LPPSEUDOOBJ lpPseudoObj =
        !           693:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           694: 
        !           695:     OleDbgOut2("PseudoObj_OleObj_InitFromData\r\n");
        !           696: 
        !           697:     // REVIEW: NOT YET IMPLEMENTED
        !           698: 
        !           699:     return ResultFromScode(E_NOTIMPL);
        !           700: }
        !           701: 
        !           702: 
        !           703: STDMETHODIMP PseudoObj_OleObj_GetClipboardData(
        !           704:         LPOLEOBJECT             lpThis,
        !           705:         DWORD                   reserved,
        !           706:         LPDATAOBJECT FAR*       lplpDataObject
        !           707: )
        !           708: {
        !           709:     LPPSEUDOOBJ lpPseudoObj =
        !           710:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           711: 
        !           712:     OleDbgOut2("PseudoObj_OleObj_GetClipboardData\r\n");
        !           713: 
        !           714:     // REVIEW: NOT YET IMPLEMENTED
        !           715: 
        !           716:     return ResultFromScode(E_NOTIMPL);
        !           717: }
        !           718: 
        !           719: 
        !           720: STDMETHODIMP PseudoObj_OleObj_DoVerb(
        !           721:         LPOLEOBJECT             lpThis,
        !           722:         LONG                    lVerb,
        !           723:         LPMSG                   lpmsg,
        !           724:         LPOLECLIENTSITE         lpActiveSite,
        !           725:                LONG                                    lindex,
        !           726:                HWND                                    hwndParent,
        !           727:                LPCRECT                                 lprcPosRect
        !           728: )
        !           729: {
        !           730:     LPPSEUDOOBJ lpPseudoObj =
        !           731:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           732:     LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpPseudoObj->m_lpDoc;
        !           733:     LPSERVERDOC lpServerDoc = lpPseudoObj->m_lpDoc;
        !           734:     LINERANGE lrSel;
        !           735:        HRESULT hrErr;
        !           736: 
        !           737:     OLEDBG_BEGIN2("PseudoObj_OleObj_DoVerb\r\n");
        !           738: 
        !           739:        /* OLE2NOTE: we must first ask our Document to perform the same
        !           740:        **    verb. then if the verb is NOT OLEIVERB_HIDE we should also
        !           741:        **    select the range of our pseudo object.
        !           742:        **    however, we must give our document its own embedding site as
        !           743:        **    its active site.
        !           744:        */
        !           745:        hrErr = SvrDoc_OleObj_DoVerb(
        !           746:                        (LPOLEOBJECT)&lpServerDoc->m_OleObject, 
        !           747:                        lVerb,
        !           748:                        lpmsg,
        !           749:                        lpServerDoc->m_lpOleClientSite,
        !           750:                        lindex, 
        !           751:                        NULL,   /* we have no hwndParent to give */
        !           752:                        NULL    /* we have no lprcPosRect to give */
        !           753:        );
        !           754:        if (hrErr != NOERROR ) {
        !           755:                OLEDBG_END2
        !           756:                return hrErr;
        !           757:        }
        !           758: 
        !           759:        if (lVerb != OLEIVERB_HIDE) {
        !           760:                PseudoObj_GetSel(lpPseudoObj, &lrSel);
        !           761:                OutlineDoc_SetSel(lpOutlineDoc, &lrSel);
        !           762:        }
        !           763:     
        !           764:     OLEDBG_END2
        !           765:        return NOERROR;
        !           766: }
        !           767: 
        !           768: 
        !           769: 
        !           770: STDMETHODIMP PseudoObj_OleObj_EnumVerbs(
        !           771:         LPOLEOBJECT         lpThis,
        !           772:         LPENUMOLEVERB FAR*  lplpenumOleVerb 
        !           773: )
        !           774: {
        !           775:     OleDbgOut2("PseudoObj_OleObj_EnumVerbs\r\n");
        !           776: 
        !           777:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !           778:     *lplpenumOleVerb = NULL;
        !           779: 
        !           780:     // Tell OLE to enumerate our verbs using the REGDB
        !           781:     return ResultFromScode(OLE_S_USEREG);
        !           782: }
        !           783: 
        !           784: 
        !           785: STDMETHODIMP PseudoObj_OleObj_Update(LPOLEOBJECT lpThis)
        !           786: {
        !           787:     OleDbgOut2("PseudoObj_OleObj_Update\r\n");
        !           788: 
        !           789:     /* OLE2NOTE: a server-only app is always "up-to-date". 
        !           790:     **    a container-app which contains links where the link source
        !           791:     **    has changed since the last update of the link would be
        !           792:     **    considered "out-of-date". the "Update" method instructs the
        !           793:     **    object to get an update from any out-of-date links.
        !           794:     */
        !           795: 
        !           796:     return NOERROR;
        !           797: }
        !           798: 
        !           799: 
        !           800: STDMETHODIMP PseudoObj_OleObj_IsUpToDate(LPOLEOBJECT lpThis)
        !           801: {
        !           802:     LPPSEUDOOBJ lpPseudoObj =
        !           803:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           804: 
        !           805:     OleDbgOut2("PseudoObj_OleObj_IsUpToDate\r\n");
        !           806: 
        !           807:     /* OLE2NOTE: a server-only app is always "up-to-date". 
        !           808:     **    a container-app which contains links where the link source
        !           809:     **    has changed since the last update of the link would be
        !           810:     **    considered "out-of-date".
        !           811:     */
        !           812:     return NOERROR;
        !           813: }
        !           814: 
        !           815: 
        !           816: STDMETHODIMP PseudoObj_OleObj_GetUserClassID(
        !           817:         LPOLEOBJECT             lpThis, 
        !           818:         LPCLSID                 lpclsid
        !           819: )
        !           820: {
        !           821:     LPPSEUDOOBJ lpPseudoObj =
        !           822:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           823:     LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpPseudoObj->m_lpDoc;
        !           824: 
        !           825:     OleDbgOut2("PseudoObj_OleObj_GetUserClassID\r\n");
        !           826: 
        !           827:        /* OLE2NOTE: we must be carefull to return the correct CLSID here.
        !           828:        **    if we are currently preforming a "TreatAs (aka. ActivateAs)"
        !           829:        **    operation then we need to return the class of the object
        !           830:        **    written in the storage of the object. otherwise we would
        !           831:        **    return our own class id. 
        !           832:        */
        !           833:        return ServerDoc_GetClassID(lpServerDoc, lpclsid);
        !           834: }
        !           835: 
        !           836: 
        !           837: STDMETHODIMP PseudoObj_OleObj_GetUserType(
        !           838:         LPOLEOBJECT             lpThis,
        !           839:         DWORD                   dwFormOfType, 
        !           840:         LPSTR FAR*              lpszUserType
        !           841: )
        !           842: {
        !           843:     OleDbgOut2("PseudoObj_OleObj_GetUserType\r\n");
        !           844: 
        !           845:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !           846:     *lpszUserType = NULL;
        !           847: 
        !           848:     // Tell OLE to enumerate our verbs using the REGDB
        !           849:     return ResultFromScode(OLE_S_USEREG);
        !           850: 
        !           851: #if defined( LATER )
        !           852:     LPPSEUDOOBJ lpPseudoObj =
        !           853:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           854:     LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpPseudoObj->m_lpDoc;
        !           855: 
        !           856:        /* OLE2NOTE: we must be carefull to return the correct UserType here.
        !           857:        **    if we are currently preforming a "TreatAs (aka. ActivateAs)"
        !           858:        **    operation then we need to return the UserType of the object
        !           859:        **    written in the storage of the object. otherwise we would
        !           860:        **    return our own UserType.
        !           861:        */
        !           862:        return ServerDoc_GetUserType(lpServerDoc, dwFormOfType, lpszUserType);
        !           863: #endif
        !           864: }
        !           865: 
        !           866: 
        !           867: STDMETHODIMP PseudoObj_OleObj_SetExtent(
        !           868:         LPOLEOBJECT             lpThis,
        !           869:         DWORD                   dwDrawAspect,
        !           870:         LPSIZEL                 lplgrc
        !           871: )
        !           872: {
        !           873:     OleDbgOut2("PseudoObj_OleObj_SetExtent\r\n");
        !           874:     
        !           875:     // OLE2NOTE: a pseudo object does NOT support SetExtent
        !           876:     
        !           877:     return ResultFromScode(E_FAIL);
        !           878: }
        !           879: 
        !           880: 
        !           881: STDMETHODIMP PseudoObj_OleObj_GetExtent(
        !           882:         LPOLEOBJECT             lpThis,
        !           883:         DWORD                   dwDrawAspect,
        !           884:         LPSIZEL                 lplgrc
        !           885: )
        !           886: {
        !           887:     OleDbgOut2("PseudoObj_OleObj_GetExtent\r\n");
        !           888:     
        !           889:     return ResultFromScode(E_NOTIMPL);
        !           890: }
        !           891: 
        !           892: 
        !           893: STDMETHODIMP PseudoObj_OleObj_Advise(
        !           894:         LPOLEOBJECT lpThis, 
        !           895:         LPADVISESINK lpAdvSink, 
        !           896:         LPDWORD lpdwConnection
        !           897: )
        !           898: {
        !           899:     LPPSEUDOOBJ lpPseudoObj =
        !           900:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           901:     HRESULT hrErr;
        !           902:     SCODE   sc;
        !           903: 
        !           904:     OLEDBG_BEGIN2("PseudoObj_OleObj_Advise\r\n");
        !           905: 
        !           906:     if (lpPseudoObj->m_lpOleAdviseHldr == NULL && 
        !           907:         CreateOleAdviseHolder(&lpPseudoObj->m_lpOleAdviseHldr) != NOERROR) {
        !           908:         sc = E_OUTOFMEMORY;
        !           909:         goto error;
        !           910:     }
        !           911: 
        !           912:     OLEDBG_BEGIN2("IOleAdviseHolder::Advise called\r\n")
        !           913:     hrErr = lpPseudoObj->m_lpOleAdviseHldr->lpVtbl->Advise(
        !           914:             lpPseudoObj->m_lpOleAdviseHldr, 
        !           915:             lpAdvSink, 
        !           916:             lpdwConnection
        !           917:     );
        !           918:     OLEDBG_END2
        !           919: 
        !           920:     OLEDBG_END2
        !           921:     return hrErr;
        !           922: 
        !           923: error:
        !           924:     OLEDBG_END2
        !           925:     return ResultFromScode(sc);
        !           926: }
        !           927: 
        !           928: 
        !           929: STDMETHODIMP PseudoObj_OleObj_Unadvise(LPOLEOBJECT lpThis, DWORD dwConnection)
        !           930: {
        !           931:     LPPSEUDOOBJ lpPseudoObj =
        !           932:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           933:     HRESULT hrErr;
        !           934:     SCODE   sc;
        !           935: 
        !           936:     OLEDBG_BEGIN2("PseudoObj_OleObj_Unadvise\r\n");
        !           937: 
        !           938:     if (lpPseudoObj->m_lpOleAdviseHldr == NULL) {
        !           939:         sc = E_FAIL;
        !           940:         goto error;
        !           941:     }
        !           942: 
        !           943:     OLEDBG_BEGIN2("IOleAdviseHolder::Unadvise called\r\n")
        !           944:     hrErr = lpPseudoObj->m_lpOleAdviseHldr->lpVtbl->Unadvise(
        !           945:             lpPseudoObj->m_lpOleAdviseHldr, 
        !           946:             dwConnection
        !           947:     );
        !           948:     OLEDBG_END2
        !           949: 
        !           950:     OLEDBG_END2
        !           951:     return hrErr;
        !           952: 
        !           953: error:
        !           954:     OLEDBG_END2
        !           955:     return ResultFromScode(sc);
        !           956: }
        !           957: 
        !           958: 
        !           959: STDMETHODIMP PseudoObj_OleObj_EnumAdvise(
        !           960:         LPOLEOBJECT lpThis, 
        !           961:         LPENUMSTATDATA FAR* lplpenumAdvise
        !           962: )
        !           963: {
        !           964:     LPPSEUDOOBJ lpPseudoObj =
        !           965:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !           966:     HRESULT hrErr;
        !           967:     SCODE   sc;
        !           968: 
        !           969:     OLEDBG_BEGIN2("PseudoObj_OleObj_EnumAdvise\r\n");
        !           970:     
        !           971:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !           972:     *lplpenumAdvise = NULL;
        !           973: 
        !           974:     if (lpPseudoObj->m_lpOleAdviseHldr == NULL) {
        !           975:         sc = E_FAIL;
        !           976:         goto error;
        !           977:     }
        !           978: 
        !           979:     OLEDBG_BEGIN2("IOleAdviseHolder::EnumAdvise called\r\n")
        !           980:     hrErr = lpPseudoObj->m_lpOleAdviseHldr->lpVtbl->EnumAdvise(
        !           981:             lpPseudoObj->m_lpOleAdviseHldr, 
        !           982:             lplpenumAdvise
        !           983:     );
        !           984:     OLEDBG_END2
        !           985: 
        !           986:     OLEDBG_END2
        !           987:     return hrErr;
        !           988: 
        !           989: error:
        !           990:     OLEDBG_END2
        !           991:     return ResultFromScode(sc);
        !           992: }
        !           993: 
        !           994: 
        !           995: STDMETHODIMP PseudoObj_OleObj_GetMiscStatus(
        !           996:         LPOLEOBJECT             lpThis,
        !           997:         DWORD                   dwAspect,
        !           998:         DWORD FAR*              lpdwStatus
        !           999: )
        !          1000: {
        !          1001:     LPPSEUDOOBJ lpPseudoObj =
        !          1002:             ((struct CPseudoObjOleObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1003: 
        !          1004:     OleDbgOut2("PseudoObj_OleObj_GetMiscStatus\r\n");
        !          1005: 
        !          1006:     // Tell OLE to get our user type name from the REGDB
        !          1007:     return ResultFromScode(OLE_S_USEREG);
        !          1008: }
        !          1009: 
        !          1010: 
        !          1011: STDMETHODIMP PseudoObj_OleObj_SetColorScheme(
        !          1012:         LPOLEOBJECT             lpThis,
        !          1013:         LPLOGPALETTE            lpLogpal
        !          1014: )
        !          1015: {
        !          1016:     OleDbgOut2("PseudoObj_OleObj_SetColorScheme\r\n");
        !          1017: 
        !          1018:     // REVIEW: NOT YET IMPLEMENTED
        !          1019: 
        !          1020:     return ResultFromScode(E_NOTIMPL);
        !          1021: }
        !          1022: 
        !          1023: 
        !          1024: /*************************************************************************
        !          1025: ** PseudoObj::IDataObject interface implementation
        !          1026: *************************************************************************/
        !          1027: 
        !          1028: STDMETHODIMP PseudoObj_DataObj_QueryInterface (
        !          1029:         LPDATAOBJECT      lpThis,
        !          1030:         REFIID            riid,
        !          1031:         LPVOID FAR*       lplpvObj
        !          1032: )
        !          1033: {
        !          1034:     LPPSEUDOOBJ lpPseudoObj =
        !          1035:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1036: 
        !          1037:     return PseudoObj_QueryInterface(lpPseudoObj, riid, lplpvObj);
        !          1038: }
        !          1039: 
        !          1040: 
        !          1041: STDMETHODIMP_(ULONG) PseudoObj_DataObj_AddRef(LPDATAOBJECT lpThis)
        !          1042: {
        !          1043:     LPPSEUDOOBJ lpPseudoObj =
        !          1044:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1045: 
        !          1046:     OleDbgAddRefMethod(lpThis, "IDataObject");
        !          1047: 
        !          1048:     return PseudoObj_AddRef((LPPSEUDOOBJ)lpPseudoObj);
        !          1049: }
        !          1050: 
        !          1051: 
        !          1052: STDMETHODIMP_(ULONG) PseudoObj_DataObj_Release (LPDATAOBJECT lpThis)
        !          1053: {
        !          1054:     LPPSEUDOOBJ lpPseudoObj =
        !          1055:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1056:         
        !          1057:     OleDbgReleaseMethod(lpThis, "IDataObject");
        !          1058: 
        !          1059:     return PseudoObj_Release((LPPSEUDOOBJ)lpPseudoObj);
        !          1060: }
        !          1061: 
        !          1062: 
        !          1063: STDMETHODIMP PseudoObj_DataObj_GetData (
        !          1064:         LPDATAOBJECT    lpThis,
        !          1065:         LPFORMATETC     lpformatetc,
        !          1066:         LPSTGMEDIUM     lpMedium
        !          1067: )
        !          1068: {
        !          1069:     LPPSEUDOOBJ lpPseudoObj =
        !          1070:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1071:     LPSERVERDOC  lpServerDoc = lpPseudoObj->m_lpDoc;
        !          1072:     LPOUTLINEDOC  lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1073:     LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
        !          1074:     LPOLEAPP  lpOleApp = (LPOLEAPP)lpServerApp;
        !          1075:     LPOUTLINEAPP  lpOutlineApp = (LPOUTLINEAPP)lpServerApp;
        !          1076:     LINERANGE lrSel;
        !          1077:     SCODE sc = S_OK;
        !          1078: 
        !          1079:     OLEDBG_BEGIN2("PseudoObj_DataObj_GetData\r\n")
        !          1080: 
        !          1081:     PseudoObj_GetSel(lpPseudoObj, &lrSel);
        !          1082:     
        !          1083:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !          1084:     lpMedium->tymed = TYMED_NULL;
        !          1085:     lpMedium->pUnkForRelease = NULL;    // we transfer ownership to caller
        !          1086:     lpMedium->u.hGlobal = NULL;
        !          1087: 
        !          1088:     if (lpformatetc->cfFormat == lpOutlineApp->m_cfOutline) {
        !          1089:         // Verify caller asked for correct medium
        !          1090:         if (!(lpformatetc->tymed & TYMED_HGLOBAL)) {
        !          1091:             sc = DATA_E_FORMATETC;
        !          1092:             goto error;
        !          1093:         }
        !          1094: 
        !          1095:         lpMedium->u.hGlobal = OutlineDoc_GetOutlineData (lpOutlineDoc,&lrSel);
        !          1096:         if (! lpMedium->u.hGlobal) return ResultFromScode(E_OUTOFMEMORY);
        !          1097:         lpMedium->tymed = TYMED_HGLOBAL;
        !          1098:         OleDbgOut3("PseudoObj_DataObj_GetData: rendered CF_OUTLINE\r\n");
        !          1099: 
        !          1100:     } else if(lpformatetc->cfFormat == CF_METAFILEPICT &&
        !          1101:                (lpformatetc->dwAspect & (DVASPECT_CONTENT | DVASPECT_DOCPRINT)) ) {
        !          1102:         // Verify caller asked for correct medium
        !          1103:         if (!(lpformatetc->tymed & TYMED_MFPICT)) {
        !          1104:             sc = DATA_E_FORMATETC;
        !          1105:             goto error;
        !          1106:         }
        !          1107: 
        !          1108:         lpMedium->u.hGlobal=ServerDoc_GetMetafilePictData(lpServerDoc,&lrSel);
        !          1109:         if (! lpMedium->u.hGlobal) {
        !          1110:             sc = E_OUTOFMEMORY;
        !          1111:             goto error;
        !          1112:         }
        !          1113:         lpMedium->tymed = TYMED_MFPICT;
        !          1114:         OleDbgOut3("PseudoObj_DataObj_GetData: rendered CF_METAFILEPICT\r\n");
        !          1115: 
        !          1116:     } else if (lpformatetc->cfFormat == CF_METAFILEPICT &&
        !          1117:                (lpformatetc->dwAspect & DVASPECT_ICON | DVASPECT_DOCPRINT) ) {
        !          1118:                CLSID clsid;
        !          1119:         // Verify caller asked for correct medium
        !          1120:         if (!(lpformatetc->tymed & TYMED_MFPICT)) {
        !          1121:             sc = DATA_E_FORMATETC;
        !          1122:             goto error;
        !          1123:         }
        !          1124: 
        !          1125:                /* OLE2NOTE: we should return the default icon for our class.
        !          1126:                **    we must be carefull to use the correct CLSID here.
        !          1127:                **    if we are currently preforming a "TreatAs (aka. ActivateAs)"
        !          1128:                **    operation then we need to use the class of the object
        !          1129:                **    written in the storage of the object. otherwise we would
        !          1130:                **    use our own class id. 
        !          1131:                */
        !          1132:                if (ServerDoc_GetClassID(lpServerDoc, (LPCLSID)&clsid) != NOERROR) {
        !          1133:                        sc = DATA_E_FORMATETC;
        !          1134:             goto error;
        !          1135:                }                       
        !          1136: 
        !          1137:         lpMedium->u.hGlobal=GetIconOfClass(
        !          1138:                 g_lpApp->m_hInst,(REFCLSID)&clsid, NULL, FALSE);
        !          1139:         if (! lpMedium->u.hGlobal) {
        !          1140:             sc = E_OUTOFMEMORY;
        !          1141:             goto error;
        !          1142:         }
        !          1143: 
        !          1144:         lpMedium->tymed = TYMED_MFPICT;
        !          1145:         OleDbgOut3(
        !          1146:             "PseudoObj_DataObj_GetData: rendered CF_METAFILEPICT (icon)\r\n");
        !          1147:                return NOERROR;
        !          1148: 
        !          1149:     } else if (lpformatetc->cfFormat == CF_TEXT) {
        !          1150:         // Verify caller asked for correct medium
        !          1151:         if (!(lpformatetc->tymed & TYMED_HGLOBAL)) {
        !          1152:             sc = DATA_E_FORMATETC;
        !          1153:             goto error;
        !          1154:         }
        !          1155:         
        !          1156:         lpMedium->u.hGlobal = OutlineDoc_GetTextData (lpOutlineDoc, &lrSel);
        !          1157:         if (! lpMedium->u.hGlobal) {
        !          1158:             sc = E_OUTOFMEMORY;
        !          1159:             goto error;
        !          1160:         }
        !          1161:         lpMedium->tymed = TYMED_HGLOBAL;
        !          1162:         OleDbgOut3("PseudoObj_DataObj_GetData: rendered CF_TEXT\r\n");
        !          1163: 
        !          1164:     } else {
        !          1165:         sc = DATA_E_FORMATETC;
        !          1166:         goto error;
        !          1167:     }
        !          1168: 
        !          1169:     OLEDBG_END2
        !          1170:     return NOERROR;
        !          1171: 
        !          1172: error:
        !          1173:     OLEDBG_END2
        !          1174:     return ResultFromScode(sc);
        !          1175: }
        !          1176: 
        !          1177: 
        !          1178: STDMETHODIMP PseudoObj_DataObj_GetDataHere (
        !          1179:         LPDATAOBJECT    lpThis,
        !          1180:         LPFORMATETC     lpformatetc,
        !          1181:         LPSTGMEDIUM     lpMedium
        !          1182: )
        !          1183: {
        !          1184:     LPPSEUDOOBJ lpPseudoObj =
        !          1185:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1186:     LPSERVERDOC  lpServerDoc = lpPseudoObj->m_lpDoc;
        !          1187:     LPOUTLINEDOC  lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1188:     LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
        !          1189:     LPOLEAPP  lpOleApp = (LPOLEAPP)lpServerApp;
        !          1190:     LPOUTLINEAPP  lpOutlineApp = (LPOUTLINEAPP)lpServerApp;
        !          1191: 
        !          1192:     OleDbgOut("PseudoObj_DataObj_GetDataHere\r\n");
        !          1193: 
        !          1194:     /* Caller is requesting data to be returned in Caller allocated
        !          1195:     **    medium, but we do NOT support this. we only support
        !          1196:     **    global memory blocks that WE allocate for the caller.
        !          1197:     */
        !          1198:     return ResultFromScode(DATA_E_FORMATETC);
        !          1199: }
        !          1200: 
        !          1201: 
        !          1202: STDMETHODIMP PseudoObj_DataObj_QueryGetData (
        !          1203:         LPDATAOBJECT    lpThis,
        !          1204:         LPFORMATETC     lpformatetc
        !          1205: )
        !          1206: {
        !          1207:     LPPSEUDOOBJ lpPseudoObj =
        !          1208:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1209:     LPSERVERDOC  lpServerDoc = lpPseudoObj->m_lpDoc;
        !          1210:     LPOUTLINEDOC  lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1211:     LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
        !          1212:     LPOLEAPP  lpOleApp = (LPOLEAPP)lpServerApp;
        !          1213:     LPOUTLINEAPP  lpOutlineApp = (LPOUTLINEAPP)lpServerApp;
        !          1214: 
        !          1215:     OleDbgOut2("PseudoObj_DataObj_QueryGetData\r\n");
        !          1216: 
        !          1217:     /* Caller is querying if we support certain format but does not
        !          1218:     **    want any data actually returned.
        !          1219:     */
        !          1220:     if (lpformatetc->cfFormat == CF_METAFILEPICT &&
        !          1221:                (lpformatetc->dwAspect & 
        !          1222:                        (DVASPECT_CONTENT | DVASPECT_CONTENT | DVASPECT_DOCPRINT)) ) {
        !          1223:         return OleStdQueryFormatMedium(lpformatetc, TYMED_HGLOBAL);
        !          1224: 
        !          1225:     } else if (lpformatetc->cfFormat == (lpOutlineApp)->m_cfOutline ||
        !          1226:             lpformatetc->cfFormat == CF_TEXT) {
        !          1227:         return OleStdQueryFormatMedium(lpformatetc, TYMED_HGLOBAL);
        !          1228:     }
        !          1229: 
        !          1230:     return ResultFromScode(DATA_E_FORMATETC);
        !          1231: }
        !          1232: 
        !          1233: 
        !          1234: STDMETHODIMP PseudoObj_DataObj_GetCanonicalFormatEtc(
        !          1235:         LPDATAOBJECT    lpThis,
        !          1236:         LPFORMATETC     lpformatetc,
        !          1237:         LPFORMATETC     lpformatetcOut
        !          1238: )
        !          1239: {
        !          1240:     OleDbgOut2("PseudoObj_DataObj_GetCanonicalFormatEtc\r\n");
        !          1241:     
        !          1242:     OleDbgAssertSz(0, "NOT_YET_IMPLEMENTED\r\n");
        !          1243:     return ResultFromScode(E_NOTIMPL);
        !          1244: }
        !          1245: 
        !          1246: 
        !          1247: STDMETHODIMP PseudoObj_DataObj_SetData (
        !          1248:         LPDATAOBJECT    lpThis,
        !          1249:         LPFORMATETC     lpformatetc,
        !          1250:         LPSTGMEDIUM     lpmedium,
        !          1251:         BOOL            fRelease
        !          1252: )
        !          1253: {
        !          1254:     LPPSEUDOOBJ lpPseudoObj =
        !          1255:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1256:     LPSERVERDOC  lpServerDoc = lpPseudoObj->m_lpDoc;
        !          1257:     LPOUTLINEDOC  lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
        !          1258:     LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
        !          1259:     
        !          1260:     OleDbgOut2("PseudoObj_DataObj_SetData\r\n");
        !          1261: 
        !          1262:     // REVIEW: NOT-YET-IMPLEMENTED
        !          1263:     return ResultFromScode(E_NOTIMPL);
        !          1264: }
        !          1265: 
        !          1266: 
        !          1267: STDMETHODIMP PseudoObj_DataObj_EnumFormatEtc(
        !          1268:         LPDATAOBJECT            lpThis,
        !          1269:         DWORD                   dwDirection,
        !          1270:         LPENUMFORMATETC FAR*    lplpenumFormatEtc
        !          1271: )
        !          1272: {
        !          1273:     SCODE sc;
        !          1274: 
        !          1275:     OleDbgOut2("PseudoObj_DataObj_EnumFormatEtc\r\n");
        !          1276: 
        !          1277:     /* OLE2NOTE: a pseudo object only needs to enumerate the static list
        !          1278:     **    of formats that are registered for our app in the
        !          1279:     **    registration database. OLE provides a default enumerator
        !          1280:     **    which enumerates from the registration database. this default
        !          1281:     **    enumerator is requested by returning OLE_S_USEREG. it is NOT
        !          1282:     **    required that a pseudo object (ie. non-DataTransferDoc)
        !          1283:     **    enumerate the OLE formats: CF_LINKSOURCE, CF_EMBEDSOURCE, or
        !          1284:     **    CF_EMBEDDEDOBJECT. we do NOT use pseudo objects for data
        !          1285:     **    transfers.
        !          1286:     */
        !          1287:     if (dwDirection == DATADIR_GET) 
        !          1288:         sc = OLE_S_USEREG;
        !          1289:     else if (dwDirection == DATADIR_SET) 
        !          1290:         sc = E_NOTIMPL;
        !          1291:     else 
        !          1292:         sc = E_INVALIDARG;
        !          1293: 
        !          1294:     return ResultFromScode(sc);
        !          1295: }
        !          1296: 
        !          1297: 
        !          1298: STDMETHODIMP PseudoObj_DataObj_Advise(
        !          1299:         LPDATAOBJECT    lpThis,
        !          1300:         FORMATETC FAR*  lpFormatetc, 
        !          1301:         DWORD           advf, 
        !          1302:         LPADVISESINK    lpAdvSink, 
        !          1303:         DWORD FAR*      lpdwConnection
        !          1304: )
        !          1305: {
        !          1306:     LPPSEUDOOBJ lpPseudoObj =
        !          1307:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1308:     HRESULT hrErr;
        !          1309:     SCODE   sc;
        !          1310: 
        !          1311:     OLEDBG_BEGIN2("PseudoObj_DataObj_Advise\r\n")
        !          1312: 
        !          1313:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !          1314:     *lpdwConnection = 0;
        !          1315: 
        !          1316:     if (lpPseudoObj->m_lpDataAdviseHldr == NULL && 
        !          1317:         CreateDataAdviseHolder(&lpPseudoObj->m_lpDataAdviseHldr) != NOERROR) {
        !          1318:         sc = E_OUTOFMEMORY;
        !          1319:         goto error;
        !          1320:     }
        !          1321: 
        !          1322:     OLEDBG_BEGIN2("IOleAdviseHolder::Advise called\r\n")
        !          1323:     hrErr = lpPseudoObj->m_lpDataAdviseHldr->lpVtbl->Advise(
        !          1324:             lpPseudoObj->m_lpDataAdviseHldr, 
        !          1325:             (LPDATAOBJECT)&lpPseudoObj->m_DataObject,
        !          1326:             lpFormatetc, 
        !          1327:             advf, 
        !          1328:             lpAdvSink, 
        !          1329:             lpdwConnection
        !          1330:     );
        !          1331:     OLEDBG_END2
        !          1332: 
        !          1333:     OLEDBG_END2
        !          1334:     return hrErr;
        !          1335: 
        !          1336: error:
        !          1337:     OLEDBG_END2
        !          1338:     return ResultFromScode(sc);
        !          1339: }
        !          1340: 
        !          1341: 
        !          1342: STDMETHODIMP PseudoObj_DataObj_Unadvise(LPDATAOBJECT lpThis, DWORD dwConnection)
        !          1343: {
        !          1344:     LPPSEUDOOBJ lpPseudoObj =
        !          1345:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1346:     HRESULT hrErr;
        !          1347:     SCODE   sc;
        !          1348: 
        !          1349:     OLEDBG_BEGIN2("PseudoObj_DataObj_Unadvise\r\n");
        !          1350: 
        !          1351:     // no one registered
        !          1352:     if (lpPseudoObj->m_lpDataAdviseHldr == NULL) {
        !          1353:         sc = E_FAIL;
        !          1354:         goto error;
        !          1355:     }
        !          1356: 
        !          1357:     OLEDBG_BEGIN2("IOleAdviseHolder::Unadvise called\r\n")
        !          1358:     hrErr = lpPseudoObj->m_lpDataAdviseHldr->lpVtbl->Unadvise(
        !          1359:             lpPseudoObj->m_lpDataAdviseHldr, 
        !          1360:             dwConnection
        !          1361:     );
        !          1362:     OLEDBG_END2
        !          1363: 
        !          1364:     OLEDBG_END2
        !          1365:     return hrErr;
        !          1366: 
        !          1367: error:
        !          1368:     OLEDBG_END2
        !          1369:     return ResultFromScode(sc);
        !          1370: }
        !          1371: 
        !          1372: 
        !          1373: STDMETHODIMP PseudoObj_DataObj_EnumAdvise(
        !          1374:         LPDATAOBJECT lpThis,
        !          1375:         LPENUMSTATDATA FAR* lplpenumAdvise
        !          1376: )
        !          1377: {
        !          1378:     LPPSEUDOOBJ lpPseudoObj =
        !          1379:             ((struct CPseudoObjDataObjectImpl FAR*)lpThis)->lpPseudoObj;
        !          1380:     HRESULT hrErr;
        !          1381:     SCODE   sc;
        !          1382: 
        !          1383:     OLEDBG_BEGIN2("PseudoObj_DataObj_EnumAdvise\r\n");
        !          1384: 
        !          1385:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !          1386:     *lplpenumAdvise = NULL;
        !          1387: 
        !          1388:     if (lpPseudoObj->m_lpDataAdviseHldr == NULL) {
        !          1389:         sc = E_FAIL;
        !          1390:         goto error;
        !          1391:     }
        !          1392: 
        !          1393:     OLEDBG_BEGIN2("IOleAdviseHolder::EnumAdvise called\r\n")
        !          1394:     hrErr = lpPseudoObj->m_lpDataAdviseHldr->lpVtbl->EnumAdvise(
        !          1395:             lpPseudoObj->m_lpDataAdviseHldr, 
        !          1396:             lplpenumAdvise
        !          1397:     );
        !          1398:     OLEDBG_END2
        !          1399: 
        !          1400:     OLEDBG_END2
        !          1401:     return hrErr;
        !          1402: 
        !          1403: error:
        !          1404:     OLEDBG_END2
        !          1405:     return ResultFromScode(sc);
        !          1406: }

unix.superglobalmegacorp.com

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