📄 datacache.c
字号:
* DataCache_GetExtent (IViewObject2)
*
* This method retrieves the "natural" size of this cached object.
*
* See Windows documentation for more details on IViewObject2 methods.
*/
static HRESULT WINAPI DataCache_GetExtent(
IViewObject2* iface,
DWORD dwDrawAspect,
LONG lindex,
DVTARGETDEVICE* ptd,
LPSIZEL lpsizel)
{
DataCache *This = impl_from_IViewObject2(iface);
HRESULT hres = E_FAIL;
DataCacheEntry *cache_entry;
TRACE("(%p, %x, %d, %p, %p)\n",
iface, dwDrawAspect, lindex, ptd, lpsizel);
/*
* Sanity check
*/
if (lpsizel==NULL)
return E_POINTER;
/*
* Initialize the out parameter.
*/
lpsizel->cx = 0;
lpsizel->cy = 0;
/*
* This flag should be set to -1.
*/
if (lindex!=-1)
FIXME("Unimplemented flag lindex = %d\n", lindex);
/*
* Right now, we support only the callback from
* the default handler.
*/
if (ptd!=NULL)
FIXME("Unimplemented ptd = %p\n", ptd);
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
{
/* FIXME: compare ptd too */
if ((cache_entry->fmtetc.dwAspect != dwDrawAspect) ||
(cache_entry->fmtetc.lindex != lindex))
continue;
/* if the data hasn't been loaded yet, do it now */
if ((cache_entry->stgmedium.tymed == TYMED_NULL) && cache_entry->storage)
{
hres = DataCacheEntry_LoadData(cache_entry);
if (FAILED(hres))
continue;
}
/* no data */
if (cache_entry->stgmedium.tymed == TYMED_NULL)
continue;
switch (cache_entry->data_cf)
{
case CF_METAFILEPICT:
{
METAFILEPICT *mfpict;
if ((cache_entry->stgmedium.tymed != TYMED_MFPICT) ||
!((mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict))))
continue;
lpsizel->cx = mfpict->xExt;
lpsizel->cy = mfpict->yExt;
GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);
return S_OK;
}
}
}
WARN("no data could be found to get the extents from\n");
/*
* This method returns OLE_E_BLANK when it fails.
*/
return OLE_E_BLANK;
}
/*********************************************************
* Method implementation for the IOleCache2
* part of the DataCache class.
*/
/************************************************************************
* DataCache_IOleCache2_QueryInterface (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
IOleCache2* iface,
REFIID riid,
void** ppvObject)
{
DataCache *this = impl_from_IOleCache2(iface);
return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
}
/************************************************************************
* DataCache_IOleCache2_AddRef (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static ULONG WINAPI DataCache_IOleCache2_AddRef(
IOleCache2* iface)
{
DataCache *this = impl_from_IOleCache2(iface);
return IUnknown_AddRef(this->outerUnknown);
}
/************************************************************************
* DataCache_IOleCache2_Release (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static ULONG WINAPI DataCache_IOleCache2_Release(
IOleCache2* iface)
{
DataCache *this = impl_from_IOleCache2(iface);
return IUnknown_Release(this->outerUnknown);
}
static HRESULT WINAPI DataCache_Cache(
IOleCache2* iface,
FORMATETC* pformatetc,
DWORD advf,
DWORD* pdwConnection)
{
DataCache *This = impl_from_IOleCache2(iface);
DataCacheEntry *cache_entry;
HRESULT hr;
TRACE("(%p, 0x%x, %p)\n", pformatetc, advf, pdwConnection);
TRACE("pformatetc = %s\n", debugstr_formatetc(pformatetc));
*pdwConnection = 0;
cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetc);
if (cache_entry)
{
TRACE("found an existing cache entry\n");
*pdwConnection = cache_entry->id;
return CACHE_S_SAMECACHE;
}
hr = DataCache_CreateEntry(This, pformatetc, &cache_entry);
if (SUCCEEDED(hr))
*pdwConnection = cache_entry->id;
return hr;
}
static HRESULT WINAPI DataCache_Uncache(
IOleCache2* iface,
DWORD dwConnection)
{
DataCache *This = impl_from_IOleCache2(iface);
DataCacheEntry *cache_entry;
TRACE("(%d)\n", dwConnection);
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
if (cache_entry->id == dwConnection)
{
DataCacheEntry_Destroy(cache_entry);
return S_OK;
}
WARN("no connection found for %d\n", dwConnection);
return OLE_E_NOCONNECTION;
}
static HRESULT WINAPI DataCache_EnumCache(
IOleCache2* iface,
IEnumSTATDATA** ppenumSTATDATA)
{
FIXME("stub\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DataCache_InitCache(
IOleCache2* iface,
IDataObject* pDataObject)
{
FIXME("stub\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DataCache_IOleCache2_SetData(
IOleCache2* iface,
FORMATETC* pformatetc,
STGMEDIUM* pmedium,
BOOL fRelease)
{
DataCache *This = impl_from_IOleCache2(iface);
DataCacheEntry *cache_entry;
HRESULT hr;
TRACE("(%p, %p, %s)\n", pformatetc, pmedium, fRelease ? "TRUE" : "FALSE");
TRACE("formatetc = %s\n", debugstr_formatetc(pformatetc));
cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetc);
if (cache_entry)
{
hr = DataCacheEntry_SetData(cache_entry, pformatetc, pmedium, fRelease);
if (SUCCEEDED(hr))
DataCache_FireOnViewChange(This, cache_entry->fmtetc.dwAspect,
cache_entry->fmtetc.lindex);
return hr;
}
WARN("cache entry not found\n");
return OLE_E_BLANK;
}
static HRESULT WINAPI DataCache_UpdateCache(
IOleCache2* iface,
LPDATAOBJECT pDataObject,
DWORD grfUpdf,
LPVOID pReserved)
{
FIXME("(%p, 0x%x, %p): stub\n", pDataObject, grfUpdf, pReserved);
return E_NOTIMPL;
}
static HRESULT WINAPI DataCache_DiscardCache(
IOleCache2* iface,
DWORD dwDiscardOptions)
{
DataCache *This = impl_from_IOleCache2(iface);
DataCacheEntry *cache_entry;
HRESULT hr = S_OK;
TRACE("(%d)\n", dwDiscardOptions);
if (dwDiscardOptions == DISCARDCACHE_SAVEIFDIRTY)
hr = DataCache_Save((IPersistStorage *)&This->lpvtblIPersistStorage,
This->presentationStorage, TRUE);
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
{
hr = DataCacheEntry_DiscardData(cache_entry);
if (FAILED(hr))
break;
}
return hr;
}
/*********************************************************
* Method implementation for the IOleCacheControl
* part of the DataCache class.
*/
/************************************************************************
* DataCache_IOleCacheControl_QueryInterface (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
IOleCacheControl* iface,
REFIID riid,
void** ppvObject)
{
DataCache *this = impl_from_IOleCacheControl(iface);
return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
}
/************************************************************************
* DataCache_IOleCacheControl_AddRef (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
IOleCacheControl* iface)
{
DataCache *this = impl_from_IOleCacheControl(iface);
return IUnknown_AddRef(this->outerUnknown);
}
/************************************************************************
* DataCache_IOleCacheControl_Release (IUnknown)
*
* See Windows documentation for more details on IUnknown methods.
*/
static ULONG WINAPI DataCache_IOleCacheControl_Release(
IOleCacheControl* iface)
{
DataCache *this = impl_from_IOleCacheControl(iface);
return IUnknown_Release(this->outerUnknown);
}
static HRESULT WINAPI DataCache_OnRun(
IOleCacheControl* iface,
LPDATAOBJECT pDataObject)
{
FIXME("stub\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DataCache_OnStop(
IOleCacheControl* iface)
{
FIXME("stub\n");
return E_NOTIMPL;
}
/*
* Virtual function tables for the DataCache class.
*/
static const IUnknownVtbl DataCache_NDIUnknown_VTable =
{
DataCache_NDIUnknown_QueryInterface,
DataCache_NDIUnknown_AddRef,
DataCache_NDIUnknown_Release
};
static const IDataObjectVtbl DataCache_IDataObject_VTable =
{
DataCache_IDataObject_QueryInterface,
DataCache_IDataObject_AddRef,
DataCache_IDataObject_Release,
DataCache_GetData,
DataCache_GetDataHere,
DataCache_QueryGetData,
DataCache_GetCanonicalFormatEtc,
DataCache_IDataObject_SetData,
DataCache_EnumFormatEtc,
DataCache_DAdvise,
DataCache_DUnadvise,
DataCache_EnumDAdvise
};
static const IPersistStorageVtbl DataCache_IPersistStorage_VTable =
{
DataCache_IPersistStorage_QueryInterface,
DataCache_IPersistStorage_AddRef,
DataCache_IPersistStorage_Release,
DataCache_GetClassID,
DataCache_IsDirty,
DataCache_InitNew,
DataCache_Load,
DataCache_Save,
DataCache_SaveCompleted,
DataCache_HandsOffStorage
};
static const IViewObject2Vtbl DataCache_IViewObject2_VTable =
{
DataCache_IViewObject2_QueryInterface,
DataCache_IViewObject2_AddRef,
DataCache_IViewObject2_Release,
DataCache_Draw,
DataCache_GetColorSet,
DataCache_Freeze,
DataCache_Unfreeze,
DataCache_SetAdvise,
DataCache_GetAdvise,
DataCache_GetExtent
};
static const IOleCache2Vtbl DataCache_IOleCache2_VTable =
{
DataCache_IOleCache2_QueryInterface,
DataCache_IOleCache2_AddRef,
DataCache_IOleCache2_Release,
DataCache_Cache,
DataCache_Uncache,
DataCache_EnumCache,
DataCache_InitCache,
DataCache_IOleCache2_SetData,
DataCache_UpdateCache,
DataCache_DiscardCache
};
static const IOleCacheControlVtbl DataCache_IOleCacheControl_VTable =
{
DataCache_IOleCacheControl_QueryInterface,
DataCache_IOleCacheControl_AddRef,
DataCache_IOleCacheControl_Release,
DataCache_OnRun,
DataCache_OnStop
};
/******************************************************************************
* CreateDataCache [OLE32.@]
*
* Creates a data cache to allow an object to render one or more of its views,
* whether running or not.
*
* PARAMS
* pUnkOuter [I] Outer unknown for the object.
* rclsid [I]
* riid [I] IID of interface to return.
* ppvObj [O] Address where the data cache object will be stored on return.
*
* RETURNS
* Success: S_OK.
* Failure: HRESULT code.
*
* NOTES
* The following interfaces are supported by the returned data cache object:
* IOleCache, IOleCache2, IOleCacheControl, IPersistStorae, IDataObject,
* IViewObject and IViewObject2.
*/
HRESULT WINAPI CreateDataCache(
LPUNKNOWN pUnkOuter,
REFCLSID rclsid,
REFIID riid,
LPVOID* ppvObj)
{
DataCache* newCache = NULL;
HRESULT hr = S_OK;
TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid), pUnkOuter, debugstr_guid(riid), ppvObj);
/*
* Sanity check
*/
if (ppvObj==0)
return E_POINTER;
*ppvObj = 0;
/*
* If this cache is constructed for aggregation, make sure
* the caller is requesting the IUnknown interface.
* This is necessary because it's the only time the non-delegating
* IUnknown point
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -