From b2a0c584339dc9757d6f8b64ff41878bb4949d8d Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 15 Oct 2009 20:00:27 +0000 Subject: [PATCH] - Update user32_winetest to Wine-1.1.31. svn path=/trunk/; revision=43499 --- rostests/winetests/user32/class.c | 4 +- rostests/winetests/user32/cursoricon.c | 146 +++++++++++++++++- rostests/winetests/user32/dde.c | 34 +++-- rostests/winetests/user32/dialog.c | 19 ++- rostests/winetests/user32/input.c | 85 +++++++---- rostests/winetests/user32/msg.c | 203 ++++++++++++++++++++++++- rostests/winetests/user32/resource.rc | 7 + rostests/winetests/user32/sysparams.c | 3 +- rostests/winetests/user32/text.c | 2 +- rostests/winetests/user32/win.c | 54 +++++++ 10 files changed, 502 insertions(+), 55 deletions(-) diff --git a/rostests/winetests/user32/class.c b/rostests/winetests/user32/class.c index f8a4cd822ae..0e7b0e4bed7 100755 --- a/rostests/winetests/user32/class.c +++ b/rostests/winetests/user32/class.c @@ -598,8 +598,8 @@ static void test_builtinproc(void) HWND hwnd; int i; - pDefWindowProcA = GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcA"); - pDefWindowProcW = GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcW"); + pDefWindowProcA = (void *)GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcA"); + pDefWindowProcW = (void *)GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcW"); for (i = 0; i < 4; i++) { diff --git a/rostests/winetests/user32/cursoricon.c b/rostests/winetests/user32/cursoricon.c index 3f8bd82b3d3..ff86cd0d1ab 100644 --- a/rostests/winetests/user32/cursoricon.c +++ b/rostests/winetests/user32/cursoricon.c @@ -1039,6 +1039,8 @@ static void check_DrawIcon(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, COLOR HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color)); if (!hicon) return; SetPixelV(hdc, 0, 0, background); + SetPixelV(hdc, GetSystemMetrics(SM_CXICON)-1, GetSystemMetrics(SM_CYICON)-1, background); + SetPixelV(hdc, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), background); DrawIcon(hdc, 0, 0, hicon); result = GetPixel(hdc, 0, 0); @@ -1047,6 +1049,21 @@ static void check_DrawIcon(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, COLOR "Overlaying Mask %d on Color %06X with DrawIcon. " "Expected a close match to %06X (modern), or %06X (legacy). Got %06X from line %d\n", maskvalue, color, modern_expected, legacy_expected, result, line); + + result = GetPixel(hdc, GetSystemMetrics(SM_CXICON)-1, GetSystemMetrics(SM_CYICON)-1); + + ok (color_match(result, modern_expected) || /* Windows 2000 and up */ + broken(color_match(result, legacy_expected)), /* Windows NT 4.0, 9X and below */ + "Overlaying Mask %d on Color %06X with DrawIcon. " + "Expected a close match to %06X (modern), or %06X (legacy). Got %06X from line %d\n", + maskvalue, color, modern_expected, legacy_expected, result, line); + + result = GetPixel(hdc, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); + + ok (color_match(result, background), + "Overlaying Mask %d on Color %06X with DrawIcon. " + "Expected unchanged background color %06X. Got %06X from line %d\n", + maskvalue, color, background, result, line); } static void test_DrawIcon(void) @@ -1070,8 +1087,8 @@ static void test_DrawIcon(void) memset(&bitmapInfo, 0, sizeof(bitmapInfo)); bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bitmapInfo.bmiHeader.biWidth = 1; - bitmapInfo.bmiHeader.biHeight = 1; + bitmapInfo.bmiHeader.biWidth = GetSystemMetrics(SM_CXICON)+1; + bitmapInfo.bmiHeader.biHeight = GetSystemMetrics(SM_CYICON)+1; bitmapInfo.bmiHeader.biBitCount = 32; bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biCompression = BI_RGB; @@ -1212,6 +1229,130 @@ cleanup: DeleteDC(hdcDst); } +static void check_DrawState_Size(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, HBRUSH hbr, UINT flags, int line) +{ + COLORREF result, background; + BOOL passed[2]; + HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color)); + background = 0x00FFFFFF; + /* Set color of the 2 pixels that will be checked afterwards */ + SetPixelV(hdc, 0, 0, background); + SetPixelV(hdc, 2, 2, background); + + /* Let DrawState calculate the size of the icon (it's 1x1) */ + DrawState(hdc, hbr, NULL, (LPARAM) hicon, 0, 1, 1, 0, 0, (DST_ICON | flags )); + + result = GetPixel(hdc, 0, 0); + passed[0] = color_match(result, background); + result = GetPixel(hdc, 2, 2); + passed[0] = passed[0] & color_match(result, background); + + /* Check if manually specifying the icon size DOESN'T work */ + + /* IMPORTANT: For Icons, DrawState wants the size of the source image, not the + * size in which it should be ultimately drawn. Therefore giving + * width/height 2x2 if the icon is only 1x1 pixels in size should + * result in drawing it with size 1x1. The size parameters must be + * ignored if a Icon has to be drawn! */ + DrawState(hdc, hbr, NULL, (LPARAM) hicon, 0, 1, 1, 2, 2, (DST_ICON | flags )); + + result = GetPixel(hdc, 0, 0); + passed[1] = color_match(result, background); + result = GetPixel(hdc, 2, 2); + passed[1] = passed[0] & color_match(result, background); + + if(!passed[0]&&!passed[1]) + ok (passed[1], + "DrawState failed to draw a 1x1 Icon in the correct size, independent of the " + "width and height settings passed to it, for Icon with: Overlaying Mask %d on " + "Color %06X with flags %08X. Line %d\n", + maskvalue, color, (DST_ICON | flags), line); + else if(!passed[1]) + ok (passed[1], + "DrawState failed to draw a 1x1 Icon in the correct size, if the width and height " + "parameters passed to it are bigger than the real Icon size, for Icon with: Overlaying " + "Mask %d on Color %06X with flags %08X. Line %d\n", + maskvalue, color, (DST_ICON | flags), line); + else + ok (passed[0], + "DrawState failed to draw a 1x1 Icon in the correct size, if the width and height " + "parameters passed to it are 0, for Icon with: Overlaying Mask %d on " + "Color %06X with flags %08X. Line %d\n", + maskvalue, color, (DST_ICON | flags), line); +} + +static void check_DrawState_Color(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, HBRUSH hbr, UINT flags, + COLORREF background, COLORREF modern_expected, COLORREF legacy_expected, int line) +{ + COLORREF result; + HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color)); + if (!hicon) return; + /* Set color of the pixel that will be checked afterwards */ + SetPixelV(hdc, 1, 1, background); + + DrawState(hdc, hbr, NULL, (LPARAM) hicon, 0, 1, 1, 0, 0, ( DST_ICON | flags )); + + /* Check the color of the pixel is correct */ + result = GetPixel(hdc, 1, 1); + + ok (color_match(result, modern_expected) || /* Windows 2000 and up */ + broken(color_match(result, legacy_expected)), /* Windows NT 4.0, 9X and below */ + "DrawState drawing Icon with Overlaying Mask %d on Color %06X with flags %08X. " + "Expected a close match to %06X (modern) or %06X (legacy). Got %06X from line %d\n", + maskvalue, color, (DST_ICON | flags), modern_expected, legacy_expected, result, line); +} + +static void test_DrawState(void) +{ + BITMAPINFO bitmapInfo; + HDC hdcDst = NULL; + HBITMAP bmpDst = NULL; + HBITMAP bmpOld = NULL; + UINT32 bits = 0; + + hdcDst = CreateCompatibleDC(0); + ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n"); + if (!hdcDst) + return; + + if(GetDeviceCaps(hdcDst, BITSPIXEL) <= 8) + { + skip("Windows will distort DrawIconEx colors at 8-bpp and less due to palletizing.\n"); + goto cleanup; + } + + memset(&bitmapInfo, 0, sizeof(bitmapInfo)); + bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmapInfo.bmiHeader.biWidth = 3; + bitmapInfo.bmiHeader.biHeight = 3; + bitmapInfo.bmiHeader.biBitCount = 32; + bitmapInfo.bmiHeader.biPlanes = 1; + bitmapInfo.bmiHeader.biCompression = BI_RGB; + bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32); + bmpDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok (bmpDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n"); + if (!bmpDst || !bits) + goto cleanup; + bmpOld = SelectObject(hdcDst, bmpDst); + + /* potential flags to test with DrawState are: */ + /* DSS_DISABLED embosses the icon */ + /* DSS_MONO draw Icon using a brush as parameter 5 */ + /* DSS_NORMAL draw Icon without any modifications */ + /* DSS_UNION draw the Icon dithered */ + + check_DrawState_Size(hdcDst, FALSE, 0x00A0B0C0, 32, 0, DSS_NORMAL, __LINE__); + check_DrawState_Color(hdcDst, FALSE, 0x00A0B0C0, 32, 0, DSS_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__); + +cleanup: + if(bmpOld) + SelectObject(hdcDst, bmpOld); + if(bmpDst) + DeleteObject(bmpDst); + if(hdcDst) + DeleteDC(hdcDst); +} + static void test_DestroyCursor(void) { static const BYTE bmp_bits[4096]; @@ -1321,6 +1462,7 @@ START_TEST(cursoricon) test_CreateIconFromResource(); test_DrawIcon(); test_DrawIconEx(); + test_DrawState(); test_DestroyCursor(); do_parent(); test_child_process(); diff --git a/rostests/winetests/user32/dde.c b/rostests/winetests/user32/dde.c index 6625837eb6e..9e1da709c37 100755 --- a/rostests/winetests/user32/dde.c +++ b/rostests/winetests/user32/dde.c @@ -2390,23 +2390,33 @@ START_TEST(dde) test_end_to_end_server(proc.hProcess, proc.hThread, TRUE); - sprintf(buffer, "%s dde endw", argv[0]); - CreateProcessA(NULL, buffer, NULL, NULL, FALSE, - CREATE_SUSPENDED, NULL, NULL, &startup, &proc); + /* Don't bother testing W interfaces on Win9x/WinMe */ + SetLastError(0xdeadbeef); + lstrcmpW(NULL, NULL); + if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("Skipping W-interface tests\n"); + } + else + { + sprintf(buffer, "%s dde endw", argv[0]); + CreateProcessA(NULL, buffer, NULL, NULL, FALSE, + CREATE_SUSPENDED, NULL, NULL, &startup, &proc); - test_end_to_end_server(proc.hProcess, proc.hThread, FALSE); + test_end_to_end_server(proc.hProcess, proc.hThread, FALSE); - sprintf(buffer, "%s dde enda", argv[0]); - CreateProcessA(NULL, buffer, NULL, NULL, FALSE, - CREATE_SUSPENDED, NULL, NULL, &startup, &proc); + sprintf(buffer, "%s dde enda", argv[0]); + CreateProcessA(NULL, buffer, NULL, NULL, FALSE, + CREATE_SUSPENDED, NULL, NULL, &startup, &proc); - test_end_to_end_server(proc.hProcess, proc.hThread, FALSE); + test_end_to_end_server(proc.hProcess, proc.hThread, FALSE); - sprintf(buffer, "%s dde endw", argv[0]); - CreateProcessA(NULL, buffer, NULL, NULL, FALSE, - CREATE_SUSPENDED, NULL, NULL, &startup, &proc); + sprintf(buffer, "%s dde endw", argv[0]); + CreateProcessA(NULL, buffer, NULL, NULL, FALSE, + CREATE_SUSPENDED, NULL, NULL, &startup, &proc); - test_end_to_end_server(proc.hProcess, proc.hThread, TRUE); + test_end_to_end_server(proc.hProcess, proc.hThread, TRUE); + } test_dde_aw_transaction(); diff --git a/rostests/winetests/user32/dialog.c b/rostests/winetests/user32/dialog.c index dfb24833629..5879fbcb569 100755 --- a/rostests/winetests/user32/dialog.c +++ b/rostests/winetests/user32/dialog.c @@ -930,6 +930,19 @@ static INT_PTR CALLBACK DestroyOnCloseDlgWinProc (HWND hDlg, UINT uiMsg, return FALSE; } + +static INT_PTR CALLBACK TestDefButtonDlgProc (HWND hDlg, UINT uiMsg, + WPARAM wParam, LPARAM lParam) +{ + switch (uiMsg) + { + case WM_INITDIALOG: + EndDialog(hDlg, LOWORD(SendMessage(hDlg, DM_GETDEFID, 0, 0))); + return TRUE; + } + return FALSE; +} + static void test_DialogBoxParamA(void) { INT_PTR ret; @@ -965,8 +978,12 @@ static void test_DialogBoxParamA(void) SetLastError(0xdeadbeef); ret = DefDlgProcA(0, WM_ERASEBKGND, 0, 0); ok(ret == 0, "DefDlgProcA returned %ld, expected 0\n", ret); - ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, + ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || + broken(GetLastError() == 0xdeadbeef), "got %d, expected ERROR_INVALID_WINDOW_HANDLE\n", GetLastError()); + + ret = DialogBoxParamA(GetModuleHandle(NULL), "TEST_EMPTY_DIALOG", 0, TestDefButtonDlgProc, 0); + ok(ret == IDOK, "Expected IDOK\n"); } static void test_DisabledDialogTest(void) diff --git a/rostests/winetests/user32/input.c b/rostests/winetests/user32/input.c index 7506535e2c4..aaeefb21768 100755 --- a/rostests/winetests/user32/input.c +++ b/rostests/winetests/user32/input.c @@ -72,12 +72,13 @@ static struct { LONG last_hook_syskey_down; LONG last_hook_syskey_up; BOOL expect_alt; + BOOL sendinput_broken; } key_status; static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t); static int (WINAPI *pGetMouseMovePointsEx) (UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEPOINT, int, DWORD); -#define MAXKEYEVENTS 10 +#define MAXKEYEVENTS 12 #define MAXKEYMESSAGES MAXKEYEVENTS /* assuming a key event generates one and only one message */ @@ -891,6 +892,11 @@ static void test_Input_blackbox(void) HWND window; HHOOK hook; + if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409) + { + skip("Skipping Input_blackbox test on non-US keyboard\n"); + return; + } window = CreateWindow("Static", NULL, WS_POPUP|WS_HSCROLL|WS_VSCROLL |WS_VISIBLE, 0, 0, 200, 60, NULL, NULL, NULL, NULL); @@ -950,6 +956,7 @@ static void reset_key_status(void) key_status.last_hook_syskey_down = -1; key_status.last_hook_syskey_up = -1; key_status.expect_alt = FALSE; + key_status.sendinput_broken = FALSE; } static void test_unicode_keys(HWND hwnd, HHOOK hook) @@ -968,38 +975,42 @@ static void test_unicode_keys(HWND hwnd, HHOOK hook) inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE; reset_key_status(); - SendInput(1, (INPUT*)inputs, sizeof(INPUT)); + pSendInput(1, (INPUT*)inputs, sizeof(INPUT)); while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){ if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){ TranslateMessage(&msg); } DispatchMessageW(&msg); } - ok(key_status.last_key_down == VK_PACKET, - "Last keydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_down); - ok(key_status.last_char == 0x3c0, - "Last char msg wparam should have been 0x3c0 (was: 0x%x)\n", key_status.last_char); - if(hook) - ok(key_status.last_hook_down == 0x3c0, - "Last hookdown msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_down); + if(!key_status.sendinput_broken){ + ok(key_status.last_key_down == VK_PACKET, + "Last keydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_down); + ok(key_status.last_char == 0x3c0, + "Last char msg wparam should have been 0x3c0 (was: 0x%x)\n", key_status.last_char); + if(hook) + ok(key_status.last_hook_down == 0x3c0, + "Last hookdown msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_down); + } inputs[1].u.ki.wVk = 0; inputs[1].u.ki.wScan = 0x3c0; inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; reset_key_status(); - SendInput(1, (INPUT*)(inputs+1), sizeof(INPUT)); + pSendInput(1, (INPUT*)(inputs+1), sizeof(INPUT)); while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){ if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){ TranslateMessage(&msg); } DispatchMessageW(&msg); } - ok(key_status.last_key_up == VK_PACKET, - "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up); - if(hook) - ok(key_status.last_hook_up == 0x3c0, - "Last hookup msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_up); + if(!key_status.sendinput_broken){ + ok(key_status.last_key_up == VK_PACKET, + "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up); + if(hook) + ok(key_status.last_hook_up == 0x3c0, + "Last hookup msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_up); + } /* holding alt, pressing & releasing a unicode character, releasing alt */ inputs[0].u.ki.wVk = VK_LMENU; @@ -1012,20 +1023,22 @@ static void test_unicode_keys(HWND hwnd, HHOOK hook) reset_key_status(); key_status.expect_alt = TRUE; - SendInput(2, (INPUT*)inputs, sizeof(INPUT)); + pSendInput(2, (INPUT*)inputs, sizeof(INPUT)); while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){ if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){ TranslateMessage(&msg); } DispatchMessageW(&msg); } - ok(key_status.last_syskey_down == VK_PACKET, - "Last syskeydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_syskey_down); - ok(key_status.last_syschar == 0x3041, - "Last syschar msg should have been 0x3041 (was: 0x%x)\n", key_status.last_syschar); - if(hook) - ok(key_status.last_hook_syskey_down == 0x3041, - "Last hooksysdown msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_syskey_down); + if(!key_status.sendinput_broken){ + ok(key_status.last_syskey_down == VK_PACKET, + "Last syskeydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_syskey_down); + ok(key_status.last_syschar == 0x3041, + "Last syschar msg should have been 0x3041 (was: 0x%x)\n", key_status.last_syschar); + if(hook) + ok(key_status.last_hook_syskey_down == 0x3041, + "Last hooksysdown msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_syskey_down); + } inputs[1].u.ki.wVk = 0; inputs[1].u.ki.wScan = 0x3041; @@ -1037,18 +1050,20 @@ static void test_unicode_keys(HWND hwnd, HHOOK hook) reset_key_status(); key_status.expect_alt = TRUE; - SendInput(2, (INPUT*)inputs, sizeof(INPUT)); + pSendInput(2, (INPUT*)inputs, sizeof(INPUT)); while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){ if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){ TranslateMessage(&msg); } DispatchMessageW(&msg); } - ok(key_status.last_key_up == VK_PACKET, - "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up); - if(hook) - ok(key_status.last_hook_up == 0x3041, - "Last hook up msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_up); + if(!key_status.sendinput_broken){ + ok(key_status.last_key_up == VK_PACKET, + "Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up); + if(hook) + ok(key_status.last_hook_up == 0x3041, + "Last hook up msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_up); + } } static LRESULT CALLBACK unicode_wnd_proc( HWND hWnd, UINT msg, WPARAM wParam, @@ -1081,8 +1096,16 @@ static LRESULT CALLBACK llkbd_unicode_hook(int nCode, WPARAM wParam, LPARAM lPar { if(nCode == HC_ACTION){ LPKBDLLHOOKSTRUCT info = (LPKBDLLHOOKSTRUCT)lParam; - ok(info->vkCode == VK_PACKET || (key_status.expect_alt && info->vkCode == VK_LMENU), "vkCode should have been VK_PACKET[%04x], was: %04x\n", VK_PACKET, info->vkCode); - key_status.expect_alt = FALSE; + if(!info->vkCode){ + key_status.sendinput_broken = TRUE; + win_skip("SendInput doesn't support unicode on this platform\n"); + }else{ + if(key_status.expect_alt){ + ok(info->vkCode == VK_LMENU, "vkCode should have been VK_LMENU[0x%04x], was: 0x%x\n", VK_LMENU, info->vkCode); + key_status.expect_alt = FALSE; + }else + ok(info->vkCode == VK_PACKET, "vkCode should have been VK_PACKET[0x%04x], was: 0x%x\n", VK_PACKET, info->vkCode); + } switch(wParam){ case WM_KEYDOWN: key_status.last_hook_down = info->scanCode; diff --git a/rostests/winetests/user32/msg.c b/rostests/winetests/user32/msg.c index 30acaa25f09..761f3aa8ddc 100755 --- a/rostests/winetests/user32/msg.c +++ b/rostests/winetests/user32/msg.c @@ -5257,7 +5257,7 @@ static WNDPROC old_button_proc; static LRESULT CALLBACK button_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - static long defwndproc_counter = 0; + static LONG defwndproc_counter = 0; LRESULT ret; struct recvd_message msg; @@ -5458,7 +5458,7 @@ static WNDPROC old_static_proc; static LRESULT CALLBACK static_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - static long defwndproc_counter = 0; + static LONG defwndproc_counter = 0; LRESULT ret; struct recvd_message msg; @@ -5553,7 +5553,7 @@ static WNDPROC old_combobox_proc; static LRESULT CALLBACK combobox_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - static long defwndproc_counter = 0; + static LONG defwndproc_counter = 0; LRESULT ret; struct recvd_message msg; @@ -7813,6 +7813,12 @@ static VOID CALLBACK tfunc(HWND hwnd, UINT uMsg, UINT_PTR id, DWORD dwTime) { } +static VOID CALLBACK tfunc_crash(HWND hwnd, UINT uMsg, UINT_PTR id, DWORD dwTime) +{ + /* Crash on purpose */ + *(volatile int *)0 = 2; +} + #define TIMER_ID 0x19 static DWORD WINAPI timer_thread_proc(LPVOID x) @@ -7834,6 +7840,7 @@ static void test_timers(void) { struct timer_info info; DWORD id; + MSG msg; info.hWnd = CreateWindow ("TestWindowClass", NULL, WS_OVERLAPPEDWINDOW , @@ -7856,6 +7863,26 @@ static void test_timers(void) ok( KillTimer(info.hWnd, TIMER_ID), "KillTimer failed\n"); ok(DestroyWindow(info.hWnd), "failed to destroy window\n"); + + /* Test timer callback with crash */ + SetLastError(0xdeadbeef); + info.hWnd = CreateWindowW(testWindowClassW, NULL, + WS_OVERLAPPEDWINDOW , + CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0, + NULL, NULL, 0); + if ((!info.hWnd && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) || /* Win9x/Me */ + (!pGetMenuInfo)) /* Win95/NT4 */ + { + win_skip("Test would crash on Win9x/WinMe/NT4\n"); + DestroyWindow(info.hWnd); + return; + } + info.id = SetTimer(info.hWnd, TIMER_ID, 0, tfunc_crash); + ok(info.id, "SetTimer failed\n"); + Sleep(150); + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg); + + ok(DestroyWindow(info.hWnd), "failed to destroy window\n"); } static int count = 0; @@ -8984,7 +9011,7 @@ static WNDPROC old_edit_proc; static LRESULT CALLBACK edit_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - static long defwndproc_counter = 0; + static LONG defwndproc_counter = 0; LRESULT ret; struct recvd_message msg; @@ -11724,6 +11751,171 @@ static void test_defwinproc(void) DestroyWindow( hwnd); } +#define clear_clipboard(hwnd) clear_clipboard_(__LINE__, (hwnd)) +static void clear_clipboard_(int line, HWND hWnd) +{ + BOOL succ; + succ = OpenClipboard(hWnd); + ok_(__FILE__, line)(succ, "OpenClipboard failed, err=%u\n", GetLastError()); + succ = EmptyClipboard(); + ok_(__FILE__, line)(succ, "EmptyClipboard failed, err=%u\n", GetLastError()); + succ = CloseClipboard(); + ok_(__FILE__, line)(succ, "CloseClipboard failed, err=%u\n", GetLastError()); +} + +#define expect_HWND(expected, got) expect_HWND_(__LINE__, (expected), (got)) +static void expect_HWND_(int line, HWND expected, HWND got) +{ + ok_(__FILE__, line)(got==expected, "Expected %p, got %p\n", expected, got); +} + +static WNDPROC pOldViewerProc; + +static LRESULT CALLBACK recursive_viewer_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static BOOL recursion_guard; + + if (message == WM_DRAWCLIPBOARD && !recursion_guard) + { + recursion_guard = TRUE; + clear_clipboard(hWnd); + recursion_guard = FALSE; + } + return CallWindowProcA(pOldViewerProc, hWnd, message, wParam, lParam); +} + +static void test_clipboard_viewers(void) +{ + static struct message wm_change_cb_chain[] = + { + { WM_CHANGECBCHAIN, sent|wparam|lparam, 0, 0 }, + { 0 } + }; + static const struct message wm_clipboard_destroyed[] = + { + { WM_DESTROYCLIPBOARD, sent|wparam|lparam, 0, 0 }, + { 0 } + }; + static struct message wm_clipboard_changed[] = + { + { WM_DRAWCLIPBOARD, sent|wparam|lparam, 0, 0 }, + { 0 } + }; + static struct message wm_clipboard_changed_and_owned[] = + { + { WM_DESTROYCLIPBOARD, sent|wparam|lparam, 0, 0 }, + { WM_DRAWCLIPBOARD, sent|wparam|lparam, 0, 0 }, + { 0 } + }; + + HINSTANCE hInst = GetModuleHandleA(NULL); + HWND hWnd1, hWnd2, hWnd3; + HWND hOrigViewer; + HWND hRet; + + hWnd1 = CreateWindowExA(0, "TestWindowClass", "Clipboard viewer test wnd 1", + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + GetDesktopWindow(), NULL, hInst, NULL); + hWnd2 = CreateWindowExA(0, "SimpleWindowClass", "Clipboard viewer test wnd 2", + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + GetDesktopWindow(), NULL, hInst, NULL); + hWnd3 = CreateWindowExA(0, "SimpleWindowClass", "Clipboard viewer test wnd 3", + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + GetDesktopWindow(), NULL, hInst, NULL); + trace("clipbd viewers: hWnd1=%p, hWnd2=%p, hWnd3=%p\n", hWnd1, hWnd2, hWnd3); + assert(hWnd1 && hWnd2 && hWnd3); + + flush_sequence(); + + /* Test getting the clipboard viewer and setting the viewer to NULL. */ + hOrigViewer = GetClipboardViewer(); + hRet = SetClipboardViewer(NULL); + ok_sequence(WmEmptySeq, "set viewer to NULL", FALSE); + expect_HWND(hOrigViewer, hRet); + expect_HWND(NULL, GetClipboardViewer()); + + /* Test registering hWnd1 as a viewer. */ + hRet = SetClipboardViewer(hWnd1); + wm_clipboard_changed[0].wParam = (WPARAM) GetClipboardOwner(); + ok_sequence(wm_clipboard_changed, "set viewer NULL->1", FALSE); + expect_HWND(NULL, hRet); + expect_HWND(hWnd1, GetClipboardViewer()); + + /* Test that changing the clipboard actually refreshes the registered viewer. */ + clear_clipboard(hWnd1); + wm_clipboard_changed[0].wParam = (WPARAM) GetClipboardOwner(); + ok_sequence(wm_clipboard_changed, "clear clipbd (viewer=owner=1)", FALSE); + + /* Again, but with different owner. */ + clear_clipboard(hWnd2); + wm_clipboard_changed_and_owned[1].wParam = (WPARAM) GetClipboardOwner(); + ok_sequence(wm_clipboard_changed_and_owned, "clear clipbd (viewer=1, owner=2)", FALSE); + + /* Test re-registering same window. */ + hRet = SetClipboardViewer(hWnd1); + wm_clipboard_changed[0].wParam = (WPARAM) GetClipboardOwner(); + ok_sequence(wm_clipboard_changed, "set viewer 1->1", FALSE); + expect_HWND(hWnd1, hRet); + expect_HWND(hWnd1, GetClipboardViewer()); + + /* Test ChangeClipboardChain. */ + ChangeClipboardChain(hWnd2, hWnd3); + wm_change_cb_chain[0].wParam = (WPARAM) hWnd2; + wm_change_cb_chain[0].lParam = (LPARAM) hWnd3; + ok_sequence(wm_change_cb_chain, "change chain (viewer=1, remove=2, next=3)", FALSE); + expect_HWND(hWnd1, GetClipboardViewer()); + + ChangeClipboardChain(hWnd2, NULL); + wm_change_cb_chain[0].wParam = (WPARAM) hWnd2; + wm_change_cb_chain[0].lParam = 0; + ok_sequence(wm_change_cb_chain, "change chain (viewer=1, remove=2, next=NULL)", FALSE); + expect_HWND(hWnd1, GetClipboardViewer()); + + ChangeClipboardChain(NULL, hWnd2); + ok_sequence(WmEmptySeq, "change chain (viewer=1, remove=NULL, next=2)", TRUE); + expect_HWND(hWnd1, GetClipboardViewer()); + + /* Actually change clipboard viewer with ChangeClipboardChain. */ + ChangeClipboardChain(hWnd1, hWnd2); + ok_sequence(WmEmptySeq, "change chain (viewer=remove=1, next=2)", FALSE); + expect_HWND(hWnd2, GetClipboardViewer()); + + /* Test that no refresh messages are sent when viewer has unregistered. */ + clear_clipboard(hWnd2); + ok_sequence(WmEmptySeq, "clear clipd (viewer=2, owner=1)", FALSE); + + /* Register hWnd1 again. */ + ChangeClipboardChain(hWnd2, hWnd1); + ok_sequence(WmEmptySeq, "change chain (viewer=remove=2, next=1)", FALSE); + expect_HWND(hWnd1, GetClipboardViewer()); + + /* Subclass hWnd1 so that when it receives a WM_DRAWCLIPBOARD message, it + * changes the clipboard. When this happens, the system shouldn't send + * another WM_DRAWCLIPBOARD (as this could cause an infinite loop). + */ + pOldViewerProc = (WNDPROC) SetWindowLongPtrA(hWnd1, GWLP_WNDPROC, (LONG_PTR) recursive_viewer_proc); + clear_clipboard(hWnd2); + /* The clipboard owner is changed in recursive_viewer_proc: */ + wm_clipboard_changed[0].wParam = (WPARAM) hWnd2; + ok_sequence(wm_clipboard_changed, "recursive clear clipbd (viewer=1, owner=2)", TRUE); + + /* Test unregistering. */ + ChangeClipboardChain(hWnd1, NULL); + ok_sequence(WmEmptySeq, "change chain (viewer=remove=1, next=NULL)", FALSE); + expect_HWND(NULL, GetClipboardViewer()); + + clear_clipboard(hWnd1); + ok_sequence(wm_clipboard_destroyed, "clear clipbd (no viewer, owner=1)", FALSE); + + DestroyWindow(hWnd1); + DestroyWindow(hWnd2); + DestroyWindow(hWnd3); + SetClipboardViewer(hOrigViewer); +} + static void test_PostMessage(void) { static const struct @@ -11787,7 +11979,7 @@ static void test_PostMessage(void) START_TEST(msg) { BOOL ret; - FARPROC pIsWinEventHookInstalled = 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/ + BOOL (WINAPI *pIsWinEventHookInstalled)(DWORD)= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/ init_procs(); @@ -11867,6 +12059,7 @@ START_TEST(msg) test_menu_messages(); test_paintingloop(); test_defwinproc(); + test_clipboard_viewers(); /* keep it the last test, under Windows it tends to break the tests * which rely on active/foreground windows being correct. */ diff --git a/rostests/winetests/user32/resource.rc b/rostests/winetests/user32/resource.rc index 79c036cbdb0..1869475f4a6 100755 --- a/rostests/winetests/user32/resource.rc +++ b/rostests/winetests/user32/resource.rc @@ -98,6 +98,13 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 END +TEST_EMPTY_DIALOG DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN +END + MULTI_EDIT_DIALOG DIALOG DISCARDABLE 0, 0, 160, 75 STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_CENTER CAPTION "Multiple Edit Test" diff --git a/rostests/winetests/user32/sysparams.c b/rostests/winetests/user32/sysparams.c index 7b2edafedba..dd1e708a947 100755 --- a/rostests/winetests/user32/sysparams.c +++ b/rostests/winetests/user32/sysparams.c @@ -942,7 +942,8 @@ static void test_SPI_SETSCREENSAVEACTIVE( void ) /* 17 */ rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &v, 0 ); ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError()); - eq( v, vals[i], "SPI_{GET,SET}SCREENSAVEACTIVE", "%d" ); + ok(v == vals[i] || broken(! v) /* Win 7 */, + "SPI_{GET,SET}SCREENSAVEACTIVE: got %d instead of %d\n", v, vals[i]); } rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, old_b, 0, SPIF_UPDATEINIFILE ); diff --git a/rostests/winetests/user32/text.c b/rostests/winetests/user32/text.c index 080e5dd59f5..88ea6b566c0 100755 --- a/rostests/winetests/user32/text.c +++ b/rostests/winetests/user32/text.c @@ -80,7 +80,7 @@ static void test_DrawTextCalcRect(void) ok( textheight, "DrawTextA error %u\n", GetLastError()); trace("MM_HIENGLISH rect.bottom %d\n", rect.bottom); - todo_wine ok(rect.bottom < 0, "In MM_HIENGLISH, DrawText with " + ok(rect.bottom < 0, "In MM_HIENGLISH, DrawText with " "DT_CALCRECT should return a negative rectangle bottom. " "(bot=%d)\n", rect.bottom); diff --git a/rostests/winetests/user32/win.c b/rostests/winetests/user32/win.c index cf1de2562df..63f25bcc99e 100644 --- a/rostests/winetests/user32/win.c +++ b/rostests/winetests/user32/win.c @@ -3218,6 +3218,59 @@ static void test_window_styles(void) check_window_style(0, WS_EX_APPWINDOW, WS_CLIPSIBLINGS|WS_CAPTION, WS_EX_APPWINDOW|WS_EX_WINDOWEDGE); } +static void test_scrollwindow( HWND hwnd) +{ + HDC hdc; + RECT rc, rc2, rc3; + COLORREF colr; + + ShowWindow( hwnd, SW_SHOW); + UpdateWindow( hwnd); + flush_events( TRUE ); + GetClientRect( hwnd, &rc); + hdc = GetDC( hwnd); + /* test ScrollWindow(Ex) with no clip rectangle */ + /* paint the lower half of the window black */ + rc2 = rc; + rc2.top = ( rc2.top + rc2.bottom) / 2; + FillRect( hdc, &rc2, GetStockObject(BLACK_BRUSH)); + /* paint the upper half of the window white */ + rc2.bottom = rc2.top; + rc2.top =0; + FillRect( hdc, &rc2, GetStockObject(WHITE_BRUSH)); + /* scroll lower half up */ + rc2 = rc; + rc2.top = ( rc2.top + rc2.bottom) / 2; + ScrollWindowEx( hwnd, 0, - rc2.top, &rc2, NULL, NULL, NULL, SW_ERASE); + flush_events(FALSE); + /* expected: black should have scrolled to the upper half */ + colr = GetPixel( hdc, (rc2.left+rc2.right)/ 2, rc2.bottom / 4 ); + ok ( colr == 0, "pixel should be black, color is %08x\n", colr); + /* Repeat that test of ScrollWindow(Ex) now with clip rectangle */ + /* paint the lower half of the window black */ + rc2 = rc; + rc2.top = ( rc2.top + rc2.bottom) / 2; + FillRect( hdc, &rc2, GetStockObject(BLACK_BRUSH)); + /* paint the upper half of the window white */ + rc2.bottom = rc2.top; + rc2.top =0; + FillRect( hdc, &rc2, GetStockObject(WHITE_BRUSH)); + /* scroll lower half up */ + rc2 = rc; + rc2.top = ( rc2.top + rc2.bottom) / 2; + rc3 = rc; + rc3.left = rc3.right / 4; + rc3.right -= rc3.right / 4; + ScrollWindowEx( hwnd, 0, - rc2.top, &rc2, &rc3, NULL, NULL, SW_ERASE); + flush_events(FALSE); + /* expected: black should have scrolled to the upper half */ + colr = GetPixel( hdc, (rc2.left+rc2.right)/ 2, rc2.bottom / 4 ); + ok ( colr == 0, "pixel should be black, color is %08x\n", colr); + + /* clean up */ + ReleaseDC( hwnd, hdc); +} + static void test_scrollvalidate( HWND parent) { HDC hdc; @@ -5724,6 +5777,7 @@ START_TEST(win) test_mouse_input(hwndMain); test_validatergn(hwndMain); test_nccalcscroll( hwndMain); + test_scrollwindow( hwndMain); test_scrollvalidate( hwndMain); test_scrolldc( hwndMain); test_scroll(); -- 2.17.1