Module: wine Branch: master Commit: 4311691a88da680dd0c81078b8151d5300806323 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4311691a88da680dd0c81078b8...
Author: Huw Davies huw@codeweavers.com Date: Thu Apr 16 12:13:39 2009 +0100
ole32: If there's a current data object on the ole clipboard GetData should use it.
---
dlls/ole32/clipboard.c | 110 +++++++++++++++++++++++++++++++++++++---------- 1 files changed, 86 insertions(+), 24 deletions(-)
diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c index 9e92abe..83d923e 100644 --- a/dlls/ole32/clipboard.c +++ b/dlls/ole32/clipboard.c @@ -859,14 +859,71 @@ static ULONG WINAPI OLEClipbrd_IDataObject_Release( return ref; }
+/************************************************************ + * get_current_ole_clip_window + * + * Return the window that owns the ole clipboard. + * + * If the clipboard is flushed or not owned by ole this will + * return NULL. + */ +static HWND get_current_ole_clip_window(void) +{ + HGLOBAL h; + HWND *ptr, wnd; + + h = GetClipboardData(dataobject_clipboard_format); + if(!h) return NULL; + ptr = GlobalLock(h); + if(!ptr) return NULL; + wnd = *ptr; + GlobalUnlock(h); + return wnd; +} + +/************************************************************ + * get_current_dataobject + * + * Return an unmarshalled IDataObject if there is a current + * (ie non-flushed) object on the ole clipboard. + */ +static HRESULT get_current_dataobject(IDataObject **data) +{ + HRESULT hr = S_FALSE; + HWND wnd = get_current_ole_clip_window(); + HGLOBAL h; + void *ptr; + IStream *stm; + LARGE_INTEGER pos; + + *data = NULL; + if(!wnd) return S_FALSE; + + h = GetPropW(wnd, wine_marshal_dataobject); + if(!h) return S_FALSE; + ptr = GlobalLock(h); + if(!ptr) return S_FALSE; + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stm); + if(FAILED(hr)) goto end; + + hr = IStream_Write(stm, ptr, GlobalSize(h), NULL); + if(SUCCEEDED(hr)) + { + pos.QuadPart = 0; + IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(stm, &IID_IDataObject, (void**)data); + } + IStream_Release(stm); + +end: + GlobalUnlock(h); + return hr; +}
/************************************************************************ * OLEClipbrd_IDataObject_GetData (IDataObject) * - * The OLE Clipboard's implementation of this method delegates to - * a data source if there is one or wraps around the windows clipboard - * - * See Windows documentation for more details on IDataObject methods. */ static HRESULT WINAPI OLEClipbrd_IDataObject_GetData( IDataObject* iface, @@ -874,39 +931,40 @@ static HRESULT WINAPI OLEClipbrd_IDataObject_GetData( STGMEDIUM* pmedium) { HANDLE h, hData = 0; - ole_clipbrd *This = impl_from_IDataObject(iface); HRESULT hr; + IDataObject *data;
TRACE("(%p,%p,%p)\n", iface, pformatetcIn, pmedium);
if ( !pformatetcIn || !pmedium ) return E_INVALIDARG;
- /* - * If we have a data source placed on the clipboard (via OleSetClipboard) - * simply delegate to the source object's QueryGetData - * NOTE: This code assumes that the IDataObject is in the same address space! - * We will need to add marshalling support when Wine handles multiple processes. - */ - if ( This->src_data ) + if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN; + + hr = get_current_dataobject(&data); + if ( hr == S_OK ) { - return IDataObject_GetData(This->src_data, pformatetcIn, pmedium); + hr = IDataObject_GetData(data, pformatetcIn, pmedium); + IDataObject_Release(data); + CloseClipboard(); + return hr; }
- if ( pformatetcIn->lindex != -1 ) - return DV_E_FORMATETC; - - if ( (pformatetcIn->tymed & TYMED_HGLOBAL) != TYMED_HGLOBAL ) - return DV_E_TYMED; -/* - if ( pformatetcIn->dwAspect != DVASPECT_CONTENT ) - return DV_E_DVASPECT; -*/ - /* * Otherwise, get the data from the windows clipboard using GetClipboardData */ - if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN; + + if ( pformatetcIn->lindex != -1 ) + { + hr = DV_E_FORMATETC; + goto end; + } + + if ( (pformatetcIn->tymed & TYMED_HGLOBAL) != TYMED_HGLOBAL ) + { + hr = DV_E_TYMED; + goto end; + }
h = GetClipboardData(pformatetcIn->cfFormat); hr = dup_global_mem(h, GMEM_MOVEABLE, &hData); @@ -918,12 +976,16 @@ static HRESULT WINAPI OLEClipbrd_IDataObject_GetData( pmedium->u.hGlobal = hData; pmedium->pUnkForRelease = NULL;
+end: if ( !CloseClipboard() ) return CLIPBRD_E_CANT_CLOSE;
if(FAILED(hr)) return hr; return (hData == 0) ? DV_E_FORMATETC : S_OK; }
+/************************************************************************ + * OLEClipbrd_IDataObject_GetDataHere (IDataObject) + */ static HRESULT WINAPI OLEClipbrd_IDataObject_GetDataHere( IDataObject* iface, LPFORMATETC pformatetc,