When ole has set the clipboard data, the clipboard manager may preempt this data (by sending a WM_RENDERFORMAT message). At this point the clipboard ownership may be occupied by the clipboard manager; resulting in a failure to flush the ole clipboard.
Signed-off-by: Haoyang Chen chenhaoyang@uniontech.com --- dlls/ole32/clipboard.c | 2 ++ dlls/ole32/tests/clipboard.c | 10 ++++++++++ 2 files changed, 12 insertions(+)
diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c index e61b3076883..ebc498d52e7 100644 --- a/dlls/ole32/clipboard.c +++ b/dlls/ole32/clipboard.c @@ -2261,6 +2261,7 @@ HRESULT WINAPI OleFlushClipboard(void) HRESULT hr; ole_clipbrd *clipbrd; HWND wnd; + MSG msg;
TRACE("()\n");
@@ -2273,6 +2274,7 @@ HRESULT WINAPI OleFlushClipboard(void) */ if (!clipbrd->src_data) return S_OK;
+ PeekMessageW(&msg, wnd, WM_RENDERFORMAT, WM_RENDERFORMAT, PM_REMOVE); if (!OpenClipboard(wnd)) return CLIPBRD_E_CANT_OPEN;
SendMessageW(wnd, WM_RENDERALLFORMATS, 0, 0); diff --git a/dlls/ole32/tests/clipboard.c b/dlls/ole32/tests/clipboard.c index fd8f287680b..47700e7f3fd 100644 --- a/dlls/ole32/tests/clipboard.c +++ b/dlls/ole32/tests/clipboard.c @@ -1085,6 +1085,7 @@ static void test_set_clipboard_DRAWCLIPBOARD(void) HWND viewer; int ret; HANDLE thread; + int i;
hr = DataObjectImpl_CreateText("data", &data); ok(hr == S_OK, "Failed to create data object: 0x%08x\n", hr); @@ -1120,6 +1121,15 @@ static void test_set_clipboard_DRAWCLIPBOARD(void) ret = SendMessageA( viewer, WM_USER, 0, 0 ); ok( ret == 2, "%u WM_DRAWCLIPBOARD received\n", ret );
+ Sleep(500); + + for (i = 0; i < 10; i++) + { + hr = OleFlushClipboard(); + if (hr == S_OK) break; + Sleep(100); + } + ok(hr == S_OK, "got %08x\n", hr); clip_data = NULL; hr = OleFlushClipboard(); ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);