|
|
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: /////////////////////////////////////////////////////////////////////////////
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.