From d5ebadd0d9359fc2eac304d6b151b1b077afc451 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sun, 28 Feb 2016 08:05:03 +0100 Subject: [PATCH] Added patch to replicate Windows behavior of WM_SETTEXT handler regarding WM_CTLCOLOR* messages. --- patches/patchinstall.sh | 21 +++ ...-Windows-behavior-of-WM_SETTEXT-hand.patch | 73 +++++++++ ...-tests-for-button-WM_CTLCOLOR-messag.patch | 151 ++++++++++++++++++ patches/user32-WM_CTLCOLORBTN/definition | 1 + 4 files changed, 246 insertions(+) create mode 100644 patches/user32-WM_CTLCOLORBTN/0001-user32-Replicate-Windows-behavior-of-WM_SETTEXT-hand.patch create mode 100644 patches/user32-WM_CTLCOLORBTN/0002-user32-tests-Add-tests-for-button-WM_CTLCOLOR-messag.patch create mode 100644 patches/user32-WM_CTLCOLORBTN/definition diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 6cb06d0c..20859072 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -324,6 +324,7 @@ patch_enable_all () enable_user32_Refresh_MDI_Menus="$1" enable_user32_ScrollWindowEx="$1" enable_user32_SetCoalescableTimer="$1" + enable_user32_WM_CTLCOLORBTN="$1" enable_user32_WM_MDICALCCHILDSCROLL="$1" enable_user32_WndProc="$1" enable_uxtheme_GTK_Theming="$1" @@ -1125,6 +1126,9 @@ patch_enable () user32-SetCoalescableTimer) enable_user32_SetCoalescableTimer="$2" ;; + user32-WM_CTLCOLORBTN) + enable_user32_WM_CTLCOLORBTN="$2" + ;; user32-WM_MDICALCCHILDSCROLL) enable_user32_WM_MDICALCCHILDSCROLL="$2" ;; @@ -6582,6 +6586,23 @@ if test "$enable_user32_SetCoalescableTimer" -eq 1; then ) >> "$patchlist" fi +# Patchset user32-WM_CTLCOLORBTN +# | +# | This patchset fixes the following Wine bugs: +# | * [#25790] Replicate Windows behavior of WM_SETTEXT handler regarding WM_CTLCOLOR* messages +# | +# | Modified files: +# | * dlls/user32/button.c, dlls/user32/tests/msg.c +# | +if test "$enable_user32_WM_CTLCOLORBTN" -eq 1; then + patch_apply user32-WM_CTLCOLORBTN/0001-user32-Replicate-Windows-behavior-of-WM_SETTEXT-hand.patch + patch_apply user32-WM_CTLCOLORBTN/0002-user32-tests-Add-tests-for-button-WM_CTLCOLOR-messag.patch + ( + echo '+ { "Alexander Law", "user32: Replicate Windows behavior of WM_SETTEXT handler regarding WM_CTLCOLOR*.", 1 },'; + echo '+ { "Sebastian Lackner", "user32/tests: Add tests for button WM_CTLCOLOR* messages.", 1 },'; + ) >> "$patchlist" +fi + # Patchset user32-WM_MDICALCCHILDSCROLL # | # | Modified files: diff --git a/patches/user32-WM_CTLCOLORBTN/0001-user32-Replicate-Windows-behavior-of-WM_SETTEXT-hand.patch b/patches/user32-WM_CTLCOLORBTN/0001-user32-Replicate-Windows-behavior-of-WM_SETTEXT-hand.patch new file mode 100644 index 00000000..16a89298 --- /dev/null +++ b/patches/user32-WM_CTLCOLORBTN/0001-user32-Replicate-Windows-behavior-of-WM_SETTEXT-hand.patch @@ -0,0 +1,73 @@ +From e48498bd46044ebfad0ae16e8f6dd08976b49b14 Mon Sep 17 00:00:00 2001 +From: Alexander Law +Date: Mon, 31 Jan 2011 22:59:13 +0300 +Subject: user32: Replicate Windows behavior of WM_SETTEXT handler regarding + WM_CTLCOLOR*. + +--- + dlls/user32/button.c | 49 +++++++++++++++++++++++++++++-------------------- + 1 file changed, 29 insertions(+), 20 deletions(-) + +diff --git a/dlls/user32/button.c b/dlls/user32/button.c +index 9c52147..5b52510 100644 +--- a/dlls/user32/button.c ++++ b/dlls/user32/button.c +@@ -385,26 +385,35 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, + case WM_SETTEXT: + { + /* Clear an old text here as Windows does */ +- HDC hdc = GetDC(hWnd); +- HBRUSH hbrush; +- RECT client, rc; +- HWND parent = GetParent(hWnd); +- +- if (!parent) parent = hWnd; +- hbrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC, +- (WPARAM)hdc, (LPARAM)hWnd); +- if (!hbrush) /* did the app forget to call DefWindowProc ? */ +- hbrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC, +- (WPARAM)hdc, (LPARAM)hWnd); +- +- GetClientRect(hWnd, &client); +- rc = client; +- BUTTON_CalcLabelRect(hWnd, hdc, &rc); +- /* Clip by client rect bounds */ +- if (rc.right > client.right) rc.right = client.right; +- if (rc.bottom > client.bottom) rc.bottom = client.bottom; +- FillRect(hdc, &rc, hbrush); +- ReleaseDC(hWnd, hdc); ++ if (IsWindowVisible(hWnd)) ++ { ++ HDC hdc = GetDC(hWnd); ++ HBRUSH hbrush; ++ RECT client, rc; ++ HWND parent = GetParent(hWnd); ++ UINT message = (btn_type == BS_PUSHBUTTON || ++ btn_type == BS_DEFPUSHBUTTON || ++ btn_type == BS_PUSHLIKE || ++ btn_type == BS_USERBUTTON || ++ btn_type == BS_OWNERDRAW) ? ++ WM_CTLCOLORBTN : WM_CTLCOLORSTATIC; ++ ++ if (!parent) parent = hWnd; ++ hbrush = (HBRUSH)SendMessageW(parent, message, ++ (WPARAM)hdc, (LPARAM)hWnd); ++ if (!hbrush) /* did the app forget to call DefWindowProc ? */ ++ hbrush = (HBRUSH)DefWindowProcW(parent, message, ++ (WPARAM)hdc, (LPARAM)hWnd); ++ ++ GetClientRect(hWnd, &client); ++ rc = client; ++ BUTTON_CalcLabelRect(hWnd, hdc, &rc); ++ /* Clip by client rect bounds */ ++ if (rc.right > client.right) rc.right = client.right; ++ if (rc.bottom > client.bottom) rc.bottom = client.bottom; ++ FillRect(hdc, &rc, hbrush); ++ ReleaseDC(hWnd, hdc); ++ } + + if (unicode) DefWindowProcW( hWnd, WM_SETTEXT, wParam, lParam ); + else DefWindowProcA( hWnd, WM_SETTEXT, wParam, lParam ); +-- +2.7.1 + diff --git a/patches/user32-WM_CTLCOLORBTN/0002-user32-tests-Add-tests-for-button-WM_CTLCOLOR-messag.patch b/patches/user32-WM_CTLCOLORBTN/0002-user32-tests-Add-tests-for-button-WM_CTLCOLOR-messag.patch new file mode 100644 index 00000000..7eaeb677 --- /dev/null +++ b/patches/user32-WM_CTLCOLORBTN/0002-user32-tests-Add-tests-for-button-WM_CTLCOLOR-messag.patch @@ -0,0 +1,151 @@ +From aa33498b984e6505af86206a61d14b51c3531644 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 28 Feb 2016 07:55:21 +0100 +Subject: user32/tests: Add tests for button WM_CTLCOLOR* messages. + +--- + dlls/user32/tests/msg.c | 80 ++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 69 insertions(+), 11 deletions(-) + +diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c +index b2a005a..6794d92 100644 +--- a/dlls/user32/tests/msg.c ++++ b/dlls/user32/tests/msg.c +@@ -5483,6 +5483,35 @@ static const struct message WmSetFontStaticSeq[] = + { WM_CTLCOLORSTATIC, sent|defwinproc }, + { 0 } + }; ++static const struct message WmSetTextButtonSeq[] = ++{ ++ { WM_SETTEXT, sent }, ++ { WM_CTLCOLORBTN, sent|parent }, ++ { WM_CTLCOLORBTN, sent|parent }, ++ { WM_COMMAND, sent|parent|optional }, ++ { WM_DRAWITEM, sent|parent|optional }, ++ { 0 } ++}; ++static const struct message WmSetTextStaticSeq[] = ++{ ++ { WM_SETTEXT, sent }, ++ { WM_CTLCOLORSTATIC, sent|parent }, ++ { WM_CTLCOLORSTATIC, sent|parent }, ++ { 0 } ++}; ++static const struct message WmSetTextGroupSeq[] = ++{ ++ { WM_SETTEXT, sent }, ++ { WM_CTLCOLORSTATIC, sent|parent }, ++ { WM_CTLCOLORSTATIC, sent|parent|optional }, /* FIXME: Missing in Wine */ ++ { WM_CTLCOLORSTATIC, sent|parent|optional }, /* FIXME: Missing in Wine */ ++ { 0 } ++}; ++static const struct message WmSetTextInvisibleSeq[] = ++{ ++ { WM_SETTEXT, sent }, ++ { 0 } ++}; + static const struct message WmSetStyleButtonSeq[] = + { + { BM_SETSTYLE, sent }, +@@ -5652,51 +5681,63 @@ static void test_button_messages(void) + const struct message *lbuttondown; + const struct message *lbuttonup; + const struct message *setfont; ++ const struct message *settext; + } button[] = { + { BS_PUSHBUTTON, DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON, + WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq, + WmSetStateButtonSeq, WmSetStateButtonSeq, WmSetCheckIgnoredSeq, +- WmLButtonDownSeq, WmLButtonUpSeq, WmSetFontButtonSeq }, ++ WmLButtonDownSeq, WmLButtonUpSeq, WmSetFontButtonSeq, ++ WmSetTextButtonSeq }, + { BS_DEFPUSHBUTTON, DLGC_BUTTON | DLGC_DEFPUSHBUTTON, + WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq, + WmSetStateButtonSeq, WmSetStateButtonSeq, WmSetCheckIgnoredSeq, +- WmLButtonDownSeq, WmLButtonUpSeq, WmSetFontButtonSeq }, ++ WmLButtonDownSeq, WmLButtonUpSeq, WmSetFontButtonSeq, ++ WmSetTextButtonSeq }, + { BS_CHECKBOX, DLGC_BUTTON, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq, + WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq, +- WmLButtonDownStaticSeq, WmLButtonUpStaticSeq, WmSetFontStaticSeq }, ++ WmLButtonDownStaticSeq, WmLButtonUpStaticSeq, WmSetFontStaticSeq, ++ WmSetTextStaticSeq }, + { BS_AUTOCHECKBOX, DLGC_BUTTON, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq, + WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq, +- WmLButtonDownStaticSeq, WmLButtonUpAutoSeq, WmSetFontStaticSeq }, ++ WmLButtonDownStaticSeq, WmLButtonUpAutoSeq, WmSetFontStaticSeq, ++ WmSetTextStaticSeq }, + { BS_RADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq, + WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq, +- WmLButtonDownStaticSeq, WmLButtonUpStaticSeq, WmSetFontStaticSeq }, ++ WmLButtonDownStaticSeq, WmLButtonUpStaticSeq, WmSetFontStaticSeq, ++ WmSetTextStaticSeq }, + { BS_3STATE, DLGC_BUTTON, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq, + WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq, +- WmLButtonDownStaticSeq, WmLButtonUpStaticSeq, WmSetFontStaticSeq }, ++ WmLButtonDownStaticSeq, WmLButtonUpStaticSeq, WmSetFontStaticSeq, ++ WmSetTextStaticSeq }, + { BS_AUTO3STATE, DLGC_BUTTON, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq, + WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq, +- WmLButtonDownStaticSeq, WmLButtonUpAutoSeq, WmSetFontStaticSeq }, ++ WmLButtonDownStaticSeq, WmLButtonUpAutoSeq, WmSetFontStaticSeq, ++ WmSetTextStaticSeq }, + { BS_GROUPBOX, DLGC_STATIC, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq, + WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckIgnoredSeq, +- WmLButtonDownStaticSeq, WmLButtonUpStaticSeq, WmSetFontStaticSeq }, ++ WmLButtonDownStaticSeq, WmLButtonUpStaticSeq, WmSetFontStaticSeq, ++ WmSetTextGroupSeq }, + { BS_USERBUTTON, DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON, + WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleUserSeq, + WmSetStateUserSeq, WmClearStateButtonSeq, WmSetCheckIgnoredSeq, +- WmLButtonDownSeq, WmLButtonUpSeq, WmSetFontButtonSeq }, ++ WmLButtonDownSeq, WmLButtonUpSeq, WmSetFontButtonSeq, ++ WmSetTextButtonSeq }, + { BS_AUTORADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON, + WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq, + WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq, +- NULL /* avoid infinite loop */, WmLButtonUpBrokenSeq, WmSetFontStaticSeq }, ++ NULL /* avoid infinite loop */, WmLButtonUpBrokenSeq, WmSetFontStaticSeq, ++ WmSetTextStaticSeq }, + { BS_OWNERDRAW, DLGC_BUTTON, + WmSetFocusOwnerdrawSeq, WmKillFocusOwnerdrawSeq, WmSetStyleOwnerdrawSeq, + WmSetStateOwnerdrawSeq, WmClearStateOwnerdrawSeq, WmSetCheckIgnoredSeq, +- WmLButtonDownSeq, WmLButtonUpSeq, WmSetFontButtonSeq }, ++ WmLButtonDownSeq, WmLButtonUpSeq, WmSetFontButtonSeq, ++ WmSetTextButtonSeq }, + }; + unsigned int i; + HWND hwnd, parent; +@@ -5830,6 +5871,23 @@ static void test_button_messages(void) + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + ok_sequence(button[i].setcheck, "BM_SETCHECK on a button", FALSE); + ++ flush_sequence(); ++ ++ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"Text 1"); ++ sprintf(desc, "button[%i]: WM_SETTEXT on a visible button", i); ++ ok_sequence(button[i].settext, desc, FALSE); ++ ++ ShowWindow(parent, SW_HIDE); ++ flush_events(); ++ flush_sequence(); ++ ++ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"Text 2"); ++ sprintf(desc, "button[%i]: WM_SETTEXT on an invisible button", i); ++ ok_sequence(WmSetTextInvisibleSeq, desc, FALSE); ++ ++ ShowWindow(parent, SW_SHOW); ++ flush_events(); ++ + state = SendMessageA(hwnd, BM_GETCHECK, 0, 0); + if (button[i].style == BS_PUSHBUTTON || + button[i].style == BS_DEFPUSHBUTTON || +-- +2.7.1 + diff --git a/patches/user32-WM_CTLCOLORBTN/definition b/patches/user32-WM_CTLCOLORBTN/definition new file mode 100644 index 00000000..d77bf379 --- /dev/null +++ b/patches/user32-WM_CTLCOLORBTN/definition @@ -0,0 +1 @@ +Fixes: [25790] Replicate Windows behavior of WM_SETTEXT handler regarding WM_CTLCOLOR* messages