Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1162 lines
30 KiB

  1. /*---------------------------------------------------------------------------
  2. | OBJ.C
  3. | This file has the IUnknown, IOleObject, IStdMarshalInfo and IDataObject
  4. | interfaces of the OLE2 object (docMain). it also has other helper functions
  5. |
  6. | Created By: Vij Rajarajan (VijR)
  7. +---------------------------------------------------------------------------*/
  8. #define SERVERONLY
  9. #include <Windows.h>
  10. #include <shellapi.h>
  11. #include "mpole.h"
  12. #include "mplayer.h"
  13. extern int FAR PASCAL ReallyDoVerb (LPDOC, LONG, LPMSG, LPOLECLIENTSITE,
  14. BOOL, BOOL);
  15. extern BOOL FindRealFileName(LPTSTR szFile, int iLen);
  16. // static functions.
  17. HANDLE PASCAL GetDib (VOID);
  18. HANDLE GetMetafilePict (VOID);
  19. HANDLE GetMPlayerIcon(void);
  20. extern void FAR PASCAL SetEmbeddedObjectFlag(BOOL flag);
  21. extern HPALETTE CopyPalette(HPALETTE hpal);
  22. extern HBITMAP FAR PASCAL BitmapMCI(void);
  23. extern HPALETTE FAR PASCAL PaletteMCI(void);
  24. extern void DoInPlaceDeactivate(LPDOC lpdoc);
  25. HANDLE FAR PASCAL PictureFromDib(HANDLE hdib, HPALETTE hpal);
  26. HANDLE FAR PASCAL DibFromBitmap(HBITMAP hbm, HPALETTE hpal);
  27. void FAR PASCAL DitherMCI(HANDLE hdib, HPALETTE hpal);
  28. /* GetMetafilePict
  29. * ---------------
  30. *
  31. * RETURNS: A handle to the object's data in metafile format.
  32. */
  33. HANDLE GetMetafilePict ( )
  34. {
  35. HPALETTE hpal;
  36. HANDLE hdib;
  37. HANDLE hmfp;
  38. HDC hdc;
  39. DPF("GetMetafilePict called on thread %d\n", GetCurrentThreadId());
  40. hdib = (HANDLE)SendMessage(ghwndApp, WM_GETDIB, 0, 0);
  41. /* If we're dithered, don't use a palette */
  42. hdc = GetDC(NULL);
  43. if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
  44. && (gwOptions & OPT_DITHER))
  45. hpal = NULL;
  46. else
  47. hpal = PaletteMCI();
  48. if (hpal)
  49. hpal = CopyPalette(hpal);
  50. ReleaseDC(NULL, hdc);
  51. hmfp = PictureFromDib(hdib, hpal);
  52. if (hpal)
  53. DeleteObject(hpal);
  54. GLOBALFREE(hdib);
  55. return hmfp;
  56. }
  57. /**************************************************************************
  58. //## Somebody wants a dib (OLE)
  59. ***************************************************************************/
  60. HANDLE PASCAL GetDib( VOID )
  61. {
  62. HBITMAP hbm;
  63. HPALETTE hpal;
  64. HANDLE hdib;
  65. HDC hdc;
  66. DPF("GetDib\n");
  67. hbm = BitmapMCI();
  68. hpal = PaletteMCI();
  69. hdib = DibFromBitmap(hbm, hpal);
  70. //
  71. // if we are on a palette device. possibly dither to the VGA colors
  72. // for apps that dont deal with palettes!
  73. //
  74. hdc = GetDC(NULL);
  75. if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) &&
  76. (gwOptions & OPT_DITHER))
  77. {
  78. DitherMCI(hdib, hpal);
  79. hpal = NULL; // no longer working with a palette
  80. }
  81. ReleaseDC(NULL, hdc);
  82. if (hbm)
  83. DeleteObject(hbm);
  84. return hdib;
  85. }
  86. /**************************************************************************
  87. * GetMPlayerIcon: This function extracts the our Icon and gives it out
  88. * as a Metafile incase the client wants DVASPECT_ICON
  89. ***************************************************************************/
  90. HANDLE GetMPlayerIcon (void)
  91. {
  92. HICON hicon;
  93. HDC hdc;
  94. HANDLE hmfp = NULL;
  95. LPMETAFILEPICT pmfp=NULL;
  96. static int cxIcon = 0;
  97. static int cyIcon = 0;
  98. static int cxIconHiMetric = 0;
  99. static int cyIconHiMetric = 0;
  100. hicon = GetIconForCurrentDevice(GI_LARGE, IDI_DDEFAULT);
  101. if ((HICON)1==hicon || NULL==hicon)
  102. return NULL;
  103. if (!(hmfp = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE,
  104. sizeof(METAFILEPICT))))
  105. return NULL;
  106. pmfp = (METAFILEPICT FAR*) GLOBALLOCK (hmfp);
  107. if (0==cxIcon)
  108. {
  109. // In units of pixels
  110. cxIcon = GetSystemMetrics (SM_CXICON);
  111. cyIcon = GetSystemMetrics (SM_CYICON);
  112. // In units of .01 millimeter
  113. cxIconHiMetric = cxIcon * HIMETRIC_PER_INCH / giXppli;
  114. cyIconHiMetric = cyIcon * HIMETRIC_PER_INCH / giYppli;;
  115. }
  116. pmfp->mm = MM_ANISOTROPIC;
  117. pmfp->xExt = cxIconHiMetric;
  118. pmfp->yExt = cyIconHiMetric;
  119. hdc = CreateMetaFile (NULL);
  120. SetWindowOrgEx (hdc, 0, 0, NULL);
  121. SetWindowExtEx (hdc, cxIcon, cyIcon, NULL);
  122. DrawIcon (hdc, 0, 0, hicon);
  123. pmfp->hMF = CloseMetaFile (hdc);
  124. GLOBALUNLOCK (hmfp);
  125. if (NULL == pmfp->hMF) {
  126. GLOBALFREE (hmfp);
  127. return NULL;
  128. }
  129. return hmfp;
  130. }
  131. #ifdef DEBUG
  132. #define DBG_CHECK_GUID(guid) \
  133. if (IsEqualIID(&guid, riidReq)) \
  134. return #guid
  135. LPSTR DbgGetIIDString(REFIID riidReq)
  136. {
  137. static CHAR UnknownIID[64];
  138. DBG_CHECK_GUID(IID_IUnknown);
  139. DBG_CHECK_GUID(IID_IClassFactory);
  140. DBG_CHECK_GUID(IID_IMalloc);
  141. DBG_CHECK_GUID(IID_IMarshal);
  142. DBG_CHECK_GUID(IID_IRpcChannel);
  143. DBG_CHECK_GUID(IID_IRpcStub);
  144. DBG_CHECK_GUID(IID_IStubManager);
  145. DBG_CHECK_GUID(IID_IRpcProxy);
  146. DBG_CHECK_GUID(IID_IProxyManager);
  147. DBG_CHECK_GUID(IID_IPSFactory);
  148. DBG_CHECK_GUID(IID_ILockBytes);
  149. DBG_CHECK_GUID(IID_IStorage);
  150. DBG_CHECK_GUID(IID_IStream);
  151. DBG_CHECK_GUID(IID_IEnumSTATSTG);
  152. DBG_CHECK_GUID(IID_IBindCtx);
  153. DBG_CHECK_GUID(IID_IMoniker);
  154. DBG_CHECK_GUID(IID_IRunningObjectTable);
  155. DBG_CHECK_GUID(IID_IInternalMoniker);
  156. DBG_CHECK_GUID(IID_IRootStorage);
  157. DBG_CHECK_GUID(IID_IDfReserved1);
  158. DBG_CHECK_GUID(IID_IDfReserved2);
  159. DBG_CHECK_GUID(IID_IDfReserved3);
  160. DBG_CHECK_GUID(IID_IMessageFilter);
  161. DBG_CHECK_GUID(CLSID_StdMarshal);
  162. DBG_CHECK_GUID(IID_IStdMarshalInfo);
  163. DBG_CHECK_GUID(IID_IExternalConnection);
  164. DBG_CHECK_GUID(IID_IEnumUnknown);
  165. DBG_CHECK_GUID(IID_IEnumString);
  166. DBG_CHECK_GUID(IID_IEnumMoniker);
  167. DBG_CHECK_GUID(IID_IEnumFORMATETC);
  168. DBG_CHECK_GUID(IID_IEnumOLEVERB);
  169. DBG_CHECK_GUID(IID_IEnumSTATDATA);
  170. DBG_CHECK_GUID(IID_IEnumGeneric);
  171. DBG_CHECK_GUID(IID_IEnumHolder);
  172. DBG_CHECK_GUID(IID_IEnumCallback);
  173. DBG_CHECK_GUID(IID_IPersistStream);
  174. DBG_CHECK_GUID(IID_IPersistStorage);
  175. DBG_CHECK_GUID(IID_IPersistFile);
  176. DBG_CHECK_GUID(IID_IPersist);
  177. DBG_CHECK_GUID(IID_IViewObject);
  178. DBG_CHECK_GUID(IID_IDataObject);
  179. DBG_CHECK_GUID(IID_IAdviseSink);
  180. DBG_CHECK_GUID(IID_IDataAdviseHolder);
  181. DBG_CHECK_GUID(IID_IOleAdviseHolder);
  182. DBG_CHECK_GUID(IID_IOleObject);
  183. DBG_CHECK_GUID(IID_IOleInPlaceObject);
  184. DBG_CHECK_GUID(IID_IOleWindow);
  185. DBG_CHECK_GUID(IID_IOleInPlaceUIWindow);
  186. DBG_CHECK_GUID(IID_IOleInPlaceFrame);
  187. DBG_CHECK_GUID(IID_IOleInPlaceActiveObject);
  188. DBG_CHECK_GUID(IID_IOleClientSite);
  189. DBG_CHECK_GUID(IID_IOleInPlaceSite);
  190. DBG_CHECK_GUID(IID_IParseDisplayName);
  191. DBG_CHECK_GUID(IID_IOleContainer);
  192. DBG_CHECK_GUID(IID_IOleItemContainer);
  193. DBG_CHECK_GUID(IID_IOleLink);
  194. DBG_CHECK_GUID(IID_IOleCache);
  195. DBG_CHECK_GUID(IID_IOleManager);
  196. DBG_CHECK_GUID(IID_IOlePresObj);
  197. DBG_CHECK_GUID(IID_IDropSource);
  198. DBG_CHECK_GUID(IID_IDropTarget);
  199. DBG_CHECK_GUID(IID_IDebug);
  200. DBG_CHECK_GUID(IID_IDebugStream);
  201. DBG_CHECK_GUID(IID_IAdviseSink2);
  202. DBG_CHECK_GUID(IID_IRunnableObject);
  203. DBG_CHECK_GUID(IID_IViewObject2);
  204. DBG_CHECK_GUID(IID_IOleCache2);
  205. DBG_CHECK_GUID(IID_IOleCacheControl);
  206. wsprintfA(UnknownIID, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  207. riidReq->Data1, riidReq->Data2, riidReq->Data3,
  208. riidReq->Data4[0], riidReq->Data4[1],
  209. riidReq->Data4[2], riidReq->Data4[3],
  210. riidReq->Data4[4], riidReq->Data4[5],
  211. riidReq->Data4[6], riidReq->Data4[7]);
  212. return UnknownIID;
  213. }
  214. #endif
  215. /**************************************************************************
  216. ***************** IUnknown INTERFACE IMPLEMENTATION.
  217. **************************************************************************/
  218. STDMETHODIMP UnkQueryInterface(
  219. LPUNKNOWN lpUnkObj, // Unknown object ptr
  220. REFIID riidReq, // IID required
  221. LPVOID FAR * lplpUnk // pre for returning the interface
  222. )
  223. {
  224. LPDOC lpdoc;
  225. lpdoc = ((struct COleObjectImpl FAR*)lpUnkObj)->lpdoc;
  226. DPF1("QueryInterface( %s )\n", DbgGetIIDString(riidReq));
  227. if (IsEqualIID(riidReq, &IID_IOleObject)) {
  228. *lplpUnk = (LPVOID) &lpdoc->m_Ole;
  229. lpdoc->cRef++;
  230. return NOERROR;
  231. } else if (IsEqualIID(riidReq, &IID_IDataObject)) {
  232. *lplpUnk = (LPVOID) &lpdoc->m_Data;
  233. lpdoc->cRef++;
  234. return NOERROR;
  235. } else if (IsEqualIID(riidReq, &IID_IUnknown)) {
  236. *lplpUnk = (LPVOID) &lpdoc->m_Ole;
  237. lpdoc->cRef++;
  238. return NOERROR;
  239. } else if (IsEqualIID(riidReq, &IID_IPersist) || IsEqualIID(riidReq, &IID_IPersistStorage)) {
  240. *lplpUnk = (LPVOID) &lpdoc->m_PersistStorage;
  241. lpdoc->cRef++;
  242. return NOERROR;
  243. } else if (IsEqualIID(riidReq, &IID_IPersistFile)) {
  244. *lplpUnk = (LPVOID) &lpdoc->m_PersistFile;
  245. lpdoc->cRef++;
  246. return NOERROR;
  247. } else if (IsEqualIID(riidReq, &IID_IOleWindow) || IsEqualIID(riidReq, &IID_IOleInPlaceObject)) {
  248. *lplpUnk = (LPVOID) &lpdoc->m_InPlace;
  249. lpdoc->cRef++;
  250. return NOERROR;
  251. } else if (IsEqualIID(riidReq, &IID_IOleInPlaceActiveObject)) {
  252. *lplpUnk = (LPVOID) &lpdoc->m_IPActive;
  253. lpdoc->cRef++;
  254. return NOERROR;
  255. } else {
  256. *lplpUnk = (LPVOID) NULL;
  257. DPF1("E_NOINTERFACE\n");
  258. RETURN_RESULT(E_NOINTERFACE);
  259. }
  260. }
  261. STDMETHODIMP_(ULONG) UnkAddRef(LPUNKNOWN lpUnkObj)
  262. {
  263. LPDOC lpdoc;
  264. lpdoc = ((struct COleObjectImpl FAR*)lpUnkObj)->lpdoc;
  265. return ++lpdoc->cRef;
  266. }
  267. STDMETHODIMP_(ULONG) UnkRelease (LPUNKNOWN lpUnkObj)
  268. {
  269. LPDOC lpdoc;
  270. lpdoc = ((struct COleObjectImpl FAR*)lpUnkObj)->lpdoc;
  271. if (--lpdoc->cRef == 0)
  272. {
  273. DPF1("\n**^*^*^*^*^*^*^*^*^*^*^*^*Refcnt OK\n");
  274. if (!(gfOle2IPPlaying || gfOle2IPEditing) && srvrMain.cLock == 0)
  275. PostCloseMessage();
  276. return 0;
  277. }
  278. return lpdoc->cRef;
  279. }
  280. /**************************************************************************
  281. ************* IOleObject INTERFACE IMPLEMENTATION
  282. **************************************************************************/
  283. //delegate to the common IUnknown Implemenation.
  284. STDMETHODIMP OleObjQueryInterface(
  285. LPOLEOBJECT lpOleObj, // ole object ptr
  286. REFIID riidReq, // IID required
  287. LPVOID FAR * lplpUnk // pre for returning the interface
  288. )
  289. {
  290. return( UnkQueryInterface((LPUNKNOWN)lpOleObj, riidReq, lplpUnk));
  291. }
  292. STDMETHODIMP_(ULONG) OleObjAddRef(
  293. LPOLEOBJECT lpOleObj // ole object ptr
  294. )
  295. {
  296. return UnkAddRef((LPUNKNOWN) lpOleObj);
  297. }
  298. STDMETHODIMP_(ULONG) OleObjRelease (
  299. LPOLEOBJECT lpOleObj // ole object ptr
  300. )
  301. {
  302. LPDOC lpdoc;
  303. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  304. return UnkRelease((LPUNKNOWN) lpOleObj);
  305. }
  306. //Save the Client site pointer.
  307. STDMETHODIMP OleObjSetClientSite(
  308. LPOLEOBJECT lpOleObj,
  309. LPOLECLIENTSITE lpclientSite
  310. )
  311. {
  312. LPDOC lpdoc;
  313. DPF("OleObjSetClientSite\n");
  314. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  315. if (lpdoc->lpoleclient)
  316. IOleClientSite_Release(lpdoc->lpoleclient);
  317. lpdoc->lpoleclient = (LPOLECLIENTSITE) lpclientSite;
  318. // OLE2NOTE: to be able to hold onto clientSite pointer, we must AddRef it
  319. if (lpclientSite)
  320. IOleClientSite_AddRef(lpclientSite);
  321. return NOERROR;
  322. }
  323. STDMETHODIMP OleObjGetClientSite (
  324. LPOLEOBJECT lpOleObj,
  325. LPOLECLIENTSITE FAR* lplpclientSite
  326. )
  327. {
  328. DPF("OleObjGetClientSite\n");
  329. return NOERROR;
  330. }
  331. /* CheckIfInPPViewer
  332. *
  333. * Hack to stop PowerPoint viewer from crashing when we're trying to play in place.
  334. *
  335. * PP Viewer was written under the assumption that Media Player was not a full-blown
  336. * OLE2 server. Much of the code was stubbed out to make the Viewer small.
  337. * Unfortunately this means it crashes when certain calls are made for in-place
  338. * activation. These are the problem interface methods:
  339. *
  340. * OnInPlaceActivate/Deactivate
  341. * OnUIActivate/Deactivate
  342. * OnPosRectChange
  343. *
  344. * If we're in PP Viewer we simply do not make these calls.
  345. *
  346. * We detect that we're in PP Viewer by finding the parent of the window whose
  347. * handle is passed to DoVerb. The window handle passed in to DoVerb is of
  348. * "ppSlideShowWin" class, which is the same as in PP Slide Show, which works
  349. * correctly. However its parent's class is "PP4VDialog" (as distinct from
  350. * "PPApplicationClass"). So, if we find this class name, set a global flag
  351. * to test before making the troublesome calls.
  352. *
  353. * Andrew Bell (andrewbe) 11 May 1995
  354. *
  355. */
  356. STATICFN void CheckIfInPPViewer(HWND hwndParent)
  357. {
  358. HWND hwndGrandParent;
  359. TCHAR ClassName[256];
  360. gfInPPViewer = FALSE;
  361. if (hwndParent)
  362. {
  363. hwndGrandParent = GetParent(hwndParent);
  364. if (hwndGrandParent)
  365. {
  366. if (GetClassName(hwndGrandParent, ClassName, CHAR_COUNT(ClassName)) > 0)
  367. {
  368. if (lstrcmp(ClassName, TEXT("PP4VDialog")) == 0)
  369. {
  370. DPF0("Detected that we're in PP Viewer\n");
  371. gfInPPViewer = TRUE;
  372. }
  373. }
  374. }
  375. }
  376. }
  377. //delegate to ReallyDoVerb.
  378. STDMETHODIMP OleObjDoVerb(
  379. LPOLEOBJECT lpOleObj,
  380. LONG lVerb,
  381. LPMSG lpmsg,
  382. LPOLECLIENTSITE pActiveSite,
  383. LONG lindex,
  384. HWND hwndParent,
  385. LPCRECT lprcPosRect
  386. )
  387. {
  388. LPDOC lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  389. DPF("OleObjDoVerb\n");
  390. CheckIfInPPViewer(hwndParent);
  391. RETURN_RESULT( ReallyDoVerb(lpdoc, lVerb, lpmsg, pActiveSite, TRUE, TRUE));
  392. }
  393. STDMETHODIMP OleObjEnumVerbs(
  394. LPOLEOBJECT lpOleObj,
  395. IEnumOLEVERB FAR* FAR* lplpenumOleVerb )
  396. {
  397. DPF("OleObjEnumVerbs\n");
  398. *lplpenumOleVerb = NULL;
  399. RETURN_RESULT( OLE_S_USEREG); //Use the reg db.
  400. }
  401. STDMETHODIMP OleObjUpdate(LPOLEOBJECT lpOleObj)
  402. {
  403. DPF("OleObjUpdate\n");
  404. // we can't contain links so there is nothing to update
  405. return NOERROR;
  406. }
  407. STDMETHODIMP OleObjIsUpToDate(LPOLEOBJECT lpOleObj)
  408. {
  409. DPF("OleObjIsUpToDate\n");
  410. // we can't contain links so there is nothing to update
  411. return NOERROR;
  412. }
  413. /*
  414. From OLE2HELP.HLP:
  415. GetUserClassID returns the CLSID as the user knows it. For embedded objects,
  416. this is always the CLSID that is persistently stored and is returned by
  417. IPersist::GetClassID. For linked objects, this is the CLSID of the last
  418. bound link source. If a Treat As operation is taking place, this is the CLSID
  419. of the application being emulated (also the CLSID that will be written into storage).
  420. I can't follow the logic here. What if it's an embedded object and a Treat As
  421. operation? However, AlexGo tells me that my IOleObject interfaces should return
  422. the OLE2 Class ID.
  423. */
  424. STDMETHODIMP OleObjGetUserClassID
  425. (LPOLEOBJECT lpOleObj,
  426. CLSID FAR* pClsid)
  427. {
  428. DPF1("OleObjGetUserClassID\n");
  429. *pClsid = gClsID;
  430. return NOERROR;
  431. }
  432. /**************************************************************************
  433. * Set our UserTypeName to "Media Clip"
  434. **************************************************************************/
  435. STDMETHODIMP OleObjGetUserType
  436. (LPOLEOBJECT lpOleObj,
  437. DWORD dwFormOfType,
  438. LPWSTR FAR* pszUserType)
  439. {
  440. LPMALLOC lpMalloc;
  441. LPWSTR lpstr;
  442. int clen;
  443. DPF1("OleObjGetUserType\n");
  444. *pszUserType = NULL;
  445. if(CoGetMalloc(MEMCTX_TASK,&lpMalloc) != 0)
  446. RETURN_RESULT(E_OUTOFMEMORY);
  447. clen = STRING_BYTE_COUNT(gachClassRoot);
  448. #ifndef UNICODE
  449. clen *= (sizeof(WCHAR) / sizeof(CHAR));
  450. #endif
  451. lpstr = IMalloc_Alloc(lpMalloc, clen);
  452. IMalloc_Release(lpMalloc);
  453. #ifdef UNICODE
  454. lstrcpy(lpstr,gachClassRoot);
  455. #else
  456. AnsiToUnicodeString(gachClassRoot, lpstr, -1);
  457. #endif /* UNICODE */
  458. *pszUserType = lpstr;
  459. return NOERROR;
  460. }
  461. /**************************************************************************
  462. * Get the name of the client and set the title.
  463. **************************************************************************/
  464. STDMETHODIMP OleObjSetHostNames (
  465. LPOLEOBJECT lpOleObj,
  466. LPCWSTR lpszClientAppW,
  467. LPCWSTR lpszClientObjW
  468. )
  469. {
  470. LPDOC lpdoc;
  471. LPTSTR lpszClientApp;
  472. LPTSTR lpszClientObj;
  473. DPF1("OleObjSetHostNames\n");
  474. #ifdef UNICODE
  475. lpszClientApp = (LPTSTR)lpszClientAppW;
  476. lpszClientObj = (LPTSTR)lpszClientObjW;
  477. #else
  478. lpszClientApp = AllocateAnsiString(lpszClientAppW);
  479. lpszClientObj = AllocateAnsiString(lpszClientObjW);
  480. if( !lpszClientApp || !lpszClientObj )
  481. RETURN_RESULT(E_OUTOFMEMORY);
  482. #endif /* UNICODE */
  483. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  484. // object is embedded.
  485. lpdoc->doctype = doctypeEmbedded;
  486. if (lpszClientObj == NULL)
  487. lpszClientObj = lpszClientApp;
  488. SetTitle(lpdoc, lpszClientObj);
  489. SetMPlayerIcon();
  490. lstrcpy (szClient, lpszClientApp);
  491. if (lpszClientObj)
  492. {
  493. LPTSTR lpszFileName = FileName(lpszClientObj);
  494. if (lpszFileName)
  495. lstrcpy (szClientDoc, lpszFileName);
  496. }
  497. // this is the only time we know the object will be an embedding
  498. SetEmbeddedObjectFlag(TRUE);
  499. #ifndef UNICODE
  500. FreeAnsiString(lpszClientApp);
  501. FreeAnsiString(lpszClientObj);
  502. #endif /* NOT UNICODE */
  503. return NOERROR;
  504. }
  505. /**************************************************************************
  506. * The client closed the object. The server will now shut down.
  507. **************************************************************************/
  508. STDMETHODIMP OleObjClose (
  509. LPOLEOBJECT lpOleObj,
  510. DWORD dwSaveOptions
  511. )
  512. {
  513. LPDOC lpdoc;
  514. DPF1("OleObjClose\n");
  515. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  516. /* Hack to stop PowerPoint crashing:
  517. *
  518. * Win95 bug #19848: Crash saving PowerPoint with out-of-place mplayer
  519. *
  520. * If we don't call IOleClientSite::SaveObject() at this point,
  521. * PowerPoint will crash under certain circumstances.
  522. *
  523. * This is an extract from mail I received from TuanN, the PPT dev:
  524. *
  525. * The fundamental problem is that PP expects to receive the
  526. * IAdviseSink::SaveObject() as a result of calling IOleObject::Close().
  527. * Since the Media Player did not send that notficiation in this test case,
  528. * PP tries to perform an Undo operation during the ensuing OnClose()
  529. * notification and thus erroneously destroys the embedded object.
  530. * The reason we throw away the object is because PP thinks that this
  531. * object is still virgin (no OnViewChange). Please refer to SaveObject(),
  532. * OnClose() in CtCommon.cpp and slide\sextern.c for more info. In the test
  533. * case, during OnClose(), the "revert" state is TRUE, PP will do a
  534. * Ex_REVERTED operation (stack calls: SClosePicts, SClear,
  535. * SSaveforUndo--> object deleted).
  536. *
  537. * AndrewBe, 6 December 1994
  538. */
  539. if (lpdoc->lpoleclient)
  540. IOleClientSite_SaveObject(lpdoc->lpoleclient);
  541. DoInPlaceDeactivate(lpdoc);
  542. SendDocMsg(lpdoc,OLE_CLOSED);
  543. DestroyDoc(lpdoc);
  544. ExitApplication();
  545. //CoDisconnectObject((LPUNKNOWN)lpdoc, NULL);
  546. SendMessage(ghwndApp, WM_COMMAND, (WPARAM)IDM_EXIT, 0L);
  547. return NOERROR;
  548. }
  549. STDMETHODIMP OleObjSetMoniker(LPOLEOBJECT lpOleObj,
  550. DWORD dwWhichMoniker, LPMONIKER pmk)
  551. {
  552. DPF("OleObjSetMoniker\n");
  553. return NOERROR;
  554. }
  555. STDMETHODIMP OleObjGetMoniker(LPOLEOBJECT lpOleObj,
  556. DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER FAR* lplpmk)
  557. {
  558. LPDOC lpdoc;
  559. DPF("OleObjGetMoniker\n");
  560. *lplpmk = NULL;
  561. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  562. if (lpdoc->lpoleclient != NULL)
  563. {
  564. return( IOleClientSite_GetMoniker(lpdoc->lpoleclient,
  565. dwAssign, dwWhichMoniker, lplpmk));
  566. }
  567. else if (lpdoc->doctype == doctypeFromFile)
  568. {
  569. // use file moniker
  570. WCHAR sz[cchFilenameMax];
  571. if (GlobalGetAtomNameW(lpdoc->aDocName, sz, CHAR_COUNT(sz)) == 0)
  572. RETURN_RESULT( E_FAIL);
  573. return( (HRESULT)CreateFileMoniker(sz, lplpmk));
  574. }
  575. else
  576. RETURN_RESULT( E_FAIL);
  577. }
  578. STDMETHODIMP OleObjInitFromData (
  579. LPOLEOBJECT lpOleObj,
  580. LPDATAOBJECT lpDataObj,
  581. BOOL fCreation,
  582. DWORD dwReserved
  583. )
  584. {
  585. DPF("OleObjInitFromData - E_NOTIMPL\n");
  586. RETURN_RESULT( E_NOTIMPL);
  587. }
  588. STDMETHODIMP OleObjGetClipboardData (
  589. LPOLEOBJECT lpOleObj,
  590. DWORD dwReserved,
  591. LPDATAOBJECT FAR* lplpDataObj
  592. )
  593. {
  594. DPF("OleObjGetClipboardData - E_NOTIMPL\n");
  595. RETURN_RESULT( E_NOTIMPL);
  596. }
  597. STDMETHODIMP OleObjSetExtent(
  598. LPOLEOBJECT lpOleObj,
  599. DWORD dwAspect,
  600. LPSIZEL lpsizel)
  601. {
  602. DPF("OleObjSetExtent\n");
  603. #ifdef LATER
  604. gscaleInitXY[SCALE_X].denom = lpsizel->cx;
  605. gscaleInitXY[SCALE_Y].denom = lpsizel->cy;
  606. #endif
  607. return NOERROR;
  608. }
  609. //Get the object extent from the Metafile. GetMetafilePict saves the extents
  610. // in extWidth and extHeight
  611. STDMETHODIMP OleObjGetExtent(
  612. LPOLEOBJECT lpOleObj,
  613. DWORD dwAspect,
  614. LPSIZEL lpSizel)
  615. {
  616. HGLOBAL hTmpMF;
  617. LPDOC lpdoc;
  618. DPF("OleObjGetExtent\n");
  619. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  620. if((dwAspect & (DVASPECT_CONTENT | DVASPECT_DOCPRINT)) == 0)
  621. RETURN_RESULT( E_INVALIDARG);
  622. // There may be a potential memory leak here -- hTmpMF contains a handle to a
  623. // metafile that must be deleted. See code in cdrag.c.
  624. // Not changed here at this time since I do not want to break anything.
  625. // SteveZ
  626. hTmpMF = GetMetafilePict();
  627. GLOBALUNLOCK(hTmpMF);
  628. GLOBALFREE(hTmpMF);
  629. lpSizel->cx = extWidth;
  630. lpSizel->cy = extHeight;
  631. return NOERROR;
  632. }
  633. STDMETHODIMP OleObjAdvise(LPOLEOBJECT lpOleObj, LPADVISESINK lpAdvSink, LPDWORD lpdwConnection)
  634. {
  635. LPDOC lpdoc;
  636. DPF("OleObjAdvise\n");
  637. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  638. if (lpdoc->lpoaholder == NULL &&
  639. CreateOleAdviseHolder(&lpdoc->lpoaholder) != S_OK)
  640. RETURN_RESULT( E_OUTOFMEMORY);
  641. return( IOleAdviseHolder_Advise(lpdoc->lpoaholder, lpAdvSink, lpdwConnection));
  642. }
  643. STDMETHODIMP OleObjUnadvise(LPOLEOBJECT lpOleObj, DWORD dwConnection)
  644. {
  645. LPDOC lpdoc;
  646. DPF("OleObjUnadvise\n");
  647. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  648. if (lpdoc->lpoaholder == NULL)
  649. RETURN_RESULT( E_FAIL);
  650. return( IOleAdviseHolder_Unadvise(lpdoc->lpoaholder, dwConnection));
  651. }
  652. STDMETHODIMP OleObjEnumAdvise(LPOLEOBJECT lpOleObj, LPENUMSTATDATA FAR* lplpenumAdvise)
  653. {
  654. LPDOC lpdoc;
  655. DPF("OleObjEnumAdvise\n");
  656. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  657. if (lpdoc->lpoaholder == NULL)
  658. RETURN_RESULT( E_FAIL);
  659. return(IOleAdviseHolder_EnumAdvise(lpdoc->lpoaholder, lplpenumAdvise));
  660. }
  661. STDMETHODIMP OleObjGetMiscStatus
  662. (LPOLEOBJECT lpOleObj,
  663. DWORD dwAspect,
  664. DWORD FAR* pdwStatus)
  665. {
  666. DPF("OleObjGetMiscStatus\n");
  667. RETURN_RESULT( OLE_S_USEREG);
  668. }
  669. STDMETHODIMP OleObjSetColorScheme(LPOLEOBJECT lpOleObj, LPLOGPALETTE lpLogPal)
  670. {
  671. DPF("OleObjSetColorScheme\n");
  672. return NOERROR;
  673. }
  674. STDMETHODIMP OleObjLockObject(LPOLEOBJECT lpOleObj, BOOL fLock)
  675. {
  676. LPDOC lpdoc;
  677. DPF("OleObjLockObject\n");
  678. lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
  679. if (fLock)
  680. lpdoc->cLock++;
  681. else
  682. {
  683. if (!lpdoc->cLock)
  684. RETURN_RESULT( E_FAIL);
  685. if (--lpdoc->cLock == 0)
  686. OleObjClose(lpOleObj, OLECLOSE_SAVEIFDIRTY);
  687. return NOERROR;
  688. }
  689. return NOERROR;
  690. }
  691. /**************************************************************************
  692. ************* IDataObject INTERFACE IMPLEMENTATION.
  693. **************************************************************************/
  694. //Delegate to the common IUnknown implementation.
  695. STDMETHODIMP DataObjQueryInterface (
  696. LPDATAOBJECT lpDataObj, // data object ptr
  697. REFIID riidReq, // IID required
  698. LPVOID FAR * lplpUnk // pre for returning the interface
  699. )
  700. {
  701. return( UnkQueryInterface((LPUNKNOWN)lpDataObj, riidReq, lplpUnk));
  702. }
  703. STDMETHODIMP_(ULONG) DataObjAddRef(
  704. LPDATAOBJECT lpDataObj // data object ptr
  705. )
  706. {
  707. return UnkAddRef((LPUNKNOWN) lpDataObj);
  708. }
  709. STDMETHODIMP_(ULONG) DataObjRelease (
  710. LPDATAOBJECT lpDataObj // data object ptr
  711. )
  712. {
  713. LPDOC lpdoc;
  714. lpdoc = ((struct CDataObjectImpl FAR*)lpDataObj)->lpdoc;
  715. return UnkRelease((LPUNKNOWN) lpDataObj);
  716. }
  717. /**************************************************************************
  718. * DataObjGetData:
  719. * Provides the data for METAFILE and DIB formats.
  720. **************************************************************************/
  721. STDMETHODIMP DataObjGetData (
  722. LPDATAOBJECT lpDataObj,
  723. LPFORMATETC lpformatetc,
  724. LPSTGMEDIUM lpMedium
  725. )
  726. {
  727. LPDOC lpdoc;
  728. DPF1("DataObjGetData\n");
  729. if (lpMedium == NULL) RETURN_RESULT( E_FAIL);
  730. // null out in case of error
  731. lpMedium->tymed = TYMED_NULL;
  732. lpMedium->pUnkForRelease = NULL;
  733. lpMedium->hGlobal = NULL;
  734. lpdoc = ((struct CDataObjectImpl FAR*)lpDataObj)->lpdoc;
  735. VERIFY_LINDEX(lpformatetc->lindex);
  736. if (lpformatetc->dwAspect == DVASPECT_ICON)
  737. {
  738. if (lpformatetc->cfFormat != CF_METAFILEPICT)
  739. RETURN_RESULT( DATA_E_FORMATETC);
  740. }
  741. else
  742. {
  743. if (!(lpformatetc->dwAspect & (DVASPECT_CONTENT | DVASPECT_DOCPRINT)))
  744. RETURN_RESULT( DATA_E_FORMATETC); // we support only these 2 aspects
  745. }
  746. if (lpMedium->tymed != TYMED_NULL)
  747. // all the other formats we only give out in our own global block
  748. RETURN_RESULT( DATA_E_FORMATETC);
  749. lpMedium->tymed = TYMED_HGLOBAL;
  750. if (lpformatetc->cfFormat == CF_METAFILEPICT)
  751. {
  752. lpMedium->tymed = TYMED_MFPICT;
  753. DPF1("Before getmeta\n");
  754. if (lpformatetc->dwAspect == DVASPECT_ICON)
  755. lpMedium->hGlobal = GetMPlayerIcon ();
  756. else
  757. lpMedium->hGlobal = GetMetafilePict ();
  758. DPF1("After getmeta\n");
  759. if (!lpMedium->hGlobal)
  760. RETURN_RESULT( E_OUTOFMEMORY);
  761. #ifdef DEBUG
  762. if (__iDebugLevel >= 1)
  763. {
  764. /* Useful check to validate what we're passing back to the container.
  765. */
  766. if (OpenClipboard(ghwndApp))
  767. {
  768. EmptyClipboard();
  769. SetClipboardData(CF_METAFILEPICT, lpMedium->hGlobal);
  770. CloseClipboard();
  771. }
  772. }
  773. #endif
  774. return NOERROR;
  775. }
  776. if (lpformatetc->cfFormat == CF_DIB)
  777. {
  778. lpMedium->tymed = TYMED_HGLOBAL;
  779. lpMedium->hGlobal = (HANDLE)GetDib();
  780. if (!(lpMedium->hGlobal))
  781. RETURN_RESULT( E_OUTOFMEMORY);
  782. #ifdef DEBUG
  783. if (__iDebugLevel >= 1)
  784. {
  785. /* Useful check to validate what we're passing back to the container.
  786. */
  787. if (OpenClipboard(ghwndApp))
  788. {
  789. EmptyClipboard();
  790. SetClipboardData(CF_DIB, lpMedium->hGlobal);
  791. CloseClipboard();
  792. }
  793. }
  794. #endif
  795. return NOERROR;
  796. }
  797. RETURN_RESULT( DATA_E_FORMATETC);
  798. }
  799. STDMETHODIMP DataObjGetDataHere (
  800. LPDATAOBJECT lpDataObj,
  801. LPFORMATETC lpformatetc,
  802. LPSTGMEDIUM lpMedium
  803. )
  804. {
  805. RETURN_RESULT( E_NOTIMPL);
  806. }
  807. STDMETHODIMP DataObjQueryGetData (
  808. LPDATAOBJECT lpDataObj,
  809. LPFORMATETC lpformatetc
  810. )
  811. { // this is only a query
  812. if ((lpformatetc->cfFormat == CF_METAFILEPICT) &&
  813. (lpformatetc->tymed & TYMED_MFPICT))
  814. return NOERROR;
  815. if ((lpformatetc->cfFormat == CF_DIB) &&
  816. (lpformatetc->tymed & TYMED_HGLOBAL))
  817. return NOERROR;
  818. RETURN_RESULT( DATA_E_FORMATETC);
  819. }
  820. STDMETHODIMP DataObjGetCanonicalFormatEtc(
  821. LPDATAOBJECT lpDataObj,
  822. LPFORMATETC lpformatetc,
  823. LPFORMATETC lpformatetcOut
  824. )
  825. {
  826. RETURN_RESULT(DATA_S_SAMEFORMATETC);
  827. }
  828. STDMETHODIMP DataObjEnumFormatEtc(
  829. LPDATAOBJECT lpDataObj,
  830. DWORD dwDirection,
  831. LPENUMFORMATETC FAR* lplpenumFormatEtc
  832. )
  833. {
  834. *lplpenumFormatEtc = NULL;
  835. RETURN_RESULT( OLE_S_USEREG);
  836. }
  837. STDMETHODIMP DataObjAdvise(LPDATAOBJECT lpDataObject,
  838. FORMATETC FAR* pFormatetc, DWORD advf,
  839. IAdviseSink FAR* pAdvSink, DWORD FAR* pdwConnection)
  840. {
  841. LPDOC lpdoc;
  842. lpdoc = ((struct CDataObjectImpl FAR*)lpDataObject)->lpdoc;
  843. VERIFY_LINDEX(pFormatetc->lindex);
  844. if (pFormatetc->cfFormat == 0 && pFormatetc->dwAspect == -1 &&
  845. pFormatetc->ptd == NULL && pFormatetc->tymed == -1)
  846. // wild card advise; don't check
  847. ;
  848. else
  849. if (DataObjQueryGetData(lpDataObject, pFormatetc) != S_OK)
  850. RETURN_RESULT( DATA_E_FORMATETC);
  851. if (lpdoc->lpdaholder == NULL &&
  852. CreateDataAdviseHolder(&lpdoc->lpdaholder) != S_OK)
  853. RETURN_RESULT( E_OUTOFMEMORY);
  854. return( IDataAdviseHolder_Advise(lpdoc->lpdaholder, lpDataObject,
  855. pFormatetc, advf, pAdvSink, pdwConnection));
  856. }
  857. STDMETHODIMP DataObjUnadvise(LPDATAOBJECT lpDataObject, DWORD dwConnection)
  858. {
  859. LPDOC lpdoc;
  860. lpdoc = ((struct CDataObjectImpl FAR*)lpDataObject)->lpdoc;
  861. if (lpdoc->lpdaholder == NULL)
  862. // no one registered
  863. RETURN_RESULT( E_INVALIDARG);
  864. return( IDataAdviseHolder_Unadvise(lpdoc->lpdaholder, dwConnection));
  865. }
  866. STDMETHODIMP DataObjEnumAdvise(LPDATAOBJECT lpDataObject,
  867. LPENUMSTATDATA FAR* ppenumAdvise)
  868. {
  869. LPDOC lpdoc;
  870. lpdoc = ((struct CDataObjectImpl FAR*)lpDataObject)->lpdoc;
  871. if (lpdoc->lpdaholder == NULL)
  872. RETURN_RESULT( E_FAIL);
  873. return( IDataAdviseHolder_EnumAdvise(lpdoc->lpdaholder, ppenumAdvise));
  874. }
  875. /**************************************************************************
  876. * DataObjSetData:
  877. * This should never be called.!! The data is actually fed through
  878. * IPersistStorage.
  879. **************************************************************************/
  880. STDMETHODIMP DataObjSetData (
  881. LPDATAOBJECT lpDataObj,
  882. LPFORMATETC lpformatetc,
  883. LPSTGMEDIUM lpmedium,
  884. BOOL fRelease
  885. )
  886. {
  887. LPVOID lpMem;
  888. LPSTR lpnative;
  889. LPDOC lpdoc = ((struct CDataObjectImpl FAR *)lpDataObj)->lpdoc;
  890. DPF1("*DOSETDATA");
  891. if(lpformatetc->cfFormat !=cfNative)
  892. RETURN_RESULT(DATA_E_FORMATETC);
  893. lpMem = GLOBALLOCK(lpmedium->hGlobal);
  894. if (lpMem)
  895. {
  896. SCODE scode;
  897. lpnative = lpMem;
  898. scode = ItemSetData((LPBYTE)lpnative);
  899. if(scode == S_OK)
  900. fDocChanged = FALSE;
  901. GLOBALUNLOCK(lpmedium->hGlobal);
  902. RETURN_RESULT(scode);
  903. }
  904. RETURN_RESULT(E_OUTOFMEMORY);
  905. }