user32/tests: Add tests for clipboard sequence number and notifications.
This commit is contained in:
parent
ba757eaec7
commit
9ce9ba30ea
|
@ -24,6 +24,9 @@
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
|
|
||||||
|
static BOOL (WINAPI *pAddClipboardFormatListener)(HWND hwnd);
|
||||||
|
static DWORD (WINAPI *pGetClipboardSequenceNumber)(void);
|
||||||
|
|
||||||
static DWORD WINAPI open_clipboard_thread(LPVOID arg)
|
static DWORD WINAPI open_clipboard_thread(LPVOID arg)
|
||||||
{
|
{
|
||||||
HWND hWnd = arg;
|
HWND hWnd = arg;
|
||||||
|
@ -278,9 +281,14 @@ static CRITICAL_SECTION clipboard_cs;
|
||||||
static HWND next_wnd;
|
static HWND next_wnd;
|
||||||
static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||||
{
|
{
|
||||||
|
static UINT wm_drawclipboard;
|
||||||
|
static UINT wm_clipboardupdate;
|
||||||
|
LRESULT ret;
|
||||||
|
|
||||||
switch(msg) {
|
switch(msg) {
|
||||||
case WM_DRAWCLIPBOARD:
|
case WM_DRAWCLIPBOARD:
|
||||||
EnterCriticalSection(&clipboard_cs);
|
EnterCriticalSection(&clipboard_cs);
|
||||||
|
wm_drawclipboard++;
|
||||||
LeaveCriticalSection(&clipboard_cs);
|
LeaveCriticalSection(&clipboard_cs);
|
||||||
break;
|
break;
|
||||||
case WM_CHANGECBCHAIN:
|
case WM_CHANGECBCHAIN:
|
||||||
|
@ -289,10 +297,21 @@ static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARA
|
||||||
else if (next_wnd)
|
else if (next_wnd)
|
||||||
SendMessageA(next_wnd, msg, wp, lp);
|
SendMessageA(next_wnd, msg, wp, lp);
|
||||||
break;
|
break;
|
||||||
|
case WM_CLIPBOARDUPDATE:
|
||||||
|
wm_clipboardupdate++;
|
||||||
|
break;
|
||||||
case WM_USER:
|
case WM_USER:
|
||||||
ChangeClipboardChain(hwnd, next_wnd);
|
ChangeClipboardChain(hwnd, next_wnd);
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
break;
|
break;
|
||||||
|
case WM_USER+1:
|
||||||
|
ret = wm_drawclipboard;
|
||||||
|
wm_drawclipboard = 0;
|
||||||
|
return ret;
|
||||||
|
case WM_USER+2:
|
||||||
|
ret = wm_clipboardupdate;
|
||||||
|
wm_clipboardupdate = 0;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProcA(hwnd, msg, wp, lp);
|
return DefWindowProcA(hwnd, msg, wp, lp);
|
||||||
|
@ -302,24 +321,183 @@ static DWORD WINAPI clipboard_thread(void *param)
|
||||||
{
|
{
|
||||||
HWND win = param;
|
HWND win = param;
|
||||||
BOOL r;
|
BOOL r;
|
||||||
|
HANDLE handle;
|
||||||
|
UINT count, old_seq = 0, seq;
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber) old_seq = pGetClipboardSequenceNumber();
|
||||||
|
|
||||||
EnterCriticalSection(&clipboard_cs);
|
EnterCriticalSection(&clipboard_cs);
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
next_wnd = SetClipboardViewer(win);
|
next_wnd = SetClipboardViewer(win);
|
||||||
ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
|
ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
|
||||||
LeaveCriticalSection(&clipboard_cs);
|
LeaveCriticalSection(&clipboard_cs);
|
||||||
|
if (pAddClipboardFormatListener)
|
||||||
|
{
|
||||||
|
r = pAddClipboardFormatListener(win);
|
||||||
|
ok( r, "AddClipboardFormatListener failed err %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
ok( seq == old_seq, "sequence changed\n" );
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
r = OpenClipboard(win);
|
r = OpenClipboard(win);
|
||||||
ok(r, "OpenClipboard failed: %d\n", GetLastError());
|
ok(r, "OpenClipboard failed: %d\n", GetLastError());
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
ok( seq == old_seq, "sequence changed\n" );
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
r = EmptyClipboard();
|
r = EmptyClipboard();
|
||||||
ok(r, "EmptyClipboard failed: %d\n", GetLastError());
|
ok(r, "EmptyClipboard failed: %d\n", GetLastError());
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||||
|
old_seq = seq;
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
|
r = EmptyClipboard();
|
||||||
|
ok(r, "EmptyClipboard failed: %d\n", GetLastError());
|
||||||
|
/* sequence changes again, even though it was already empty */
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||||
|
old_seq = seq;
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
|
handle = SetClipboardData( CF_TEXT, create_text() );
|
||||||
|
ok(handle != 0, "SetClipboardData failed: %d\n", GetLastError());
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||||
|
old_seq = seq;
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
|
SetClipboardData( CF_UNICODETEXT, 0 );
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||||
|
old_seq = seq;
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
|
SetClipboardData( CF_UNICODETEXT, 0 ); /* same data again */
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||||
|
old_seq = seq;
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
EnterCriticalSection(&clipboard_cs);
|
EnterCriticalSection(&clipboard_cs);
|
||||||
r = CloseClipboard();
|
r = CloseClipboard();
|
||||||
ok(r, "CloseClipboard failed: %d\n", GetLastError());
|
ok(r, "CloseClipboard failed: %d\n", GetLastError());
|
||||||
LeaveCriticalSection(&clipboard_cs);
|
LeaveCriticalSection(&clipboard_cs);
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||||
|
old_seq = seq;
|
||||||
|
}
|
||||||
|
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||||
|
ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||||
|
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||||
|
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||||
|
|
||||||
|
r = OpenClipboard(win);
|
||||||
|
ok(r, "OpenClipboard failed: %d\n", GetLastError());
|
||||||
|
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
ok( seq == old_seq, "sequence changed\n" );
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
|
SetClipboardData( CF_WAVE, 0 );
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
|
||||||
|
old_seq = seq;
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
|
r = CloseClipboard();
|
||||||
|
ok(r, "CloseClipboard failed: %d\n", GetLastError());
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
/* no synthesized format, so CloseClipboard doesn't change the sequence */
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||||
|
old_seq = seq;
|
||||||
|
}
|
||||||
|
count = SendMessageA( win, WM_USER+1, 0, 0 );
|
||||||
|
ok( count, "WM_DRAWCLIPBOARD not received\n" );
|
||||||
|
count = SendMessageA( win, WM_USER+2, 0, 0 );
|
||||||
|
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
|
||||||
|
|
||||||
|
r = OpenClipboard(win);
|
||||||
|
ok(r, "OpenClipboard failed: %d\n", GetLastError());
|
||||||
|
r = CloseClipboard();
|
||||||
|
ok(r, "CloseClipboard failed: %d\n", GetLastError());
|
||||||
|
/* nothing changed */
|
||||||
|
if (pGetClipboardSequenceNumber)
|
||||||
|
{
|
||||||
|
seq = pGetClipboardSequenceNumber();
|
||||||
|
ok( seq == old_seq, "sequence changed\n" );
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
r = PostMessageA(win, WM_USER, 0, 0);
|
r = PostMessageA(win, WM_USER, 0, 0);
|
||||||
ok(r, "PostMessage failed: %d\n", GetLastError());
|
ok(r, "PostMessage failed: %d\n", GetLastError());
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -361,6 +539,11 @@ static void test_messages(void)
|
||||||
|
|
||||||
START_TEST(clipboard)
|
START_TEST(clipboard)
|
||||||
{
|
{
|
||||||
|
HMODULE mod = GetModuleHandleA( "user32" );
|
||||||
|
|
||||||
|
pAddClipboardFormatListener = (void *)GetProcAddress( mod, "AddClipboardFormatListener" );
|
||||||
|
pGetClipboardSequenceNumber = (void *)GetProcAddress( mod, "GetClipboardSequenceNumber" );
|
||||||
|
|
||||||
test_RegisterClipboardFormatA();
|
test_RegisterClipboardFormatA();
|
||||||
test_ClipboardOwner();
|
test_ClipboardOwner();
|
||||||
test_synthesized();
|
test_synthesized();
|
||||||
|
|
Loading…
Reference in New Issue