ole32: Create CF_DIB and CF_BITMAP entries when either is cached.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
20a8f1adf4
commit
e27708f2fd
|
@ -2079,6 +2079,7 @@ static HRESULT WINAPI DataCache_Cache(
|
||||||
DataCache *This = impl_from_IOleCache2(iface);
|
DataCache *This = impl_from_IOleCache2(iface);
|
||||||
DataCacheEntry *cache_entry;
|
DataCacheEntry *cache_entry;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
FORMATETC fmt_cpy;
|
||||||
|
|
||||||
TRACE("(%p, 0x%x, %p)\n", pformatetc, advf, pdwConnection);
|
TRACE("(%p, 0x%x, %p)\n", pformatetc, advf, pdwConnection);
|
||||||
|
|
||||||
|
@ -2087,9 +2088,16 @@ static HRESULT WINAPI DataCache_Cache(
|
||||||
|
|
||||||
TRACE("pformatetc = %s\n", debugstr_formatetc(pformatetc));
|
TRACE("pformatetc = %s\n", debugstr_formatetc(pformatetc));
|
||||||
|
|
||||||
|
fmt_cpy = *pformatetc; /* No need for a deep copy */
|
||||||
|
if (fmt_cpy.cfFormat == CF_BITMAP && fmt_cpy.tymed == TYMED_GDI)
|
||||||
|
{
|
||||||
|
fmt_cpy.cfFormat = CF_DIB;
|
||||||
|
fmt_cpy.tymed = TYMED_HGLOBAL;
|
||||||
|
}
|
||||||
|
|
||||||
*pdwConnection = 0;
|
*pdwConnection = 0;
|
||||||
|
|
||||||
cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetc);
|
cache_entry = DataCache_GetEntryForFormatEtc(This, &fmt_cpy);
|
||||||
if (cache_entry)
|
if (cache_entry)
|
||||||
{
|
{
|
||||||
TRACE("found an existing cache entry\n");
|
TRACE("found an existing cache entry\n");
|
||||||
|
@ -2097,7 +2105,7 @@ static HRESULT WINAPI DataCache_Cache(
|
||||||
return CACHE_S_SAMECACHE;
|
return CACHE_S_SAMECACHE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = DataCache_CreateEntry(This, pformatetc, advf, &cache_entry, FALSE);
|
hr = DataCache_CreateEntry(This, &fmt_cpy, advf, &cache_entry, FALSE);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -2134,24 +2142,44 @@ static HRESULT WINAPI DataCache_EnumCache(IOleCache2 *iface,
|
||||||
{
|
{
|
||||||
DataCache *This = impl_from_IOleCache2( iface );
|
DataCache *This = impl_from_IOleCache2( iface );
|
||||||
DataCacheEntry *cache_entry;
|
DataCacheEntry *cache_entry;
|
||||||
int i = 0, count = list_count( &This->cache_list );
|
int i = 0, count = 0;
|
||||||
STATDATA *data;
|
STATDATA *data;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "(%p, %p)\n", This, enum_stat );
|
TRACE( "(%p, %p)\n", This, enum_stat );
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
if (cache_entry->fmtetc.cfFormat == CF_DIB)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
data = CoTaskMemAlloc( count * sizeof(*data) );
|
data = CoTaskMemAlloc( count * sizeof(*data) );
|
||||||
if (!data) return E_OUTOFMEMORY;
|
if (!data) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
|
LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
|
||||||
{
|
{
|
||||||
if (i == count) break;
|
if (i == count) goto fail;
|
||||||
hr = copy_formatetc( &data[i].formatetc, &cache_entry->fmtetc );
|
hr = copy_formatetc( &data[i].formatetc, &cache_entry->fmtetc );
|
||||||
if (FAILED(hr)) goto fail;
|
if (FAILED(hr)) goto fail;
|
||||||
data[i].advf = cache_entry->advise_flags;
|
data[i].advf = cache_entry->advise_flags;
|
||||||
data[i].pAdvSink = NULL;
|
data[i].pAdvSink = NULL;
|
||||||
data[i].dwConnection = cache_entry->id;
|
data[i].dwConnection = cache_entry->id;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
if (cache_entry->fmtetc.cfFormat == CF_DIB)
|
||||||
|
{
|
||||||
|
if (i == count) goto fail;
|
||||||
|
hr = copy_formatetc( &data[i].formatetc, &cache_entry->fmtetc );
|
||||||
|
if (FAILED(hr)) goto fail;
|
||||||
|
data[i].formatetc.cfFormat = CF_BITMAP;
|
||||||
|
data[i].formatetc.tymed = TYMED_GDI;
|
||||||
|
data[i].advf = cache_entry->advise_flags;
|
||||||
|
data[i].pAdvSink = NULL;
|
||||||
|
data[i].dwConnection = cache_entry->id;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = EnumSTATDATA_Construct( NULL, 0, i, data, FALSE, enum_stat );
|
hr = EnumSTATDATA_Construct( NULL, 0, i, data, FALSE, enum_stat );
|
||||||
|
|
|
@ -1522,6 +1522,39 @@ static const IUnknownVtbl UnknownVtbl =
|
||||||
|
|
||||||
static IUnknown unknown = { &UnknownVtbl };
|
static IUnknown unknown = { &UnknownVtbl };
|
||||||
|
|
||||||
|
static void check_enum_cache(IOleCache2 *cache, STATDATA *expect, int num)
|
||||||
|
{
|
||||||
|
IEnumSTATDATA *enum_stat;
|
||||||
|
STATDATA stat;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = IOleCache2_EnumCache( cache, &enum_stat );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
while (IEnumSTATDATA_Next(enum_stat, 1, &stat, NULL) == S_OK)
|
||||||
|
{
|
||||||
|
ok( stat.formatetc.cfFormat == expect->formatetc.cfFormat, "got %d expect %d\n",
|
||||||
|
stat.formatetc.cfFormat, expect->formatetc.cfFormat );
|
||||||
|
ok( !stat.formatetc.ptd == !expect->formatetc.ptd, "got %p expect %p\n",
|
||||||
|
stat.formatetc.ptd, expect->formatetc.ptd );
|
||||||
|
ok( stat.formatetc.dwAspect == expect->formatetc.dwAspect, "got %d expect %d\n",
|
||||||
|
stat.formatetc.dwAspect, expect->formatetc.dwAspect );
|
||||||
|
ok( stat.formatetc.lindex == expect->formatetc.lindex, "got %d expect %d\n",
|
||||||
|
stat.formatetc.lindex, expect->formatetc.lindex );
|
||||||
|
ok( stat.formatetc.tymed == expect->formatetc.tymed, "got %d expect %d\n",
|
||||||
|
stat.formatetc.tymed, expect->formatetc.tymed );
|
||||||
|
ok( stat.advf == expect->advf, "got %d expect %d\n", stat.advf, expect->advf );
|
||||||
|
ok( stat.pAdvSink == 0, "got %p\n", stat.pAdvSink );
|
||||||
|
ok( stat.dwConnection == expect->dwConnection, "got %d expect %d\n", stat.dwConnection, expect->dwConnection );
|
||||||
|
num--;
|
||||||
|
expect++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok( num == 0, "incorrect number. num %d\n", num );
|
||||||
|
|
||||||
|
IEnumSTATDATA_Release( enum_stat );
|
||||||
|
}
|
||||||
|
|
||||||
static void test_data_cache(void)
|
static void test_data_cache(void)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -1968,12 +2001,18 @@ static void test_data_cache_dib_contents_stream(int num)
|
||||||
IDataObject *data;
|
IDataObject *data;
|
||||||
IViewObject2 *view;
|
IViewObject2 *view;
|
||||||
IStorage *stg;
|
IStorage *stg;
|
||||||
|
IOleCache2 *cache;
|
||||||
FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||||||
STGMEDIUM med;
|
STGMEDIUM med;
|
||||||
CLSID cls;
|
CLSID cls;
|
||||||
SIZEL sz;
|
SIZEL sz;
|
||||||
BYTE *ptr;
|
BYTE *ptr;
|
||||||
BITMAPINFOHEADER expect_info;
|
BITMAPINFOHEADER expect_info;
|
||||||
|
STATDATA enum_expect[] =
|
||||||
|
{
|
||||||
|
{{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
|
||||||
|
{{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
|
||||||
|
};
|
||||||
|
|
||||||
hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk );
|
hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk );
|
||||||
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
||||||
|
@ -1983,6 +2022,8 @@ static void test_data_cache_dib_contents_stream(int num)
|
||||||
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
||||||
hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view );
|
hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view );
|
||||||
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
||||||
|
hr = IUnknown_QueryInterface( unk, &IID_IOleCache2, (void **)&cache );
|
||||||
|
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
||||||
|
|
||||||
stg = create_storage( num );
|
stg = create_storage( num );
|
||||||
|
|
||||||
|
@ -2015,6 +2056,8 @@ static void test_data_cache_dib_contents_stream(int num)
|
||||||
GlobalUnlock( U(med).hGlobal );
|
GlobalUnlock( U(med).hGlobal );
|
||||||
ReleaseStgMedium( &med );
|
ReleaseStgMedium( &med );
|
||||||
|
|
||||||
|
check_enum_cache( cache, enum_expect, 2 );
|
||||||
|
|
||||||
hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz );
|
hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz );
|
||||||
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
ok( SUCCEEDED(hr), "got %08x\n", hr );
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
|
@ -2033,12 +2076,98 @@ static void test_data_cache_dib_contents_stream(int num)
|
||||||
ReleaseDC( 0, hdc );
|
ReleaseDC( 0, hdc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IOleCache2_Release( cache );
|
||||||
IViewObject2_Release( view );
|
IViewObject2_Release( view );
|
||||||
IDataObject_Release( data );
|
IDataObject_Release( data );
|
||||||
IPersistStorage_Release( persist );
|
IPersistStorage_Release( persist );
|
||||||
IUnknown_Release( unk );
|
IUnknown_Release( unk );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_data_cache_bitmap(void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
IOleCache2 *cache;
|
||||||
|
FORMATETC fmt;
|
||||||
|
DWORD conn;
|
||||||
|
STATDATA expect[] =
|
||||||
|
{
|
||||||
|
{{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 },
|
||||||
|
{{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 },
|
||||||
|
{{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 0 },
|
||||||
|
{{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
hr = CreateDataCache( NULL, &CLSID_NULL, &IID_IOleCache2, (void **)&cache );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
/* create a dib entry which will also create a bitmap entry too */
|
||||||
|
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 );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
expect[0].dwConnection = conn;
|
||||||
|
expect[1].dwConnection = conn;
|
||||||
|
|
||||||
|
check_enum_cache( cache, expect, 2 );
|
||||||
|
|
||||||
|
/* now try to add a bitmap */
|
||||||
|
fmt.cfFormat = CF_BITMAP;
|
||||||
|
fmt.tymed = TYMED_GDI;
|
||||||
|
|
||||||
|
hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
|
||||||
|
ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr );
|
||||||
|
|
||||||
|
/* metafile */
|
||||||
|
fmt.cfFormat = CF_METAFILEPICT;
|
||||||
|
fmt.tymed = TYMED_MFPICT;
|
||||||
|
|
||||||
|
hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
expect[2].dwConnection = conn;
|
||||||
|
|
||||||
|
check_enum_cache( cache, expect, 3);
|
||||||
|
|
||||||
|
/* enhmetafile */
|
||||||
|
fmt.cfFormat = CF_ENHMETAFILE;
|
||||||
|
fmt.tymed = TYMED_ENHMF;
|
||||||
|
|
||||||
|
hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
expect[3].dwConnection = conn;
|
||||||
|
|
||||||
|
check_enum_cache( cache, expect, 4 );
|
||||||
|
|
||||||
|
/* uncache everything */
|
||||||
|
hr = IOleCache2_Uncache( cache, expect[3].dwConnection );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
hr = IOleCache2_Uncache( cache, expect[2].dwConnection );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
hr = IOleCache2_Uncache( cache, expect[0].dwConnection );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
hr = IOleCache2_Uncache( cache, expect[0].dwConnection );
|
||||||
|
ok( hr == OLE_E_NOCONNECTION, "got %08x\n", hr );
|
||||||
|
|
||||||
|
check_enum_cache( cache, expect, 0 );
|
||||||
|
|
||||||
|
/* just create a bitmap entry which again adds both dib and bitmap */
|
||||||
|
fmt.cfFormat = CF_BITMAP;
|
||||||
|
fmt.tymed = TYMED_GDI;
|
||||||
|
|
||||||
|
hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
expect[0].dwConnection = conn;
|
||||||
|
expect[1].dwConnection = conn;
|
||||||
|
|
||||||
|
check_enum_cache( cache, expect, 2 );
|
||||||
|
|
||||||
|
IOleCache2_Release( cache );
|
||||||
|
}
|
||||||
|
|
||||||
static void test_default_handler(void)
|
static void test_default_handler(void)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -2791,6 +2920,7 @@ START_TEST(ole2)
|
||||||
test_data_cache();
|
test_data_cache();
|
||||||
test_data_cache_dib_contents_stream( 0 );
|
test_data_cache_dib_contents_stream( 0 );
|
||||||
test_data_cache_dib_contents_stream( 1 );
|
test_data_cache_dib_contents_stream( 1 );
|
||||||
|
test_data_cache_bitmap();
|
||||||
test_default_handler();
|
test_default_handler();
|
||||||
test_runnable();
|
test_runnable();
|
||||||
test_OleRun();
|
test_OleRun();
|
||||||
|
|
Loading…
Reference in New Issue