|
|
/*---------------------------------------------------------------------------
| OBJ.C | This file has the IUnknown, IOleObject, IStdMarshalInfo and IDataObject | interfaces of the OLE2 object (docMain). it also has other helper functions | | Created By: Vij Rajarajan (VijR) +---------------------------------------------------------------------------*/ #define SERVERONLY
#include <Windows.h>
#include <shellapi.h>
#include "mpole.h"
#include "mplayer.h"
extern int FAR PASCAL ReallyDoVerb (LPDOC, LONG, LPMSG, LPOLECLIENTSITE, BOOL, BOOL); extern BOOL FindRealFileName(LPTSTR szFile, int iLen);
// static functions.
HANDLE PASCAL GetDib (VOID);
HANDLE GetMetafilePict (VOID); HANDLE GetMPlayerIcon(void);
extern void FAR PASCAL SetEmbeddedObjectFlag(BOOL flag); extern HPALETTE CopyPalette(HPALETTE hpal); extern HBITMAP FAR PASCAL BitmapMCI(void); extern HPALETTE FAR PASCAL PaletteMCI(void); extern void DoInPlaceDeactivate(LPDOC lpdoc); HANDLE FAR PASCAL PictureFromDib(HANDLE hdib, HPALETTE hpal); HANDLE FAR PASCAL DibFromBitmap(HBITMAP hbm, HPALETTE hpal); void FAR PASCAL DitherMCI(HANDLE hdib, HPALETTE hpal);
/* GetMetafilePict
* --------------- * * RETURNS: A handle to the object's data in metafile format. */ HANDLE GetMetafilePict ( ) {
HPALETTE hpal; HANDLE hdib; HANDLE hmfp; HDC hdc;
DPF("GetMetafilePict called on thread %d\n", GetCurrentThreadId());
hdib = (HANDLE)SendMessage(ghwndApp, WM_GETDIB, 0, 0);
/* If we're dithered, don't use a palette */ hdc = GetDC(NULL); if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) && (gwOptions & OPT_DITHER)) hpal = NULL; else hpal = PaletteMCI();
if (hpal) hpal = CopyPalette(hpal);
ReleaseDC(NULL, hdc);
hmfp = PictureFromDib(hdib, hpal);
if (hpal) DeleteObject(hpal);
GLOBALFREE(hdib);
return hmfp; }
/**************************************************************************
//## Somebody wants a dib (OLE)
***************************************************************************/ HANDLE PASCAL GetDib( VOID ) { HBITMAP hbm; HPALETTE hpal; HANDLE hdib; HDC hdc;
DPF("GetDib\n");
hbm = BitmapMCI(); hpal = PaletteMCI();
hdib = DibFromBitmap(hbm, hpal);
//
// if we are on a palette device. possibly dither to the VGA colors
// for apps that dont deal with palettes!
//
hdc = GetDC(NULL); if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) && (gwOptions & OPT_DITHER)) { DitherMCI(hdib, hpal); hpal = NULL; // no longer working with a palette
} ReleaseDC(NULL, hdc);
if (hbm) DeleteObject(hbm); return hdib; }
/**************************************************************************
* GetMPlayerIcon: This function extracts the our Icon and gives it out * as a Metafile incase the client wants DVASPECT_ICON ***************************************************************************/ HANDLE GetMPlayerIcon (void) { HICON hicon; HDC hdc; HANDLE hmfp = NULL; LPMETAFILEPICT pmfp=NULL; static int cxIcon = 0; static int cyIcon = 0; static int cxIconHiMetric = 0; static int cyIconHiMetric = 0;
hicon = GetIconForCurrentDevice(GI_LARGE, IDI_DDEFAULT);
if ((HICON)1==hicon || NULL==hicon) return NULL;
if (!(hmfp = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, sizeof(METAFILEPICT)))) return NULL;
pmfp = (METAFILEPICT FAR*) GLOBALLOCK (hmfp);
if (0==cxIcon) { // In units of pixels
cxIcon = GetSystemMetrics (SM_CXICON); cyIcon = GetSystemMetrics (SM_CYICON);
// In units of .01 millimeter
cxIconHiMetric = cxIcon * HIMETRIC_PER_INCH / giXppli; cyIconHiMetric = cyIcon * HIMETRIC_PER_INCH / giYppli;; }
pmfp->mm = MM_ANISOTROPIC; pmfp->xExt = cxIconHiMetric; pmfp->yExt = cyIconHiMetric; hdc = CreateMetaFile (NULL);
SetWindowOrgEx (hdc, 0, 0, NULL); SetWindowExtEx (hdc, cxIcon, cyIcon, NULL);
DrawIcon (hdc, 0, 0, hicon); pmfp->hMF = CloseMetaFile (hdc);
GLOBALUNLOCK (hmfp);
if (NULL == pmfp->hMF) { GLOBALFREE (hmfp); return NULL; }
return hmfp; }
#ifdef DEBUG
#define DBG_CHECK_GUID(guid) \
if (IsEqualIID(&guid, riidReq)) \ return #guid
LPSTR DbgGetIIDString(REFIID riidReq) { static CHAR UnknownIID[64];
DBG_CHECK_GUID(IID_IUnknown); DBG_CHECK_GUID(IID_IClassFactory); DBG_CHECK_GUID(IID_IMalloc); DBG_CHECK_GUID(IID_IMarshal); DBG_CHECK_GUID(IID_IRpcChannel); DBG_CHECK_GUID(IID_IRpcStub); DBG_CHECK_GUID(IID_IStubManager); DBG_CHECK_GUID(IID_IRpcProxy); DBG_CHECK_GUID(IID_IProxyManager); DBG_CHECK_GUID(IID_IPSFactory); DBG_CHECK_GUID(IID_ILockBytes); DBG_CHECK_GUID(IID_IStorage); DBG_CHECK_GUID(IID_IStream); DBG_CHECK_GUID(IID_IEnumSTATSTG); DBG_CHECK_GUID(IID_IBindCtx); DBG_CHECK_GUID(IID_IMoniker); DBG_CHECK_GUID(IID_IRunningObjectTable); DBG_CHECK_GUID(IID_IInternalMoniker); DBG_CHECK_GUID(IID_IRootStorage); DBG_CHECK_GUID(IID_IDfReserved1); DBG_CHECK_GUID(IID_IDfReserved2); DBG_CHECK_GUID(IID_IDfReserved3); DBG_CHECK_GUID(IID_IMessageFilter); DBG_CHECK_GUID(CLSID_StdMarshal); DBG_CHECK_GUID(IID_IStdMarshalInfo); DBG_CHECK_GUID(IID_IExternalConnection); DBG_CHECK_GUID(IID_IEnumUnknown); DBG_CHECK_GUID(IID_IEnumString); DBG_CHECK_GUID(IID_IEnumMoniker); DBG_CHECK_GUID(IID_IEnumFORMATETC); DBG_CHECK_GUID(IID_IEnumOLEVERB); DBG_CHECK_GUID(IID_IEnumSTATDATA); DBG_CHECK_GUID(IID_IEnumGeneric); DBG_CHECK_GUID(IID_IEnumHolder); DBG_CHECK_GUID(IID_IEnumCallback); DBG_CHECK_GUID(IID_IPersistStream); DBG_CHECK_GUID(IID_IPersistStorage); DBG_CHECK_GUID(IID_IPersistFile); DBG_CHECK_GUID(IID_IPersist); DBG_CHECK_GUID(IID_IViewObject); DBG_CHECK_GUID(IID_IDataObject); DBG_CHECK_GUID(IID_IAdviseSink); DBG_CHECK_GUID(IID_IDataAdviseHolder); DBG_CHECK_GUID(IID_IOleAdviseHolder); DBG_CHECK_GUID(IID_IOleObject); DBG_CHECK_GUID(IID_IOleInPlaceObject); DBG_CHECK_GUID(IID_IOleWindow); DBG_CHECK_GUID(IID_IOleInPlaceUIWindow); DBG_CHECK_GUID(IID_IOleInPlaceFrame); DBG_CHECK_GUID(IID_IOleInPlaceActiveObject); DBG_CHECK_GUID(IID_IOleClientSite); DBG_CHECK_GUID(IID_IOleInPlaceSite); DBG_CHECK_GUID(IID_IParseDisplayName); DBG_CHECK_GUID(IID_IOleContainer); DBG_CHECK_GUID(IID_IOleItemContainer); DBG_CHECK_GUID(IID_IOleLink); DBG_CHECK_GUID(IID_IOleCache); DBG_CHECK_GUID(IID_IOleManager); DBG_CHECK_GUID(IID_IOlePresObj); DBG_CHECK_GUID(IID_IDropSource); DBG_CHECK_GUID(IID_IDropTarget); DBG_CHECK_GUID(IID_IDebug); DBG_CHECK_GUID(IID_IDebugStream); DBG_CHECK_GUID(IID_IAdviseSink2); DBG_CHECK_GUID(IID_IRunnableObject); DBG_CHECK_GUID(IID_IViewObject2); DBG_CHECK_GUID(IID_IOleCache2); DBG_CHECK_GUID(IID_IOleCacheControl);
wsprintfA(UnknownIID, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", riidReq->Data1, riidReq->Data2, riidReq->Data3, riidReq->Data4[0], riidReq->Data4[1], riidReq->Data4[2], riidReq->Data4[3], riidReq->Data4[4], riidReq->Data4[5], riidReq->Data4[6], riidReq->Data4[7]);
return UnknownIID; }
#endif
/**************************************************************************
***************** IUnknown INTERFACE IMPLEMENTATION. **************************************************************************/
STDMETHODIMP UnkQueryInterface( LPUNKNOWN lpUnkObj, // Unknown object ptr
REFIID riidReq, // IID required
LPVOID FAR * lplpUnk // pre for returning the interface
) { LPDOC lpdoc;
lpdoc = ((struct COleObjectImpl FAR*)lpUnkObj)->lpdoc;
DPF1("QueryInterface( %s )\n", DbgGetIIDString(riidReq));
if (IsEqualIID(riidReq, &IID_IOleObject)) { *lplpUnk = (LPVOID) &lpdoc->m_Ole; lpdoc->cRef++; return NOERROR;
} else if (IsEqualIID(riidReq, &IID_IDataObject)) { *lplpUnk = (LPVOID) &lpdoc->m_Data; lpdoc->cRef++; return NOERROR;
} else if (IsEqualIID(riidReq, &IID_IUnknown)) { *lplpUnk = (LPVOID) &lpdoc->m_Ole; lpdoc->cRef++; return NOERROR;
} else if (IsEqualIID(riidReq, &IID_IPersist) || IsEqualIID(riidReq, &IID_IPersistStorage)) { *lplpUnk = (LPVOID) &lpdoc->m_PersistStorage; lpdoc->cRef++; return NOERROR;
} else if (IsEqualIID(riidReq, &IID_IPersistFile)) { *lplpUnk = (LPVOID) &lpdoc->m_PersistFile; lpdoc->cRef++; return NOERROR;
} else if (IsEqualIID(riidReq, &IID_IOleWindow) || IsEqualIID(riidReq, &IID_IOleInPlaceObject)) { *lplpUnk = (LPVOID) &lpdoc->m_InPlace; lpdoc->cRef++; return NOERROR;
} else if (IsEqualIID(riidReq, &IID_IOleInPlaceActiveObject)) { *lplpUnk = (LPVOID) &lpdoc->m_IPActive; lpdoc->cRef++; return NOERROR;
} else { *lplpUnk = (LPVOID) NULL; DPF1("E_NOINTERFACE\n"); RETURN_RESULT(E_NOINTERFACE); } }
STDMETHODIMP_(ULONG) UnkAddRef(LPUNKNOWN lpUnkObj) { LPDOC lpdoc;
lpdoc = ((struct COleObjectImpl FAR*)lpUnkObj)->lpdoc; return ++lpdoc->cRef; }
STDMETHODIMP_(ULONG) UnkRelease (LPUNKNOWN lpUnkObj) { LPDOC lpdoc;
lpdoc = ((struct COleObjectImpl FAR*)lpUnkObj)->lpdoc; if (--lpdoc->cRef == 0) { DPF1("\n**^*^*^*^*^*^*^*^*^*^*^*^*Refcnt OK\n"); if (!(gfOle2IPPlaying || gfOle2IPEditing) && srvrMain.cLock == 0) PostCloseMessage(); return 0; }
return lpdoc->cRef; }
/**************************************************************************
************* IOleObject INTERFACE IMPLEMENTATION **************************************************************************/
//delegate to the common IUnknown Implemenation.
STDMETHODIMP OleObjQueryInterface( LPOLEOBJECT lpOleObj, // ole object ptr
REFIID riidReq, // IID required
LPVOID FAR * lplpUnk // pre for returning the interface
) { return( UnkQueryInterface((LPUNKNOWN)lpOleObj, riidReq, lplpUnk)); }
STDMETHODIMP_(ULONG) OleObjAddRef( LPOLEOBJECT lpOleObj // ole object ptr
) { return UnkAddRef((LPUNKNOWN) lpOleObj); }
STDMETHODIMP_(ULONG) OleObjRelease ( LPOLEOBJECT lpOleObj // ole object ptr
) { LPDOC lpdoc;
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
return UnkRelease((LPUNKNOWN) lpOleObj); }
//Save the Client site pointer.
STDMETHODIMP OleObjSetClientSite( LPOLEOBJECT lpOleObj, LPOLECLIENTSITE lpclientSite ) { LPDOC lpdoc;
DPF("OleObjSetClientSite\n");
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
if (lpdoc->lpoleclient) IOleClientSite_Release(lpdoc->lpoleclient);
lpdoc->lpoleclient = (LPOLECLIENTSITE) lpclientSite;
// OLE2NOTE: to be able to hold onto clientSite pointer, we must AddRef it
if (lpclientSite) IOleClientSite_AddRef(lpclientSite);
return NOERROR; }
STDMETHODIMP OleObjGetClientSite ( LPOLEOBJECT lpOleObj, LPOLECLIENTSITE FAR* lplpclientSite ) { DPF("OleObjGetClientSite\n");
return NOERROR; }
/* CheckIfInPPViewer
* * Hack to stop PowerPoint viewer from crashing when we're trying to play in place. * * PP Viewer was written under the assumption that Media Player was not a full-blown * OLE2 server. Much of the code was stubbed out to make the Viewer small. * Unfortunately this means it crashes when certain calls are made for in-place * activation. These are the problem interface methods: * * OnInPlaceActivate/Deactivate * OnUIActivate/Deactivate * OnPosRectChange * * If we're in PP Viewer we simply do not make these calls. * * We detect that we're in PP Viewer by finding the parent of the window whose * handle is passed to DoVerb. The window handle passed in to DoVerb is of * "ppSlideShowWin" class, which is the same as in PP Slide Show, which works * correctly. However its parent's class is "PP4VDialog" (as distinct from * "PPApplicationClass"). So, if we find this class name, set a global flag * to test before making the troublesome calls. * * Andrew Bell (andrewbe) 11 May 1995 * */ STATICFN void CheckIfInPPViewer(HWND hwndParent) { HWND hwndGrandParent; TCHAR ClassName[256];
gfInPPViewer = FALSE;
if (hwndParent) { hwndGrandParent = GetParent(hwndParent);
if (hwndGrandParent) { if (GetClassName(hwndGrandParent, ClassName, CHAR_COUNT(ClassName)) > 0) { if (lstrcmp(ClassName, TEXT("PP4VDialog")) == 0) { DPF0("Detected that we're in PP Viewer\n"); gfInPPViewer = TRUE; } } } } }
//delegate to ReallyDoVerb.
STDMETHODIMP OleObjDoVerb( LPOLEOBJECT lpOleObj, LONG lVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect ) { LPDOC lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
DPF("OleObjDoVerb\n");
CheckIfInPPViewer(hwndParent);
RETURN_RESULT( ReallyDoVerb(lpdoc, lVerb, lpmsg, pActiveSite, TRUE, TRUE)); }
STDMETHODIMP OleObjEnumVerbs( LPOLEOBJECT lpOleObj, IEnumOLEVERB FAR* FAR* lplpenumOleVerb ) { DPF("OleObjEnumVerbs\n");
*lplpenumOleVerb = NULL; RETURN_RESULT( OLE_S_USEREG); //Use the reg db.
}
STDMETHODIMP OleObjUpdate(LPOLEOBJECT lpOleObj) { DPF("OleObjUpdate\n");
// we can't contain links so there is nothing to update
return NOERROR; }
STDMETHODIMP OleObjIsUpToDate(LPOLEOBJECT lpOleObj) { DPF("OleObjIsUpToDate\n");
// we can't contain links so there is nothing to update
return NOERROR; }
/*
From OLE2HELP.HLP:
GetUserClassID returns the CLSID as the user knows it. For embedded objects, this is always the CLSID that is persistently stored and is returned by IPersist::GetClassID. For linked objects, this is the CLSID of the last bound link source. If a Treat As operation is taking place, this is the CLSID of the application being emulated (also the CLSID that will be written into storage).
I can't follow the logic here. What if it's an embedded object and a Treat As operation? However, AlexGo tells me that my IOleObject interfaces should return the OLE2 Class ID. */ STDMETHODIMP OleObjGetUserClassID (LPOLEOBJECT lpOleObj, CLSID FAR* pClsid) { DPF1("OleObjGetUserClassID\n");
*pClsid = gClsID;
return NOERROR; }
/**************************************************************************
* Set our UserTypeName to "Media Clip" **************************************************************************/
STDMETHODIMP OleObjGetUserType (LPOLEOBJECT lpOleObj, DWORD dwFormOfType, LPWSTR FAR* pszUserType) { LPMALLOC lpMalloc; LPWSTR lpstr; int clen;
DPF1("OleObjGetUserType\n");
*pszUserType = NULL; if(CoGetMalloc(MEMCTX_TASK,&lpMalloc) != 0) RETURN_RESULT(E_OUTOFMEMORY); clen = STRING_BYTE_COUNT(gachClassRoot); #ifndef UNICODE
clen *= (sizeof(WCHAR) / sizeof(CHAR)); #endif
lpstr = IMalloc_Alloc(lpMalloc, clen); IMalloc_Release(lpMalloc); #ifdef UNICODE
lstrcpy(lpstr,gachClassRoot); #else
AnsiToUnicodeString(gachClassRoot, lpstr, -1); #endif /* UNICODE */
*pszUserType = lpstr; return NOERROR; }
/**************************************************************************
* Get the name of the client and set the title. **************************************************************************/ STDMETHODIMP OleObjSetHostNames ( LPOLEOBJECT lpOleObj, LPCWSTR lpszClientAppW, LPCWSTR lpszClientObjW ) { LPDOC lpdoc; LPTSTR lpszClientApp; LPTSTR lpszClientObj;
DPF1("OleObjSetHostNames\n");
#ifdef UNICODE
lpszClientApp = (LPTSTR)lpszClientAppW; lpszClientObj = (LPTSTR)lpszClientObjW; #else
lpszClientApp = AllocateAnsiString(lpszClientAppW); lpszClientObj = AllocateAnsiString(lpszClientObjW); if( !lpszClientApp || !lpszClientObj ) RETURN_RESULT(E_OUTOFMEMORY); #endif /* UNICODE */
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
// object is embedded.
lpdoc->doctype = doctypeEmbedded;
if (lpszClientObj == NULL) lpszClientObj = lpszClientApp;
SetTitle(lpdoc, lpszClientObj); SetMPlayerIcon(); lstrcpy (szClient, lpszClientApp); if (lpszClientObj) { LPTSTR lpszFileName = FileName(lpszClientObj); if (lpszFileName) lstrcpy (szClientDoc, lpszFileName); }
// this is the only time we know the object will be an embedding
SetEmbeddedObjectFlag(TRUE);
#ifndef UNICODE
FreeAnsiString(lpszClientApp); FreeAnsiString(lpszClientObj); #endif /* NOT UNICODE */
return NOERROR; }
/**************************************************************************
* The client closed the object. The server will now shut down. **************************************************************************/ STDMETHODIMP OleObjClose ( LPOLEOBJECT lpOleObj, DWORD dwSaveOptions ) { LPDOC lpdoc;
DPF1("OleObjClose\n");
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
/* Hack to stop PowerPoint crashing:
* * Win95 bug #19848: Crash saving PowerPoint with out-of-place mplayer * * If we don't call IOleClientSite::SaveObject() at this point, * PowerPoint will crash under certain circumstances. * * This is an extract from mail I received from TuanN, the PPT dev: * * The fundamental problem is that PP expects to receive the * IAdviseSink::SaveObject() as a result of calling IOleObject::Close(). * Since the Media Player did not send that notficiation in this test case, * PP tries to perform an Undo operation during the ensuing OnClose() * notification and thus erroneously destroys the embedded object. * The reason we throw away the object is because PP thinks that this * object is still virgin (no OnViewChange). Please refer to SaveObject(), * OnClose() in CtCommon.cpp and slide\sextern.c for more info. In the test * case, during OnClose(), the "revert" state is TRUE, PP will do a * Ex_REVERTED operation (stack calls: SClosePicts, SClear, * SSaveforUndo--> object deleted). * * AndrewBe, 6 December 1994 */ if (lpdoc->lpoleclient) IOleClientSite_SaveObject(lpdoc->lpoleclient);
DoInPlaceDeactivate(lpdoc); SendDocMsg(lpdoc,OLE_CLOSED); DestroyDoc(lpdoc); ExitApplication(); //CoDisconnectObject((LPUNKNOWN)lpdoc, NULL);
SendMessage(ghwndApp, WM_COMMAND, (WPARAM)IDM_EXIT, 0L); return NOERROR; }
STDMETHODIMP OleObjSetMoniker(LPOLEOBJECT lpOleObj, DWORD dwWhichMoniker, LPMONIKER pmk) { DPF("OleObjSetMoniker\n");
return NOERROR; }
STDMETHODIMP OleObjGetMoniker(LPOLEOBJECT lpOleObj, DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER FAR* lplpmk) { LPDOC lpdoc;
DPF("OleObjGetMoniker\n");
*lplpmk = NULL; lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
if (lpdoc->lpoleclient != NULL) { return( IOleClientSite_GetMoniker(lpdoc->lpoleclient, dwAssign, dwWhichMoniker, lplpmk)); } else if (lpdoc->doctype == doctypeFromFile) { // use file moniker
WCHAR sz[cchFilenameMax];
if (GlobalGetAtomNameW(lpdoc->aDocName, sz, CHAR_COUNT(sz)) == 0) RETURN_RESULT( E_FAIL);
return( (HRESULT)CreateFileMoniker(sz, lplpmk)); } else RETURN_RESULT( E_FAIL); }
STDMETHODIMP OleObjInitFromData ( LPOLEOBJECT lpOleObj, LPDATAOBJECT lpDataObj, BOOL fCreation, DWORD dwReserved ) { DPF("OleObjInitFromData - E_NOTIMPL\n");
RETURN_RESULT( E_NOTIMPL); }
STDMETHODIMP OleObjGetClipboardData ( LPOLEOBJECT lpOleObj, DWORD dwReserved, LPDATAOBJECT FAR* lplpDataObj ) { DPF("OleObjGetClipboardData - E_NOTIMPL\n");
RETURN_RESULT( E_NOTIMPL); }
STDMETHODIMP OleObjSetExtent( LPOLEOBJECT lpOleObj, DWORD dwAspect, LPSIZEL lpsizel) { DPF("OleObjSetExtent\n");
#ifdef LATER
gscaleInitXY[SCALE_X].denom = lpsizel->cx; gscaleInitXY[SCALE_Y].denom = lpsizel->cy; #endif
return NOERROR; }
//Get the object extent from the Metafile. GetMetafilePict saves the extents
// in extWidth and extHeight
STDMETHODIMP OleObjGetExtent( LPOLEOBJECT lpOleObj, DWORD dwAspect, LPSIZEL lpSizel) { HGLOBAL hTmpMF; LPDOC lpdoc;
DPF("OleObjGetExtent\n");
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
if((dwAspect & (DVASPECT_CONTENT | DVASPECT_DOCPRINT)) == 0) RETURN_RESULT( E_INVALIDARG); // There may be a potential memory leak here -- hTmpMF contains a handle to a
// metafile that must be deleted. See code in cdrag.c.
// Not changed here at this time since I do not want to break anything.
// SteveZ
hTmpMF = GetMetafilePict(); GLOBALUNLOCK(hTmpMF); GLOBALFREE(hTmpMF); lpSizel->cx = extWidth; lpSizel->cy = extHeight;
return NOERROR; }
STDMETHODIMP OleObjAdvise(LPOLEOBJECT lpOleObj, LPADVISESINK lpAdvSink, LPDWORD lpdwConnection) { LPDOC lpdoc;
DPF("OleObjAdvise\n");
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
if (lpdoc->lpoaholder == NULL && CreateOleAdviseHolder(&lpdoc->lpoaholder) != S_OK) RETURN_RESULT( E_OUTOFMEMORY);
return( IOleAdviseHolder_Advise(lpdoc->lpoaholder, lpAdvSink, lpdwConnection)); }
STDMETHODIMP OleObjUnadvise(LPOLEOBJECT lpOleObj, DWORD dwConnection) { LPDOC lpdoc;
DPF("OleObjUnadvise\n");
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
if (lpdoc->lpoaholder == NULL) RETURN_RESULT( E_FAIL);
return( IOleAdviseHolder_Unadvise(lpdoc->lpoaholder, dwConnection)); }
STDMETHODIMP OleObjEnumAdvise(LPOLEOBJECT lpOleObj, LPENUMSTATDATA FAR* lplpenumAdvise) { LPDOC lpdoc;
DPF("OleObjEnumAdvise\n");
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
if (lpdoc->lpoaholder == NULL) RETURN_RESULT( E_FAIL);
return(IOleAdviseHolder_EnumAdvise(lpdoc->lpoaholder, lplpenumAdvise)); }
STDMETHODIMP OleObjGetMiscStatus (LPOLEOBJECT lpOleObj, DWORD dwAspect, DWORD FAR* pdwStatus) { DPF("OleObjGetMiscStatus\n");
RETURN_RESULT( OLE_S_USEREG); }
STDMETHODIMP OleObjSetColorScheme(LPOLEOBJECT lpOleObj, LPLOGPALETTE lpLogPal) { DPF("OleObjSetColorScheme\n");
return NOERROR; }
STDMETHODIMP OleObjLockObject(LPOLEOBJECT lpOleObj, BOOL fLock) { LPDOC lpdoc;
DPF("OleObjLockObject\n");
lpdoc = ((struct COleObjectImpl FAR*)lpOleObj)->lpdoc;
if (fLock) lpdoc->cLock++; else { if (!lpdoc->cLock) RETURN_RESULT( E_FAIL);
if (--lpdoc->cLock == 0) OleObjClose(lpOleObj, OLECLOSE_SAVEIFDIRTY);
return NOERROR; }
return NOERROR; }
/**************************************************************************
************* IDataObject INTERFACE IMPLEMENTATION. **************************************************************************/
//Delegate to the common IUnknown implementation.
STDMETHODIMP DataObjQueryInterface ( LPDATAOBJECT lpDataObj, // data object ptr
REFIID riidReq, // IID required
LPVOID FAR * lplpUnk // pre for returning the interface
) { return( UnkQueryInterface((LPUNKNOWN)lpDataObj, riidReq, lplpUnk)); }
STDMETHODIMP_(ULONG) DataObjAddRef( LPDATAOBJECT lpDataObj // data object ptr
) { return UnkAddRef((LPUNKNOWN) lpDataObj); }
STDMETHODIMP_(ULONG) DataObjRelease ( LPDATAOBJECT lpDataObj // data object ptr
) { LPDOC lpdoc;
lpdoc = ((struct CDataObjectImpl FAR*)lpDataObj)->lpdoc;
return UnkRelease((LPUNKNOWN) lpDataObj); }
/**************************************************************************
* DataObjGetData: * Provides the data for METAFILE and DIB formats. **************************************************************************/ STDMETHODIMP DataObjGetData ( LPDATAOBJECT lpDataObj, LPFORMATETC lpformatetc, LPSTGMEDIUM lpMedium ) { LPDOC lpdoc;
DPF1("DataObjGetData\n");
if (lpMedium == NULL) RETURN_RESULT( E_FAIL);
// null out in case of error
lpMedium->tymed = TYMED_NULL; lpMedium->pUnkForRelease = NULL; lpMedium->hGlobal = NULL;
lpdoc = ((struct CDataObjectImpl FAR*)lpDataObj)->lpdoc;
VERIFY_LINDEX(lpformatetc->lindex);
if (lpformatetc->dwAspect == DVASPECT_ICON) { if (lpformatetc->cfFormat != CF_METAFILEPICT) RETURN_RESULT( DATA_E_FORMATETC); } else { if (!(lpformatetc->dwAspect & (DVASPECT_CONTENT | DVASPECT_DOCPRINT))) RETURN_RESULT( DATA_E_FORMATETC); // we support only these 2 aspects
}
if (lpMedium->tymed != TYMED_NULL) // all the other formats we only give out in our own global block
RETURN_RESULT( DATA_E_FORMATETC);
lpMedium->tymed = TYMED_HGLOBAL; if (lpformatetc->cfFormat == CF_METAFILEPICT) { lpMedium->tymed = TYMED_MFPICT;
DPF1("Before getmeta\n"); if (lpformatetc->dwAspect == DVASPECT_ICON) lpMedium->hGlobal = GetMPlayerIcon (); else lpMedium->hGlobal = GetMetafilePict (); DPF1("After getmeta\n");
if (!lpMedium->hGlobal) RETURN_RESULT( E_OUTOFMEMORY);
#ifdef DEBUG
if (__iDebugLevel >= 1) { /* Useful check to validate what we're passing back to the container.
*/ if (OpenClipboard(ghwndApp)) { EmptyClipboard(); SetClipboardData(CF_METAFILEPICT, lpMedium->hGlobal); CloseClipboard(); } } #endif
return NOERROR; }
if (lpformatetc->cfFormat == CF_DIB) { lpMedium->tymed = TYMED_HGLOBAL; lpMedium->hGlobal = (HANDLE)GetDib(); if (!(lpMedium->hGlobal)) RETURN_RESULT( E_OUTOFMEMORY);
#ifdef DEBUG
if (__iDebugLevel >= 1) { /* Useful check to validate what we're passing back to the container.
*/ if (OpenClipboard(ghwndApp)) { EmptyClipboard(); SetClipboardData(CF_DIB, lpMedium->hGlobal); CloseClipboard(); } } #endif
return NOERROR; } RETURN_RESULT( DATA_E_FORMATETC); }
STDMETHODIMP DataObjGetDataHere ( LPDATAOBJECT lpDataObj, LPFORMATETC lpformatetc, LPSTGMEDIUM lpMedium ) { RETURN_RESULT( E_NOTIMPL); }
STDMETHODIMP DataObjQueryGetData ( LPDATAOBJECT lpDataObj, LPFORMATETC lpformatetc ) { // this is only a query
if ((lpformatetc->cfFormat == CF_METAFILEPICT) && (lpformatetc->tymed & TYMED_MFPICT)) return NOERROR; if ((lpformatetc->cfFormat == CF_DIB) && (lpformatetc->tymed & TYMED_HGLOBAL)) return NOERROR; RETURN_RESULT( DATA_E_FORMATETC); }
STDMETHODIMP DataObjGetCanonicalFormatEtc( LPDATAOBJECT lpDataObj, LPFORMATETC lpformatetc, LPFORMATETC lpformatetcOut ) { RETURN_RESULT(DATA_S_SAMEFORMATETC); }
STDMETHODIMP DataObjEnumFormatEtc( LPDATAOBJECT lpDataObj, DWORD dwDirection, LPENUMFORMATETC FAR* lplpenumFormatEtc ) { *lplpenumFormatEtc = NULL; RETURN_RESULT( OLE_S_USEREG); }
STDMETHODIMP DataObjAdvise(LPDATAOBJECT lpDataObject, FORMATETC FAR* pFormatetc, DWORD advf, IAdviseSink FAR* pAdvSink, DWORD FAR* pdwConnection) { LPDOC lpdoc;
lpdoc = ((struct CDataObjectImpl FAR*)lpDataObject)->lpdoc;
VERIFY_LINDEX(pFormatetc->lindex); if (pFormatetc->cfFormat == 0 && pFormatetc->dwAspect == -1 && pFormatetc->ptd == NULL && pFormatetc->tymed == -1) // wild card advise; don't check
; else
if (DataObjQueryGetData(lpDataObject, pFormatetc) != S_OK) RETURN_RESULT( DATA_E_FORMATETC);
if (lpdoc->lpdaholder == NULL && CreateDataAdviseHolder(&lpdoc->lpdaholder) != S_OK) RETURN_RESULT( E_OUTOFMEMORY);
return( IDataAdviseHolder_Advise(lpdoc->lpdaholder, lpDataObject, pFormatetc, advf, pAdvSink, pdwConnection)); }
STDMETHODIMP DataObjUnadvise(LPDATAOBJECT lpDataObject, DWORD dwConnection) { LPDOC lpdoc;
lpdoc = ((struct CDataObjectImpl FAR*)lpDataObject)->lpdoc;
if (lpdoc->lpdaholder == NULL) // no one registered
RETURN_RESULT( E_INVALIDARG);
return( IDataAdviseHolder_Unadvise(lpdoc->lpdaholder, dwConnection)); }
STDMETHODIMP DataObjEnumAdvise(LPDATAOBJECT lpDataObject, LPENUMSTATDATA FAR* ppenumAdvise) { LPDOC lpdoc;
lpdoc = ((struct CDataObjectImpl FAR*)lpDataObject)->lpdoc;
if (lpdoc->lpdaholder == NULL) RETURN_RESULT( E_FAIL);
return( IDataAdviseHolder_EnumAdvise(lpdoc->lpdaholder, ppenumAdvise)); }
/**************************************************************************
* DataObjSetData: * This should never be called.!! The data is actually fed through * IPersistStorage. **************************************************************************/ STDMETHODIMP DataObjSetData ( LPDATAOBJECT lpDataObj, LPFORMATETC lpformatetc, LPSTGMEDIUM lpmedium, BOOL fRelease ) { LPVOID lpMem; LPSTR lpnative; LPDOC lpdoc = ((struct CDataObjectImpl FAR *)lpDataObj)->lpdoc; DPF1("*DOSETDATA");
if(lpformatetc->cfFormat !=cfNative) RETURN_RESULT(DATA_E_FORMATETC);
lpMem = GLOBALLOCK(lpmedium->hGlobal);
if (lpMem) { SCODE scode;
lpnative = lpMem;
scode = ItemSetData((LPBYTE)lpnative);
if(scode == S_OK) fDocChanged = FALSE;
GLOBALUNLOCK(lpmedium->hGlobal);
RETURN_RESULT(scode); }
RETURN_RESULT(E_OUTOFMEMORY); }
|