server: Notify all listeners when the contents of the clipboard have changed.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7594afeb6c
commit
c6f12bd9cc
|
@ -185,8 +185,8 @@ BOOL WINAPI CloseClipboard(void)
|
|||
{
|
||||
if (owner) USER_Driver->pEndClipboardUpdate();
|
||||
bCBHasChanged = FALSE;
|
||||
if (viewer) SendNotifyMessageW(viewer, WM_DRAWCLIPBOARD, (WPARAM) GetClipboardOwner(), 0);
|
||||
}
|
||||
if (viewer) SendNotifyMessageW( viewer, WM_DRAWCLIPBOARD, (WPARAM)GetClipboardOwner(), 0 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -513,33 +513,45 @@ static void test_synthesized(void)
|
|||
|
||||
static CRITICAL_SECTION clipboard_cs;
|
||||
static HWND next_wnd;
|
||||
static UINT wm_drawclipboard;
|
||||
static UINT wm_clipboardupdate;
|
||||
static UINT wm_destroyclipboard;
|
||||
static UINT nb_formats;
|
||||
static BOOL cross_thread;
|
||||
|
||||
static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
static UINT wm_drawclipboard;
|
||||
static UINT wm_clipboardupdate;
|
||||
static UINT wm_destroyclipboard;
|
||||
static UINT nb_formats;
|
||||
LRESULT ret;
|
||||
DWORD msg_flags = InSendMessageEx( NULL );
|
||||
|
||||
switch(msg) {
|
||||
case WM_DRAWCLIPBOARD:
|
||||
ok( msg_flags == (cross_thread ? ISMEX_NOTIFY : ISMEX_NOSEND),
|
||||
"WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags );
|
||||
EnterCriticalSection(&clipboard_cs);
|
||||
wm_drawclipboard++;
|
||||
LeaveCriticalSection(&clipboard_cs);
|
||||
break;
|
||||
case WM_CHANGECBCHAIN:
|
||||
ok( msg_flags == (cross_thread ? ISMEX_SEND : ISMEX_NOSEND),
|
||||
"WM_CHANGECBCHAIN wrong flags %x\n", msg_flags );
|
||||
if (next_wnd == (HWND)wp)
|
||||
next_wnd = (HWND)lp;
|
||||
else if (next_wnd)
|
||||
SendMessageA(next_wnd, msg, wp, lp);
|
||||
break;
|
||||
case WM_DESTROYCLIPBOARD:
|
||||
ok( msg_flags == (cross_thread ? ISMEX_SEND : ISMEX_NOSEND),
|
||||
"WM_DESTROYCLIPBOARD wrong flags %x\n", msg_flags );
|
||||
wm_destroyclipboard++;
|
||||
ok( GetClipboardOwner() == hwnd, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
|
||||
nb_formats = CountClipboardFormats();
|
||||
break;
|
||||
case WM_CLIPBOARDUPDATE:
|
||||
ok( msg_flags == ISMEX_NOSEND, "WM_CLIPBOARDUPDATE wrong flags %x\n", msg_flags );
|
||||
EnterCriticalSection(&clipboard_cs);
|
||||
wm_clipboardupdate++;
|
||||
LeaveCriticalSection(&clipboard_cs);
|
||||
break;
|
||||
case WM_USER:
|
||||
ChangeClipboardChain(hwnd, next_wnd);
|
||||
|
@ -568,9 +580,13 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
{
|
||||
HWND ret, win = param;
|
||||
BOOL r;
|
||||
MSG msg;
|
||||
HANDLE handle;
|
||||
UINT count, formats, old_seq = 0, seq;
|
||||
|
||||
cross_thread = (GetWindowThreadProcessId( win, NULL ) != GetCurrentThreadId());
|
||||
trace( "%s-threaded test\n", cross_thread ? "multi" : "single" );
|
||||
|
||||
if (pGetClipboardSequenceNumber) old_seq = pGetClipboardSequenceNumber();
|
||||
|
||||
EnterCriticalSection(&clipboard_cs);
|
||||
|
@ -615,8 +631,14 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
seq = pGetClipboardSequenceNumber();
|
||||
ok( seq == old_seq, "sequence changed\n" );
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER + 1, 0, 0 );
|
||||
ok( count, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
|
||||
|
||||
|
@ -633,6 +655,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
seq = pGetClipboardSequenceNumber();
|
||||
ok( seq == old_seq, "sequence changed\n" );
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -647,6 +675,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -663,6 +697,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -681,6 +721,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -694,6 +740,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -707,6 +759,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -723,10 +781,16 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
|
||||
r = OpenClipboard(win);
|
||||
ok(r, "OpenClipboard failed: %d\n", GetLastError());
|
||||
|
@ -736,6 +800,11 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
seq = pGetClipboardSequenceNumber();
|
||||
ok( seq == old_seq, "sequence changed\n" );
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -748,6 +817,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -762,10 +837,16 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
|
||||
r = OpenClipboard(win);
|
||||
ok(r, "OpenClipboard failed: %d\n", GetLastError());
|
||||
|
@ -777,6 +858,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
seq = pGetClipboardSequenceNumber();
|
||||
ok( seq == old_seq, "sequence changed\n" );
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -792,12 +879,18 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
r = CloseClipboard();
|
||||
ok(r, "CloseClipboard failed: %d\n", GetLastError());
|
||||
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
count = SendMessageA( win, WM_USER+3, 0, 0 );
|
||||
ok( count, "WM_DESTROYCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DESTROYCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+4, 0, 0 );
|
||||
ok( count == formats, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count );
|
||||
|
||||
|
@ -810,6 +903,14 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
|
||||
count = SendMessageA( win, WM_USER+3, 0, 0 );
|
||||
|
@ -826,10 +927,16 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
|
||||
run_process( "grab_clipboard 0" );
|
||||
|
||||
|
@ -839,10 +946,19 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
/* in this case we get a cross-thread WM_DRAWCLIPBOARD */
|
||||
cross_thread = TRUE;
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
cross_thread = FALSE;
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
todo_wine ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
|
||||
r = OpenClipboard(0);
|
||||
ok(r, "OpenClipboard failed: %d\n", GetLastError());
|
||||
|
@ -853,6 +969,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -869,10 +991,16 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
|
||||
run_process( "grab_clipboard 1" );
|
||||
|
||||
|
@ -882,10 +1010,19 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
/* in this case we get a cross-thread WM_DRAWCLIPBOARD */
|
||||
cross_thread = TRUE;
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
cross_thread = FALSE;
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
todo_wine ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
|
||||
r = OpenClipboard(0);
|
||||
ok(r, "OpenClipboard failed: %d\n", GetLastError());
|
||||
|
@ -896,6 +1033,12 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( !count, "WM_DRAWCLIPBOARD received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
|
@ -912,10 +1055,16 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
{
|
||||
ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" );
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
|
||||
}
|
||||
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||
ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||
ok( count == 1, "WM_DRAWCLIPBOARD not received\n" );
|
||||
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||
|
||||
r = PostMessageA(win, WM_USER, 0, 0);
|
||||
ok(r, "PostMessage failed: %d\n", GetLastError());
|
||||
|
@ -958,7 +1107,9 @@ static void test_messages(void)
|
|||
thread = CreateThread(NULL, 0, clipboard_thread, (void*)win, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed: %d\n", GetLastError());
|
||||
|
||||
while(GetMessageA(&msg, NULL, 0, 0)) {
|
||||
while(GetMessageA(&msg, NULL, 0, 0))
|
||||
{
|
||||
ok( msg.message != WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD was posted\n" );
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
|
@ -966,6 +1117,16 @@ static void test_messages(void)
|
|||
ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
|
||||
CloseHandle(thread);
|
||||
|
||||
DestroyWindow( win );
|
||||
|
||||
/* same tests again but inside a single thread */
|
||||
|
||||
win = CreateWindowA( "clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0 );
|
||||
ok( win != NULL, "CreateWindow failed: %d\n", GetLastError() );
|
||||
|
||||
clipboard_thread( win );
|
||||
DestroyWindow( win );
|
||||
|
||||
UnregisterClassA("clipboard_test", GetModuleHandleA(NULL));
|
||||
DeleteCriticalSection(&clipboard_cs);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ struct clipboard
|
|||
user_handle_t owner_win; /* window that owns the clipboard data */
|
||||
user_handle_t viewer; /* first window in clipboard viewer list */
|
||||
unsigned int seqno; /* clipboard change sequence number */
|
||||
unsigned int open_seqno; /* sequence number at open time */
|
||||
timeout_t seqno_timestamp; /* time stamp of last seqno increment */
|
||||
unsigned int listen_size; /* size of listeners array */
|
||||
unsigned int listen_count; /* count of listeners */
|
||||
|
@ -167,6 +168,21 @@ static int remove_listener( struct clipboard *clipboard, user_handle_t window )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* close the clipboard, and return the viewer window that should be notified if any */
|
||||
static user_handle_t close_clipboard( struct clipboard *clipboard )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
clipboard->open_win = 0;
|
||||
clipboard->open_thread = NULL;
|
||||
|
||||
if (clipboard->seqno == clipboard->open_seqno) return 0; /* unchanged */
|
||||
|
||||
for (i = 0; i < clipboard->listen_count; i++)
|
||||
post_message( clipboard->listeners[i], WM_CLIPBOARDUPDATE, 0, 0 );
|
||||
return clipboard->viewer;
|
||||
}
|
||||
|
||||
/* cleanup clipboard information upon window destruction */
|
||||
void cleanup_clipboard_window( struct desktop *desktop, user_handle_t window )
|
||||
{
|
||||
|
@ -174,18 +190,18 @@ void cleanup_clipboard_window( struct desktop *desktop, user_handle_t window )
|
|||
|
||||
if (!clipboard) return;
|
||||
|
||||
if (clipboard->open_win == window)
|
||||
{
|
||||
clipboard->open_win = 0;
|
||||
clipboard->open_thread = NULL;
|
||||
}
|
||||
remove_listener( clipboard, window );
|
||||
if (clipboard->viewer == window) clipboard->viewer = 0;
|
||||
if (clipboard->owner_win == window)
|
||||
{
|
||||
clipboard->owner_win = 0;
|
||||
clipboard->owner_thread = NULL;
|
||||
}
|
||||
if (clipboard->viewer == window) clipboard->viewer = 0;
|
||||
remove_listener( clipboard, window );
|
||||
if (clipboard->open_win == window)
|
||||
{
|
||||
user_handle_t viewer = close_clipboard( clipboard );
|
||||
if (viewer) send_notify_message( viewer, WM_DRAWCLIPBOARD, clipboard->owner_win, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when thread terminates to allow release of clipboard */
|
||||
|
@ -199,16 +215,16 @@ void cleanup_clipboard_thread(struct thread *thread)
|
|||
|
||||
if ((clipboard = winstation->clipboard))
|
||||
{
|
||||
if (thread == clipboard->open_thread)
|
||||
{
|
||||
clipboard->open_win = 0;
|
||||
clipboard->open_thread = NULL;
|
||||
}
|
||||
if (thread == clipboard->owner_thread)
|
||||
{
|
||||
clipboard->owner_win = 0;
|
||||
clipboard->owner_thread = NULL;
|
||||
}
|
||||
if (thread == clipboard->open_thread)
|
||||
{
|
||||
user_handle_t viewer = close_clipboard( clipboard );
|
||||
if (viewer) send_notify_message( viewer, WM_DRAWCLIPBOARD, clipboard->owner_win, 0 );
|
||||
}
|
||||
}
|
||||
release_object( winstation );
|
||||
}
|
||||
|
@ -256,6 +272,8 @@ DECL_HANDLER(open_clipboard)
|
|||
set_error( STATUS_INVALID_LOCK_SEQUENCE );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!clipboard->open_thread) clipboard->open_seqno = clipboard->seqno; /* first open */
|
||||
clipboard->open_win = win;
|
||||
clipboard->open_thread = current;
|
||||
|
||||
|
@ -276,10 +294,8 @@ DECL_HANDLER(close_clipboard)
|
|||
return;
|
||||
}
|
||||
if (req->changed) clipboard->seqno++;
|
||||
clipboard->open_thread = NULL;
|
||||
clipboard->open_win = 0;
|
||||
|
||||
reply->viewer = clipboard->viewer;
|
||||
reply->viewer = close_clipboard( clipboard );
|
||||
reply->owner = (clipboard->owner_thread && clipboard->owner_thread->process == current->process);
|
||||
}
|
||||
|
||||
|
|
|
@ -2112,6 +2112,33 @@ void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lpa
|
|||
release_object( thread );
|
||||
}
|
||||
|
||||
/* send a notify message to a window */
|
||||
void send_notify_message( user_handle_t win, unsigned int message, lparam_t wparam, lparam_t lparam )
|
||||
{
|
||||
struct message *msg;
|
||||
struct thread *thread = get_window_thread( win );
|
||||
|
||||
if (!thread) return;
|
||||
|
||||
if (thread->queue && (msg = mem_alloc( sizeof(*msg) )))
|
||||
{
|
||||
msg->type = MSG_NOTIFY;
|
||||
msg->win = get_user_full_handle( win );
|
||||
msg->msg = message;
|
||||
msg->wparam = wparam;
|
||||
msg->lparam = lparam;
|
||||
msg->result = NULL;
|
||||
msg->data = NULL;
|
||||
msg->data_size = 0;
|
||||
|
||||
get_message_defaults( thread->queue, &msg->x, &msg->y, &msg->time );
|
||||
|
||||
list_add_tail( &thread->queue->msg_list[SEND_MESSAGE], &msg->entry );
|
||||
set_queue_bits( thread->queue, QS_SENDMESSAGE );
|
||||
}
|
||||
release_object( thread );
|
||||
}
|
||||
|
||||
/* post a win event */
|
||||
void post_win_event( struct thread *thread, unsigned int event,
|
||||
user_handle_t win, unsigned int object_id,
|
||||
|
|
|
@ -112,6 +112,8 @@ extern int attach_thread_input( struct thread *thread_from, struct thread *threa
|
|||
extern void detach_thread_input( struct thread *thread_from );
|
||||
extern void post_message( user_handle_t win, unsigned int message,
|
||||
lparam_t wparam, lparam_t lparam );
|
||||
extern void send_notify_message( user_handle_t win, unsigned int message,
|
||||
lparam_t wparam, lparam_t lparam );
|
||||
extern void post_win_event( struct thread *thread, unsigned int event,
|
||||
user_handle_t win, unsigned int object_id,
|
||||
unsigned int child_id, client_ptr_t proc,
|
||||
|
|
Loading…
Reference in New Issue