Fixes menu update in Diablo 1.
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/user32/painting.c | 26 +++++++++++- dlls/user32/tests/win.c | 94 +++++++++++++++++++++++++++++++++++++++++ dlls/user32/win.h | 1 + 3 files changed, 120 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index 313c5fa1e6..6ab53a2372 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -725,7 +725,20 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn, { /* don't erase if the clip box is empty */ if (type != NULLREGION) + { + WND *wnd_ptr; + need_erase = !SendMessageW( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 ); + if ((wnd_ptr = WIN_GetPtr( hwnd )) && wnd_ptr != WND_OTHER_PROCESS && wnd_ptr != WND_DESKTOP) + { + if (need_erase) + wnd_ptr->flags |= WIN_PS_NEED_ERASE_BKGND; + else + wnd_ptr->flags &= ~WIN_PS_NEED_ERASE_BKGND; + + WIN_ReleasePtr( wnd_ptr ); + } + } } if (!hdc_ret) release_dc( hwnd, hdc, TRUE ); } @@ -943,6 +956,7 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps ) BOOL erase; RECT rect; UINT flags = UPDATE_NONCLIENT | UPDATE_ERASE | UPDATE_PAINT | UPDATE_INTERNALPAINT | UPDATE_NOCHILDREN; + WND *wnd_ptr;
HideCaret( hwnd );
@@ -957,7 +971,17 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps ) release_dc( hwnd, hdc, TRUE ); return 0; } - lps->fErase = erase; + + if (!(wnd_ptr = WIN_GetPtr( hwnd )) || wnd_ptr == WND_OTHER_PROCESS || wnd_ptr == WND_DESKTOP) + { + lps->fErase = erase; + } + else + { + lps->fErase = !!(wnd_ptr->flags & WIN_PS_NEED_ERASE_BKGND); + WIN_ReleasePtr( wnd_ptr ); + } + lps->rcPaint = rect; lps->hdc = hdc; return hdc; diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 25d643f54a..c02af08a90 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -11830,6 +11830,99 @@ static void test_other_process_window(const char *argv0) DestroyWindow(hwnd); }
+static BOOL test_paintstruct_erase_bkgnd; +static BOOL test_paintstruct_wm_erasebkgnd_received; +static BOOL test_paintstruct_wm_paint_received, test_paintstruct_ferase; + +static LRESULT WINAPI paintstruct_erase_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + switch (msg) + { + case WM_ERASEBKGND: + { + test_paintstruct_wm_erasebkgnd_received = TRUE; + return test_paintstruct_erase_bkgnd; + } + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc; + + test_paintstruct_wm_paint_received = TRUE; + hdc = BeginPaint(hwnd, &ps); + ok(!!hdc, "Null hdc.\n"); + test_paintstruct_ferase = ps.fErase; + EndPaint(hwnd, &ps); + return 0; + } + } + return DefWindowProcA(hwnd, msg, wparam, lparam); +} + +static void test_paintstruct_erase(void) +{ + WNDCLASSA cls; + HWND hwnd; + BOOL ret; + + cls.style = 0; + cls.lpfnWndProc = paintstruct_erase_window_procA; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleA(0); + cls.hIcon = 0; + cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = "paintstruct_erase_class"; + ret = RegisterClassA(&cls); + ok(ret, "Failed to register a test class.\n"); + + test_paintstruct_wm_paint_received = test_paintstruct_wm_erasebkgnd_received = FALSE; + test_paintstruct_erase_bkgnd = FALSE; + hwnd = CreateWindowExA(0, "paintstruct_erase_class", NULL, WS_POPUP | WS_VISIBLE, + 100, 100, 100, 100, 0, 0, NULL, NULL); + ok(!!hwnd, "CreateWindowEx failed.\n"); + + flush_events(TRUE); + ok(test_paintstruct_wm_erasebkgnd_received, "WM_ERASEBKGND not received.\n"); + ok(test_paintstruct_wm_paint_received, "WM_PAINT not received.\n"); + ok(test_paintstruct_ferase, "Unexpected fErase %#x.\n", test_paintstruct_ferase); + + test_paintstruct_wm_paint_received = test_paintstruct_wm_erasebkgnd_received = FALSE; + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE); + flush_events(TRUE); + ok(!test_paintstruct_wm_erasebkgnd_received, "WM_ERASEBKGND received.\n"); + ok(test_paintstruct_wm_paint_received, "WM_PAINT not received.\n"); + ok(test_paintstruct_ferase, "Unexpected fErase %#x.\n", test_paintstruct_ferase); + + test_paintstruct_wm_paint_received = test_paintstruct_wm_erasebkgnd_received = FALSE; + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE); + flush_events(TRUE); + ok(!test_paintstruct_wm_erasebkgnd_received, "WM_ERASEBKGND received.\n"); + ok(test_paintstruct_wm_paint_received, "WM_PAINT not received.\n"); + ok(test_paintstruct_ferase, "Unexpected fErase %#x.\n", test_paintstruct_ferase); + + test_paintstruct_erase_bkgnd = TRUE; + test_paintstruct_wm_paint_received = test_paintstruct_wm_erasebkgnd_received = FALSE; + RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE); + flush_events(TRUE); + ok(test_paintstruct_wm_erasebkgnd_received, "WM_ERASEBKGND not received.\n"); + ok(test_paintstruct_wm_paint_received, "WM_PAINT not received.\n"); + ok(!test_paintstruct_ferase, "Unexpected fErase %#x.\n", test_paintstruct_ferase); + + test_paintstruct_wm_paint_received = test_paintstruct_wm_erasebkgnd_received = FALSE; + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE); + flush_events(TRUE); + ok(!test_paintstruct_wm_erasebkgnd_received, "WM_ERASEBKGND received.\n"); + ok(test_paintstruct_wm_paint_received, "WM_PAINT not received.\n"); + ok(!test_paintstruct_ferase, "Unexpected fErase %#x.\n", test_paintstruct_ferase); + + DestroyWindow(hwnd); + UnregisterClassA("paintstruct_erase_class", GetModuleHandleA(NULL)); +} + START_TEST(win) { char **argv; @@ -11995,6 +12088,7 @@ START_TEST(win) test_window_placement(); test_arrange_iconic_windows(); test_other_process_window(argv[0]); + test_paintstruct_erase();
/* add the tests above this line */ if (hhook) UnhookWindowsHookEx(hhook); diff --git a/dlls/user32/win.h b/dlls/user32/win.h index 1f51fd6331..eecfa20eea 100644 --- a/dlls/user32/win.h +++ b/dlls/user32/win.h @@ -79,6 +79,7 @@ typedef struct tagWND #define WIN_NEEDS_SHOW_OWNEDPOPUP 0x0020 /* WM_SHOWWINDOW:SC_SHOW must be sent in the next ShowOwnedPopup call */ #define WIN_CHILDREN_MOVED 0x0040 /* children may have moved, ignore stored positions */ #define WIN_HAS_IME_WIN 0x0080 /* the window has been registered with imm32 */ +#define WIN_PS_NEED_ERASE_BKGND 0x0100 /* Need to set fErase in PAINTSTRUCT */
/* Window functions */ extern HWND get_hwnd_message_parent(void) DECLSPEC_HIDDEN;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=68096
Your paranoid android.
=== w1064v1809 (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 0003004C win.c:3188: Test failed: GetActiveWindow() = 0003004C win.c:3889: Test failed: hwnd 00020174/001502CE message 0737 win.c:3894: Test failed: hwnd 001502CE/001502CE message 0202 win.c:3899: Test failed: hwnd 001502CE/001502CE message 0203
=== w1064v1809_2scr (32 bit report) ===
user32: win.c:9451: Test failed: Timed out waiting for the child process win.c:3849: Test failed: hwnd 000301A6 message 0738
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3724: Test failed: message 0738 available win.c:3849: Test failed: hwnd 000202F2 message 7fff win.c:3928: Test failed: hwnd 000202F2/000C02A6 message 7fff win.c:3931: Test failed: hwnd 000202F2/000C02A6 message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:3849: Test failed: hwnd 00010388 message 0282 win.c:3928: Test failed: hwnd 00010388/000C03D4 message 0282 win.c:3931: Test failed: hwnd 00010388/000C03D4 message 0282
=== w1064v1809 (64 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000000000003004A win.c:3167: Test failed: GetFocus() = 0000000000000000 win.c:3179: Test failed: GetFocus() = 0000000000000000 win.c:3182: Test failed: GetFocus() = 0000000000000000 win.c:3185: Test failed: GetFocus() = 0000000000000000 win.c:3188: Test failed: GetActiveWindow() = 000000000003004A win.c:3192: Test failed: GetFocus() = 0000000000000000 win.c:3195: Test failed: GetFocus() = 0000000000000000 win.c:3889: Test failed: hwnd 0000000000020174/00000000000C02C6 message 0737 win.c:3894: Test failed: hwnd 00000000000C02C6/00000000000C02C6 message 0202 win.c:3899: Test failed: hwnd 00000000000C02C6/00000000000C02C6 message 0203 win.c:3903: Test failed: message 0202 available
=== debiant (64 bit WoW report) ===
user32: clipboard.c:1383: Test failed: gle 5 clipboard.c:1385: Test failed: gle 1418 clipboard.c:1388: Test failed: got 00000000 clipboard.c:1389: Test failed: expected moveable mem 00000000 clipboard.c:1391: Test failed: got 00000000 clipboard.c:1392: Test failed: expected moveable mem 00000000 clipboard.c:1395: Test failed: got 00000000 clipboard.c:1396: Test failed: expected bitmap 00000000 clipboard.c:1398: Test failed: got 00000000 clipboard.c:1399: Test failed: expected bitmap 00000000 clipboard.c:1401: Test failed: got 00000000 clipboard.c:1402: Test failed: expected bitmap 00000000 clipboard.c:1404: Test failed: got 00000000 clipboard.c:1405: Test failed: expected palette 00000000 clipboard.c:1407: Test failed: got 00000000 clipboard.c:1408: Test failed: expected moveable mem 00000000 clipboard.c:1410: Test failed: got 00000000 clipboard.c:1411: Test failed: expected moveable mem 00000000 clipboard.c:1425: Test failed: got 00000000 clipboard.c:1426: Test failed: expected fixed mem 00000000 clipboard.c:1428: Test failed: got 00000000 clipboard.c:1429: Test failed: expected fixed mem 00000000 clipboard.c:1431: Test failed: got 00000000 clipboard.c:1432: Test failed: expected moveable mem 00000000 clipboard.c:1444: Test failed: wrong data 00000000 clipboard.c:1445: Test failed: expected moveable mem 00000000 clipboard.c:1448: Test failed: wrong data 00000000, cf 0000c040 clipboard.c:1449: Test failed: expected moveable mem 00000000 clipboard.c:1452: Test failed: wrong data 00000000 clipboard.c:1453: Test failed: expected moveable mem 00000000 clipboard.c:1456: Test failed: wrong data 00000000 clipboard.c:1457: Test failed: expected moveable mem 00000000 clipboard.c:1460: Test failed: wrong data 00000000 clipboard.c:1461: Test failed: expected fixed mem 00000000 clipboard.c:1464: Test failed: wrong data 00000000 clipboard.c:1465: Test failed: expected fixed mem 00000000 clipboard.c:1468: Test failed: wrong data 00000000 clipboard.c:1469: Test failed: expected moveable mem 00000000 clipboard.c:1475: Test failed: got 00000000 clipboard.c:1476: Test failed: expected moveable mem 00000000 clipboard.c:1477: Test failed: expected freed mem 0021E43A clipboard.c:1480: Test failed: got 00000000 clipboard.c:1481: Test failed: expected fixed mem 00000000 clipboard.c:1486: Test failed: gle 1418 clipboard.c:1549: Test failed: wrong data 00000000 clipboard.c:1552: Test failed: wrong data 00000000, cf 0000c040 clipboard.c:1555: Test failed: wrong data 00000000 clipboard.c:1558: Test failed: wrong data 00000000 clipboard.c:1561: Test failed: wrong data 00000000 clipboard.c:1564: Test failed: wrong data 00000000 clipboard.c:1567: Test failed: wrong data 00000000 clipboard.c:1574: Test failed: expected fixed mem 00000000 clipboard.c:1576: Test failed: expected fixed mem 00000000 clipboard.c:1578: Test failed: expected fixed mem 00000000 clipboard.c:1580: Test failed: expected bitmap 00000000 clipboard.c:1582: Test failed: expected bitmap 00000000 clipboard.c:1584: Test failed: expected palette 00000000 clipboard.c:1586: Test failed: expected fixed mem 00000000 clipboard.c:1588: Test failed: expected fixed mem 00000000 clipboard.c:1600: Test failed: expected freed mem 0021E1C2 clipboard.c:1601: Test failed: expected freed mem 00BEECB2 clipboard.c:1602: Test failed: expected freed mem 00BEECEA clipboard.c:1603: Test failed: expected freed mem 00BED442 clipboard.c:1604: Test failed: expected freed mem 00BECBE2