Annotation of mstools/mfc/src/olecli.cpp, revision 1.1.1.2

1.1       root        1: // This is a part of the Microsoft Foundation Classes C++ library. 
                      2: // Copyright (C) 1992 Microsoft Corporation 
                      3: // All rights reserved. 
                      4: //  
                      5: // This source code is only intended as a supplement to the 
                      6: // Microsoft Foundation Classes Reference and Microsoft 
                      7: // QuickHelp documentation provided with the library. 
                      8: // See these sources for detailed information regarding the 
                      9: // Microsoft Foundation Classes product. 
                     10: 
                     11: 
                     12: #include "afxole.h"
                     13: #pragma hdrstop
                     14: 
                     15: #include "oleptr_.h"
                     16: 
                     17: #ifdef AFX_OLE_SEG
                     18: #pragma code_seg(AFX_OLE_SEG)
                     19: #endif
                     20: 
                     21: #ifdef _DEBUG
                     22: #undef THIS_FILE
                     23: static char BASED_CODE THIS_FILE[] = __FILE__;
                     24: #endif
                     25: 
                     26: #define OLEEXPORT FAR PASCAL _export
                     27: 
                     28: /////////////////////////////////////////////////////////////////////////////
                     29: #ifdef _DEBUG
                     30: // character strings to use for debug traces
                     31: 
                     32: static char BASED_CODE szCHANGED[] = "OLE_CHANGED";
                     33: static char BASED_CODE szSAVED[] = "OLE_SAVED";
                     34: static char BASED_CODE szCLOSED[] = "OLE_CLOSED";
                     35: static char BASED_CODE szRENAMED[] = "OLE_RENAMED";
                     36: static char BASED_CODE szQUERY_PAINT[] = "OLE_QUERY_PAINT";
                     37: static char BASED_CODE szRELEASE[] = "OLE_RELEASE";
                     38: static char BASED_CODE szQUERY_RETRY[] = "OLE_QUERY_RETRY";
                     39: 
                     40: static char FAR* BASED_CODE notifyStrings[] =
                     41: {
                     42:        szCHANGED,
                     43:        szSAVED,
                     44:        szCLOSED,
                     45:        szRENAMED,
                     46:        szQUERY_PAINT,
                     47:        szRELEASE,
                     48:        szQUERY_RETRY,
                     49: };
                     50: #endif //_DEBUG
                     51: 
                     52: // Standard protocol strings
                     53: static char BASED_CODE lpszStaticProtocol[] = "Static";
                     54: static char BASED_CODE lpszStdProtocol[] = "StdFileEditing";
                     55: 
                     56: /////////////////////////////////////////////////////////////////////////////
                     57: // Client view of OLEOBJECT (includes OLECLIENT)
                     58: 
                     59: IMPLEMENT_DYNAMIC(COleClientItem, CObject)
                     60: 
                     61: inline COleClientItem *
                     62: COleClientItem::FromLp(LPOLECLIENT lpClient)
                     63: {
                     64:        ASSERT(lpClient != NULL);
                     65:        COleClientItem* pOleClient;
                     66:        pOleClient = (COleClientItem*) GetPtrFromFarPtr(lpClient, sizeof(CObject));
                     67:        ASSERT(lpClient == &pOleClient->m_oleClient);
                     68:        return pOleClient;
                     69: }
                     70: 
                     71: // friend class to get access to COleClientItem protected implementations
                     72: struct _afxOleClientItemImplementation
                     73: {
                     74:        static int OLEEXPORT
                     75:        Client_CallBack(LPOLECLIENT lpClient, OLE_NOTIFICATION wNotification,
                     76:                LPOLEOBJECT lpObject)
                     77:        {
                     78:                COleClientItem* pOleClient = COleClientItem::FromLp(lpClient);
                     79:                ASSERT(pOleClient != NULL);
                     80: 
                     81:        #ifdef _DEBUG
                     82:                if (wNotification != OLE_QUERY_PAINT)
                     83:                {
                     84:                        if (afxTraceFlags & 0x10)
                     85:                                TRACE("OLE Client_Callback %d [%Fs] for $%lx\n",
                     86:                                        wNotification, (LPCSTR)notifyStrings[wNotification], lpObject);
                     87:                }
                     88:        #else
                     89:                (void)lpObject; // not used
                     90:        #endif
                     91:                return pOleClient->ClientCallBack(wNotification);
                     92:        }
                     93: };
                     94: 
                     95: static struct _OLECLIENTVTBL NEAR clientVtbl =
                     96: {
                     97:        &_afxOleClientItemImplementation::Client_CallBack
                     98: };
                     99: 
                    100: // Many creation variants
                    101: COleClientItem::COleClientItem(COleClientDoc* pContainerDoc)
                    102: {
                    103:        ASSERT(pContainerDoc != NULL);
                    104:        ASSERT(pContainerDoc->IsOpen());
                    105: 
                    106:        m_oleClient.lpvtbl = &clientVtbl;
                    107:        m_lpObject = NULL;
                    108:        m_lastStatus = OLE_OK;
                    109:        m_pDocument = pContainerDoc;
                    110: }
                    111: 
                    112: COleClientItem::~COleClientItem()
                    113: {
                    114:        if (m_lpObject != NULL)
                    115:        {
                    116:                // wait for object to be not busy
                    117:                UINT nType = GetType();
                    118: 
                    119:                if (nType != OT_STATIC)
                    120:                        WaitForServer();
                    121:                // release linked, delete others
                    122:                CheckAsync((nType == OT_LINK) ?
                    123:                  ::OleRelease(m_lpObject) : ::OleDelete(m_lpObject));
                    124:        }
                    125: }
                    126: 
                    127: void COleClientItem::Release()
                    128: {
                    129:        if (m_lpObject == NULL)
                    130:                return;
                    131: 
                    132:        CheckAsync(::OleRelease(m_lpObject));
                    133: 
                    134:        // detach
                    135:        m_lpObject = NULL;
                    136: }
                    137: 
                    138: void COleClientItem::Delete()
                    139: {
                    140:        if (m_lpObject == NULL)
                    141:                return;
                    142: 
                    143:        CheckAsync(::OleDelete(m_lpObject));
                    144: 
                    145:        // detach
                    146:        m_lpObject = NULL;
                    147: }
                    148: 
                    149: //////////////////////////////////////////////////////////////////////////////
                    150: // Create error handling
                    151: 
1.1.1.2 ! root      152: #ifdef _NTWIN
        !           153: #pragma warning(disable: 4062)
        !           154: #endif
        !           155: 
1.1       root      156: BOOL COleClientItem::CheckCreate(OLESTATUS status)
                    157: {
                    158:        m_lastStatus = status;
                    159: 
                    160:        switch (status)
                    161:        {
                    162:        case OLE_OK:
                    163:                ASSERT(m_lpObject != NULL);
                    164:                return TRUE;            // immediate create success
                    165: 
                    166:        case OLE_WAIT_FOR_RELEASE:  // synchronous create
                    167:                ASSERT(m_lpObject != NULL);
                    168:                WaitForServer();
                    169:                return (m_lastStatus == OLE_OK);
                    170: 
                    171:        // cases to treat as exceptions
                    172:        case OLE_ERROR_PROTECT_ONLY:
                    173:        case OLE_ERROR_MEMORY:
                    174:        case OLE_ERROR_OBJECT:
                    175:        case OLE_ERROR_OPTION:
                    176:                TRACE("Warning: COleClientItem::Create?() failed %d\n", status);
                    177:                AfxThrowOleException(status);
                    178:                break;
                    179:        }
                    180: 
                    181:        // the rest are non-exceptional conditions for create
                    182:        TRACE("Warning: COleClientItem::Create?() failed %d, returning FALSE\n", status);
                    183:        m_lpObject = NULL;      // just in case
                    184:        return FALSE;           // create failed
                    185: }
                    186: 
1.1.1.2 ! root      187: #ifdef _NTWIN
        !           188: #pragma warning(default: 4062)
        !           189: #endif
        !           190: 
