From edc2b347f254fc3f9b9d12d7ec6c478d939b9a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20G=C3=B3mez=20Del=20Real?= Date: Wed, 6 Dec 2017 10:52:26 -0500 Subject: [PATCH] ole32: Add support for saving enhmetafiles to CONTENTS and Presentation streams. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sergio Gómez Del Real Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/ole32/datacache.c | 58 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 869f122a385..b418301276a 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -939,8 +939,61 @@ static HRESULT save_mfpict(DataCacheEntry *entry, BOOL contents, IStream *stream return hr; } -static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; +static HRESULT save_emf(DataCacheEntry *entry, BOOL contents, IStream *stream) +{ + HRESULT hr = S_OK; + int data_size = 0; + BYTE *data; + if (!contents) + { + PresentationDataHeader header; + METAFILEPICT *mfpict; + HDC hdc = GetDC(0); + + init_stream_header(entry, &header); + hr = write_clipformat(stream, entry->fmtetc.cfFormat); + if (FAILED(hr)) + { + ReleaseDC(0, hdc); + return hr; + } + data_size = GetWinMetaFileBits(entry->stgmedium.u.hEnhMetaFile, 0, NULL, MM_ANISOTROPIC, hdc); + header.dwSize = data_size; + data = HeapAlloc(GetProcessHeap(), 0, header.dwSize); + if (!data) + { + ReleaseDC(0, hdc); + return E_OUTOFMEMORY; + } + GetWinMetaFileBits(entry->stgmedium.u.hEnhMetaFile, header.dwSize, data, MM_ANISOTROPIC, hdc); + ReleaseDC(0, hdc); + mfpict = (METAFILEPICT *)data; + header.dwObjectExtentX = mfpict->xExt; + header.dwObjectExtentY = mfpict->yExt; + hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL); + if (hr == S_OK && data_size) + hr = IStream_Write(stream, data, data_size, NULL); + HeapFree(GetProcessHeap(), 0, data); + } + else + { + data_size = GetEnhMetaFileBits(entry->stgmedium.u.hEnhMetaFile, 0, NULL); + data = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) + sizeof(ENHMETAHEADER) + data_size); + if (!data) return E_OUTOFMEMORY; + *((DWORD *)data) = sizeof(ENHMETAHEADER); + GetEnhMetaFileBits(entry->stgmedium.u.hEnhMetaFile, data_size, data + sizeof(DWORD) + sizeof(ENHMETAHEADER)); + memcpy(data + sizeof(DWORD), data + sizeof(DWORD) + sizeof(ENHMETAHEADER), sizeof(ENHMETAHEADER)); + data_size += sizeof(DWORD) + sizeof(ENHMETAHEADER); + if (hr == S_OK && data_size) + hr = IStream_Write(stream, data, data_size, NULL); + HeapFree(GetProcessHeap(), 0, data); + } + + return hr; +} + +static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; static HRESULT create_stream(DataCacheEntry *cache_entry, IStorage *storage, BOOL contents, IStream **stream) { @@ -981,6 +1034,9 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag case CF_METAFILEPICT: hr = save_mfpict(cache_entry, contents, stream); break; + case CF_ENHMETAFILE: + hr = save_emf(cache_entry, contents, stream); + break; default: FIXME("got unsupported clipboard format %x\n", cache_entry->fmtetc.cfFormat); }