ole32: Rewrite the clipboard window's wndproc to use the cached enum data.
This commit is contained in:
parent
b958dfdc47
commit
5e557d83ca
|
@ -103,9 +103,13 @@ typedef struct
|
||||||
/* then follows any DVTARGETDEVICE structures referenced in the FORMATETCs */
|
/* then follows any DVTARGETDEVICE structures referenced in the FORMATETCs */
|
||||||
} ole_priv_data;
|
} ole_priv_data;
|
||||||
|
|
||||||
/* Create an empty data structure. The only thing that really matters
|
/*****************************************************************************
|
||||||
here is setting count and size members. This is used by the enumerator as a
|
* create_empty_priv_data
|
||||||
convenience when there's an empty list. */
|
*
|
||||||
|
* Create an empty data structure. The only thing that really matters
|
||||||
|
* here is setting count and size members. This is used by the enumerator as a
|
||||||
|
* convenience when there's an empty list.
|
||||||
|
*/
|
||||||
static HRESULT create_empty_priv_data(ole_priv_data **data)
|
static HRESULT create_empty_priv_data(ole_priv_data **data)
|
||||||
{
|
{
|
||||||
ole_priv_data *ptr;
|
ole_priv_data *ptr;
|
||||||
|
@ -592,138 +596,62 @@ end:
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* OLEClipbrd_WndProc(HWND, unsigned, WORD, LONG)
|
* clipbrd_wndproc
|
||||||
* Processes messages sent to the OLE clipboard window.
|
|
||||||
* Note that we will intercept messages in our WndProc only when data
|
|
||||||
* has been placed in the clipboard via OleSetClipboard().
|
|
||||||
* i.e. Only when OLE owns the windows clipboard.
|
|
||||||
*/
|
*/
|
||||||
static LRESULT CALLBACK OLEClipbrd_WndProc
|
static LRESULT CALLBACK clipbrd_wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||||
(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
{
|
||||||
switch (message)
|
ole_clipbrd *clipbrd = theOleClipboard;
|
||||||
{
|
|
||||||
/*
|
switch (message)
|
||||||
* WM_RENDERFORMAT
|
{
|
||||||
* We receive this message to allow us to handle delayed rendering of
|
|
||||||
* a specific clipboard format when an application requests data in
|
|
||||||
* that format by calling GetClipboardData.
|
|
||||||
* (Recall that in OleSetClipboard, we used SetClipboardData to
|
|
||||||
* make all HGLOBAL formats supported by the source IDataObject
|
|
||||||
* available using delayed rendering)
|
|
||||||
* On receiving this message we must actually render the data in the
|
|
||||||
* specified format and place it on the clipboard by calling the
|
|
||||||
* SetClipboardData function.
|
|
||||||
*/
|
|
||||||
case WM_RENDERFORMAT:
|
case WM_RENDERFORMAT:
|
||||||
{
|
{
|
||||||
FORMATETC rgelt;
|
UINT cf = wparam;
|
||||||
|
ole_priv_data_entry *entry;
|
||||||
|
|
||||||
ZeroMemory( &rgelt, sizeof(FORMATETC));
|
TRACE("(): WM_RENDERFORMAT(cfFormat=%x)\n", cf);
|
||||||
|
entry = find_format_in_list(clipbrd->cached_enum->entries, clipbrd->cached_enum->count, cf);
|
||||||
|
|
||||||
/*
|
if(entry)
|
||||||
* Initialize FORMATETC to a Windows clipboard friendly format
|
render_format(clipbrd->pIDataObjectSrc, &entry->fmtetc);
|
||||||
*/
|
|
||||||
rgelt.cfFormat = (UINT) wParam;
|
|
||||||
rgelt.dwAspect = DVASPECT_CONTENT;
|
|
||||||
rgelt.lindex = -1;
|
|
||||||
rgelt.tymed = TYMED_HGLOBAL;
|
|
||||||
|
|
||||||
TRACE("(): WM_RENDERFORMAT(cfFormat=%d)\n", rgelt.cfFormat);
|
break;
|
||||||
|
|
||||||
/*
|
|
||||||
* Render the clipboard data.
|
|
||||||
* (We must have a source data object or we wouldn't be in this WndProc)
|
|
||||||
*/
|
|
||||||
render_format( (IDataObject*)&(theOleClipboard->lpvtbl), &rgelt );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* WM_RENDERALLFORMATS
|
|
||||||
* Sent before the clipboard owner window is destroyed.
|
|
||||||
* We should receive this message only when OleUninitialize is called
|
|
||||||
* while we have an IDataObject in the clipboard.
|
|
||||||
* For the content of the clipboard to remain available to other
|
|
||||||
* applications, we must render data in all the formats the source IDataObject
|
|
||||||
* is capable of generating, and place the data on the clipboard by calling
|
|
||||||
* SetClipboardData.
|
|
||||||
*/
|
|
||||||
case WM_RENDERALLFORMATS:
|
case WM_RENDERALLFORMATS:
|
||||||
{
|
{
|
||||||
IEnumFORMATETC* penumFormatetc = NULL;
|
DWORD i;
|
||||||
FORMATETC rgelt;
|
ole_priv_data_entry *entries = clipbrd->cached_enum->entries;
|
||||||
|
|
||||||
TRACE("(): WM_RENDERALLFORMATS\n");
|
TRACE("(): WM_RENDERALLFORMATS\n");
|
||||||
|
|
||||||
/*
|
for(i = 0; i < clipbrd->cached_enum->count; i++)
|
||||||
* Render all HGLOBAL formats supported by the source into
|
|
||||||
* the windows clipboard.
|
|
||||||
*/
|
|
||||||
if ( FAILED( IDataObject_EnumFormatEtc( (IDataObject*)&(theOleClipboard->lpvtbl),
|
|
||||||
DATADIR_GET, &penumFormatetc) ) )
|
|
||||||
{
|
|
||||||
WARN("(): WM_RENDERALLFORMATS failed to retrieve EnumFormatEtc!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ( S_OK == IEnumFORMATETC_Next(penumFormatetc, 1, &rgelt, NULL) )
|
|
||||||
{
|
|
||||||
if ( rgelt.tymed == TYMED_HGLOBAL )
|
|
||||||
{
|
{
|
||||||
/*
|
if(entries[i].first_use)
|
||||||
* Render the clipboard data.
|
render_format(clipbrd->pIDataObjectSrc, &entries[i].fmtetc);
|
||||||
*/
|
|
||||||
if ( FAILED(render_format( (IDataObject*)&(theOleClipboard->lpvtbl), &rgelt )) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
TRACE("(): WM_RENDERALLFORMATS(cfFormat=%d)\n", rgelt.cfFormat);
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
IEnumFORMATETC_Release(penumFormatetc);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* WM_DESTROYCLIPBOARD
|
|
||||||
* This is sent by EmptyClipboard before the clipboard is emptied.
|
|
||||||
* We should release any IDataObject we are holding onto when we receive
|
|
||||||
* this message, since it indicates that the OLE clipboard should be empty
|
|
||||||
* from this point on.
|
|
||||||
*/
|
|
||||||
case WM_DESTROYCLIPBOARD:
|
case WM_DESTROYCLIPBOARD:
|
||||||
{
|
{
|
||||||
TRACE("(): WM_DESTROYCLIPBOARD\n");
|
TRACE("(): WM_DESTROYCLIPBOARD\n");
|
||||||
/*
|
|
||||||
* Release the data object we are holding on to
|
if ( clipbrd->pIDataObjectSrc )
|
||||||
*/
|
{
|
||||||
if ( theOleClipboard->pIDataObjectSrc )
|
IDataObject_Release(clipbrd->pIDataObjectSrc);
|
||||||
{
|
clipbrd->pIDataObjectSrc = NULL;
|
||||||
IDataObject_Release(theOleClipboard->pIDataObjectSrc);
|
HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum);
|
||||||
theOleClipboard->pIDataObjectSrc = NULL;
|
clipbrd->cached_enum = NULL;
|
||||||
HeapFree(GetProcessHeap(), 0, theOleClipboard->cached_enum);
|
}
|
||||||
theOleClipboard->cached_enum = NULL;
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
case WM_ASKCBFORMATNAME:
|
|
||||||
case WM_CHANGECBCHAIN:
|
|
||||||
case WM_DRAWCLIPBOARD:
|
|
||||||
case WM_SIZECLIPBOARD:
|
|
||||||
case WM_HSCROLLCLIPBOARD:
|
|
||||||
case WM_VSCROLLCLIPBOARD:
|
|
||||||
case WM_PAINTCLIPBOARD:
|
|
||||||
*/
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProcA(hWnd, message, wParam, lParam);
|
return DefWindowProcA(hwnd, message, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1196,7 +1124,7 @@ static HWND OLEClipbrd_CreateWindow(void)
|
||||||
* We don't bother doing this since the FindClassByAtom code
|
* We don't bother doing this since the FindClassByAtom code
|
||||||
* would have to be changed to deal with this idiosyncrasy. */
|
* would have to be changed to deal with this idiosyncrasy. */
|
||||||
wcex.style = CS_GLOBALCLASS;
|
wcex.style = CS_GLOBALCLASS;
|
||||||
wcex.lpfnWndProc = OLEClipbrd_WndProc;
|
wcex.lpfnWndProc = clipbrd_wndproc;
|
||||||
wcex.hInstance = 0;
|
wcex.hInstance = 0;
|
||||||
wcex.lpszClassName = OLEClipbrd_WNDCLASS;
|
wcex.lpszClassName = OLEClipbrd_WNDCLASS;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue