ole32: Add support for rendering stream data to the clipboard.
This commit is contained in:
parent
5e557d83ca
commit
1e8727aacf
|
@ -547,16 +547,96 @@ static inline ole_priv_data_entry *find_format_in_list(ole_priv_data_entry *entr
|
||||||
return NULL;
|
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_format
|
||||||
*
|
*
|
||||||
* Render the clipboard data. Note that this call will delegate to the
|
* Render the clipboard data. Note that this call will delegate to the
|
||||||
* source data object.
|
* source data object.
|
||||||
* Note: This function assumes it is passed an HGLOBAL format to render.
|
|
||||||
*/
|
*/
|
||||||
static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
|
static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
|
||||||
{
|
{
|
||||||
STGMEDIUM std;
|
|
||||||
HGLOBAL clip_data = NULL;
|
HGLOBAL clip_data = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -566,35 +646,33 @@ static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
|
||||||
return render_embed_source_hack(data, 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);
|
hr = get_data_from_stream(data, fmt, &clip_data);
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
else if(fmt->tymed & TYMED_HGLOBAL)
|
||||||
if(std.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;
|
hr = DV_E_FORMATETC;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = dup_global_mem(std.u.hGlobal, &clip_data);
|
if(SUCCEEDED(hr))
|
||||||
if(FAILED(hr)) goto end;
|
|
||||||
|
|
||||||
if ( !SetClipboardData( fmt->cfFormat, clip_data ) )
|
|
||||||
{
|
{
|
||||||
WARN("() : Failed to set rendered clipboard data into clipboard!\n");
|
if ( !SetClipboardData(fmt->cfFormat, clip_data) )
|
||||||
GlobalFree(clip_data);
|
{
|
||||||
hr = CLIPBRD_E_CANT_SET;
|
WARN("() : Failed to set rendered clipboard data into clipboard!\n");
|
||||||
|
GlobalFree(clip_data);
|
||||||
|
hr = CLIPBRD_E_CANT_SET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
|
||||||
ReleaseStgMedium(&std);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* clipbrd_wndproc
|
* clipbrd_wndproc
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue