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