⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datacache.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
 * 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 + -