1.1       root      191: 
                    192: void COleClientItem::CheckAsync(OLESTATUS status)
                    193:        // special case for possible Async requests
                    194: {
                    195:        if (status == OLE_WAIT_FOR_RELEASE)
                    196:        {
                    197:                ASSERT(m_lpObject != NULL);
                    198:                WaitForServer();
                    199:                status = m_lastStatus;      // set by ASYNC release
                    200:                ASSERT(status != OLE_WAIT_FOR_RELEASE);
                    201:        }
                    202:        CheckGeneral(status);   // may throw an exception
                    203: }
                    204: 
                    205: void COleClientItem::CheckGeneral(OLESTATUS status)
                    206:        // set 'm_lastStatus'
                    207:        // throw exception if not ok to continue
                    208: {
                    209:        ASSERT(status != OLE_WAIT_FOR_RELEASE);
                    210:                // Async must be handled as a special case before this
                    211: 
                    212:        m_lastStatus = status;
                    213:        if (status == OLE_OK || status > OLE_WARN_DELETE_DATA)
                    214:        {
                    215:                // ok, or just a warning
                    216:                return;
                    217:        }
                    218: 
                    219:        // otherwise this error wasn't expected, so throw an exception
                    220:        TRACE("Warning: COleClientItem operation failed %d, throwing exception\n", status);
                    221:        AfxThrowOleException(status);
                    222: }
                    223: 
                    224: 
                    225: //////////////////////////////////////////////////////////////////////////////
                    226: // Create variants for real OLEOBJECTs
                    227: 
                    228: // From clipboard
                    229: BOOL COleClientItem::CanPaste(OLEOPT_RENDER renderopt,
                    230:                OLECLIPFORMAT cfFormat)
                    231: {
                    232:        return ::OleQueryCreateFromClip(lpszStdProtocol,
                    233:                renderopt, cfFormat) == OLE_OK ||
                    234:                ::OleQueryCreateFromClip(lpszStaticProtocol,
                    235:                renderopt, cfFormat) == OLE_OK;
                    236: }
                    237: 
                    238: BOOL COleClientItem::CanPasteLink(OLEOPT_RENDER renderopt,
                    239:                OLECLIPFORMAT cfFormat)
                    240: {
                    241:        return ::OleQueryLinkFromClip(lpszStdProtocol,
                    242:          renderopt, cfFormat) == OLE_OK;
                    243: }
                    244: 
                    245: 
                    246: BOOL COleClientItem::CreateFromClipboard(LPCSTR lpszObjname,
                    247:        OLEOPT_RENDER renderopt, OLECLIPFORMAT cfFormat)
                    248: {
                    249:        ASSERT(m_lpObject == NULL);     // one time only
                    250:        ASSERT(m_pDocument != NULL);
                    251:        ASSERT(m_pDocument->IsOpen());
                    252:        ASSERT(lpszObjname != NULL);
                    253: 
                    254:        return CheckCreate(::OleCreateFromClip(lpszStdProtocol,
                    255:                &m_oleClient, m_pDocument->m_lhClientDoc, lpszObjname,
                    256:                &m_lpObject, renderopt, cfFormat));
                    257: }
                    258: 
                    259: BOOL COleClientItem::CreateStaticFromClipboard(LPCSTR lpszObjname,
                    260:        OLEOPT_RENDER renderopt, OLECLIPFORMAT cfFormat)
                    261: {
                    262:        ASSERT(m_lpObject == NULL);     // one time only
                    263:        ASSERT(m_pDocument != NULL);
                    264:        ASSERT(m_pDocument->IsOpen());
                    265:        ASSERT(lpszObjname != NULL);
                    266: 
                    267:        return CheckCreate(::OleCreateFromClip(lpszStaticProtocol,
                    268:                &m_oleClient, m_pDocument->m_lhClientDoc, lpszObjname,
                    269:                &m_lpObject, renderopt, cfFormat));
                    270: }
                    271: 
                    272: BOOL COleClientItem::CreateLinkFromClipboard(LPCSTR lpszObjname,
                    273:        OLEOPT_RENDER renderopt, OLECLIPFORMAT cfFormat)
                    274: {
                    275:        ASSERT(m_lpObject == NULL);     // one time only
                    276:        ASSERT(m_pDocument != NULL);
                    277:        ASSERT(m_pDocument->IsOpen());
                    278:        ASSERT(lpszObjname != NULL);
                    279: 
                    280:        return CheckCreate(::OleCreateLinkFromClip(lpszStdProtocol,
                    281:                &m_oleClient, m_pDocument->m_lhClientDoc, lpszObjname,
                    282:                &m_lpObject, renderopt, cfFormat));
                    283: }
                    284: 
                    285: 
                    286: // create from a protocol name or other template
                    287: BOOL COleClientItem::CreateNewObject(LPCSTR lpszClass, LPCSTR lpszObjname,
                    288:        OLEOPT_RENDER renderopt, OLECLIPFORMAT cfFormat)
                    289: {
                    290:        ASSERT(m_lpObject == NULL);     // one time only
                    291:        ASSERT(m_pDocument != NULL);
                    292:        ASSERT(m_pDocument->IsOpen());
                    293:        ASSERT(lpszClass != NULL);
                    294:        ASSERT(lpszObjname != NULL);
                    295: 
                    296:        return CheckCreate(::OleCreate(lpszStdProtocol,
                    297:                &m_oleClient, lpszClass,
                    298:                m_pDocument->m_lhClientDoc, lpszObjname,
                    299:                &m_lpObject, renderopt, cfFormat));
                    300: }
                    301: 
                    302: // create invisible
                    303: BOOL COleClientItem::CreateInvisibleObject(LPCSTR lpszClass, LPCSTR lpszObjname,
                    304:        OLEOPT_RENDER renderopt, OLECLIPFORMAT cfFormat, BOOL bActivate)
                    305: {
                    306:        ASSERT(m_lpObject == NULL);     // one time only
                    307:        ASSERT(m_pDocument != NULL);
                    308:        ASSERT(m_pDocument->IsOpen());
                    309:        ASSERT(lpszClass != NULL);
                    310:        ASSERT(lpszObjname != NULL);
                    311: 
                    312:        return CheckCreate(::OleCreateInvisible(lpszStdProtocol,
                    313:                &m_oleClient, lpszClass,
                    314:                m_pDocument->m_lhClientDoc, lpszObjname,
                    315:                &m_lpObject, renderopt, cfFormat, bActivate));
                    316: }
                    317: 
                    318: 
                    319: /////////////////////////////////////////////////////////////////////////////
                    320: // More advanced creation
                    321: 
                    322: BOOL COleClientItem::CreateCloneFrom(COleClientItem* pSrcObject,
                    323:        LPCSTR lpszObjname)
                    324: {
                    325:        ASSERT(m_lpObject == NULL);     // one time only
                    326:        ASSERT(pSrcObject != NULL);
                    327:        ASSERT(m_pDocument != NULL);
                    328:        ASSERT(m_pDocument->IsOpen());
                    329:        ASSERT(lpszObjname != NULL);
                    330: 
                    331:        return CheckCreate(::OleClone(pSrcObject->m_lpObject,
                    332:                &m_oleClient, m_pDocument->m_lhClientDoc, lpszObjname,
                    333:                &m_lpObject));
                    334: }
                    335: 
                    336: 
                    337: /////////////////////////////////////////////////////////////////////////////
                    338: // Default implementations
                    339: 
                    340: int COleClientItem::ClientCallBack(OLE_NOTIFICATION wNotification)
                    341: {
                    342:        switch (wNotification)
                    343:        {
                    344:        case OLE_CHANGED:   // OLE linked item updated
                    345:        case OLE_SAVED:     // OLE server document saved
                    346:        case OLE_CLOSED:    // OLE server document closed
                    347:                OnChange(wNotification);
                    348:                break;
                    349:        case OLE_RENAMED:
                    350:                OnRenamed();
                    351:                break;
                    352:        case OLE_RELEASE:
                    353:                OnRelease();
                    354:                break;
                    355:        default:
                    356:                // ignore it (eg: QueryPaint and QueryRetry)
                    357:                break;
                    358:        }
                    359: 
                    360:        return TRUE;    // return TRUE in general
                    361: }
                    362: 
                    363: void COleClientItem::OnRenamed()
                    364: {
                    365:        // ignore normally
                    366: }
                    367: 
                    368: void COleClientItem::OnRelease()
                    369: {
                    370:        ASSERT(m_lpObject != NULL);
                    371:        // default will store the release error
                    372:        m_lastStatus = ::OleQueryReleaseError(m_lpObject);
                    373:        ASSERT(m_lastStatus != OLE_WAIT_FOR_RELEASE);
                    374: 
                    375:        if (m_lastStatus != OLE_OK)
                    376:        {
                    377:                // operation failed
                    378: #ifdef _DEBUG
                    379:                TRACE("Warning: COleClientItem::OnRelease with error %d ($%lx)\n", m_lastStatus,
                    380:                                m_lpObject);
                    381: #endif
                    382:                return;
                    383:        }
                    384: 
                    385:        // Success
                    386:        OLE_RELEASE_METHOD nWhyReleased = ::OleQueryReleaseMethod(m_lpObject);
                    387: 
                    388:        if (nWhyReleased == OLE_DELETE)
                    389:                m_lpObject = NULL;  // detach
                    390: }
                    391: 
                    392: /////////////////////////////////////////////////////////////////////////////
                    393: // COleClientItem - attributes
                    394: 
                    395: 
                    396: UINT COleClientItem::GetType()
                    397: {
                    398:        ASSERT(m_lpObject != NULL);
                    399:        LONG lType;
                    400: 
                    401:        CheckGeneral(::OleQueryType(m_lpObject, &lType));
                    402:        ASSERT(lType == OT_LINK || lType == OT_EMBEDDED || lType == OT_STATIC);
                    403:        return (UINT)lType;
                    404: }
                    405: 
                    406: 
                    407: CString COleClientItem::GetName()
                    408: {
                    409:        ASSERT(m_lpObject != NULL);
                    410:        char szT[OLE_MAXNAMESIZE];
                    411: 
                    412:        UINT cb = OLE_MAXNAMESIZE;
                    413:        CheckGeneral(::OleQueryName(m_lpObject, szT, &cb));
                    414: 
                    415:        ASSERT(cb == strlen(szT));
                    416:        return CString(szT);
                    417: }
                    418: 
                    419: 
                    420: BOOL COleClientItem::GetSize(LPPOINT lpSize)
                    421: {
                    422:        ASSERT(m_lpObject != NULL);
                    423: 
                    424:        m_lastStatus = ::OleQuerySize(m_lpObject, (DWORD FAR*)lpSize);
                    425:        if (m_lastStatus == OLE_ERROR_BLANK)
                    426:                return FALSE;   // no size set yet
                    427:        CheckGeneral(m_lastStatus);     // may throw exception
                    428:        return TRUE;
                    429: }
                    430: 
                    431: BOOL COleClientItem::GetBounds(LPRECT lpBounds)
                    432: {
                    433:        ASSERT(m_lpObject != NULL);
                    434: 
                    435:        m_lastStatus = ::OleQueryBounds(m_lpObject, lpBounds);
                    436:        if (m_lastStatus == OLE_ERROR_BLANK)
                    437:                return FALSE;   // no size set yet
                    438:        CheckGeneral(m_lastStatus);     // may throw exception
                    439:        return TRUE;
                    440: }
                    441: 
                    442: BOOL COleClientItem::IsOpen()
                    443: {
                    444:        ASSERT(m_lpObject != NULL);
                    445: 
                    446:        m_lastStatus = ::OleQueryOpen(m_lpObject);
                    447:        if (m_lastStatus == OLE_ERROR_NOT_OPEN)
                    448:                return FALSE;       // not open
                    449:        CheckGeneral(m_lastStatus);     // may throw exception
                    450:        return TRUE;
                    451: }
                    452: 
                    453: /////////////////////////////////////////////////////////////////////////////
                    454: // Data exchange plus helpers
                    455: 
                    456: HANDLE
                    457: COleClientItem::GetData(OLECLIPFORMAT nFormat, BOOL& bMustDelete)
                    458: {
                    459:        HANDLE hData = NULL;
                    460: 
                    461:        CheckGeneral(::OleGetData(m_lpObject, nFormat, &hData));
                    462: 
                    463:        ASSERT(hData != NULL);
                    464:        bMustDelete = (m_lastStatus == OLE_WARN_DELETE_DATA);
                    465:        return hData;
                    466: }
                    467: 
                    468: 
                    469: void
                    470: COleClientItem::SetData(OLECLIPFORMAT nFormat, HANDLE hData)
                    471: {
                    472:        ASSERT(m_lpObject != NULL);
                    473:        CheckAsync(::OleSetData(m_lpObject, nFormat, hData));
                    474: }
                    475: 
                    476: void
                    477: COleClientItem::RequestData(OLECLIPFORMAT nFormat)
                    478: {
                    479:        ASSERT(m_lpObject != NULL);
                    480:        CheckAsync(::OleRequestData(m_lpObject, nFormat));
                    481: }
                    482: 
                    483: /////////////////////////////////////////////////////////////////////////////
                    484: // Rare or implementation specific attributes
                    485: 
                    486: BOOL
                    487: COleClientItem::IsEqual(COleClientItem* pObject)
                    488: {
                    489:        ASSERT(m_lpObject != NULL);
                    490:        ASSERT(pObject != NULL);
                    491:        ASSERT(pObject->m_lpObject != NULL);
                    492: 
                    493:        m_lastStatus = ::OleEqual(m_lpObject, pObject->m_lpObject);
                    494:        if (m_lastStatus == OLE_ERROR_NOT_EQUAL)
                    495:                return FALSE;       // FALSE => not equal
                    496:        CheckGeneral(m_lastStatus);     // may throw exception
                    497:        return TRUE;    // otherwise equal
                    498: }
                    499: 
                    500: HANDLE
                    501: COleClientItem::GetLinkFormatData()
                    502: // Return global HANDLE of block containing link information
                    503: //   will return NULL if error or not appropriate type
                    504: //   Both link formats are:  "szClass0szDocument0szItem00" */
                    505: {
                    506:        OLECLIPFORMAT cf = NULL;
                    507: 
                    508:        // first determine the format of the link data
                    509:        switch (GetType())
                    510:        {
                    511:        default:
                    512:                return NULL;    // Static or other (i.e. no link format)
                    513:        case OT_EMBEDDED:
                    514:                cf = (OLECLIPFORMAT)::RegisterClipboardFormat("OwnerLink");
                    515:                break;
                    516:        case OT_LINK:
                    517:                cf = (OLECLIPFORMAT)::RegisterClipboardFormat("ObjectLink");
                    518:                break;
                    519:        }
                    520:        ASSERT(cf != NULL);
                    521: 
                    522:        // now get the link data
                    523:        BOOL bMustDelete;
                    524:        HANDLE h;
                    525:        if ((h = GetData(cf, bMustDelete)) == NULL)
                    526:                return NULL;
                    527:        ASSERT(!bMustDelete);       // must not have to delete clip format data
                    528:        return h;
                    529: }
                    530: 
                    531: 
                    532: /////////////////////////////////////////////////////////////////////////////
                    533: // Special link attributes
                    534: 
                    535: OLEOPT_UPDATE COleClientItem::GetLinkUpdateOptions()
                    536: {
                    537:        ASSERT(m_lpObject != NULL);
                    538:        OLEOPT_UPDATE updateOpt;
                    539: 
                    540:        CheckGeneral(::OleGetLinkUpdateOptions(m_lpObject, &updateOpt));
                    541:        return updateOpt;
                    542: }
                    543: 
                    544: void
                    545: COleClientItem::SetLinkUpdateOptions(OLEOPT_UPDATE updateOpt)
                    546: {
                    547:        ASSERT(m_lpObject != NULL);
                    548: 
                    549:        CheckAsync(::OleSetLinkUpdateOptions(m_lpObject, updateOpt));
                    550: }
                    551: 
                    552: /////////////////////////////////////////////////////////////////////////////
                    553: // COleClientItem - general operations
                    554: 
                    555: BOOL
                    556: COleClientItem::Draw(CDC *pDC, LPRECT lpBounds, LPRECT lpWBounds,
                    557:        CDC* pFormatDC)
                    558: {
                    559:        ASSERT(m_lpObject != NULL);
                    560:        ASSERT(pDC != NULL);
                    561:        // pFormatDC may be null
                    562: 
                    563:        m_lastStatus = ::OleDraw(m_lpObject, pDC->m_hDC, lpBounds,
                    564:           lpWBounds, pFormatDC->GetSafeHdc());
                    565: 
                    566:        if (m_lastStatus == OLE_ERROR_ABORT || m_lastStatus == OLE_ERROR_DRAW ||
                    567:          m_lastStatus == OLE_ERROR_BLANK)
                    568:                return FALSE;       // expected errors
                    569: 
                    570:        CheckGeneral(m_lastStatus);     // may throw exception
                    571:        return TRUE;    // it worked
                    572: }
                    573: 
                    574: void
                    575: COleClientItem::Activate(UINT nVerb, BOOL bShow, BOOL bTakeFocus,
                    576:        CWnd* pWndContainer, LPRECT lpBounds)
                    577: {
                    578:        ASSERT(m_lpObject != NULL);
                    579: 
                    580:        CheckAsync(::OleActivate(m_lpObject, nVerb, bShow,
                    581:                bTakeFocus, pWndContainer->GetSafeHwnd(), lpBounds));
                    582: }
                    583: 
                    584: /////////////////////////////////////////////////////////////////////////////
                    585: // more advanced operations
                    586: 
                    587: void
                    588: COleClientItem::Rename(LPCSTR lpszNewname)
                    589: {
                    590:        ASSERT(m_lpObject != NULL);
                    591:        ASSERT(lpszNewname != NULL);
                    592:        CheckGeneral(::OleRename(m_lpObject, lpszNewname));
                    593: }
                    594: 
                    595: void
                    596: COleClientItem::CopyToClipboard()
                    597: {
                    598:        ASSERT(m_lpObject != NULL);
                    599: 
                    600:        CheckGeneral(::OleCopyToClipboard(m_lpObject));
                    601: }
                    602: 
                    603: void
                    604: COleClientItem::SetTargetDevice(HANDLE hData)
                    605: {
                    606:        ASSERT(m_lpObject != NULL);
                    607:        ASSERT(hData != NULL);
                    608:        CheckAsync(::OleSetTargetDevice(m_lpObject, hData));
                    609: }
                    610: 
                    611: /////////////////////////////////////////////////////////////////////////////
                    612: // Embedded COleClient operations
                    613: 
                    614: void
                    615: COleClientItem::SetHostNames(LPCSTR lpszHost, LPCSTR lpszHostObj)
                    616: {
                    617:        ASSERT(m_lpObject != NULL);
                    618:        ASSERT(lpszHost != NULL);
                    619:        ASSERT(lpszHostObj != NULL);
                    620: 
                    621:        CheckAsync(::OleSetHostNames(m_lpObject, lpszHost, lpszHostObj));
                    622: }
                    623: 
                    624: void
                    625: COleClientItem::SetBounds(LPRECT lpRect)
                    626: {
                    627:        ASSERT(m_lpObject != NULL);
                    628:        CheckAsync(::OleSetBounds(m_lpObject, lpRect));
                    629: }
                    630: 
                    631: void
                    632: COleClientItem::SetColorScheme(LPLOGPALETTE lpLogPalette)
                    633: {
                    634:        ASSERT(m_lpObject != NULL);
                    635:        CheckAsync(::OleSetColorScheme(m_lpObject, lpLogPalette));
                    636: }
                    637: 
                    638: /////////////////////////////////////////////////////////////////////////////
                    639: // Linked COleClient operations
                    640: 
                    641: void
                    642: COleClientItem::UpdateLink()
                    643: {
                    644:        ASSERT(m_lpObject != NULL);
                    645: 
                    646:        CheckAsync(::OleUpdate(m_lpObject));
                    647: }
                    648: 
                    649: void COleClientItem::CloseLink()
                    650: {
                    651:        if (m_lpObject == NULL)
                    652:                return;
                    653: 
                    654:        CheckAsync(::OleClose(m_lpObject));
                    655:        // Does not detach since this can be reactivated later
                    656: }
                    657: 
                    658: void
                    659: COleClientItem::ReconnectLink()
                    660: {
                    661:        ASSERT(m_lpObject != NULL);
                    662:        CheckAsync(::OleReconnect(m_lpObject));
                    663: }
                    664: 
                    665: BOOL COleClientItem::FreezeLink(LPCSTR lpszFrozenName)
                    666: {
                    667:        ASSERT(m_lpObject != NULL);
                    668:        ASSERT(m_pDocument != NULL);
                    669:        ASSERT(m_pDocument->IsOpen());
                    670:        ASSERT(lpszFrozenName != NULL);
                    671: 
                    672:        ASSERT(GetType() == OT_LINK);
                    673: 
                    674:        LPOLEOBJECT lpOriginalObject = m_lpObject;
                    675:        m_lpObject = NULL;
                    676:        if (!CheckCreate(::OleObjectConvert(lpOriginalObject,
                    677:                lpszStaticProtocol,
                    678:                &m_oleClient, m_pDocument->m_lhClientDoc, lpszFrozenName,
                    679:                &m_lpObject)))
                    680:        {
                    681:                m_lpObject = lpOriginalObject;
                    682:                return FALSE;
                    683:        }
                    684:        ASSERT(GetType() == OT_STATIC);
                    685: 
                    686:        // copy from link worked - now get rid of the original
                    687:        ASSERT(m_lpObject != lpOriginalObject);
                    688:        ASSERT(m_lpObject != NULL);
                    689: 
                    690:        LPOLEOBJECT lpNewObject = m_lpObject;
                    691:        m_lpObject = lpOriginalObject;
                    692:        ASSERT(GetType() == OT_LINK);
                    693:        Delete();
                    694: 
                    695:        ASSERT(m_lpObject == NULL);
                    696:        m_lpObject = lpNewObject;
                    697:        ASSERT(GetType() == OT_STATIC);
                    698: 
                    699:        return TRUE;
                    700: }
                    701: 
                    702: /////////////////////////////////////////////////////////////////////////////
                    703: /////////////////////////////////////////////////////////////////////////////
                    704: // _COleStream - implementation class connecting OLESTREAM and CArchive
                    705: 
                    706: struct _COleStream : public _OLESTREAM
                    707: {
                    708:        CArchive*   m_pArchive;
                    709:        _COleStream(CArchive& ar);
                    710: };
                    711: 
                    712: static UINT CalcSize(DWORD cbTotal, const void FAR* lpStart)
                    713: {
                    714:        // return size to read/write (16K max unless limited by segment bounds)
                    715:        DWORD cbThisSeg = 0x10000 - _AFX_FP_OFF(lpStart);
                    716:        DWORD cb = min(cbThisSeg, cbTotal);
                    717:        return (cb > 16384) ? 16384 : (UINT)cb;
                    718: }
                    719: 
                    720: // class for static exports
                    721: struct _afxOleStreamImplementation
                    722: {
                    723:        static DWORD OLEEXPORT
                    724:        Get(LPOLESTREAM lpStream, void FAR* lpBuffer, DWORD dwCount)
                    725:        {
                    726:                register _COleStream* pStream =
                    727:                        (_COleStream*)GetPtrFromFarPtr(lpStream, 0);
                    728:                ASSERT(((LPVOID)pStream) == (LPVOID)lpStream);  // no near/far mismatch
                    729: 
                    730:                DWORD dwToRead = dwCount;
                    731:                while (dwToRead > 0)
                    732:                {
                    733:                        UINT nRead = CalcSize(dwToRead, lpBuffer);
                    734:                        pStream->m_pArchive->Read(lpBuffer, nRead);
                    735:                        dwToRead -= nRead;
                    736:                        lpBuffer = ((BYTE _huge*)lpBuffer) + nRead;
                    737:                }
                    738:                return dwCount;
                    739:        }
                    740: 
                    741:        static DWORD OLEEXPORT
                    742:        Put(LPOLESTREAM lpStream, OLE_CONST void FAR* lpBuffer, DWORD dwCount)
                    743:        {
                    744:                register _COleStream* pStream =
                    745:                        (_COleStream*)GetPtrFromFarPtr(lpStream, 0);
                    746:                ASSERT(((LPVOID)pStream) == (LPVOID)lpStream);  // no near/far mismatch
                    747: 
                    748:                DWORD dwToWrite = dwCount;
                    749:                while (dwToWrite > 0)
                    750:                {
                    751:                        UINT nWrite = CalcSize(dwToWrite, lpBuffer);
                    752:                        pStream->m_pArchive->Write(lpBuffer, nWrite);
                    753:                        dwToWrite -= nWrite;
                    754:                        lpBuffer = ((OLE_CONST BYTE _huge*)lpBuffer) + nWrite;
                    755:                }
                    756:                return dwCount;
                    757:        }
                    758: };
                    759: 
                    760: static struct _OLESTREAMVTBL NEAR streamVtbl =
                    761: {
                    762:        &_afxOleStreamImplementation::Get,
                    763:        &_afxOleStreamImplementation::Put
                    764: };
                    765: 
                    766: _COleStream::_COleStream(CArchive& ar)
                    767: {
                    768:        m_pArchive = &ar;
                    769:        lpstbl = &streamVtbl;           // OLE VTable setup
                    770: }
                    771: 
                    772: /////////////////////////////////////////////////////////////////////////////
                    773: // COleClientItem - serialization
                    774: 
                    775: void COleClientItem::Serialize(CArchive& ar)
                    776: {
                    777:        ASSERT(GetDocument() != NULL);  // must 'SetDocument' first
                    778:        _COleStream oleStream(ar);
                    779: 
                    780:        if (ar.IsStoring())
                    781:        {
                    782:                ASSERT(m_lpObject != NULL);
                    783:                ar << (WORD) GetType();
                    784:                ar << GetName();        // save our document name
                    785: 
                    786:                // Save object
                    787:                CheckGeneral(::OleSaveToStream(m_lpObject, &oleStream));
                    788:        }
                    789:        else
                    790:        {
                    791:                ASSERT(m_lpObject == NULL);
                    792: 
                    793:                WORD nType;
                    794:                ar >> nType;
                    795:                LPCSTR lpszProtocol;
                    796: 
                    797:                if (nType == OT_LINK || nType == OT_EMBEDDED)
                    798:                {
                    799:                        lpszProtocol = lpszStdProtocol;
                    800:                }
                    801:                else if (nType == OT_STATIC)
                    802:                {
                    803:                        lpszProtocol = lpszStaticProtocol;
                    804:                }
                    805:                else
                    806:                {
                    807:                        // unknown type (i.e. bad file format)
                    808:                        AfxThrowOleException(OLE_ERROR_GENERIC);
                    809:                }
                    810: 
                    811:                CString name;
                    812:                ar >> name; // document name
                    813:                if (!CheckCreate(::OleLoadFromStream(&oleStream, lpszProtocol,
                    814:                        &m_oleClient, m_pDocument->m_lhClientDoc, name, &m_lpObject)))
                    815:                {
                    816:                        // throw an exception regardless
                    817:                        AfxThrowOleException(GetLastStatus());
                    818:                }
                    819:        }
                    820: }
                    821: 
                    822: /////////////////////////////////////////////////////////////////////////////
                    823: // COleClientDoc - wrapper for LHCLIENTDOC
                    824: 
                    825: IMPLEMENT_DYNAMIC(COleClientDoc, CObject)
                    826: 
                    827: COleClientDoc::COleClientDoc()
                    828: {
                    829:        m_lhClientDoc = NULL;       // not open
                    830: }
                    831: 
                    832: void
                    833: COleClientDoc::Revoke()
                    834: {
                    835:        if (!IsOpen())
                    836:                return;
                    837:        LHCLIENTDOC lh = m_lhClientDoc;
                    838:        ASSERT(lh != NULL);
                    839:        m_lhClientDoc = NULL;
                    840:        CheckGeneral(::OleRevokeClientDoc(lh));
                    841: }
                    842: 
                    843: COleClientDoc::~COleClientDoc()
                    844: {
                    845:        Revoke();
                    846: }
                    847: 
                    848: void COleClientDoc::CheckGeneral(OLESTATUS status) const
                    849:        // throw exception if not ok to continue
                    850: {
                    851:        ASSERT(status != OLE_WAIT_FOR_RELEASE);
                    852: 
                    853:        if (status == OLE_OK || status > OLE_WARN_DELETE_DATA)
                    854:        {
                    855:                // ok, or just a warning
                    856:                return;
                    857:        }
                    858: 
                    859:        // otherwise this error wasn't expected, so throw an exception
                    860:        TRACE("Warning: COleClientDoc operation failed %d, throwing exception\n", status);
                    861:        AfxThrowOleException(status);
                    862: }
                    863: 
                    864: BOOL
                    865: COleClientDoc::Register(LPCSTR lpszClass, LPCSTR lpszDoc)
                    866: {
                    867:        ASSERT(m_lhClientDoc == NULL);      // one time only
                    868:        return ::OleRegisterClientDoc(lpszClass, lpszDoc,
                    869:                 0L /*reserved*/, &m_lhClientDoc) == OLE_OK;
                    870: }
                    871: 
                    872: void
                    873: COleClientDoc::NotifyRename(LPCSTR lpszNewName)
                    874: {
                    875:        ASSERT(IsOpen());
                    876:        ASSERT(lpszNewName != NULL);
                    877: 
                    878:        CheckGeneral(::OleRenameClientDoc(m_lhClientDoc, lpszNewName));
                    879: }
                    880: 
                    881: void
                    882: COleClientDoc::NotifyRevert()
                    883: {
                    884:        ASSERT(IsOpen());
                    885: 
                    886:        CheckGeneral(::OleRevertClientDoc(m_lhClientDoc));
                    887: }
                    888: 
                    889: void
                    890: COleClientDoc::NotifySaved()
                    891: {
                    892:        ASSERT(IsOpen());
                    893: 
                    894:        CheckGeneral(::OleSavedClientDoc(m_lhClientDoc));
                    895: }
                    896: 
                    897: /////////////////////////////////////////////////////////////////////////////
                    898: // Diagnostics
                    899: 
                    900: #ifdef _DEBUG
                    901: void COleClientItem::AssertValid() const
                    902: {
                    903:        CObject::AssertValid();
                    904:        ASSERT(m_pDocument != NULL);
                    905: }
                    906: 
                    907: void COleClientItem::Dump(CDumpContext& dc) const
                    908: {
                    909:        CObject::Dump(dc);
                    910: 
                    911:        // shallow dump
                    912:        dc << "\n\tm_pDocument = " << (void*) m_pDocument;
                    913:        dc << "\n\tm_lpObject = " << m_lpObject;
                    914:        dc << "\n\tm_lastStatus = " << (int)m_lastStatus;
                    915: }
                    916: 
                    917: 
                    918: void COleClientDoc::AssertValid() const
                    919: {
                    920:        CObject::AssertValid();
                    921:        ASSERT(m_lhClientDoc != NULL);
                    922:                // only valid if truely open
                    923: }
                    924: 
                    925: void COleClientDoc::Dump(CDumpContext& dc) const
                    926: {
                    927:        CObject::Dump(dc);
                    928:        dc << "\n\tm_lhClientDoc = " << m_lhClientDoc;
                    929: }
                    930: 
                    931: #endif //_DEBUG
                    932: 
                    933: 
                    934: /////////////////////////////////////////////////////////////////////////////

unix.superglobalmegacorp.com

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