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

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

unix.superglobalmegacorp.com

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