user32/tests: Added test cases for WM_CHAR conversions.
This commit is contained in:
parent
82964f5032
commit
b9540cf9e7
|
@ -61,6 +61,9 @@ static BOOL (WINAPI *pUnhookWinEvent)(HWINEVENTHOOK);
|
|||
|
||||
static void dump_winpos_flags(UINT flags);
|
||||
|
||||
static const WCHAR testWindowClassW[] =
|
||||
{ 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
|
||||
|
||||
/*
|
||||
FIXME: add tests for these
|
||||
Window Edge Styles (Win31/Win95/98 look), in order of precedence:
|
||||
|
@ -6355,6 +6358,7 @@ static LRESULT WINAPI ShowWindowProcA(HWND hwnd, UINT message, WPARAM wParam, LP
|
|||
static BOOL RegisterWindowClasses(void)
|
||||
{
|
||||
WNDCLASSA cls;
|
||||
WNDCLASSW clsW;
|
||||
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = MsgCheckProcA;
|
||||
|
@ -6396,6 +6400,18 @@ static BOOL RegisterWindowClasses(void)
|
|||
cls.lpszClassName = "TestDialogClass";
|
||||
if(!RegisterClassA(&cls)) return FALSE;
|
||||
|
||||
clsW.style = 0;
|
||||
clsW.lpfnWndProc = MsgCheckProcW;
|
||||
clsW.cbClsExtra = 0;
|
||||
clsW.cbWndExtra = 0;
|
||||
clsW.hInstance = GetModuleHandleW(0);
|
||||
clsW.hIcon = 0;
|
||||
clsW.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
|
||||
clsW.hbrBackground = GetStockObject(WHITE_BRUSH);
|
||||
clsW.lpszMenuName = NULL;
|
||||
clsW.lpszClassName = testWindowClassW;
|
||||
RegisterClassW(&clsW); /* ignore error, this fails on Win9x */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -6558,9 +6574,6 @@ static const struct message WmGetTextLengthAfromW[] = {
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
static const WCHAR testWindowClassW[] =
|
||||
{ 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
|
||||
|
||||
static const WCHAR dummy_window_text[] = {'d','u','m','m','y',' ','t','e','x','t',0};
|
||||
|
||||
/* dummy window proc for WM_GETTEXTLENGTH test */
|
||||
|
@ -6602,18 +6615,6 @@ static void test_message_conversion(void)
|
|||
* meaningless on those platforms */
|
||||
if(!RegisterClassW(&cls)) return;
|
||||
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = MsgCheckProcW;
|
||||
cls.cbClsExtra = 0;
|
||||
cls.cbWndExtra = 0;
|
||||
cls.hInstance = GetModuleHandleW(0);
|
||||
cls.hIcon = 0;
|
||||
cls.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
|
||||
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
|
||||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = testWindowClassW;
|
||||
if(!RegisterClassW(&cls)) return;
|
||||
|
||||
hwnd = CreateWindowExW(0, wszMsgConversionClass, NULL, WS_OVERLAPPED,
|
||||
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||
ok(hwnd != NULL, "Window creation failed\n");
|
||||
|
@ -9274,6 +9275,215 @@ static void test_SetForegroundWindow(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_dbcs_wm_char(void)
|
||||
{
|
||||
BYTE dbch[2];
|
||||
WCHAR wch, bad_wch;
|
||||
HWND hwnd, hwnd2;
|
||||
MSG msg;
|
||||
DWORD_PTR res;
|
||||
CPINFOEXA cpinfo;
|
||||
UINT i, j, k;
|
||||
struct message wmCharSeq[2];
|
||||
|
||||
GetCPInfoExA( CP_ACP, 0, &cpinfo );
|
||||
if (cpinfo.MaxCharSize != 2)
|
||||
{
|
||||
skip( "Skipping DBCS WM_CHAR test in SBCS codepage '%s'\n", cpinfo.CodePageName );
|
||||
return;
|
||||
}
|
||||
|
||||
dbch[0] = dbch[1] = 0;
|
||||
wch = 0;
|
||||
bad_wch = cpinfo.UnicodeDefaultChar;
|
||||
for (i = 0; !wch && i < MAX_LEADBYTES && cpinfo.LeadByte[i]; i += 2)
|
||||
for (j = cpinfo.LeadByte[i]; !wch && j <= cpinfo.LeadByte[i+1]; j++)
|
||||
for (k = 128; k <= 255; k++)
|
||||
{
|
||||
char str[2];
|
||||
WCHAR wstr[2];
|
||||
str[0] = j;
|
||||
str[1] = k;
|
||||
if (MultiByteToWideChar( CP_ACP, 0, str, 2, wstr, 2 ) == 1 &&
|
||||
WideCharToMultiByte( CP_ACP, 0, wstr, 1, str, 2, NULL, NULL ) == 2 &&
|
||||
(BYTE)str[0] == j && (BYTE)str[1] == k &&
|
||||
HIBYTE(wstr[0]) && HIBYTE(wstr[0]) != 0xff)
|
||||
{
|
||||
dbch[0] = j;
|
||||
dbch[1] = k;
|
||||
wch = wstr[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wch)
|
||||
{
|
||||
skip( "Skipping DBCS WM_CHAR test, no appropriate char found\n" );
|
||||
return;
|
||||
}
|
||||
trace( "using dbcs char %02x,%02x wchar %04x bad wchar %04x codepage '%s'\n",
|
||||
dbch[0], dbch[1], wch, bad_wch, cpinfo.CodePageName );
|
||||
|
||||
hwnd = CreateWindowExW(0, testWindowClassW, NULL,
|
||||
WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, 0, NULL);
|
||||
hwnd2 = CreateWindowExW(0, testWindowClassW, NULL,
|
||||
WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, 0, NULL);
|
||||
ok (hwnd != 0, "Failed to create overlapped window\n");
|
||||
ok (hwnd2 != 0, "Failed to create overlapped window\n");
|
||||
flush_sequence();
|
||||
|
||||
memset( wmCharSeq, 0, sizeof(wmCharSeq) );
|
||||
wmCharSeq[0].message = WM_CHAR;
|
||||
wmCharSeq[0].flags = sent|wparam;
|
||||
wmCharSeq[0].wParam = wch;
|
||||
|
||||
/* posted message */
|
||||
PostMessageA( hwnd, WM_CHAR, dbch[0], 0 );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
|
||||
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
|
||||
ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* posted thread message */
|
||||
PostThreadMessageA( GetCurrentThreadId(), WM_CHAR, dbch[0], 0 );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
|
||||
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
|
||||
ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* sent message */
|
||||
flush_sequence();
|
||||
SendMessageA( hwnd, WM_CHAR, dbch[0], 0 );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* sent message with timeout */
|
||||
flush_sequence();
|
||||
SendMessageTimeoutA( hwnd, WM_CHAR, dbch[0], 0, SMTO_NORMAL, 0, &res );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
SendMessageTimeoutA( hwnd, WM_CHAR, dbch[1], 0, SMTO_NORMAL, 0, &res );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* sent message with timeout and callback */
|
||||
flush_sequence();
|
||||
SendMessageTimeoutA( hwnd, WM_CHAR, dbch[0], 0, SMTO_NORMAL, 0, &res );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
SendMessageCallbackA( hwnd, WM_CHAR, dbch[1], 0, NULL, 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* sent message with callback */
|
||||
flush_sequence();
|
||||
SendNotifyMessageA( hwnd, WM_CHAR, dbch[0], 0 );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
SendMessageCallbackA( hwnd, WM_CHAR, dbch[1], 0, NULL, 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* direct window proc call */
|
||||
flush_sequence();
|
||||
CallWindowProcA( (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ), hwnd, WM_CHAR, dbch[0], 0 );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
CallWindowProcA( (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ), hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
|
||||
/* dispatch message */
|
||||
msg.hwnd = hwnd;
|
||||
msg.message = WM_CHAR;
|
||||
msg.wParam = dbch[0];
|
||||
msg.lParam = 0;
|
||||
DispatchMessageA( &msg );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
msg.wParam = dbch[1];
|
||||
DispatchMessageA( &msg );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
|
||||
/* window handle is irrelevant */
|
||||
flush_sequence();
|
||||
SendMessageA( hwnd2, WM_CHAR, dbch[0], 0 );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* interleaved post and send */
|
||||
flush_sequence();
|
||||
PostMessageA( hwnd2, WM_CHAR, dbch[0], 0 );
|
||||
SendMessageA( hwnd2, WM_CHAR, dbch[0], 0 );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
|
||||
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
|
||||
ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* interleaved sent message and winproc */
|
||||
flush_sequence();
|
||||
SendMessageA( hwnd, WM_CHAR, dbch[0], 0 );
|
||||
CallWindowProcA( (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ), hwnd, WM_CHAR, dbch[0], 0 );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
CallWindowProcA( (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ), hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
|
||||
/* interleaved winproc and dispatch */
|
||||
msg.hwnd = hwnd;
|
||||
msg.message = WM_CHAR;
|
||||
msg.wParam = dbch[0];
|
||||
msg.lParam = 0;
|
||||
CallWindowProcA( (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ), hwnd, WM_CHAR, dbch[0], 0 );
|
||||
DispatchMessageA( &msg );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
msg.wParam = dbch[1];
|
||||
DispatchMessageA( &msg );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
CallWindowProcA( (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ), hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
|
||||
/* interleaved sends */
|
||||
flush_sequence();
|
||||
SendMessageA( hwnd, WM_CHAR, dbch[0], 0 );
|
||||
SendMessageCallbackA( hwnd, WM_CHAR, dbch[0], 0, NULL, 0 );
|
||||
ok_sequence( WmEmptySeq, "no messages", FALSE );
|
||||
SendMessageTimeoutA( hwnd, WM_CHAR, dbch[1], 0, SMTO_NORMAL, 0, &res );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
|
||||
/* dbcs WM_CHAR */
|
||||
flush_sequence();
|
||||
SendMessageA( hwnd2, WM_CHAR, (dbch[1] << 8) | dbch[0], 0 );
|
||||
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
/* other char messages are not magic */
|
||||
PostMessageA( hwnd, WM_SYSCHAR, dbch[0], 0 );
|
||||
ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
|
||||
ok( msg.message == WM_SYSCHAR, "unexpected message %x\n", msg.message );
|
||||
ok( msg.wParam == bad_wch, "bad wparam %lx/%x\n", msg.wParam, bad_wch );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
PostMessageA( hwnd, WM_DEADCHAR, dbch[0], 0 );
|
||||
ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
|
||||
ok( msg.message == WM_DEADCHAR, "unexpected message %x\n", msg.message );
|
||||
ok( msg.wParam == bad_wch, "bad wparam %lx/%x\n", msg.wParam, bad_wch );
|
||||
ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(msg)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -9344,6 +9554,7 @@ START_TEST(msg)
|
|||
test_dialog_messages();
|
||||
test_nullCallback();
|
||||
test_SetForegroundWindow();
|
||||
test_dbcs_wm_char();
|
||||
|
||||
UnhookWindowsHookEx(hCBT_hook);
|
||||
if (pUnhookWinEvent)
|
||||
|
|
Loading…
Reference in New Issue