Huw Davies : ole32: Add support for rendering stream data to the clipboard.
Alexandre Julliard
julliard at winehq.org
Thu Apr 16 14:34:49 CDT 2009
Module: wine
Branch: master
Commit: 1e8727aacf891d8b229adc7a3ec40c88d733a786
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1e8727aacf891d8b229adc7a3ec40c88d733a786
Author: Huw Davies <huw at codeweavers.com>
Date: Thu Apr 16 12:04:56 2009 +0100
ole32: Add support for rendering stream data to the clipboard.
---
dlls/ole32/clipboard.c | 116 ++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 97 insertions(+), 19 deletions(-)
diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c
index f52496f..2152bbe 100644
--- a/dlls/ole32/clipboard.c
+++ b/dlls/ole32/clipboard.c
@@ -547,16 +547,96 @@ static inline ole_priv_data_entry *find_format_in_list(ole_priv_data_entry *entr
return NULL;
}
+/***************************************************************************
+ * get_data_from_stream
+ *
+ * Returns stream data in an HGLOBAL.
+ */
+static HRESULT get_data_from_stream(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
+{
+ HGLOBAL h;
+ IStream *stm = NULL;
+ HRESULT hr;
+ FORMATETC stm_fmt;
+ STGMEDIUM med;
+
+ *mem = NULL;
+
+ h = GlobalAlloc( GMEM_DDESHARE|GMEM_MOVEABLE, 0 );
+ if(!h) return E_OUTOFMEMORY;
+
+ hr = CreateStreamOnHGlobal(h, FALSE, &stm);
+ if(FAILED(hr)) goto error;
+
+ stm_fmt = *fmt;
+ med.tymed = stm_fmt.tymed = TYMED_ISTREAM;
+ med.u.pstm = stm;
+ med.pUnkForRelease = NULL;
+
+ hr = IDataObject_GetDataHere(data, &stm_fmt, &med);
+ if(FAILED(hr))
+ {
+ LARGE_INTEGER offs;
+ ULARGE_INTEGER pos;
+
+ med.u.pstm = NULL;
+ hr = IDataObject_GetData(data, &stm_fmt, &med);
+ if(FAILED(hr)) goto error;
+
+ offs.QuadPart = 0;
+ IStream_Seek(med.u.pstm, offs, STREAM_SEEK_CUR, &pos);
+ IStream_Seek(med.u.pstm, offs, STREAM_SEEK_SET, NULL);
+ hr = IStream_CopyTo(med.u.pstm, stm, pos, NULL, NULL);
+ ReleaseStgMedium(&med);
+ if(FAILED(hr)) goto error;
+ }
+ *mem = h;
+ IStream_Release(stm);
+ return S_OK;
+
+error:
+ if(stm) IStream_Release(stm);
+ GlobalFree(h);
+ return hr;
+}
+
+/***************************************************************************
+ * get_data_from_global
+ *
+ * Returns global data in an HGLOBAL.
+ */
+static HRESULT get_data_from_global(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
+{
+ HGLOBAL h;
+ HRESULT hr;
+ FORMATETC mem_fmt;
+ STGMEDIUM med;
+
+ *mem = NULL;
+
+ mem_fmt = *fmt;
+ mem_fmt.tymed = TYMED_HGLOBAL;
+
+ hr = IDataObject_GetData(data, &mem_fmt, &med);
+ if(FAILED(hr)) return hr;
+
+ hr = dup_global_mem(med.u.hGlobal, &h);
+
+ if(SUCCEEDED(hr)) *mem = h;
+
+ ReleaseStgMedium(&med);
+
+ return hr;
+}
+
/***********************************************************************
* render_format
*
* Render the clipboard data. Note that this call will delegate to the
* source data object.
- * Note: This function assumes it is passed an HGLOBAL format to render.
*/
static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
{
- STGMEDIUM std;
HGLOBAL clip_data = NULL;
HRESULT hr;
@@ -566,35 +646,33 @@ static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
return render_embed_source_hack(data, fmt);
}
- if (FAILED(hr = IDataObject_GetData(data, fmt, &std)))
+ if(fmt->tymed & TYMED_ISTREAM)
{
- WARN("() : IDataObject_GetData failed to render clipboard data! (%x)\n", hr);
- return hr;
+ hr = get_data_from_stream(data, fmt, &clip_data);
}
-
- if(std.tymed != TYMED_HGLOBAL)
+ else if(fmt->tymed & TYMED_HGLOBAL)
{
- FIXME("got tymed %x\n", std.tymed);
+ hr = get_data_from_global(data, fmt, &clip_data);
+ }
+ else
+ {
+ FIXME("Unhandled tymed %x\n", fmt->tymed);
hr = DV_E_FORMATETC;
- goto end;
}
- hr = dup_global_mem(std.u.hGlobal, &clip_data);
- if(FAILED(hr)) goto end;
-
- if ( !SetClipboardData( fmt->cfFormat, clip_data ) )
+ if(SUCCEEDED(hr))
{
- WARN("() : Failed to set rendered clipboard data into clipboard!\n");
- GlobalFree(clip_data);
- hr = CLIPBRD_E_CANT_SET;
+ if ( !SetClipboardData(fmt->cfFormat, clip_data) )
+ {
+ WARN("() : Failed to set rendered clipboard data into clipboard!\n");
+ GlobalFree(clip_data);
+ hr = CLIPBRD_E_CANT_SET;
+ }
}
-end:
- ReleaseStgMedium(&std);
return hr;
}
-
/***********************************************************************
* clipbrd_wndproc
*/
More information about the wine-cvs
mailing list