Author: cwittich Date: Mon Aug 24 14:42:47 2009 New Revision: 42911
URL: http://svn.reactos.org/svn/reactos?rev=42911&view=rev Log: sync user32 winetest with wine 1.1.28
Modified: trunk/rostests/winetests/user32/combo.c trunk/rostests/winetests/user32/cursoricon.c trunk/rostests/winetests/user32/dialog.c trunk/rostests/winetests/user32/input.c trunk/rostests/winetests/user32/menu.c trunk/rostests/winetests/user32/msg.c trunk/rostests/winetests/user32/win.c
Modified: trunk/rostests/winetests/user32/combo.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/combo.c?r... ============================================================================== --- trunk/rostests/winetests/user32/combo.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/combo.c [iso-8859-1] Mon Aug 24 14:42:47 2009 @@ -94,27 +94,28 @@
static void test_setfont(DWORD style) { - HWND hCombo = build_combo(style); - HFONT hFont1 = CreateFont(10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett"); - HFONT hFont2 = CreateFont(8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett"); + HWND hCombo; + HFONT hFont1, hFont2; RECT r; int i;
+ if (!is_font_installed("Marlett")) + { + skip("Marlett font not available\n"); + return; + } + trace("Style %x\n", style); + + hCombo = build_combo(style); + hFont1 = CreateFont(10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett"); + hFont2 = CreateFont(8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett"); + GetClientRect(hCombo, &r); expect_rect(r, 0, 0, 100, 24); SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r); MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); todo_wine expect_rect(r, 5, 5, 105, 105); - - if (!is_font_installed("Marlett")) - { - skip("Marlett font not available\n"); - DestroyWindow(hCombo); - DeleteObject(hFont1); - DeleteObject(hFont2); - return; - }
if (font_height(hFont1) == 10 && font_height(hFont2) == 8) { @@ -140,11 +141,14 @@ todo_wine expect_rect(r, 5, 5, 105, 99); } else - skip("Invalid Marlett font heights\n"); + { + ok(0, "Expected Marlett font heights 10/8, got %d/%d\n", + font_height(hFont1), font_height(hFont2)); + }
for (i = 1; i < 30; i++) { - HFONT hFont = CreateFont(i, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett"); + HFONT hFont = CreateFont(i, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett"); int height = font_height(hFont);
SendMessage(hCombo, WM_SETFONT, (WPARAM)hFont, FALSE);
Modified: trunk/rostests/winetests/user32/cursoricon.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/cursorico... ============================================================================== --- trunk/rostests/winetests/user32/cursoricon.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/cursoricon.c [iso-8859-1] Mon Aug 24 14:42:47 2009 @@ -956,6 +956,262 @@ HeapFree(GetProcessHeap(), 0, hotspot); }
+static HICON create_test_icon(HDC hdc, int width, int height, int bpp, + BOOL maskvalue, UINT32 *color, int colorSize) +{ + ICONINFO iconInfo; + BITMAPINFO bitmapInfo; + UINT32 *buffer = NULL; + UINT32 mask = maskvalue ? 0xFFFFFFFF : 0x00000000; + + memset(&bitmapInfo, 0, sizeof(bitmapInfo)); + bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmapInfo.bmiHeader.biWidth = width; + bitmapInfo.bmiHeader.biHeight = height; + bitmapInfo.bmiHeader.biPlanes = 1; + bitmapInfo.bmiHeader.biBitCount = bpp; + bitmapInfo.bmiHeader.biCompression = BI_RGB; + bitmapInfo.bmiHeader.biSizeImage = colorSize; + + iconInfo.fIcon = TRUE; + iconInfo.xHotspot = 0; + iconInfo.yHotspot = 0; + + iconInfo.hbmMask = CreateBitmap( width, height, 1, 1, &mask ); + if(!iconInfo.hbmMask) return NULL; + + iconInfo.hbmColor = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0); + if(!iconInfo.hbmColor || !buffer) + { + DeleteObject(iconInfo.hbmMask); + return NULL; + } + + memcpy(buffer, color, colorSize); + + return CreateIconIndirect(&iconInfo); +} + +static BOOL color_match(COLORREF a, COLORREF b) +{ + /* 5-bit accuracy is a sufficient test. This will match, so long as + * colors are never truncated to less that 3x5-bit accuracy i.e. + * paletized. */ + return (a & 0x00F8F8F8) == (b & 0x00F8F8F8); +} + +static void check_alpha_draw(HDC hdc, BOOL drawiconex, BOOL alpha, int bpp, int line) +{ + HICON hicon; + UINT32 mask; + UINT32 color[2]; + COLORREF modern_expected, legacy_expected, result; + + mask = 0x00000000; + color[0] = 0x00A0B0C0; + color[1] = alpha ? 0xFF000000 : 0x00000000; + modern_expected = alpha ? 0x00FFFFFF : 0x00C0B0A0; + legacy_expected = 0x00C0B0A0; + + hicon = create_test_icon(hdc, 2, 1, bpp, 0, color, sizeof(color)); + if (!hicon) return; + + SetPixelV(hdc, 0, 0, 0x00FFFFFF); + + if(drawiconex) + DrawIconEx(hdc, 0, 0, hicon, 2, 1, 0, NULL, DI_NORMAL); + else + DrawIcon(hdc, 0, 0, hicon); + + result = GetPixel(hdc, 0, 0); + ok (color_match(result, modern_expected) || /* Windows 2000 and up */ + broken(color_match(result, legacy_expected)), /* Windows NT 4.0, 9X and below */ + "%s. Expected a close match to %06X (modern) or %06X (legacy) with %s. " + "Got %06X from line %d\n", + alpha ? "Alpha blending" : "Not alpha blending", modern_expected, legacy_expected, + drawiconex ? "DrawIconEx" : "DrawIcon", result, line); +} + +static void check_DrawIcon(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, 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; + SetPixelV(hdc, 0, 0, background); + DrawIcon(hdc, 0, 0, hicon); + result = GetPixel(hdc, 0, 0); + + 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); +} + +static void test_DrawIcon(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 DrawIcon 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 = 1; + bitmapInfo.bmiHeader.biHeight = 1; + 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); + + /* Mask is only heeded if alpha channel is always zero */ + check_DrawIcon(hdcDst, FALSE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__); + check_DrawIcon(hdcDst, TRUE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x003F4F5F, 0x003F4F5F, __LINE__); + + /* Test alpha blending */ + /* Windows 2000 and up will alpha blend, earlier Windows versions will not */ + check_DrawIcon(hdcDst, FALSE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__); + check_DrawIcon(hdcDst, TRUE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x003F4F5F, __LINE__); + + check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 32, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__); + check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 32, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__); + check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF, 0x00C0B0A0, __LINE__); + check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF, 0x003F4F5F, __LINE__); + + check_DrawIcon(hdcDst, FALSE, 0x01FFFFFF, 32, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__); + check_DrawIcon(hdcDst, TRUE, 0x01FFFFFF, 32, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__); + + /* Test detecting of alpha channel */ + /* If a single pixel's alpha channel is non-zero, the icon + will be alpha blended, otherwise it will be draw with + and + xor blts. */ + check_alpha_draw(hdcDst, FALSE, FALSE, 32, __LINE__); + check_alpha_draw(hdcDst, FALSE, TRUE, 32, __LINE__); + +cleanup: + if(bmpOld) + SelectObject(hdcDst, bmpOld); + if(bmpDst) + DeleteObject(bmpDst); + if(hdcDst) + DeleteDC(hdcDst); +} + +static void check_DrawIconEx(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, 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; + SetPixelV(hdc, 0, 0, background); + DrawIconEx(hdc, 0, 0, hicon, 1, 1, 0, NULL, flags); + result = GetPixel(hdc, 0, 0); + + 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 DrawIconEx flags %08X. " + "Expected a close match to %06X (modern) or %06X (legacy). Got %06X from line %d\n", + maskvalue, color, flags, modern_expected, legacy_expected, result, line); +} + +static void test_DrawIconEx(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 = 1; + bitmapInfo.bmiHeader.biHeight = 1; + 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); + + /* Test null, image only, and mask only drawing */ + check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, 0, 0x00102030, 0x00102030, 0x00102030, __LINE__); + check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, 0, 0x00102030, 0x00102030, 0x00102030, __LINE__); + + check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_MASK, 0x00FFFFFF, 0x00000000, 0x00000000, __LINE__); + check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_MASK, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, __LINE__); + + todo_wine + { + check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, DI_IMAGE, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__); + check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, DI_IMAGE, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__); + } + + /* Test normal drawing */ + check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__); + todo_wine check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x003F4F5F, 0x003F4F5F, __LINE__); + check_DrawIconEx(hdcDst, FALSE, 0xFFA0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__); + + /* Test alpha blending */ + /* Windows 2000 and up will alpha blend, earlier Windows versions will not */ + check_DrawIconEx(hdcDst, TRUE, 0xFFA0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x003F4F5F, __LINE__); + + check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_NORMAL, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__); + check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_NORMAL, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__); + check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00DFD7CF, 0x00C0B0A0, __LINE__); + check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00DFD7CF, 0x003F4F5F, __LINE__); + + check_DrawIconEx(hdcDst, FALSE, 0x01FFFFFF, 32, DI_NORMAL, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__); + check_DrawIconEx(hdcDst, TRUE, 0x01FFFFFF, 32, DI_NORMAL, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__); + + /* Test detecting of alpha channel */ + /* If a single pixel's alpha channel is non-zero, the icon + will be alpha blended, otherwise it will be draw with + and + xor blts. */ + check_alpha_draw(hdcDst, TRUE, FALSE, 32, __LINE__); + check_alpha_draw(hdcDst, TRUE, TRUE, 32, __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]; @@ -1063,6 +1319,8 @@ test_CreateIcon(); test_LoadImage(); test_CreateIconFromResource(); + test_DrawIcon(); + test_DrawIconEx(); test_DestroyCursor(); do_parent(); test_child_process();
Modified: trunk/rostests/winetests/user32/dialog.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/dialog.c?... ============================================================================== --- trunk/rostests/winetests/user32/dialog.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/dialog.c [iso-8859-1] Mon Aug 24 14:42:47 2009 @@ -901,23 +901,72 @@ "string retrieved using GetDlgItemText should have been NULL terminated\n"); }
+static INT_PTR CALLBACK DestroyDlgWinProc (HWND hDlg, UINT uiMsg, + WPARAM wParam, LPARAM lParam) +{ + if (uiMsg == WM_INITDIALOG) + { + DestroyWindow(hDlg); + return TRUE; + } + return FALSE; +} + +static INT_PTR CALLBACK DestroyOnCloseDlgWinProc (HWND hDlg, UINT uiMsg, + WPARAM wParam, LPARAM lParam) +{ + switch (uiMsg) + { + case WM_INITDIALOG: + PostMessage(hDlg, WM_CLOSE, 0, 0); + return TRUE; + case WM_CLOSE: + DestroyWindow(hDlg); + return TRUE; + case WM_DESTROY: + PostQuitMessage(0); + return TRUE; + } + return FALSE; +} + static void test_DialogBoxParamA(void) { - int ret; + INT_PTR ret; HWND hwnd_invalid = (HWND)0x4444;
SetLastError(0xdeadbeef); ret = DialogBoxParamA(GetModuleHandle(NULL), "IDD_DIALOG" , hwnd_invalid, 0 , 0); - ok(0 == ret || broken(ret == -1), "DialogBoxParamA returned %d, expected 0\n", ret); + ok(0 == ret || broken(ret == -1), "DialogBoxParamA returned %ld, expected 0\n", ret); ok(ERROR_INVALID_WINDOW_HANDLE == GetLastError() || broken(GetLastError() == 0xdeadbeef), "got %d, expected ERROR_INVALID_WINDOW_HANDLE\n",GetLastError()); + + /* Test a dialog which destroys itself on WM_INITDIALOG. */ + SetLastError(0xdeadbeef); + ret = DialogBoxParamA(GetModuleHandle(NULL), "IDD_DIALOG", 0, DestroyDlgWinProc, 0); + ok(-1 == ret, "DialogBoxParamA returned %ld, expected -1\n", ret); + ok(ERROR_INVALID_WINDOW_HANDLE == GetLastError() || + GetLastError() == ERROR_SUCCESS || + broken(GetLastError() == 0xdeadbeef), + "got %d, expected ERROR_INVALID_WINDOW_HANDLE\n",GetLastError()); + + /* Test a dialog which destroys itself on WM_CLOSE. */ + ret = DialogBoxParamA(GetModuleHandle(NULL), "IDD_DIALOG", 0, DestroyOnCloseDlgWinProc, 0); + ok(0 == ret, "DialogBoxParamA returned %ld, expected 0\n", ret); + SetLastError(0xdeadbeef); ret = DialogBoxParamA(GetModuleHandle(NULL), "RESOURCE_INVALID" , 0, 0, 0); - ok(-1 == ret, "DialogBoxParamA returned %d, expected -1\n", ret); + ok(-1 == ret, "DialogBoxParamA returned %ld, expected -1\n", ret); ok(ERROR_RESOURCE_NAME_NOT_FOUND == GetLastError() || broken(GetLastError() == 0xdeadbeef), "got %d, expected ERROR_RESOURCE_NAME_NOT_FOUND\n",GetLastError()); + + 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, + "got %d, expected ERROR_INVALID_WINDOW_HANDLE\n", GetLastError()); }
static void test_DisabledDialogTest(void) @@ -1020,6 +1069,63 @@ DestroyWindow(hDlg); }
+static void test_SaveRestoreFocus(void) +{ + HWND hDlg; + HRSRC hResource; + HANDLE hTemplate; + DLGTEMPLATE* pTemplate; + LONG_PTR foundId; + HWND foundHwnd; + + /* create the dialog */ + hResource = FindResourceA(g_hinst, "MULTI_EDIT_DIALOG", RT_DIALOG); + hTemplate = LoadResource(g_hinst, hResource); + pTemplate = LockResource(hTemplate); + + hDlg = CreateDialogIndirectParamA(g_hinst, pTemplate, NULL, messageBoxFontDlgWinProc, 0); + ok (hDlg != 0, "Failed to create test dialog.\n"); + + foundId = GetWindowLongPtr(GetFocus(), GWLP_ID); + ok (foundId == 1000, "First edit box should have gained focus on dialog creation. Expected: %d, Found: %ld\n", 1000, foundId); + + /* de- then reactivate the dialog */ + SendMessage(hDlg, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), 0); + SendMessage(hDlg, WM_ACTIVATE, MAKEWPARAM(WA_ACTIVE, 0), 0); + + foundId = GetWindowLongPtr(GetFocus(), GWLP_ID); + ok (foundId == 1000, "First edit box should have regained focus after dialog reactivation. Expected: %d, Found: %ld\n", 1000, foundId); + + /* select the next tabbable item */ + SetFocus(GetNextDlgTabItem(hDlg, GetFocus(), FALSE)); + + foundId = GetWindowLongPtr(GetFocus(), GWLP_ID); + ok (foundId == 1001, "Second edit box should have gained focus. Expected: %d, Found: %ld\n", 1001, foundId); + + /* de- then reactivate the dialog */ + SendMessage(hDlg, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), 0); + SendMessage(hDlg, WM_ACTIVATE, MAKEWPARAM(WA_ACTIVE, 0), 0); + + foundId = GetWindowLongPtr(GetFocus(), GWLP_ID); + ok (foundId == 1001, "Second edit box should have gained focus after dialog reactivation. Expected: %d, Found: %ld\n", 1001, foundId); + + /* disable the 2nd box */ + EnableWindow(GetFocus(), FALSE); + + foundHwnd = GetFocus(); + ok (foundHwnd == NULL, "Second edit box should have lost focus after being disabled. Expected: %p, Found: %p\n", NULL, foundHwnd); + + /* de- then reactivate the dialog */ + SendMessage(hDlg, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), 0); + SendMessage(hDlg, WM_ACTIVATE, MAKEWPARAM(WA_ACTIVE, 0), 0); + + foundHwnd = GetFocus(); + ok (foundHwnd == NULL, "No controls should have gained focus after dialog reactivation. Expected: %p, Found: %p\n", NULL, foundHwnd); + + /* clean up */ + DestroyWindow(hDlg); +} + START_TEST(dialog) { g_hinst = GetModuleHandleA (0); @@ -1034,4 +1140,5 @@ test_DialogBoxParamA(); test_DisabledDialogTest(); test_MessageBoxFontTest(); -} + test_SaveRestoreFocus(); +}
Modified: trunk/rostests/winetests/user32/input.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/input.c?r... ============================================================================== --- trunk/rostests/winetests/user32/input.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/input.c [iso-8859-1] Mon Aug 24 14:42:47 2009 @@ -44,7 +44,7 @@ * */
-#define _WIN32_WINNT 0x401 +#define _WIN32_WINNT 0x500 #define _WIN32_IE 0x0500
#include <stdarg.h> @@ -59,6 +59,20 @@ /* globals */ static HWND hWndTest; static LONG timetag = 0x10000000; + +static struct { + LONG last_key_down; + LONG last_key_up; + LONG last_syskey_down; + LONG last_syskey_up; + LONG last_char; + LONG last_syschar; + LONG last_hook_down; + LONG last_hook_up; + LONG last_hook_syskey_down; + LONG last_hook_syskey_up; + BOOL expect_alt; +} key_status;
static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t); static int (WINAPI *pGetMouseMovePointsEx) (UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEPOINT, int, DWORD); @@ -824,7 +838,8 @@ Msg != WM_GETTEXT && Msg != WM_GETICON && Msg != WM_IME_SELECT && - Msg != WM_DEVICECHANGE) + Msg != WM_DEVICECHANGE && + Msg != WM_TIMECHANGE) { ok(sent_messages_cnt < MAXKEYMESSAGES, "Too many messages\n"); if (sent_messages_cnt < MAXKEYMESSAGES) @@ -922,6 +937,224 @@ UnhookWindowsHookEx(hook); }
+static void reset_key_status(void) +{ + key_status.last_key_down = -1; + key_status.last_key_up = -1; + key_status.last_syskey_down = -1; + key_status.last_syskey_up = -1; + key_status.last_char = -1; + key_status.last_syschar = -1; + key_status.last_hook_down = -1; + key_status.last_hook_up = -1; + key_status.last_hook_syskey_down = -1; + key_status.last_hook_syskey_up = -1; + key_status.expect_alt = FALSE; +} + +static void test_unicode_keys(HWND hwnd, HHOOK hook) +{ + TEST_INPUT inputs[2]; + MSG msg; + + /* init input data that never changes */ + inputs[1].type = inputs[0].type = INPUT_KEYBOARD; + inputs[1].u.ki.dwExtraInfo = inputs[0].u.ki.dwExtraInfo = 0; + inputs[1].u.ki.time = inputs[0].u.ki.time = 0; + + /* pressing & releasing a single unicode character */ + inputs[0].u.ki.wVk = 0; + inputs[0].u.ki.wScan = 0x3c0; + inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE; + + reset_key_status(); + SendInput(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); + + 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)); + 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); + + /* holding alt, pressing & releasing a unicode character, releasing alt */ + inputs[0].u.ki.wVk = VK_LMENU; + inputs[0].u.ki.wScan = 0; + inputs[0].u.ki.dwFlags = 0; + + inputs[1].u.ki.wVk = 0; + inputs[1].u.ki.wScan = 0x3041; + inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE; + + reset_key_status(); + key_status.expect_alt = TRUE; + SendInput(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); + + inputs[1].u.ki.wVk = 0; + inputs[1].u.ki.wScan = 0x3041; + inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; + + inputs[0].u.ki.wVk = VK_LMENU; + inputs[0].u.ki.wScan = 0; + inputs[0].u.ki.dwFlags = KEYEVENTF_KEYUP; + + reset_key_status(); + key_status.expect_alt = TRUE; + SendInput(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); +} + +static LRESULT CALLBACK unicode_wnd_proc( HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam ) +{ + switch(msg){ + case WM_KEYDOWN: + key_status.last_key_down = wParam; + break; + case WM_SYSKEYDOWN: + key_status.last_syskey_down = wParam; + break; + case WM_KEYUP: + key_status.last_key_up = wParam; + break; + case WM_SYSKEYUP: + key_status.last_syskey_up = wParam; + break; + case WM_CHAR: + key_status.last_char = wParam; + break; + case WM_SYSCHAR: + key_status.last_syschar = wParam; + break; + } + return DefWindowProcW(hWnd, msg, wParam, lParam); +} + +static LRESULT CALLBACK llkbd_unicode_hook(int nCode, WPARAM wParam, LPARAM lParam) +{ + 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; + switch(wParam){ + case WM_KEYDOWN: + key_status.last_hook_down = info->scanCode; + break; + case WM_KEYUP: + key_status.last_hook_up = info->scanCode; + break; + case WM_SYSKEYDOWN: + key_status.last_hook_syskey_down = info->scanCode; + break; + case WM_SYSKEYUP: + key_status.last_hook_syskey_up = info->scanCode; + break; + } + } + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +static void test_Input_unicode(void) +{ + WCHAR classNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e', + 'K','e','y','T','e','s','t','C','l','a','s','s',0}; + WCHAR windowNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e', + 'K','e','y','T','e','s','t',0}; + MSG msg; + WNDCLASSW wclass; + HANDLE hInstance = GetModuleHandleW(NULL); + HHOOK hook; + + wclass.lpszClassName = classNameW; + wclass.style = CS_HREDRAW | CS_VREDRAW; + wclass.lpfnWndProc = unicode_wnd_proc; + wclass.hInstance = hInstance; + wclass.hIcon = LoadIcon(0, IDI_APPLICATION); + wclass.hCursor = LoadCursor( NULL, IDC_ARROW); + wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wclass.lpszMenuName = 0; + wclass.cbClsExtra = 0; + wclass.cbWndExtra = 0; + if(!RegisterClassW(&wclass)){ + win_skip("Unicode functions not supported\n"); + return; + } + /* create the test window that will receive the keystrokes */ + hWndTest = CreateWindowW(wclass.lpszClassName, windowNameW, + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100, + NULL, NULL, hInstance, NULL); + + assert(hWndTest); + assert(IsWindowUnicode(hWndTest)); + + hook = SetWindowsHookExW(WH_KEYBOARD_LL, llkbd_unicode_hook, GetModuleHandleW(NULL), 0); + if(!hook) + win_skip("unable to set WH_KEYBOARD_LL hook\n"); + + ShowWindow(hWndTest, SW_SHOW); + SetWindowPos(hWndTest, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); + SetForegroundWindow(hWndTest); + UpdateWindow(hWndTest); + + /* flush pending messages */ + while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageW(&msg); + + SetFocus(hWndTest); + + test_unicode_keys(hWndTest, hook); + + if(hook) + UnhookWindowsHookEx(hook); + DestroyWindow(hWndTest); +} + static void test_keynames(void) { int i, len; @@ -1319,6 +1552,7 @@ { test_Input_blackbox(); test_Input_whitebox(); + test_Input_unicode(); } else win_skip("SendInput is not available\n");
Modified: trunk/rostests/winetests/user32/menu.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/menu.c?re... ============================================================================== --- trunk/rostests/winetests/user32/menu.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/menu.c [iso-8859-1] Mon Aug 24 14:42:47 2009 @@ -536,7 +536,7 @@ mi.cbSize = sizeof(mi); mi.fMask = MIM_STYLE; pGetMenuInfo( hmenu, &mi); - mi.dwStyle |= mnuopt == 1 ? MNS_NOCHECK : MNS_CHECKORBMP; + if( mnuopt) mi.dwStyle |= mnuopt == 1 ? MNS_NOCHECK : MNS_CHECKORBMP; ret = pSetMenuInfo( hmenu, &mi); ok( ret, "SetMenuInfo failed with error %d\n", GetLastError()); } @@ -2451,6 +2451,48 @@ return hmenu; }
+/* use InsertMenuItem: does not set the MFT_BITMAP flag, + * and does not accept non-magic bitmaps with invalid + * bitmap handles */ +static HMENU create_menuitem_from_data(const struct menu_data *item, INT item_count) +{ + HMENU hmenu; + INT i; + BOOL ret; + MENUITEMINFO mii = { sizeof( MENUITEMINFO)}; + + hmenu = CreateMenu(); + assert(hmenu != 0); + + for (i = 0; i < item_count; i++) + { + SetLastError(0xdeadbeef); + + mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STATE; + mii.fType = 0; + if( item[i].type & MFT_BITMAP) + { + mii.fMask |= MIIM_BITMAP; + mii.hbmpItem = (HBITMAP)item[i].str; + } + else if( item[i].type & MFT_SEPARATOR) + mii.fType = MFT_SEPARATOR; + else + { + mii.fMask |= MIIM_STRING; + mii.dwTypeData = (LPSTR)item[i].str; + mii.cch = strlen( item[i].str); + } + mii.fState = 0; + if( item[i].type & MF_HELP) mii.fType |= MF_HELP; + mii.wID = item[i].id; + ret = InsertMenuItem( hmenu, -1, TRUE, &mii); + ok(ret, "%d: InsertMenuItem(%04x, %04x, %p) error %u\n", + i, item[i].type, item[i].id, item[i].str, GetLastError()); + } + return hmenu; +} + static void compare_menu_data(HMENU hmenu, const struct menu_data *item, INT item_count) { INT count, i; @@ -2479,14 +2521,12 @@ "%u: expected fType %04x, got %04x\n", i, item[i].type, mii.fType); ok(mii.wID == item[i].id, "%u: expected wID %04x, got %04x\n", i, item[i].id, mii.wID); - if (item[i].type & (MF_BITMAP | MF_SEPARATOR)) - { + if (mii.hbmpItem || !item[i].str) /* For some reason Windows sets high word to not 0 for * not "magic" ids. */ ok(LOWORD(mii.hbmpItem) == LOWORD(item[i].str), "%u: expected hbmpItem %p, got %p\n", i, item[i].str, mii.hbmpItem); - } else { ok(mii.cch == strlen(item[i].str), @@ -2499,6 +2539,7 @@
static void test_InsertMenu(void) { + HBITMAP hbm = CreateBitmap(1,1,1,1,NULL); /* Note: XP treats only bitmap handles 1 - 6 as "magic" ones * regardless of their id. */ @@ -2514,16 +2555,28 @@ { MF_STRING|MF_HELP, 2, "Help" }, { MF_BITMAP|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(1) } }; - static const struct menu_data in2[] = + static const struct menu_data out1a[] = { { MF_STRING, 1, "File" }, - { MF_BITMAP|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(100) }, + { MF_STRING|MF_HELP, 2, "Help" }, + { MF_HELP, SC_CLOSE, MAKEINTRESOURCE(1) } + }; + const struct menu_data in2[] = + { + { MF_STRING, 1, "File" }, + { MF_BITMAP|MF_HELP, SC_CLOSE, (char*)hbm }, { MF_STRING|MF_HELP, 2, "Help" } }; - static const struct menu_data out2[] = + const struct menu_data out2[] = { { MF_STRING, 1, "File" }, - { MF_BITMAP|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(100) }, + { MF_BITMAP|MF_HELP, SC_CLOSE, (char*)hbm }, + { MF_STRING|MF_HELP, 2, "Help" } + }; + const struct menu_data out2a[] = + { + { MF_STRING, 1, "File" }, + { MF_HELP, SC_CLOSE, (char*)hbm }, { MF_STRING|MF_HELP, 2, "Help" } }; static const struct menu_data in3[] = @@ -2550,9 +2603,16 @@ { MF_STRING|MF_HELP, 2, "Help" }, { MF_BITMAP|MF_HELP, 1, MAKEINTRESOURCE(1) } }; + static const struct menu_data out4a[] = + { + { MF_STRING, 1, "File" }, + { MF_STRING|MF_HELP, 2, "Help" }, + { MF_HELP, 1, MAKEINTRESOURCE(1) } + }; HMENU hmenu;
#define create_menu(a) create_menu_from_data((a), sizeof(a)/sizeof((a)[0])) +#define create_menuitem(a) create_menuitem_from_data((a), sizeof(a)/sizeof((a)[0])) #define compare_menu(h, a) compare_menu_data((h), (a), sizeof(a)/sizeof((a)[0]))
hmenu = create_menu(in1); @@ -2571,7 +2631,25 @@ compare_menu(hmenu, out4); DestroyMenu(hmenu);
+ /* now using InsertMenuItemInfo */ + hmenu = create_menuitem(in1); + compare_menu(hmenu, out1a); + DestroyMenu(hmenu); + + hmenu = create_menuitem(in2); + compare_menu(hmenu, out2a); + DestroyMenu(hmenu); + + hmenu = create_menuitem(in3); + compare_menu(hmenu, out3); + DestroyMenu(hmenu); + + hmenu = create_menuitem(in4); + compare_menu(hmenu, out4a); + DestroyMenu(hmenu); + #undef create_menu +#undef create_menuitem #undef compare_menu }
@@ -2932,6 +3010,166 @@ DestroyWindow( hwnd); }
+/* show menu trees have a maximum depth */ +static void test_menu_maxdepth(void) +{ +#define NR_MENUS 100 + HMENU hmenus[ NR_MENUS]; + int i; + DWORD ret; + + SetLastError(12345678); + for( i = 0; i < NR_MENUS; i++) { + hmenus[i] = CreatePopupMenu(); + if( !hmenus[i]) break; + } + ok( i == NR_MENUS, "could not create more than %d menu's\n", i); + for( i = 1; i < NR_MENUS; i++) { + ret = AppendMenuA( hmenus[i], MF_POPUP, (UINT_PTR)hmenus[i-1],"test"); + if( !ret) break; + } + trace("Maximum depth is %d\n", i); + ok( GetLastError() == 12345678, "unexpected error %d\n", GetLastError()); + ok( i < NR_MENUS || + broken( i == NR_MENUS), /* win98, NT */ + "no ( or very large) limit on menu depth!\n"); + + for( i = 0; i < NR_MENUS; i++) + DestroyMenu( hmenus[i]); +} + +/* bug #12171 */ +static void test_menu_circref(void) +{ + HMENU menu1, menu2; + DWORD ret; + + menu1 = CreatePopupMenu(); + menu2 = CreatePopupMenu(); + ok( menu1 && menu2, "error creating menus.\n"); + ret = AppendMenuA( menu1, MF_POPUP, (UINT_PTR)menu2, "winetest"); + ok( ret, "AppendMenu failed, error is %d\n", GetLastError()); + ret = AppendMenuA( menu1, MF_STRING | MF_HILITE, 123, "winetest"); + ok( ret, "AppendMenu failed, error is %d\n", GetLastError()); + /* app chooses an id that happens to clash with its own hmenu */ + ret = AppendMenuA( menu2, MF_STRING, (UINT_PTR)menu2, "winetest"); + ok( ret, "AppendMenu failed, error is %d\n", GetLastError()); + /* now attempt to change the string of the first item of menu1 */ + ret = ModifyMenuA( menu1, (UINT_PTR)menu2, MF_POPUP, (UINT_PTR)menu2, "menu 2"); + ok( !ret || + broken( ret), /* win98, NT */ + "ModifyMenu should have failed.\n"); + if( !ret) { /* will probably stack fault if the ModifyMenu succeeded */ + ret = GetMenuState( menu1, 123, 0); + ok( ret == MF_HILITE, "GetMenuState returned %x\n",ret); + } + DestroyMenu( menu2); + DestroyMenu( menu1); +} + +/* test how the menu texts are aligned when the menu items have + * different combinations of text and bitmaps (bug #13350) */ +static void test_menualign(void) +{ + BYTE bmfill[300]; + HMENU menu; + HBITMAP hbm1, hbm2, hbm3; + MENUITEMINFO mii = { sizeof(MENUITEMINFO)}; + DWORD ret; + HWND hwnd; + MENUINFO mi = { sizeof( MENUINFO)}; + + if( !winetest_interactive) { + skip( "interactive alignment tests.\n"); + return; + } + hwnd = CreateWindowEx(0, + "STATIC", + "Menu text alignment Test\nPlease make a selection.", + WS_OVERLAPPEDWINDOW, + 100, 100, + 300, 300, + NULL, NULL, 0, NULL); + ShowWindow( hwnd, SW_SHOW); + /* create bitmaps */ + memset( bmfill, 0xcc, sizeof( bmfill)); + hbm1 = CreateBitmap( 10,10,1,1,bmfill); + hbm2 = CreateBitmap( 20,20,1,1,bmfill); + hbm3 = CreateBitmap( 50,6,1,1,bmfill); + ok( hbm1 && hbm2 && hbm3, "Creating bitmaps failed\n"); + menu = CreatePopupMenu(); + ok( menu != NULL, "CreatePopupMenu() failed\n"); + if( pGetMenuInfo) { + mi.fMask = MIM_STYLE; + ret = pGetMenuInfo( menu, &mi); + ok( menu != NULL, "GetMenuInfo() failed\n"); + ok( 0 == mi.dwStyle, "menuinfo style is %x\n", mi.dwStyle); + } + /* test 1 */ + mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID; + mii.wID = 1; + mii.hbmpItem = hbm1; + mii.dwTypeData = (LPSTR) " OK: menu texts are correctly left-aligned."; + ret = InsertMenuItem( menu, -1, TRUE, &mii); + ok( ret, "InsertMenuItem() failed\n"); + mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID ; + mii.wID = 2; + mii.hbmpItem = hbm2; + mii.dwTypeData = (LPSTR) " FAIL: menu texts are NOT left-aligned."; + ret = InsertMenuItem( menu, -1, TRUE, &mii); + ok( ret, "InsertMenuItem() failed\n"); + ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL); + ok( ret != 2, "User indicated that menu text alignment test 1 failed %d\n", ret); + /* test 2*/ + mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID; + mii.wID = 3; + mii.hbmpItem = hbm3; + mii.dwTypeData = NULL; + ret = InsertMenuItem( menu, 0, TRUE, &mii); + ok( ret, "InsertMenuItem() failed\n"); + mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID; + mii.wID = 1; + mii.hbmpItem = hbm1; + /* make the text a bit longer, to keep it readable */ + /* this bug is on winXP and reproduced on wine */ + mii.dwTypeData = (LPSTR) " OK: menu texts are to the right of the bitmaps........"; + ret = SetMenuItemInfo( menu, 1, TRUE, &mii); + ok( ret, "SetMenuItemInfo() failed\n"); + mii.wID = 2; + mii.hbmpItem = hbm2; + mii.dwTypeData = (LPSTR) " FAIL: menu texts are below the first bitmap. "; + ret = SetMenuItemInfo( menu, 2, TRUE, &mii); + ok( ret, "SetMenuItemInfo() failed\n"); + ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL); + ok( ret != 2, "User indicated that menu text alignment test 2 failed %d\n", ret); + /* test 3 */ + mii.fMask = MIIM_TYPE | MIIM_ID; + mii.wID = 3; + mii.fType = MFT_BITMAP; + mii.dwTypeData = (LPSTR) hbm3; + ret = SetMenuItemInfo( menu, 0, TRUE, &mii); + ok( ret, "SetMenuItemInfo() failed\n"); + mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID; + mii.wID = 1; + mii.hbmpItem = NULL; + mii.dwTypeData = (LPSTR) " OK: menu texts are below the bitmap."; + ret = SetMenuItemInfo( menu, 1, TRUE, &mii); + ok( ret, "SetMenuItemInfo() failed\n"); + mii.wID = 2; + mii.hbmpItem = NULL; + mii.dwTypeData = (LPSTR) " FAIL: menu texts are NOT below the bitmap."; + ret = SetMenuItemInfo( menu, 2, TRUE, &mii); + ok( ret, "SetMenuItemInfo() failed\n"); + ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL); + ok( ret != 2, "User indicated that menu text alignment test 3 failed %d\n", ret); + /* cleanup */ + DeleteObject( hbm1); + DeleteObject( hbm2); + DeleteObject( hbm3); + DestroyMenu( menu); + DestroyWindow( hwnd); +} + START_TEST(menu) { init_function_pointers(); @@ -2947,6 +3185,7 @@ test_CheckMenuRadioItem(); test_menu_resource_layout(); test_InsertMenu(); + test_menualign(); }
register_menu_check_class(); @@ -2970,4 +3209,6 @@ test_menu_hilitemenuitem(); test_menu_trackpopupmenu(); test_menu_cancelmode(); -} + test_menu_maxdepth(); + test_menu_circref(); +}
Modified: trunk/rostests/winetests/user32/msg.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/msg.c?rev... ============================================================================== --- trunk/rostests/winetests/user32/msg.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/msg.c [iso-8859-1] Mon Aug 24 14:42:47 2009 @@ -581,7 +581,7 @@ { WM_GETTEXT, sent|defwinproc|optional }, { WM_WINDOWPOSCHANGED, sent }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|defwinproc|wparam, SIZE_MINIMIZED }, + { WM_SIZE, sent|defwinproc|wparam|lparam, SIZE_MINIMIZED, 0 }, { WM_NCCALCSIZE, sent|optional }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, @@ -1004,7 +1004,7 @@ { WM_CHILDACTIVATE, sent|optional }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOREDRAW|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|defwinproc|wparam, SIZE_MINIMIZED }, + { WM_SIZE, sent|defwinproc|wparam|lparam, SIZE_MINIMIZED, 0 }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 }, /* FIXME: Wine creates an icon/title window while Windows doesn't */ @@ -1044,7 +1044,7 @@ { WM_CHILDACTIVATE, sent }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOREDRAW|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|defwinproc|wparam, SIZE_MINIMIZED }, + { WM_SIZE, sent|defwinproc|wparam|lparam, SIZE_MINIMIZED, 0 }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 }, /* FIXME: Wine creates an icon/title window while Windows doesn't */ @@ -1065,7 +1065,7 @@ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOREDRAW|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|defwinproc|wparam, SIZE_MINIMIZED }, + { WM_SIZE, sent|defwinproc|wparam|lparam, SIZE_MINIMIZED, 0 }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 }, /* FIXME: Wine creates an icon/title window while Windows doesn't */ @@ -3186,7 +3186,7 @@ { WM_NCCALCSIZE, sent|wparam, 1 }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOCLIENTSIZE|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|defwinproc|wparam, SIZE_MINIMIZED }, + { WM_SIZE, sent|defwinproc|wparam|lparam, SIZE_MINIMIZED, 0 }, { WM_CHILDACTIVATE, sent|wparam|lparam|defwinproc, 0, 0 }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ @@ -5209,6 +5209,49 @@ { WM_CTLCOLORBTN, sent|defwinproc }, { 0 } }; +static const struct message WmSetStyleButtonSeq[] = +{ + { BM_SETSTYLE, sent }, + { WM_APP, sent|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */ + { WM_ERASEBKGND, sent|defwinproc|optional }, /* Win9x doesn't send it */ + { WM_CTLCOLORBTN, sent|parent }, + { 0 } +}; +static const struct message WmSetStyleStaticSeq[] = +{ + { BM_SETSTYLE, sent }, + { WM_APP, sent|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */ + { WM_ERASEBKGND, sent|defwinproc|optional }, /* Win9x doesn't send it */ + { WM_CTLCOLORSTATIC, sent|parent }, + { 0 } +}; +static const struct message WmSetStyleUserSeq[] = +{ + { BM_SETSTYLE, sent }, + { WM_APP, sent|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */ + { WM_ERASEBKGND, sent|defwinproc|optional }, /* Win9x doesn't send it */ + { WM_CTLCOLORBTN, sent|parent }, + { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_PAINT) }, + { 0 } +}; +static const struct message WmSetStyleOwnerdrawSeq[] = +{ + { BM_SETSTYLE, sent }, + { WM_APP, sent|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */ + { WM_ERASEBKGND, sent|defwinproc|optional }, /* Win9x doesn't send it */ + { WM_CTLCOLORBTN, sent|parent }, + { WM_CTLCOLORBTN, sent|parent|optional }, /* Win9x doesn't send it */ + { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000010e4 }, + { 0 } +};
static WNDPROC old_button_proc;
@@ -5268,29 +5311,30 @@ DWORD dlg_code; const struct message *setfocus; const struct message *killfocus; + const struct message *setstyle; } button[] = { { BS_PUSHBUTTON, DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON, - WmSetFocusButtonSeq, WmKillFocusButtonSeq }, + WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq }, { BS_DEFPUSHBUTTON, DLGC_BUTTON | DLGC_DEFPUSHBUTTON, - WmSetFocusButtonSeq, WmKillFocusButtonSeq }, + WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq }, { BS_CHECKBOX, DLGC_BUTTON, - WmSetFocusStaticSeq, WmKillFocusStaticSeq }, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq }, { BS_AUTOCHECKBOX, DLGC_BUTTON, - WmSetFocusStaticSeq, WmKillFocusStaticSeq }, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq }, { BS_RADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON, - WmSetFocusStaticSeq, WmKillFocusStaticSeq }, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq }, { BS_3STATE, DLGC_BUTTON, - WmSetFocusStaticSeq, WmKillFocusStaticSeq }, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq }, { BS_AUTO3STATE, DLGC_BUTTON, - WmSetFocusStaticSeq, WmKillFocusStaticSeq }, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq }, { BS_GROUPBOX, DLGC_STATIC, - WmSetFocusStaticSeq, WmKillFocusStaticSeq }, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq }, { BS_USERBUTTON, DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON, - WmSetFocusButtonSeq, WmKillFocusButtonSeq }, + WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleUserSeq }, { BS_AUTORADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON, - WmSetFocusStaticSeq, WmKillFocusStaticSeq }, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq }, { BS_OWNERDRAW, DLGC_BUTTON, - WmSetFocusOwnerdrawSeq, WmKillFocusOwnerdrawSeq } + WmSetFocusOwnerdrawSeq, WmKillFocusOwnerdrawSeq, WmSetStyleOwnerdrawSeq } }; unsigned int i; HWND hwnd, parent; @@ -5319,6 +5363,8 @@ MSG msg; DWORD style;
+ trace("button style %08x\n", button[i].style); + hwnd = CreateWindowExA(0, "my_button_class", "test", button[i].style | WS_CHILD | BS_NOTIFY, 0, 0, 50, 14, parent, (HMENU)ID_BUTTON, 0, NULL); ok(hwnd != 0, "Failed to create button window\n"); @@ -5327,9 +5373,9 @@ style &= ~(WS_CHILD | BS_NOTIFY); /* XP turns a BS_USERBUTTON into BS_PUSHBUTTON */ if (button[i].style == BS_USERBUTTON) - todo_wine ok(style == BS_PUSHBUTTON, "expected style BS_PUSHBUTTON got %x\n", style); + ok(style == BS_PUSHBUTTON, "expected style BS_PUSHBUTTON got %x\n", style); else - ok(style == button[i].style, "expected style %x got %x\n", button[i].style, style); + ok(style == button[i].style, "expected style %x got %x\n", button[i].style, style);
dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0); ok(dlg_code == button[i].dlg_code, "%u: wrong dlg_code %08x\n", i, dlg_code); @@ -5342,7 +5388,6 @@
log_all_parent_messages++;
- trace("button style %08x\n", button[i].style); ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus()); SetFocus(hwnd); SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */ @@ -5354,9 +5399,20 @@ while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg); ok_sequence(button[i].killfocus, "SetFocus(0) on a button", FALSE);
+ ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus()); + + SendMessage(hwnd, BM_SETSTYLE, button[i].style | BS_BOTTOM, TRUE); + SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */ + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg); + ok_sequence(button[i].setstyle, "BM_SETSTYLE on a button", FALSE); + + style = GetWindowLongA(hwnd, GWL_STYLE); + style &= ~(WS_VISIBLE | WS_CHILD | BS_NOTIFY); + /* XP doesn't turn a BS_USERBUTTON into BS_PUSHBUTTON here! */ + ok(style == button[i].style, "expected style %x got %x\n", button[i].style, style); + log_all_parent_messages--;
- ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus()); DestroyWindow(hwnd); }
@@ -10198,7 +10254,7 @@ { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|wparam|defwinproc, SIZE_MINIMIZED }, + { WM_SIZE, sent|wparam|lparam|defwinproc, SIZE_MINIMIZED, 0 }, { 0 } }; static const struct message WmMinimize_1[] = { @@ -10208,7 +10264,7 @@ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|wparam|defwinproc, SIZE_MINIMIZED }, + { WM_SIZE, sent|wparam|lparam|defwinproc, SIZE_MINIMIZED, 0 }, { 0 } }; static const struct message WmMinimize_2[] = { @@ -10217,7 +10273,7 @@ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|wparam|defwinproc, SIZE_MINIMIZED }, + { WM_SIZE, sent|wparam|lparam|defwinproc, SIZE_MINIMIZED, 0 }, { 0 } }; static const struct message WmMinimize_3[] = { @@ -10225,7 +10281,7 @@ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|wparam|defwinproc, SIZE_MINIMIZED }, + { WM_SIZE, sent|wparam|lparam|defwinproc, SIZE_MINIMIZED, 0 }, { 0 } }; static const struct message WmShowMinNoActivate[] = { @@ -10233,7 +10289,7 @@ { WM_WINDOWPOSCHANGING, sent }, { WM_WINDOWPOSCHANGED, sent }, { WM_MOVE, sent|defwinproc|optional }, - { WM_SIZE, sent|wparam|defwinproc|optional, SIZE_MINIMIZED }, + { WM_SIZE, sent|wparam|lparam|defwinproc|optional, SIZE_MINIMIZED, 0 }, { 0 } }; static const struct message WmMinMax_1[] = { @@ -10259,7 +10315,7 @@ { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc|optional }, - { WM_SIZE, sent|wparam|defwinproc|optional, SIZE_MINIMIZED }, + { WM_SIZE, sent|wparam|lparam|defwinproc|optional, SIZE_MINIMIZED, 0 }, { 0 } }; static const struct message WmMinMax_4[] = {
Modified: trunk/rostests/winetests/user32/win.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/win.c?rev... ============================================================================== --- trunk/rostests/winetests/user32/win.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/win.c [iso-8859-1] Mon Aug 24 14:42:47 2009 @@ -4859,6 +4859,75 @@ DestroyWindow(mw); }
+static LRESULT CALLBACK TestNCRedraw_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static UINT ncredrawflags; + PAINTSTRUCT ps; + + switch(msg) + { + case WM_CREATE: + ncredrawflags = *(UINT *) (((CREATESTRUCT *)lParam)->lpCreateParams); + return 0; + case WM_NCPAINT: + RedrawWindow(hwnd, NULL, NULL, ncredrawflags); + break; + case WM_PAINT: + BeginPaint(hwnd, &ps); + EndPaint(hwnd, &ps); + return 0; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +static void run_NCRedrawLoop(UINT flags) +{ + HWND hwnd; + MSG msg; + + UINT loopcount = 0; + + hwnd = CreateWindowA("TestNCRedrawClass", "MainWindow", + WS_OVERLAPPEDWINDOW, 0, 0, 200, 100, + NULL, NULL, 0, &flags); + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + while(PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE) != 0) + { + if (msg.message == WM_PAINT) loopcount++; + if (loopcount >= 100) break; + TranslateMessage(&msg); + DispatchMessage(&msg); + MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT); + } + if (flags == (RDW_INVALIDATE | RDW_FRAME)) + todo_wine ok(loopcount < 100, "Detected infinite WM_PAINT loop (%x).\n", flags); + else + ok(loopcount < 100, "Detected infinite WM_PAINT loop (%x).\n", flags); + DestroyWindow(hwnd); +} + +static void test_NCRedraw(void) +{ + WNDCLASSA wndclass; + + wndclass.lpszClassName = "TestNCRedrawClass"; + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = TestNCRedraw_WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = 0; + wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = NULL; + + RegisterClassA(&wndclass); + + run_NCRedrawLoop(RDW_INVALIDATE | RDW_FRAME); + run_NCRedrawLoop(RDW_INVALIDATE); +} + static void test_GetWindowModuleFileName(void) { HWND hwnd; @@ -5647,6 +5716,7 @@ test_SetMenu(hwndMain); test_SetFocus(hwndMain); test_SetActiveWindow(hwndMain); + test_NCRedraw();
test_children_zorder(hwndMain); test_popup_zorder(hwndMain2, hwndMain);