olesvr2.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 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 related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_OLE4_SEG
  12. #pragma code_seg(AFX_OLE4_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. //////////////////////////////////////////////////////////////////////////////
  20. // COleServerItem implementation
  21. COleServerItem::COleServerItem(COleServerDoc* pServerDoc, BOOL bAutoDelete)
  22. {
  23. if (pServerDoc != NULL)
  24. ASSERT_VALID(pServerDoc);
  25. m_dwRef = 0; // always start in disconnected state
  26. m_bAutoDelete = bAutoDelete;
  27. m_bNeedUnlock = FALSE;
  28. // initially, item does not have an extent
  29. m_sizeExtent.cx = 0;
  30. m_sizeExtent.cy = 0;
  31. // initialize advise holders
  32. m_lpOleAdviseHolder = NULL;
  33. m_lpDataAdviseHolder = NULL;
  34. // add presentation formats to the data source
  35. m_dataSource.m_nGrowBy = 1;
  36. FORMATETC formatEtc;
  37. formatEtc.ptd = NULL;
  38. formatEtc.dwAspect = DVASPECT_CONTENT;
  39. formatEtc.lindex = -1;
  40. // by default, a COleServerItem supports CF_METAFILEPICT
  41. formatEtc.cfFormat = CF_METAFILEPICT;
  42. formatEtc.tymed = TYMED_MFPICT;
  43. m_dataSource.DelayRenderData(0, &formatEtc);
  44. // add item to server document
  45. m_pDocument = NULL;
  46. if (pServerDoc != NULL)
  47. pServerDoc->AddItem(this);
  48. ASSERT(m_pDocument == pServerDoc);
  49. AfxOleLockApp();
  50. }
  51. COleServerItem::~COleServerItem()
  52. {
  53. m_bAutoDelete = FALSE; // no delete during destructor
  54. // release any advise holders
  55. RELEASE(m_lpOleAdviseHolder);
  56. RELEASE(m_lpDataAdviseHolder);
  57. ExternalDisconnect();
  58. // disconnect from the document
  59. COleServerDoc* pDoc = GetDocument();
  60. if (pDoc != NULL)
  61. {
  62. // remove external lock from it
  63. if (m_bNeedUnlock)
  64. {
  65. pDoc->LockExternal(FALSE, TRUE);
  66. m_bNeedUnlock = FALSE;
  67. }
  68. // reset m_pEmbeddedItem if destroying embedded item
  69. if (pDoc->m_pEmbeddedItem == this)
  70. pDoc->m_pEmbeddedItem = NULL;
  71. // remove from list
  72. pDoc->RemoveItem(this);
  73. }
  74. // cleanup any references
  75. AfxOleUnlockApp();
  76. }
  77. BOOL COleServerItem::IsBlank() const
  78. {
  79. // server items are blank in order to keep them from serializing when
  80. // COleDocument::Serialize is called.
  81. return TRUE;
  82. }
  83. BOOL COleServerItem::IsConnected() const
  84. {
  85. // if item is connected in any way, return TRUE
  86. if (m_dwRef != 0)
  87. return TRUE;
  88. // otherwise check if embedded item and document is connected
  89. if (!IsLinkedItem() && GetDocument()->m_lpClientSite != NULL)
  90. return TRUE;
  91. return FALSE; // not connected
  92. }
  93. void COleServerItem::NotifyClient(OLE_NOTIFICATION nCode, DWORD dwParam)
  94. {
  95. switch (nCode)
  96. {
  97. // IDataObject notifications
  98. case OLE_CHANGED:
  99. if (m_lpDataAdviseHolder != NULL)
  100. m_lpDataAdviseHolder->SendOnDataChange(GetDataObject(), dwParam, 0);
  101. break;
  102. // IOleObject notifications
  103. case OLE_SAVED:
  104. if (m_lpOleAdviseHolder != NULL)
  105. m_lpOleAdviseHolder->SendOnSave();
  106. break;
  107. case OLE_CLOSED:
  108. if (m_lpOleAdviseHolder != NULL)
  109. m_lpOleAdviseHolder->SendOnClose();
  110. break;
  111. case OLE_RENAMED:
  112. if (m_lpOleAdviseHolder != NULL)
  113. {
  114. // Note: the moniker should already be updated for this to work
  115. LPMONIKER lpMoniker = (LPMONIKER)dwParam;
  116. m_lpOleAdviseHolder->SendOnRename(lpMoniker);
  117. }
  118. break;
  119. default:
  120. ASSERT(FALSE);
  121. }
  122. }
  123. /////////////////////////////////////////////////////////////////////////////
  124. // Helpers for getting commonly used interfaces through interface map
  125. LPDATAOBJECT COleServerItem::GetDataObject()
  126. {
  127. LPDATAOBJECT lpDataObject =
  128. (LPDATAOBJECT)GetInterface(&IID_IDataObject);
  129. ASSERT(lpDataObject != NULL);
  130. return lpDataObject;
  131. }
  132. LPOLEOBJECT COleServerItem::GetOleObject()
  133. {
  134. LPOLEOBJECT lpOleObject =
  135. (LPOLEOBJECT)GetInterface(&IID_IOleObject);
  136. ASSERT(lpOleObject != NULL);
  137. return lpOleObject;
  138. }
  139. /////////////////////////////////////////////////////////////////////////////
  140. // COleServerItem overrides
  141. BOOL COleServerItem::OnQueryUpdateItems()
  142. {
  143. COleDocument* pDoc = GetDocument();
  144. ASSERT_VALID(pDoc);
  145. // update all of the embedded objects
  146. POSITION pos = pDoc->GetStartPosition();
  147. COleClientItem* pItem;
  148. while ((pItem = pDoc->GetNextClientItem(pos)) != NULL)
  149. {
  150. // if any item is out-of-date, then this item is out-of-date
  151. if (pItem->m_lpObject->IsUpToDate() != NULL)
  152. return TRUE; // update needed
  153. }
  154. return FALSE; // update not needed
  155. }
  156. void COleServerItem::OnUpdateItems()
  157. {
  158. COleDocument* pDoc = GetDocument();
  159. ASSERT_VALID(pDoc);
  160. // update all of the embedded objects
  161. POSITION pos = pDoc->GetStartPosition();
  162. COleClientItem* pItem;
  163. while ((pItem = pDoc->GetNextClientItem(pos)) != NULL)
  164. {
  165. // update any out-of-date item
  166. if (pItem->m_lpObject->IsUpToDate() != NULL)
  167. pItem->m_lpObject->Update();
  168. }
  169. }
  170. BOOL COleServerItem::OnSetExtent(DVASPECT dwDrawAspect, const CSize& size)
  171. {
  172. ASSERT_VALID(this);
  173. if (dwDrawAspect == DVASPECT_CONTENT)
  174. {
  175. m_sizeExtent = size; // simply remember the extent
  176. return TRUE;
  177. }
  178. return FALSE; // not implemented for that dwDrawAspect
  179. }
  180. BOOL COleServerItem::OnGetExtent(DVASPECT /*dwDrawAspect*/, CSize& rSize)
  181. {
  182. ASSERT_VALID(this);
  183. ASSERT(AfxIsValidAddress(&rSize, sizeof(CSize)));
  184. // the default implementation doesn't know what the extent is
  185. rSize.cx = 0;
  186. rSize.cy = 0;
  187. return FALSE;
  188. }
  189. void COleServerItem::OnDoVerb(LONG iVerb)
  190. {
  191. switch (iVerb)
  192. {
  193. // open - maps to OnOpen
  194. case OLEIVERB_OPEN:
  195. case -OLEIVERB_OPEN-1: // allows positive OLEIVERB_OPEN-1 in registry
  196. OnOpen();
  197. break;
  198. // primary, show, and unknown map to OnShow
  199. case OLEIVERB_PRIMARY: // OLEIVERB_PRIMARY is 0 and "Edit" in registry
  200. case OLEIVERB_SHOW:
  201. OnShow();
  202. break;
  203. // hide maps to OnHide
  204. case OLEIVERB_HIDE:
  205. case -OLEIVERB_HIDE-1: // allows positive OLEIVERB_HIDE-1 in registry
  206. OnHide();
  207. break;
  208. default:
  209. // negative verbs not understood should return E_NOTIMPL
  210. if (iVerb < 0)
  211. AfxThrowOleException(E_NOTIMPL);
  212. // positive verb not processed --
  213. // according to OLE spec, primary verb should be executed
  214. // instead.
  215. OnDoVerb(OLEIVERB_PRIMARY);
  216. // also, OLEOBJ_S_INVALIDVERB should be returned.
  217. AfxThrowOleException(OLEOBJ_S_INVALIDVERB);
  218. }
  219. }
  220. BOOL COleServerItem::OnDrawEx(CDC* pDC, DVASPECT nDrawAspect, CSize& rSize)
  221. {
  222. ASSERT_VALID(pDC);
  223. ASSERT(AfxIsValidAddress(&rSize, sizeof(CSize)));
  224. if (nDrawAspect != DVASPECT_CONTENT)
  225. return FALSE;
  226. return OnDraw(pDC, rSize);
  227. }
  228. void COleServerItem::OnShow()
  229. {
  230. ASSERT_VALID(this);
  231. // attempt in place activation (if not supported, fall back on "Open")
  232. COleServerDoc* pDoc = GetDocument();
  233. if (!pDoc->ActivateInPlace())
  234. {
  235. // by default OnShow() maps to OnOpen() if in-place activation
  236. // not supported
  237. OnOpen();
  238. }
  239. }
  240. void COleServerItem::OnOpen()
  241. {
  242. ASSERT_VALID(this);
  243. // default implementation shows the document
  244. COleServerDoc* pDoc = GetDocument();
  245. ASSERT(pDoc != NULL);
  246. pDoc->OnShowDocument(TRUE);
  247. }
  248. void COleServerItem::OnHide()
  249. {
  250. ASSERT_VALID(this);
  251. // default implementation hides the document
  252. COleServerDoc* pDoc = GetDocument();
  253. ASSERT_VALID(pDoc);
  254. pDoc->OnShowDocument(FALSE);
  255. }
  256. BOOL COleServerItem::GetMetafileData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
  257. {
  258. ASSERT_VALID(this);
  259. ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
  260. ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
  261. ASSERT(lpStgMedium->tymed == TYMED_NULL); // GetDataHere not valid
  262. ASSERT(lpStgMedium->pUnkForRelease == NULL);
  263. // medium must be TYMED_MFPICT -- cannot fill in existing HGLOBAL
  264. if (!(lpFormatEtc->tymed & TYMED_MFPICT) || lpStgMedium->hGlobal != NULL)
  265. return FALSE;
  266. // create appropriate memory metafile DC
  267. CMetaFileDC dc;
  268. if (!dc.Create())
  269. return FALSE;
  270. // create attribute DC according to lpFormatEtc->ptd
  271. HDC hAttribDC = _AfxOleCreateDC(lpFormatEtc->ptd);
  272. if (hAttribDC == NULL)
  273. return FALSE;
  274. dc.SetAttribDC(hAttribDC);
  275. // Paint directly into the metafile.
  276. CSize size(0, 0);
  277. BOOL bResult = OnDrawEx(&dc, (DVASPECT)lpFormatEtc->dwAspect, size);
  278. // attribute DC is no longer necessary
  279. dc.SetAttribDC(NULL);
  280. ::DeleteDC(hAttribDC);
  281. if (!bResult)
  282. {
  283. #ifdef _DEBUG
  284. if (afxTraceFlags & traceOle)
  285. TRACE0("calling COleServerItem::OnDrawEx()failed.\n");
  286. #endif
  287. return FALSE;
  288. }
  289. HMETAFILE hMF = dc.Close();
  290. if (hMF == NULL)
  291. return FALSE;
  292. HGLOBAL hPict;
  293. if ((hPict =
  294. ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, sizeof(METAFILEPICT))) == NULL)
  295. {
  296. DeleteMetaFile(hMF);
  297. return FALSE;
  298. }
  299. LPMETAFILEPICT lpPict;
  300. if ((lpPict = (LPMETAFILEPICT)::GlobalLock(hPict)) == NULL)
  301. {
  302. DeleteMetaFile(hMF);
  303. ::GlobalFree(hPict);
  304. return FALSE;
  305. }
  306. // set the metafile size
  307. lpPict->mm = MM_ANISOTROPIC;
  308. lpPict->hMF = hMF;
  309. if (size.cx == 0 && size.cy == 0 &&
  310. !OnGetExtent((DVASPECT)lpFormatEtc->dwAspect, size))
  311. {
  312. TRACE0("Warning: OnGetExtent failed during OnDrawEx --\n");
  313. TRACE0("\tpresentation metafile may be badly formed!\n");
  314. }
  315. lpPict->xExt = size.cx;
  316. lpPict->yExt = size.cy; // HIMETRIC height
  317. if (lpPict->yExt < 0)
  318. {
  319. TRACE0("Warning: HIMETRIC natural size is negative.\n");
  320. lpPict->yExt = -lpPict->yExt; // backward compatibility fix
  321. }
  322. #ifdef _DEBUG
  323. if (lpPict->xExt == 0 || lpPict->yExt == 0)
  324. {
  325. // usually the natural extent is set to something interesting
  326. TRACE0("Warning: COleServerItem has no natural size --\n");
  327. TRACE0("\twill not work with some apps like MS Write.\n");
  328. }
  329. #endif
  330. // return the medium with the hGlobal to the METAFILEPICT
  331. ::GlobalUnlock(hPict);
  332. lpStgMedium->hGlobal = hPict;
  333. lpStgMedium->tymed = TYMED_MFPICT;
  334. return TRUE;
  335. }
  336. BOOL COleServerItem::OnSetColorScheme(const LOGPALETTE* /*lpLogPalette*/)
  337. {
  338. ASSERT_VALID(this);
  339. return FALSE; // default does nothing
  340. }
  341. BOOL COleServerItem::OnInitFromData(
  342. COleDataObject* /*pDataObject*/, BOOL /*bCreation*/)
  343. {
  344. ASSERT_VALID(this);
  345. AfxThrowOleException(E_NOTIMPL);
  346. return FALSE;
  347. }
  348. void COleServerItem::CopyToClipboard(BOOL bIncludeLink)
  349. {
  350. ASSERT_VALID(this);
  351. COleDataSource* pDataSource = OnGetClipboardData(bIncludeLink, NULL, NULL);
  352. // put it on the clipboard
  353. pDataSource->SetClipboard();
  354. }
  355. COleDataSource* COleServerItem::OnGetClipboardData(BOOL bIncludeLink,
  356. LPPOINT lpOffset, LPSIZE lpSize)
  357. {
  358. ASSERT_VALID(this);
  359. COleDataSource* pDataSource = new COleDataSource;
  360. TRY
  361. {
  362. GetClipboardData(pDataSource, bIncludeLink, lpOffset, lpSize);
  363. }
  364. CATCH_ALL(e)
  365. {
  366. delete pDataSource;
  367. THROW_LAST();
  368. }
  369. END_CATCH_ALL
  370. ASSERT_VALID(pDataSource);
  371. return pDataSource;
  372. }
  373. DROPEFFECT COleServerItem::DoDragDrop(LPCRECT lpItemRect, CPoint ptOffset,
  374. BOOL bIncludeLink, DWORD dwEffects, LPCRECT lpRectStartDrag)
  375. {
  376. ASSERT(AfxIsValidAddress(lpItemRect, sizeof(RECT)));
  377. ASSERT_VALID(this);
  378. ASSERT_VALID(this);
  379. DROPEFFECT dropEffect = DROPEFFECT_NONE;
  380. COleDataSource *pDataSource = NULL;
  381. TRY
  382. {
  383. // get clipboard data for this item
  384. CSize sizeItem(
  385. lpItemRect->right - lpItemRect->left,
  386. lpItemRect->bottom - lpItemRect->top);
  387. pDataSource = OnGetClipboardData(bIncludeLink, &ptOffset, &sizeItem);
  388. // add DROPEFFECT_LINK if link source is available
  389. LPDATAOBJECT lpDataObject = (LPDATAOBJECT)
  390. pDataSource->GetInterface(&IID_IDataObject);
  391. ASSERT(lpDataObject != NULL);
  392. FORMATETC formatEtc;
  393. formatEtc.cfFormat = (CLIPFORMAT)_oleData.cfLinkSource;
  394. formatEtc.ptd = NULL;
  395. formatEtc.dwAspect = DVASPECT_CONTENT;
  396. formatEtc.lindex = -1;
  397. formatEtc.tymed = (DWORD) -1;
  398. if (lpDataObject->QueryGetData(&formatEtc) == S_OK)
  399. dwEffects |= DROPEFFECT_LINK;
  400. // calculate default sensitivity rectangle
  401. CRect rectDrag;
  402. if (lpRectStartDrag == NULL)
  403. {
  404. rectDrag.SetRect(lpItemRect->left, lpItemRect->top, lpItemRect->left,
  405. lpItemRect->top);
  406. lpRectStartDrag = &rectDrag;
  407. }
  408. // do drag drop operation
  409. dropEffect = pDataSource->DoDragDrop(dwEffects, lpRectStartDrag);
  410. pDataSource->InternalRelease();
  411. }
  412. CATCH_ALL(e)
  413. {
  414. if (pDataSource != NULL)
  415. pDataSource->InternalRelease();
  416. THROW_LAST();
  417. }
  418. END_CATCH_ALL
  419. return dropEffect;
  420. }
  421. void COleServerItem::GetClipboardData(COleDataSource* pDataSource,
  422. BOOL bIncludeLink, LPPOINT lpOffset, LPSIZE lpSize)
  423. {
  424. ASSERT_VALID(this);
  425. ASSERT_VALID(pDataSource);
  426. ASSERT(lpOffset == NULL ||
  427. AfxIsValidAddress(lpOffset, sizeof(POINT), FALSE));
  428. // add CF_EMBEDDEDOBJECT by creating memory storage copy of the object
  429. STGMEDIUM stgMedium;
  430. GetEmbedSourceData(&stgMedium);
  431. pDataSource->CacheData((CLIPFORMAT)_oleData.cfEmbedSource, &stgMedium);
  432. // add CF_OBJECTDESCRIPTOR
  433. GetObjectDescriptorData(lpOffset, lpSize, &stgMedium);
  434. pDataSource->CacheData((CLIPFORMAT)_oleData.cfObjectDescriptor,
  435. &stgMedium);
  436. // add any presentation entries/conversion formats that the item
  437. // can produce.
  438. AddOtherClipboardData(pDataSource);
  439. // add CF_LINKSOURCE if supporting links to pseudo objects
  440. if (bIncludeLink && GetLinkSourceData(&stgMedium))
  441. {
  442. pDataSource->CacheData((CLIPFORMAT)_oleData.cfLinkSource, &stgMedium);
  443. // add CF_LINKSOURCEDESCRIPTOR
  444. GetObjectDescriptorData(lpOffset, lpSize, &stgMedium);
  445. pDataSource->CacheData((CLIPFORMAT)_oleData.cfLinkSourceDescriptor,
  446. &stgMedium);
  447. }
  448. }
  449. void COleServerItem::GetEmbedSourceData(LPSTGMEDIUM lpStgMedium)
  450. {
  451. ASSERT_VALID(this);
  452. ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
  453. LPLOCKBYTES lpLockBytes;
  454. SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
  455. if (sc != S_OK)
  456. AfxThrowOleException(sc);
  457. ASSERT(lpLockBytes != NULL);
  458. LPSTORAGE lpStorage;
  459. sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
  460. STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &lpStorage);
  461. if (sc != S_OK)
  462. {
  463. VERIFY(lpLockBytes->Release() == 0);
  464. AfxThrowOleException(sc);
  465. }
  466. ASSERT(lpStorage != NULL);
  467. // setup for save copy as
  468. COleServerDoc* pDoc = GetDocument();
  469. pDoc->m_bSameAsLoad = FALSE;
  470. pDoc->m_bRemember = FALSE;
  471. TRY
  472. {
  473. OnSaveEmbedding(lpStorage);
  474. pDoc->CommitItems(FALSE);
  475. }
  476. CATCH_ALL(e)
  477. {
  478. // release storage and lock bytes
  479. VERIFY(lpStorage->Release() == 0);
  480. VERIFY(lpLockBytes->Release() == 0);
  481. pDoc->m_bSameAsLoad = TRUE;
  482. pDoc->m_bRemember = TRUE;
  483. THROW_LAST();
  484. }
  485. END_CATCH_ALL
  486. pDoc->m_bSameAsLoad = TRUE;
  487. pDoc->m_bRemember = TRUE;
  488. lpLockBytes->Release();
  489. // add it to the data source
  490. lpStgMedium->tymed = TYMED_ISTORAGE;
  491. lpStgMedium->pstg = lpStorage;
  492. lpStgMedium->pUnkForRelease = NULL;
  493. }
  494. void COleServerItem::AddOtherClipboardData(COleDataSource* pDataSource)
  495. {
  496. ASSERT_VALID(this);
  497. ASSERT_VALID(pDataSource);
  498. // get IEnumFORMATETC interface for the IDataObject
  499. LPDATAOBJECT lpDataObject = GetDataObject();
  500. LPENUMFORMATETC lpEnumFORMATETC;
  501. if (lpDataObject->EnumFormatEtc(DATADIR_GET, &lpEnumFORMATETC) != S_OK)
  502. return;
  503. ASSERT(lpEnumFORMATETC != NULL);
  504. // get all formats that the object will give us
  505. FORMATETC formatEtc;
  506. while (lpEnumFORMATETC->Next(1, &formatEtc, NULL) == S_OK)
  507. {
  508. STGMEDIUM stgMedium;
  509. if (lpDataObject->GetData(&formatEtc, &stgMedium) != S_OK)
  510. {
  511. // data is not available
  512. CoTaskMemFree(formatEtc.ptd);
  513. }
  514. else if (stgMedium.pUnkForRelease != NULL)
  515. {
  516. // don't cache data with pUnkForRelease != NULL
  517. ::ReleaseStgMedium(&stgMedium);
  518. CoTaskMemFree(formatEtc.ptd);
  519. }
  520. else
  521. {
  522. // cache the data (now we own the stgMedium)
  523. pDataSource->CacheData(0, &stgMedium, &formatEtc);
  524. }
  525. }
  526. // cleanup
  527. lpEnumFORMATETC->Release();
  528. }
  529. LPMONIKER COleServerItem::GetMoniker(OLEGETMONIKER nAssign)
  530. {
  531. // get IOleObject interface for this item
  532. LPOLEOBJECT lpOleObject = GetOleObject();
  533. ASSERT(lpOleObject != NULL);
  534. // get moniker from OLE object
  535. LPMONIKER lpMoniker = NULL;
  536. lpOleObject->GetMoniker(nAssign, OLEWHICHMK_OBJFULL, &lpMoniker);
  537. return lpMoniker;
  538. }
  539. BOOL COleServerItem::GetLinkSourceData(LPSTGMEDIUM lpStgMedium)
  540. {
  541. ASSERT_VALID(this);
  542. ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
  543. LPOLEOBJECT lpOleObject = GetOleObject();
  544. ASSERT(lpOleObject != NULL);
  545. // get moniker from ole object
  546. LPMONIKER lpMoniker;
  547. SCODE sc = lpOleObject->GetMoniker(OLEGETMONIKER_TEMPFORUSER,
  548. OLEWHICHMK_OBJFULL, &lpMoniker);
  549. if (sc != S_OK)
  550. {
  551. TRACE0("Warning: unable to get moniker for object.\n");
  552. return FALSE;
  553. }
  554. ASSERT(lpMoniker != NULL);
  555. // create a memory based stream to write the moniker to
  556. LPSTREAM lpStream;
  557. if (::CreateStreamOnHGlobal(NULL, TRUE, &lpStream) != S_OK)
  558. {
  559. lpMoniker->Release();
  560. AfxThrowMemoryException();
  561. }
  562. ASSERT(lpStream != NULL);
  563. // write the moniker to the stream, and add it to the clipboard
  564. sc = ::OleSaveToStream(lpMoniker, lpStream);
  565. lpMoniker->Release();
  566. if (sc != S_OK)
  567. {
  568. lpStream->Release();
  569. AfxThrowOleException(sc);
  570. }
  571. // write the class ID of the document to the stream as well
  572. COleLinkingDoc* pDoc = GetDocument();
  573. ASSERT(pDoc->m_pFactory != NULL);
  574. sc = WriteClassStm(lpStream, pDoc->m_pFactory->GetClassID());
  575. if (sc != S_OK)
  576. {
  577. lpStream->Release();
  578. AfxThrowOleException(sc);
  579. }
  580. // setup the STGMEDIUM
  581. lpStgMedium->tymed = TYMED_ISTREAM;
  582. lpStgMedium->pstm = lpStream;
  583. lpStgMedium->pUnkForRelease = NULL;
  584. return TRUE;
  585. }
  586. void COleServerItem::GetObjectDescriptorData(
  587. LPPOINT lpOffset, LPSIZE lpSize, LPSTGMEDIUM lpStgMedium)
  588. {
  589. ASSERT_VALID(this);
  590. ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
  591. ASSERT(lpOffset == NULL ||
  592. AfxIsValidAddress(lpOffset, sizeof(POINT), FALSE));
  593. LPOLEOBJECT lpOleObject = GetOleObject();
  594. ASSERT(lpOleObject != NULL);
  595. // get the object descriptor for the IOleObject
  596. POINTL pointl = { 0, 0 };
  597. if (lpOffset != NULL)
  598. {
  599. CSize ptOffset(lpOffset->x, lpOffset->y);
  600. ((CDC*)NULL)->DPtoHIMETRIC(&ptOffset);
  601. pointl.x = ptOffset.cx;
  602. pointl.y = ptOffset.cy;
  603. }
  604. SIZEL sizel;
  605. if (lpSize != NULL)
  606. {
  607. sizel.cx = lpSize->cx;
  608. sizel.cy = lpSize->cy;
  609. ((CDC*)NULL)->DPtoHIMETRIC(&sizel);
  610. }
  611. else
  612. {
  613. sizel.cx = 0;
  614. sizel.cy = 0;
  615. }
  616. InterlockedIncrement(&m_dwRef); // protect against destruction during this call
  617. HGLOBAL hGlobal = _AfxOleGetObjectDescriptorData(
  618. lpOleObject, NULL, DVASPECT_CONTENT, pointl, &sizel);
  619. InterlockedDecrement(&m_dwRef);
  620. if (hGlobal == NULL)
  621. AfxThrowMemoryException();
  622. // setup the STGMEDIUM
  623. lpStgMedium->tymed = TYMED_HGLOBAL;
  624. lpStgMedium->hGlobal = hGlobal;
  625. lpStgMedium->pUnkForRelease = NULL;
  626. }
  627. void COleServerItem::OnSaveEmbedding(LPSTORAGE lpStorage)
  628. {
  629. ASSERT(lpStorage != NULL);
  630. // always (logically) a "File.Save Copy As" operation
  631. COleServerDoc* pDoc = GetDocument();
  632. LPSTORAGE lpOrigStg = pDoc->m_lpRootStg;
  633. pDoc->m_lpRootStg = lpStorage;
  634. TRY
  635. {
  636. ASSERT(pDoc->m_lpRootStg != NULL);
  637. pDoc->SaveToStorage(this); // use helper to serialize to storage
  638. }
  639. CATCH_ALL(e)
  640. {
  641. // save as failed: re-attach original storage
  642. pDoc->m_lpRootStg = lpOrigStg;
  643. THROW_LAST();
  644. }
  645. END_CATCH_ALL
  646. // re-attach original storage
  647. pDoc->m_lpRootStg = lpOrigStg;
  648. }
  649. /////////////////////////////////////////////////////////////////////////////
  650. // COleServerItem data-object callback default implementation
  651. BOOL COleServerItem::OnRenderGlobalData(
  652. LPFORMATETC /*lpFormatEtc*/, HGLOBAL* /*phGlobal*/)
  653. {
  654. ASSERT_VALID(this);
  655. return FALSE; // default does nothing
  656. }
  657. BOOL COleServerItem::OnRenderFileData(
  658. LPFORMATETC /*lpFormatEtc*/, CFile* /*pFile*/)
  659. {
  660. ASSERT_VALID(this);
  661. return FALSE; // default does nothing
  662. }
  663. BOOL COleServerItem::OnRenderData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
  664. {
  665. ASSERT_VALID(this);
  666. ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
  667. ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
  668. // default implementation does not support extended layout
  669. if (lpFormatEtc->lindex != -1)
  670. return FALSE;
  671. // default implementation supports both types of metafiles
  672. if (lpFormatEtc->cfFormat == CF_METAFILEPICT)
  673. return GetMetafileData(lpFormatEtc, lpStgMedium);
  674. return FALSE; // cfFormat not supported
  675. }
  676. BOOL COleServerItem::OnSetData(
  677. LPFORMATETC /*lpFormatEtc*/, LPSTGMEDIUM /*lpStgMedium*/, BOOL /*bRelease*/)
  678. {
  679. ASSERT_VALID(this);
  680. return FALSE; // default does nothing
  681. }
  682. /////////////////////////////////////////////////////////////////////////////
  683. // COleServerItem OLE interface implementation
  684. BEGIN_INTERFACE_MAP(COleServerItem, CDocItem)
  685. INTERFACE_PART(COleServerItem, IID_IOleObject, OleObject)
  686. INTERFACE_PART(COleServerItem, IID_IDataObject, DataObject)
  687. END_INTERFACE_MAP()
  688. /////////////////////////////////////////////////////////////////////////////
  689. // COleServerItem::XOleObject
  690. STDMETHODIMP_(ULONG) COleServerItem::XOleObject::AddRef()
  691. {
  692. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  693. return pThis->ExternalAddRef();
  694. }
  695. STDMETHODIMP_(ULONG) COleServerItem::XOleObject::Release()
  696. {
  697. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  698. return pThis->ExternalRelease();
  699. }
  700. STDMETHODIMP COleServerItem::XOleObject::QueryInterface(
  701. REFIID iid, LPVOID* ppvObj)
  702. {
  703. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  704. return pThis->ExternalQueryInterface(&iid, ppvObj);
  705. }
  706. // COleServerItem has special Release semantics. In particular, the item
  707. // is only deleted from memory if m_bAutoDelete is TRUE.
  708. // Also, it unlocks the document if the reference count reaches zero.
  709. void COleServerItem::OnFinalRelease()
  710. {
  711. ASSERT_VALID(this);
  712. COleServerDoc* pDoc = GetDocument();
  713. ASSERT_VALID(pDoc);
  714. pDoc->InternalAddRef(); // make document stable
  715. // if connected to a document -- remove external lock from it
  716. if (m_bNeedUnlock)
  717. {
  718. pDoc->LockExternal(FALSE, TRUE);
  719. m_bNeedUnlock = FALSE;
  720. }
  721. // delete this item if no longer needed
  722. if (m_bAutoDelete)
  723. delete this;
  724. // release artificial reference (may destroy the document)
  725. pDoc->InternalRelease();
  726. }
  727. STDMETHODIMP COleServerItem::XOleObject::SetClientSite(
  728. LPOLECLIENTSITE /*pClientSite*/)
  729. {
  730. // linked objects do not support SetClientSite
  731. return E_NOTIMPL;
  732. }
  733. STDMETHODIMP COleServerItem::XOleObject::GetClientSite(
  734. LPOLECLIENTSITE* ppClientSite)
  735. {
  736. // linked objects do not support GetClientSite
  737. *ppClientSite = NULL;
  738. return E_NOTIMPL;
  739. }
  740. STDMETHODIMP COleServerItem::XOleObject::SetHostNames(
  741. LPCOLESTR /*szContainerApp*/, LPCOLESTR /*szContainerObj*/)
  742. {
  743. // linked objects do not support SetHostNames
  744. return E_NOTIMPL;
  745. }
  746. STDMETHODIMP COleServerItem::XOleObject::Close(DWORD /*dwSaveOption*/)
  747. {
  748. // linked objects do not support close
  749. return E_NOTIMPL;
  750. }
  751. STDMETHODIMP COleServerItem::XOleObject::SetMoniker(
  752. DWORD /*dwWhichMoniker*/, LPMONIKER /*pmk*/)
  753. {
  754. // linked objects do not support SetMoniker
  755. return E_NOTIMPL;
  756. }
  757. STDMETHODIMP COleServerItem::XOleObject::GetMoniker(
  758. DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMoniker)
  759. {
  760. USES_CONVERSION;
  761. METHOD_PROLOGUE_EX(COleServerItem, OleObject)
  762. ASSERT_VALID(pThis);
  763. COleServerDoc* pDoc = pThis->GetDocument();
  764. ASSERT_VALID(pDoc);
  765. ASSERT_KINDOF(COleServerDoc, pDoc);
  766. ASSERT(ppMoniker != NULL);
  767. *ppMoniker = NULL;
  768. switch (dwWhichMoniker)
  769. {
  770. case OLEWHICHMK_CONTAINER:
  771. // simply return the moniker of the container document
  772. *ppMoniker = pDoc->GetMoniker((OLEGETMONIKER)dwAssign);
  773. break;
  774. case OLEWHICHMK_OBJREL:
  775. {
  776. // no relative moniker if no item name
  777. if (pThis->m_strItemName.IsEmpty())
  778. break;
  779. // don't return relative moniker if no document moniker
  780. LPMONIKER lpMoniker = pDoc->GetMoniker((OLEGETMONIKER)dwAssign);
  781. if (lpMoniker == NULL)
  782. break;
  783. lpMoniker->Release(); // don't need document moniker
  784. // relative monikers have to handle assignment correctly
  785. switch (dwAssign)
  786. {
  787. case OLEGETMONIKER_TEMPFORUSER:
  788. case OLEGETMONIKER_ONLYIFTHERE:
  789. case OLEGETMONIKER_FORCEASSIGN:
  790. // create item moniker from name
  791. CreateItemMoniker(OLESTDDELIMOLE, T2COLE(pThis->m_strItemName),
  792. ppMoniker);
  793. break;
  794. case OLEGETMONIKER_UNASSIGN:
  795. ASSERT(FALSE); // should never get UNASSIGN
  796. break;
  797. }
  798. }
  799. break;
  800. case OLEWHICHMK_OBJFULL:
  801. {
  802. // get each sub-moniker: item & document
  803. LPMONIKER lpMoniker1, lpMoniker2;
  804. GetMoniker(dwAssign, OLEWHICHMK_CONTAINER, &lpMoniker1);
  805. GetMoniker(dwAssign, OLEWHICHMK_OBJREL, &lpMoniker2);
  806. if (lpMoniker1 != NULL && lpMoniker2 != NULL)
  807. {
  808. // create composite from two parts
  809. ::CreateGenericComposite(lpMoniker1, lpMoniker2, ppMoniker);
  810. }
  811. else if (lpMoniker1 != NULL)
  812. {
  813. // just use container moniker
  814. *ppMoniker = lpMoniker1;
  815. lpMoniker1 = NULL;
  816. }
  817. // release sub-monikers
  818. RELEASE(lpMoniker1);
  819. RELEASE(lpMoniker2);
  820. }
  821. break;
  822. }
  823. return *ppMoniker == NULL ? E_FAIL : S_OK;
  824. }
  825. STDMETHODIMP COleServerItem::XOleObject::InitFromData(
  826. LPDATAOBJECT /*pDataObject*/, BOOL /*fCreation*/, DWORD /*dwReserved*/)
  827. {
  828. // linked objects do not support InitFromData
  829. return E_NOTIMPL;
  830. }
  831. STDMETHODIMP COleServerItem::XOleObject::GetClipboardData(
  832. DWORD /*dwReserved*/, LPDATAOBJECT* ppDataObject)
  833. {
  834. METHOD_PROLOGUE_EX(COleServerItem, OleObject)
  835. ASSERT_VALID(pThis);
  836. *ppDataObject = NULL;
  837. SCODE sc;
  838. TRY
  839. {
  840. COleDataSource* pDataSource = pThis->OnGetClipboardData(TRUE, NULL, NULL);
  841. ASSERT(pDataSource != NULL);
  842. *ppDataObject =
  843. (LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);
  844. ASSERT(*ppDataObject != NULL);
  845. sc = S_OK;
  846. }
  847. CATCH_ALL(e)
  848. {
  849. sc = COleException::Process(e);
  850. DELETE_EXCEPTION(e);
  851. }
  852. END_CATCH_ALL
  853. return sc;
  854. }
  855. STDMETHODIMP COleServerItem::XOleObject::DoVerb(
  856. LONG iVerb, LPMSG /*lpmsg*/, LPOLECLIENTSITE /*pActiveSite*/, LONG /*lindex*/,
  857. HWND /*hwndParent*/, LPCRECT /*lpPosRect*/)
  858. {
  859. METHOD_PROLOGUE_EX(COleServerItem, OleObject)
  860. ASSERT_VALID(pThis);
  861. pThis->InternalAddRef(); // protect this object
  862. SCODE sc;
  863. TRY
  864. {
  865. pThis->OnDoVerb(iVerb);
  866. sc = S_OK;
  867. }
  868. CATCH_ALL(e)
  869. {
  870. sc = COleException::Process(e);
  871. DELETE_EXCEPTION(e);
  872. }
  873. END_CATCH_ALL
  874. pThis->InternalRelease(); // may 'delete this'
  875. return sc;
  876. }
  877. STDMETHODIMP COleServerItem::XOleObject::EnumVerbs(
  878. IEnumOLEVERB** ppenumOleVerb)
  879. {
  880. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  881. *ppenumOleVerb = NULL;
  882. CLSID clsid;
  883. pThis->GetOleObject()->GetUserClassID(&clsid);
  884. return OleRegEnumVerbs(clsid, ppenumOleVerb);
  885. }
  886. STDMETHODIMP COleServerItem::XOleObject::Update()
  887. {
  888. METHOD_PROLOGUE_EX(COleServerItem, OleObject)
  889. ASSERT_VALID(pThis);
  890. SCODE sc;
  891. TRY
  892. {
  893. pThis->OnUpdateItems();
  894. sc = S_OK;
  895. }
  896. CATCH_ALL(e)
  897. {
  898. sc = COleException::Process(e);
  899. DELETE_EXCEPTION(e);
  900. }
  901. END_CATCH_ALL
  902. return sc;
  903. }
  904. STDMETHODIMP COleServerItem::XOleObject::IsUpToDate()
  905. {
  906. METHOD_PROLOGUE_EX(COleServerItem, OleObject)
  907. ASSERT_VALID(pThis);
  908. SCODE sc;
  909. TRY
  910. {
  911. sc = pThis->OnQueryUpdateItems() ? S_FALSE : S_OK;
  912. }
  913. CATCH_ALL(e)
  914. {
  915. sc = COleException::Process(e);
  916. DELETE_EXCEPTION(e);
  917. }
  918. END_CATCH_ALL
  919. return sc;
  920. }
  921. STDMETHODIMP COleServerItem::XOleObject::GetUserClassID(CLSID* pClsid)
  922. {
  923. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  924. COleServerDoc* pDoc = pThis->GetDocument();
  925. return pDoc->m_xPersistFile.GetClassID(pClsid);
  926. }
  927. STDMETHODIMP COleServerItem::XOleObject::GetUserType(
  928. DWORD dwFormOfType, LPOLESTR* ppszUserType)
  929. {
  930. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  931. *ppszUserType = NULL;
  932. CLSID clsid;
  933. pThis->GetOleObject()->GetUserClassID(&clsid);
  934. return OleRegGetUserType(clsid, dwFormOfType, ppszUserType);
  935. }
  936. STDMETHODIMP COleServerItem::XOleObject::SetExtent(
  937. DWORD /*dwDrawAspect*/, LPSIZEL /*lpsizel*/)
  938. {
  939. // linked objects do not support SetExtent
  940. return E_FAIL;
  941. }
  942. STDMETHODIMP COleServerItem::XOleObject::GetExtent(
  943. DWORD dwDrawAspect, LPSIZEL lpsizel)
  944. {
  945. METHOD_PROLOGUE_EX(COleServerItem, OleObject)
  946. ASSERT_VALID(pThis);
  947. SCODE sc = E_INVALIDARG;
  948. TRY
  949. {
  950. // call to get regular windows size
  951. CSize size;
  952. if (pThis->OnGetExtent((DVASPECT)dwDrawAspect, size))
  953. {
  954. if (size.cy < 0)
  955. size.cy = -size.cy; // extents are always positive
  956. lpsizel->cx = size.cx;
  957. lpsizel->cy = size.cy;
  958. sc = S_OK;
  959. }
  960. }
  961. CATCH_ALL(e)
  962. {
  963. sc = COleException::Process(e);
  964. DELETE_EXCEPTION(e);
  965. }
  966. END_CATCH_ALL
  967. return sc;
  968. }
  969. STDMETHODIMP COleServerItem::XOleObject::Advise(
  970. IAdviseSink* pAdvSink, DWORD* pdwConnection)
  971. {
  972. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  973. *pdwConnection = 0;
  974. if (pThis->m_lpOleAdviseHolder == NULL &&
  975. ::CreateOleAdviseHolder(&pThis->m_lpOleAdviseHolder) != S_OK)
  976. {
  977. return E_OUTOFMEMORY;
  978. }
  979. ASSERT(pThis->m_lpOleAdviseHolder != NULL);
  980. return pThis->m_lpOleAdviseHolder->Advise(pAdvSink, pdwConnection);
  981. }
  982. STDMETHODIMP COleServerItem::XOleObject::Unadvise(DWORD dwConnection)
  983. {
  984. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  985. if (pThis->m_lpOleAdviseHolder == NULL)
  986. return E_FAIL;
  987. ASSERT(pThis->m_lpOleAdviseHolder != NULL);
  988. return pThis->m_lpOleAdviseHolder->Unadvise(dwConnection);
  989. }
  990. STDMETHODIMP COleServerItem::XOleObject::EnumAdvise(
  991. LPENUMSTATDATA* ppenumAdvise)
  992. {
  993. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  994. *ppenumAdvise = NULL;
  995. if (pThis->m_lpOleAdviseHolder == NULL)
  996. return E_FAIL;
  997. ASSERT(pThis->m_lpOleAdviseHolder != NULL);
  998. return pThis->m_lpOleAdviseHolder->EnumAdvise(ppenumAdvise);
  999. }
  1000. STDMETHODIMP COleServerItem::XOleObject::GetMiscStatus(
  1001. DWORD dwAspect, DWORD* pdwStatus)
  1002. {
  1003. METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
  1004. *pdwStatus = 0;
  1005. CLSID clsid;
  1006. pThis->GetOleObject()->GetUserClassID(&clsid);
  1007. return OleRegGetMiscStatus(clsid, dwAspect, pdwStatus);
  1008. }
  1009. STDMETHODIMP COleServerItem::XOleObject::SetColorScheme(LPLOGPALETTE lpLogpal)
  1010. {
  1011. METHOD_PROLOGUE_EX(COleServerItem, OleObject)
  1012. ASSERT_VALID(pThis);
  1013. SCODE sc = E_NOTIMPL;
  1014. TRY
  1015. {
  1016. // delegate to embedded item
  1017. if (pThis->OnSetColorScheme(lpLogpal))
  1018. sc = S_OK;
  1019. }
  1020. END_TRY
  1021. return sc;
  1022. }
  1023. /////////////////////////////////////////////////////////////////////////////
  1024. // COleServerItem::XDataObject
  1025. STDMETHODIMP_(ULONG) COleServerItem::XDataObject::AddRef()
  1026. {
  1027. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1028. return pThis->ExternalAddRef();
  1029. }
  1030. STDMETHODIMP_(ULONG) COleServerItem::XDataObject::Release()
  1031. {
  1032. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1033. return pThis->ExternalRelease();
  1034. }
  1035. STDMETHODIMP COleServerItem::XDataObject::QueryInterface(
  1036. REFIID iid, LPVOID* ppvObj)
  1037. {
  1038. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1039. return pThis->ExternalQueryInterface(&iid, ppvObj);
  1040. }
  1041. STDMETHODIMP COleServerItem::XDataObject::GetData(
  1042. LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
  1043. {
  1044. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1045. return pThis->m_dataSource.m_xDataObject.GetData(lpFormatEtc, lpStgMedium);
  1046. }
  1047. STDMETHODIMP COleServerItem::XDataObject::GetDataHere(
  1048. LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
  1049. {
  1050. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1051. return pThis->m_dataSource.m_xDataObject.GetDataHere(
  1052. lpFormatEtc, lpStgMedium);
  1053. }
  1054. STDMETHODIMP COleServerItem::XDataObject::QueryGetData(LPFORMATETC lpFormatEtc)
  1055. {
  1056. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1057. return pThis->m_dataSource.m_xDataObject.QueryGetData(lpFormatEtc);
  1058. }
  1059. STDMETHODIMP COleServerItem::XDataObject::GetCanonicalFormatEtc(
  1060. LPFORMATETC /*lpFormatEtcIn*/, LPFORMATETC /*lpFormatEtcOut*/)
  1061. {
  1062. // because we support the target-device (ptd) for server metafile format,
  1063. // all members of the FORMATETC are significant.
  1064. return DATA_S_SAMEFORMATETC;
  1065. }
  1066. STDMETHODIMP COleServerItem::XDataObject::SetData(
  1067. LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium, BOOL bRelease)
  1068. {
  1069. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1070. return pThis->m_dataSource.m_xDataObject.SetData(
  1071. lpFormatEtc, lpStgMedium, bRelease);
  1072. }
  1073. STDMETHODIMP COleServerItem::XDataObject::EnumFormatEtc(
  1074. DWORD dwDirection, LPENUMFORMATETC* ppenumFormatEtc)
  1075. {
  1076. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1077. return pThis->m_dataSource.m_xDataObject.EnumFormatEtc(
  1078. dwDirection, ppenumFormatEtc);
  1079. }
  1080. STDMETHODIMP COleServerItem::XDataObject::DAdvise(
  1081. FORMATETC* pFormatEtc, DWORD advf,
  1082. LPADVISESINK pAdvSink, DWORD* pdwConnection)
  1083. {
  1084. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1085. *pdwConnection = 0;
  1086. // this special case is for apps like Excel which ask for DAdvise
  1087. // on CF_METAFILEPICT, DVASPECT_ICON for insert as icon.
  1088. FORMATETC formatEtc = *pFormatEtc;
  1089. if (formatEtc.cfFormat == CF_METAFILEPICT &&
  1090. formatEtc.dwAspect == DVASPECT_ICON)
  1091. {
  1092. formatEtc.dwAspect = DVASPECT_CONTENT;
  1093. }
  1094. // make sure the FORMATETC is valid
  1095. if (!(pFormatEtc->cfFormat == 0 && pFormatEtc->ptd == NULL &&
  1096. pFormatEtc->dwAspect == -1 && pFormatEtc->lindex == -1 &&
  1097. pFormatEtc->tymed == -1) &&
  1098. pThis->GetDataObject()->QueryGetData(&formatEtc) != S_OK)
  1099. {
  1100. // it is not a wildcard advise -and- the format is not acceptable
  1101. return DATA_E_FORMATETC;
  1102. }
  1103. // create the advise holder, if necessary
  1104. if (pThis->m_lpDataAdviseHolder == NULL &&
  1105. CreateDataAdviseHolder(&pThis->m_lpDataAdviseHolder) != S_OK)
  1106. {
  1107. return E_OUTOFMEMORY;
  1108. }
  1109. ASSERT(pThis->m_lpDataAdviseHolder != NULL);
  1110. return pThis->m_lpDataAdviseHolder->Advise(this, pFormatEtc, advf,
  1111. pAdvSink, pdwConnection);
  1112. }
  1113. STDMETHODIMP COleServerItem::XDataObject::DUnadvise(DWORD dwConnection)
  1114. {
  1115. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1116. if (pThis->m_lpDataAdviseHolder == NULL)
  1117. return E_FAIL;
  1118. ASSERT(pThis->m_lpDataAdviseHolder != NULL);
  1119. return pThis->m_lpDataAdviseHolder->Unadvise(dwConnection);
  1120. }
  1121. STDMETHODIMP COleServerItem::XDataObject::EnumDAdvise(
  1122. LPENUMSTATDATA* ppenumAdvise)
  1123. {
  1124. METHOD_PROLOGUE_EX_(COleServerItem, DataObject)
  1125. *ppenumAdvise = NULL;
  1126. if (pThis->m_lpDataAdviseHolder == NULL)
  1127. return E_FAIL;
  1128. ASSERT(pThis->m_lpDataAdviseHolder != NULL);
  1129. return pThis->m_lpDataAdviseHolder->EnumAdvise(ppenumAdvise);
  1130. }
  1131. //////////////////////////////////////////////////////////////////////////////
  1132. // special CItemDataSource implementation
  1133. BOOL COleServerItem::CItemDataSource::OnRenderGlobalData(
  1134. LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal)
  1135. {
  1136. ASSERT_VALID(this);
  1137. COleServerItem* pItem = (COleServerItem*)
  1138. ((BYTE*)this - offsetof(COleServerItem, m_dataSource));
  1139. return pItem->OnRenderGlobalData(lpFormatEtc, phGlobal);
  1140. // Note: COleDataSource has no implementation
  1141. }
  1142. BOOL COleServerItem::CItemDataSource::OnRenderFileData(
  1143. LPFORMATETC lpFormatEtc, CFile* pFile)
  1144. {
  1145. ASSERT_VALID(this);
  1146. COleServerItem* pItem = (COleServerItem*)
  1147. ((BYTE*)this - offsetof(COleServerItem, m_dataSource));
  1148. return pItem->OnRenderFileData(lpFormatEtc, pFile);
  1149. // Note: COleDataSource has no implementation
  1150. }
  1151. BOOL COleServerItem::CItemDataSource::OnRenderData(
  1152. LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
  1153. {
  1154. ASSERT_VALID(this);
  1155. COleServerItem* pItem = (COleServerItem*)
  1156. ((BYTE*)this - offsetof(COleServerItem, m_dataSource));
  1157. if (pItem->OnRenderData(lpFormatEtc, lpStgMedium))
  1158. return TRUE;
  1159. return COleDataSource::OnRenderData(lpFormatEtc, lpStgMedium);
  1160. }
  1161. BOOL COleServerItem::CItemDataSource::OnSetData(
  1162. LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium, BOOL bRelease)
  1163. {
  1164. ASSERT_VALID(this);
  1165. COleServerItem* pItem = (COleServerItem*)
  1166. ((BYTE*)this - offsetof(COleServerItem, m_dataSource));
  1167. return pItem->OnSetData(lpFormatEtc, lpStgMedium, bRelease);
  1168. // Note: COleDataSource has no implementation
  1169. }
  1170. //////////////////////////////////////////////////////////////////////////////
  1171. // COleServerItem Diagnostics
  1172. #ifdef _DEBUG
  1173. void COleServerItem::AssertValid() const
  1174. {
  1175. CDocItem::AssertValid();
  1176. // must be attached to a document
  1177. ASSERT(m_pDocument != NULL);
  1178. m_dataSource.AssertValid();
  1179. }
  1180. void COleServerItem::Dump(CDumpContext& dc) const
  1181. {
  1182. CDocItem::Dump(dc);
  1183. dc << "m_bNeedUnlock = " << m_bNeedUnlock;
  1184. dc << "\nm_bAutoDelete = " << m_bAutoDelete;
  1185. dc << "\nm_strItemName = " << m_strItemName;
  1186. dc << "\nm_lpOleAdviseHolder = " << m_lpOleAdviseHolder;
  1187. dc << "\nm_lpDataAdviseHolder = " << m_lpDataAdviseHolder;
  1188. dc << "\nwith m_dataSource: " << &m_dataSource;
  1189. }
  1190. #endif
  1191. /////////////////////////////////////////////////////////////////////////////