ole32: Implement IOleCache2_UpdateCache().

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2017-10-31 13:23:33 +00:00 committed by Alexandre Julliard
parent 9cf2bd9d91
commit ca2607db32
2 changed files with 540 additions and 81 deletions

View File

@ -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 = &dib_copy;
stgmedium = &copy;
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 = &copy;
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(

View File

@ -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();