[PATCH 5/6] ole32: Implement IOleCache2_UpdateCache().
Huw Davies
huw at codeweavers.com
Tue Oct 31 08:23:33 CDT 2017
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/ole32/datacache.c | 141 ++++++++++++--
dlls/ole32/tests/ole2.c | 480 +++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 540 insertions(+), 81 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index 7a19a171e5..2c5e45134e 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -961,12 +961,33 @@ static HBITMAP synthesize_bitmap( HGLOBAL dib )
return ret;
}
+static HENHMETAFILE synthesize_emf( HMETAFILEPICT data )
+{
+ METAFILEPICT *pict;
+ HENHMETAFILE emf = 0;
+ UINT size;
+ void *bits;
+
+ if (!(pict = GlobalLock( data ))) return 0;
+
+ size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
+ if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
+ {
+ GetMetaFileBitsEx( pict->hMF, size, bits );
+ emf = SetWinMetaFileBits( size, bits, NULL, pict );
+ HeapFree( GetProcessHeap(), 0, bits );
+ }
+
+ GlobalUnlock( data );
+ return emf;
+}
+
static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
const FORMATETC *formatetc,
STGMEDIUM *stgmedium,
BOOL fRelease)
{
- STGMEDIUM dib_copy;
+ STGMEDIUM copy;
if ((!cache_entry->fmtetc.cfFormat && !formatetc->cfFormat) ||
(cache_entry->fmtetc.tymed == TYMED_NULL && formatetc->tymed == TYMED_NULL) ||
@@ -981,11 +1002,19 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
if (formatetc->cfFormat == CF_BITMAP)
{
- dib_copy.tymed = TYMED_HGLOBAL;
- dib_copy.u.hGlobal = synthesize_dib( stgmedium->u.hBitmap );
- dib_copy.pUnkForRelease = NULL;
+ copy.tymed = TYMED_HGLOBAL;
+ copy.u.hGlobal = synthesize_dib( stgmedium->u.hBitmap );
+ copy.pUnkForRelease = NULL;
+ if (fRelease) ReleaseStgMedium(stgmedium);
+ stgmedium = ©
+ fRelease = TRUE;
+ }
+ else if (formatetc->cfFormat == CF_METAFILEPICT && cache_entry->fmtetc.cfFormat == CF_ENHMETAFILE)
+ {
+ copy.tymed = TYMED_ENHMF;
+ copy.u.hEnhMetaFile = synthesize_emf( stgmedium->u.hMetaFilePict );
if (fRelease) ReleaseStgMedium(stgmedium);
- stgmedium = &dib_copy;
+ stgmedium = ©
fRelease = TRUE;
}
@@ -2381,14 +2410,102 @@ static HRESULT WINAPI DataCache_IOleCache2_SetData(
return OLE_E_BLANK;
}
-static HRESULT WINAPI DataCache_UpdateCache(
- IOleCache2* iface,
- LPDATAOBJECT pDataObject,
- DWORD grfUpdf,
- LPVOID pReserved)
+static BOOL entry_updateable( DataCacheEntry *entry, DWORD mode )
{
- FIXME("(%p, 0x%x, %p): stub\n", pDataObject, grfUpdf, pReserved);
- return E_NOTIMPL;
+ BOOL is_blank = entry->stgmedium.tymed == TYMED_NULL;
+
+ if ((mode & UPDFCACHE_ONLYIFBLANK) && !is_blank) return FALSE;
+
+ if ((mode & UPDFCACHE_NODATACACHE) && (entry->advise_flags & ADVF_NODATA)) return TRUE;
+ if ((mode & UPDFCACHE_ONSAVECACHE) && (entry->advise_flags & ADVFCACHE_ONSAVE)) return TRUE;
+ if ((mode & UPDFCACHE_ONSTOPCACHE) && (entry->advise_flags & ADVF_DATAONSTOP)) return TRUE;
+ if ((mode & UPDFCACHE_NORMALCACHE) && (entry->advise_flags == 0)) return TRUE;
+ if ((mode & UPDFCACHE_IFBLANK) && (is_blank && !(entry->advise_flags & ADVF_NODATA))) return TRUE;
+
+ return FALSE;
+}
+
+static HRESULT WINAPI DataCache_UpdateCache( IOleCache2 *iface, IDataObject *data,
+ DWORD mode, void *reserved )
+{
+ DataCache *This = impl_from_IOleCache2(iface);
+ DataCacheEntry *cache_entry;
+ STGMEDIUM med;
+ HRESULT hr = S_OK;
+ CLIPFORMAT view_list[] = { CF_METAFILEPICT, CF_ENHMETAFILE, CF_DIB, CF_BITMAP };
+ FORMATETC fmt;
+ int i, slots = 0;
+ BOOL done_one = FALSE;
+
+ TRACE( "(%p %p %08x %p)\n", iface, data, mode, reserved );
+
+ LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
+ {
+ slots++;
+
+ if (!entry_updateable( cache_entry, mode ))
+ {
+ done_one = TRUE;
+ continue;
+ }
+
+ fmt = cache_entry->fmtetc;
+
+ if (fmt.cfFormat)
+ {
+ hr = IDataObject_GetData( data, &fmt, &med );
+ if (hr != S_OK && fmt.cfFormat == CF_DIB)
+ {
+ fmt.cfFormat = CF_BITMAP;
+ fmt.tymed = TYMED_GDI;
+ hr = IDataObject_GetData( data, &fmt, &med );
+ }
+ if (hr != S_OK && fmt.cfFormat == CF_ENHMETAFILE)
+ {
+ fmt.cfFormat = CF_METAFILEPICT;
+ fmt.tymed = TYMED_MFPICT;
+ hr = IDataObject_GetData( data, &fmt, &med );
+ }
+ if (hr == S_OK)
+ {
+ hr = DataCacheEntry_SetData( cache_entry, &fmt, &med, TRUE );
+ if (hr != S_OK) ReleaseStgMedium( &med );
+ else done_one = TRUE;
+ }
+ }
+ else
+ {
+ for (i = 0; i < sizeof(view_list) / sizeof(view_list[0]); i++)
+ {
+ fmt.cfFormat = view_list[i];
+ fmt.tymed = tymed_from_cf( fmt.cfFormat );
+ hr = IDataObject_QueryGetData( data, &fmt );
+ if (hr == S_OK)
+ {
+ hr = IDataObject_GetData( data, &fmt, &med );
+ if (hr == S_OK)
+ {
+ if (fmt.cfFormat == CF_BITMAP)
+ {
+ cache_entry->fmtetc.cfFormat = CF_DIB;
+ cache_entry->fmtetc.tymed = TYMED_HGLOBAL;
+ }
+ else
+ {
+ cache_entry->fmtetc.cfFormat = fmt.cfFormat;
+ cache_entry->fmtetc.tymed = fmt.tymed;
+ }
+ hr = DataCacheEntry_SetData( cache_entry, &fmt, &med, TRUE );
+ if (hr != S_OK) ReleaseStgMedium( &med );
+ else done_one = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return (!slots || done_one) ? S_OK : CACHE_E_NOCACHE_UPDATED;
}
static HRESULT WINAPI DataCache_DiscardCache(
diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c
index aaee6773d8..9b96570999 100644
--- a/dlls/ole32/tests/ole2.c
+++ b/dlls/ole32/tests/ole2.c
@@ -112,6 +112,7 @@ struct expected_method
{
const char *method;
unsigned int flags;
+ FORMATETC fmt;
};
static const struct expected_method *expected_method_list;
@@ -124,6 +125,8 @@ static HRESULT g_QIFailsWith;
static UINT cf_test_1, cf_test_2, cf_test_3;
+static FORMATETC *g_dataobject_fmts;
+
/****************************************************************************
* PresentationDataHeader
*
@@ -150,27 +153,43 @@ typedef struct PresentationDataHeader
DWORD dwSize;
} PresentationDataHeader;
-#define CHECK_EXPECTED_METHOD(method_name) \
- do { \
- trace("%s\n", method_name); \
- ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
- if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \
- { \
- todo_wine ok(0, "Too many method calls.\n"); \
- break; \
- } \
- if (expected_method_list->method) \
- { \
- while (expected_method_list->flags & TEST_OPTIONAL && \
- strcmp(expected_method_list->method, method_name) != 0) \
- expected_method_list++; \
- todo_wine_if (expected_method_list->flags & TEST_TODO) \
- ok(!strcmp(expected_method_list->method, method_name), \
- "Expected %s to be called instead of %s\n", \
- expected_method_list->method, method_name); \
- expected_method_list++; \
- } \
- } while(0)
+static void inline check_expected_method_fmt(const char *method_name, const FORMATETC *fmt)
+{
+ trace("%s\n", method_name);
+ ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name);
+ if (!strcmp(expected_method_list->method, "WINE_EXTRA"))
+ {
+ todo_wine ok(0, "Too many method calls.\n");
+ return;
+ }
+ if (expected_method_list->method)
+ {
+ while (expected_method_list->flags & TEST_OPTIONAL &&
+ strcmp(expected_method_list->method, method_name) != 0)
+ expected_method_list++;
+ todo_wine_if (expected_method_list->flags & TEST_TODO)
+ {
+ ok(!strcmp(expected_method_list->method, method_name),
+ "Expected %s to be called instead of %s\n",
+ expected_method_list->method, method_name);
+ if (fmt)
+ {
+ ok(fmt->cfFormat == expected_method_list->fmt.cfFormat, "got cf %04x vs %04x\n",
+ fmt->cfFormat, expected_method_list->fmt.cfFormat );
+ ok(fmt->dwAspect == expected_method_list->fmt.dwAspect, "got aspect %d vs %d\n",
+ fmt->dwAspect, expected_method_list->fmt.dwAspect );
+ ok(fmt->lindex == expected_method_list->fmt.lindex, "got lindex %d vs %d\n",
+ fmt->lindex, expected_method_list->fmt.lindex );
+ ok(fmt->tymed == expected_method_list->fmt.tymed, "got tymed %d vs %d\n",
+ fmt->tymed, expected_method_list->fmt.tymed );
+ }
+ }
+ expected_method_list++;
+ }
+}
+
+#define CHECK_EXPECTED_METHOD(method_name) check_expected_method_fmt(method_name, NULL)
+#define CHECK_EXPECTED_METHOD_FMT(method_name, fmt) check_expected_method_fmt(method_name, fmt)
#define CHECK_NO_EXTRA_METHODS() \
do { \
@@ -179,6 +198,41 @@ typedef struct PresentationDataHeader
ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
} while (0)
+/* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
+static BYTE dib[] =
+{
+ 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
+
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
+ 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+static void create_dib( STGMEDIUM *med )
+{
+ void *ptr;
+
+ med->tymed = TYMED_HGLOBAL;
+ U(med)->hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) - sizeof(BITMAPFILEHEADER) );
+ ptr = GlobalLock( U(med)->hGlobal );
+ memcpy( ptr, dib + sizeof(BITMAPFILEHEADER), sizeof(dib) - sizeof(BITMAPFILEHEADER) );
+ GlobalUnlock( U(med)->hGlobal );
+ med->pUnkForRelease = NULL;
+}
+
+static void create_bitmap( STGMEDIUM *med )
+{
+ med->tymed = TYMED_GDI;
+ U(med)->hBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
+ med->pUnkForRelease = NULL;
+}
+
static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
{
CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
@@ -1385,13 +1439,40 @@ static ULONG WINAPI DataObject_Release(
return 1;
}
-static HRESULT WINAPI DataObject_GetData(
- IDataObject* iface,
- LPFORMATETC pformatetcIn,
- STGMEDIUM* pmedium)
+static inline BOOL fmtetc_equal( const FORMATETC *a, const FORMATETC *b )
{
- CHECK_EXPECTED_METHOD("DataObject_GetData");
- return E_NOTIMPL;
+ /* FIXME ptd */
+ return a->cfFormat == b->cfFormat && a->dwAspect == b->dwAspect &&
+ a->lindex == b->lindex && a->tymed == b->tymed;
+
+}
+
+static HRESULT WINAPI DataObject_GetData( IDataObject *iface, FORMATETC *fmt_in,
+ STGMEDIUM *med )
+{
+ FORMATETC *fmt;
+
+ CHECK_EXPECTED_METHOD_FMT("DataObject_GetData", fmt_in);
+
+ for (fmt = g_dataobject_fmts; fmt && fmt->cfFormat != 0; fmt++)
+ {
+ if (fmtetc_equal( fmt_in, fmt ))
+ {
+ switch (fmt->cfFormat)
+ {
+ case CF_DIB:
+ create_dib( med );
+ return S_OK;
+ case CF_BITMAP:
+ create_bitmap( med );
+ return S_OK;
+ default:
+ trace( "unhandled fmt %d\n", fmt->cfFormat );
+ }
+ }
+ }
+
+ return S_FALSE;
}
static HRESULT WINAPI DataObject_GetDataHere(
@@ -1403,12 +1484,16 @@ static HRESULT WINAPI DataObject_GetDataHere(
return E_NOTIMPL;
}
-static HRESULT WINAPI DataObject_QueryGetData(
- IDataObject* iface,
- LPFORMATETC pformatetc)
+static HRESULT WINAPI DataObject_QueryGetData( IDataObject *iface, FORMATETC *fmt_in )
{
- CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
- return S_OK;
+ FORMATETC *fmt;
+
+ CHECK_EXPECTED_METHOD_FMT("DataObject_QueryGetData", fmt_in);
+
+ for (fmt = g_dataobject_fmts; fmt && fmt->cfFormat != 0; fmt++)
+ if (fmtetc_equal( fmt_in, fmt )) return S_OK;
+
+ return S_FALSE;
}
static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
@@ -1601,9 +1686,9 @@ static void test_data_cache(void)
{ "draw_continue", 1 },
{ "draw_continue", 1 },
{ "draw_continue", 1 },
- { "DataObject_GetData", 0 },
- { "DataObject_GetData", 0 },
- { "DataObject_GetData", 0 },
+ { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_THUMBNAIL, -1, TYMED_HGLOBAL} },
+ { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_THUMBNAIL, -1, TYMED_GDI} },
+ { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_ICON, -1, TYMED_MFPICT} },
{ NULL, 0 }
};
static const struct expected_method methods_cachethenrun[] =
@@ -1611,7 +1696,6 @@ static void test_data_cache(void)
{ "DataObject_DAdvise", 0 },
{ "DataObject_DAdvise", 0 },
{ "DataObject_DAdvise", 0 },
- { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */
{ "DataObject_DAdvise", 0 },
{ "DataObject_DUnadvise", 0 },
{ "DataObject_DUnadvise", 0 },
@@ -1961,22 +2045,6 @@ static void test_data_cache(void)
static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
-/* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
-static BYTE dib[] =
-{
- 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
-
- 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
- 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
static IStorage *create_storage( int num )
{
IStorage *stg;
@@ -2001,18 +2069,6 @@ static IStorage *create_storage( int num )
return stg;
}
-static HGLOBAL create_dib( void )
-{
- HGLOBAL h;
- void *ptr;
-
- h = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) - sizeof(BITMAPFILEHEADER) );
- ptr = GlobalLock( h );
- memcpy( ptr, dib + sizeof(BITMAPFILEHEADER), sizeof(dib) - sizeof(BITMAPFILEHEADER) );
- GlobalUnlock( h );
- return h;
-}
-
static void test_data_cache_dib_contents_stream(int num)
{
HRESULT hr;
@@ -2220,9 +2276,7 @@ static void test_data_cache_cache(void)
hr = IOleCache2_QueryInterface( cache, &IID_IDataObject, (void **) &data );
ok( hr == S_OK, "got %08x\n", hr );
- med.tymed = TYMED_GDI;
- U(med).hBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
- med.pUnkForRelease = NULL;
+ create_bitmap( &med );
hr = IOleCache2_SetData( cache, &fmt, &med, TRUE );
ok( hr == S_OK, "got %08x\n", hr );
@@ -2244,8 +2298,7 @@ static void test_data_cache_cache(void)
/* Now set a 2x1 dib */
fmt.cfFormat = CF_DIB;
fmt.tymed = TYMED_HGLOBAL;
- med.tymed = TYMED_HGLOBAL;
- U(med).hGlobal = create_dib();
+ create_dib( &med );
hr = IOleCache2_SetData( cache, &fmt, &med, TRUE );
ok( hr == S_OK, "got %08x\n", hr );
@@ -2503,6 +2556,294 @@ static void test_data_cache_initnew(void)
IOleCache2_Release( cache );
}
+static void test_data_cache_updatecache( void )
+{
+ HRESULT hr;
+ IOleCache2 *cache;
+ FORMATETC fmt;
+ DWORD conn[4];
+
+ static const struct expected_method methods_dib[] =
+ {
+ { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } },
+ { NULL }
+ };
+
+ static const struct expected_method methods_dib_emf[] =
+ {
+ { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
+ { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { NULL }
+ };
+ static const struct expected_method methods_dib_wmf[] =
+ {
+ { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { NULL }
+ };
+ static const struct expected_method methods_viewcache[] =
+ {
+ { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
+ { "DataObject_QueryGetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { "DataObject_QueryGetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } },
+ { NULL }
+ };
+ static const struct expected_method methods_viewcache_with_dib[] =
+ {
+ { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
+ { "DataObject_QueryGetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { NULL }
+ };
+ static const struct expected_method methods_flags_all[] =
+ {
+ { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
+ { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { NULL }
+ };
+ static const struct expected_method methods_flags_ifblank_1[] =
+ {
+ { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { NULL }
+ };
+ static const struct expected_method methods_flags_ifblank_2[] =
+ {
+ { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
+ { NULL }
+ };
+ static const struct expected_method methods_flags_normal[] =
+ {
+ { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+ { NULL }
+ };
+ static const struct expected_method methods_empty[] =
+ {
+ { NULL }
+ };
+
+ static STATDATA view_cache[] =
+ {
+ {{ 0, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }
+ };
+ static STATDATA view_cache_after_dib[] =
+ {
+ {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 },
+ {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 }
+ };
+
+ static FORMATETC dib_fmt[] =
+ {
+ { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
+ { 0 }
+ };
+
+ hr = CreateDataCache( NULL, &CLSID_WineTestOld, &IID_IOleCache2, (void **)&cache );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* No cache slots */
+ g_dataobject_fmts = NULL;
+ expected_method_list = NULL;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* A dib cache slot */
+ fmt.cfFormat = CF_DIB;
+ fmt.ptd = NULL;
+ fmt.dwAspect = DVASPECT_CONTENT;
+ fmt.lindex = -1;
+ fmt.tymed = TYMED_HGLOBAL;
+
+ hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ expected_method_list = methods_dib;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+ ok( hr == CACHE_E_NOCACHE_UPDATED, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ /* Now with a dib available */
+ g_dataobject_fmts = dib_fmt;
+ expected_method_list = methods_dib;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* Add an EMF cache slot */
+ fmt.cfFormat = CF_ENHMETAFILE;
+ fmt.ptd = NULL;
+ fmt.dwAspect = DVASPECT_CONTENT;
+ fmt.lindex = -1;
+ fmt.tymed = TYMED_ENHMF;
+
+ hr = IOleCache2_Cache( cache, &fmt, 0, &conn[1] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ g_dataobject_fmts = dib_fmt;
+ expected_method_list = methods_dib_emf;
+
+ /* Two slots to fill, only the dib will succeed */
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ /* Replace the emf slot with a wmf */
+ hr = IOleCache2_Uncache( cache, conn[1] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ fmt.cfFormat = CF_METAFILEPICT;
+ fmt.ptd = NULL;
+ fmt.dwAspect = DVASPECT_CONTENT;
+ fmt.lindex = -1;
+ fmt.tymed = TYMED_MFPICT;
+
+ hr = IOleCache2_Cache( cache, &fmt, 0, &conn[1] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ g_dataobject_fmts = dib_fmt;
+ expected_method_list = methods_dib_wmf;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = IOleCache2_Uncache( cache, conn[1] );
+ ok( hr == S_OK, "got %08x\n", hr );
+ hr = IOleCache2_Uncache( cache, conn[0] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* View caching */
+ fmt.cfFormat = 0;
+ fmt.ptd = NULL;
+ fmt.dwAspect = DVASPECT_CONTENT;
+ fmt.lindex = -1;
+ fmt.tymed = TYMED_HGLOBAL;
+
+ hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] );
+ ok( hr == S_OK, "got %08x\n", hr );
+ view_cache[0].dwConnection = conn[0];
+
+ g_dataobject_fmts = NULL;
+ expected_method_list = methods_viewcache;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+ ok( hr == CACHE_E_NOCACHE_UPDATED, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+ check_enum_cache( cache, view_cache, 1 );
+
+ g_dataobject_fmts = dib_fmt;
+ expected_method_list = methods_viewcache_with_dib;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+ view_cache_after_dib[0].dwConnection = view_cache_after_dib[1].dwConnection = view_cache[0].dwConnection;
+ check_enum_cache( cache, view_cache_after_dib, 2 );
+
+ hr = IOleCache2_Uncache( cache, conn[0] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* Try some different flags */
+
+ fmt.cfFormat = CF_DIB;
+ fmt.ptd = NULL;
+ fmt.dwAspect = DVASPECT_CONTENT;
+ fmt.lindex = -1;
+ fmt.tymed = TYMED_HGLOBAL;
+
+ hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ fmt.cfFormat = CF_ENHMETAFILE;
+ fmt.ptd = NULL;
+ fmt.dwAspect = DVASPECT_CONTENT;
+ fmt.lindex = -1;
+ fmt.tymed = TYMED_ENHMF;
+
+ hr = IOleCache2_Cache( cache, &fmt, ADVF_NODATA, &conn[1] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ fmt.cfFormat = CF_METAFILEPICT;
+ fmt.ptd = NULL;
+ fmt.dwAspect = DVASPECT_CONTENT;
+ fmt.lindex = -1;
+ fmt.tymed = TYMED_MFPICT;
+
+ hr = IOleCache2_Cache( cache, &fmt, ADVFCACHE_ONSAVE, &conn[2] );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ g_dataobject_fmts = dib_fmt;
+ expected_method_list = methods_flags_all;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ expected_method_list = methods_flags_all;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ expected_method_list = methods_flags_ifblank_1;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK , NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ expected_method_list = methods_flags_ifblank_2;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK , NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ expected_method_list = methods_flags_all;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK | UPDFCACHE_NODATACACHE, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ expected_method_list = methods_empty;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ONLYIFBLANK | UPDFCACHE_NORMALCACHE, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ expected_method_list = methods_flags_normal;
+
+ hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ONLYIFBLANK | UPDFCACHE_NORMALCACHE, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ CHECK_NO_EXTRA_METHODS();
+
+ IOleCache2_Release( cache );
+}
+
static void test_default_handler(void)
{
HRESULT hr;
@@ -3833,6 +4174,7 @@ START_TEST(ole2)
test_data_cache_cache();
test_data_cache_init();
test_data_cache_initnew();
+ test_data_cache_updatecache();
test_default_handler();
test_runnable();
test_OleRun();
--
2.12.0
More information about the wine-patches
mailing list