Added patch to move the auto radio button group logic from BM_SETCHECK to WM_LBUTTONUP handler.

This commit is contained in:
Sebastian Lackner 2016-12-19 23:14:53 +01:00
parent 72d96cb61f
commit 4a70aa313d
4 changed files with 231 additions and 0 deletions

View File

@ -319,6 +319,7 @@ patch_enable_all ()
enable_taskmgr_Memory_Usage="$1"
enable_user_exe16_CONTAINING_RECORD="$1"
enable_user_exe16_DlgDirList="$1"
enable_user32_Auto_Radio_Button="$1"
enable_user32_Combobox_WM_SIZE="$1"
enable_user32_DM_SETDEFID="$1"
enable_user32_DeferWindowPos="$1"
@ -1136,6 +1137,9 @@ patch_enable ()
user.exe16-DlgDirList)
enable_user_exe16_DlgDirList="$2"
;;
user32-Auto_Radio_Button)
enable_user32_Auto_Radio_Button="$2"
;;
user32-Combobox_WM_SIZE)
enable_user32_Combobox_WM_SIZE="$2"
;;
@ -6723,6 +6727,23 @@ if test "$enable_user_exe16_DlgDirList" -eq 1; then
) >> "$patchlist"
fi
# Patchset user32-Auto_Radio_Button
# |
# | This patchset fixes the following Wine bugs:
# | * [#42010] Move the auto radio button group logic from BM_SETCHECK to WM_LBUTTONUP handler
# |
# | Modified files:
# | * dlls/user32/button.c, dlls/user32/tests/msg.c
# |
if test "$enable_user32_Auto_Radio_Button" -eq 1; then
patch_apply user32-Auto_Radio_Button/0001-user32-Move-the-auto-radio-button-group-logic-from-B.patch
patch_apply user32-Auto_Radio_Button/0002-user32-tests-Add-a-message-test-for-group-of-radio-b.patch
(
echo '+ { "Dmitry Timoshkov", "user32: Move the auto radio button group logic from BM_SETCHECK to WM_LBUTTONUP handler.", 1 },';
echo '+ { "Dmitry Timoshkov", "user32/tests: Add a message test for group of radio buttons.", 1 },';
) >> "$patchlist"
fi
# Patchset user32-Combobox_WM_SIZE
# |
# | This patchset fixes the following Wine bugs:

View File

@ -0,0 +1,54 @@
From f2f3dfcd09e64bd0a3af1db277884e6dd59a5368 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Mon, 19 Dec 2016 22:25:46 +0800
Subject: user32: Move the auto radio button group logic from BM_SETCHECK to
WM_LBUTTONUP handler.
This patch also changes the logic to get the control style with WM_GETDLGCODE
instead of GetWindowLong to make the message test pass.
---
dlls/user32/button.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/dlls/user32/button.c b/dlls/user32/button.c
index e85e30d..98d8289 100644
--- a/dlls/user32/button.c
+++ b/dlls/user32/button.c
@@ -334,7 +334,7 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
SendMessageW( hWnd, BM_SETCHECK, !(state & BST_CHECKED), 0 );
break;
case BS_AUTORADIOBUTTON:
- SendMessageW( hWnd, BM_SETCHECK, TRUE, 0 );
+ BUTTON_CheckAutoRadioButton( hWnd );
break;
case BS_AUTO3STATE:
SendMessageW( hWnd, BM_SETCHECK,
@@ -497,8 +497,6 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
set_button_state( hWnd, (state & ~3) | wParam );
paint_button( hWnd, btn_type, ODA_SELECT );
}
- if ((btn_type == BS_AUTORADIOBUTTON) && (wParam == BST_CHECKED) && (style & WS_CHILD))
- BUTTON_CheckAutoRadioButton( hWnd );
break;
case BM_GETSTATE:
@@ -976,13 +974,12 @@ static void BUTTON_CheckAutoRadioButton( HWND hwnd )
parent = GetParent(hwnd);
/* make sure that starting control is not disabled or invisible */
- start = sibling = GetNextDlgGroupItem( parent, hwnd, TRUE );
+ start = sibling = hwnd;
do
{
if (!sibling) break;
- if ((hwnd != sibling) &&
- ((GetWindowLongW( sibling, GWL_STYLE) & BS_TYPEMASK) == BS_AUTORADIOBUTTON))
- SendMessageW( sibling, BM_SETCHECK, BST_UNCHECKED, 0 );
+ if (SendMessageW( sibling, WM_GETDLGCODE, 0, 0 ) == (DLGC_BUTTON | DLGC_RADIOBUTTON))
+ SendMessageW( sibling, BM_SETCHECK, sibling == hwnd ? BST_CHECKED : BST_UNCHECKED, 0 );
sibling = GetNextDlgGroupItem( parent, sibling, FALSE );
} while (sibling != start);
}
--
2.9.0

View File

@ -0,0 +1,155 @@
From c7e306f0584aec0d9415ca2e8937d023c099d911 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Mon, 19 Dec 2016 22:29:35 +0800
Subject: user32/tests: Add a message test for group of radio buttons.
---
dlls/user32/tests/msg.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 125 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 45b5222..c217550 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -6009,6 +6009,130 @@ static void test_button_messages(void)
DestroyWindow(parent);
}
+#define ID_RADIO1 0x00e1
+#define ID_RADIO2 0x00e2
+
+static const struct message auto_radio_button_WM_CLICK[] =
+{
+ { BM_CLICK, sent|wparam|lparam, 0, 0 },
+ { WM_LBUTTONDOWN, sent|wparam|lparam|defwinproc, 0, 0 },
+ { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
+ { BM_SETSTATE, sent|wparam|lparam|defwinproc, BST_CHECKED, 0 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_LBUTTONUP, sent|wparam|lparam|defwinproc, 0, 0 },
+ { BM_SETSTATE, sent|wparam|lparam|defwinproc, BST_UNCHECKED, 0 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, 0, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, BST_CHECKED, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, 0, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, 0, 0 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, 0, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, 0, 0 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, 0, 0 },
+ { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_CAPTURECHANGED, sent|wparam|lparam|defwinproc, 0, 0 },
+ { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_RADIO2, BN_CLICKED) },
+ { WM_NCHITTEST, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
+ { WM_SETCURSOR, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
+ { WM_MOUSEMOVE, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
+ { 0 }
+};
+
+static void test_autoradio_messages(void)
+{
+ HWND parent, radio1, radio2, radio3, child;
+ RECT rc;
+ MSG msg;
+ DWORD ret;
+
+ subclass_button();
+
+ parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok(parent != 0, "failed to create parent window\n");
+ radio1 = CreateWindowExA(0, "my_button_class", "radio1", WS_VISIBLE | WS_CHILD | WS_GROUP | BS_AUTORADIOBUTTON | BS_NOTIFY,
+ 0, 0, 70, 18, parent, (HMENU)ID_RADIO1, 0, NULL);
+ ok(radio1 != 0, "failed to create child window\n");
+ radio3 = CreateWindowExA(0, "my_button_class", "radio3", WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON | BS_NOTIFY,
+ 0, 25, 70, 18, parent, (HMENU)-1, 0, NULL);
+ ok(radio3 != 0, "failed to create child window\n");
+ child = CreateWindowExA(0, "my_button_class", "text", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_NOTIFY,
+ 0, 50, 70, 18, parent, (HMENU)-1, 0, NULL);
+ ok(child != 0, "failed to create child window\n");
+ radio2 = CreateWindowExA(0, "my_button_class", "radio2", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_NOTIFY,
+ 0, 75, 70, 18, parent, (HMENU)ID_RADIO2, 0, NULL);
+ ok(radio2 != 0, "failed to create child window\n");
+
+ /* this avoids focus messages in the generated sequence */
+ SetFocus(radio2);
+
+ flush_events();
+ flush_sequence();
+
+ ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
+ ok(ret == BST_UNCHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
+ ok(ret == BST_UNCHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
+ ok(ret == BST_UNCHECKED, "got %08x\n", ret);
+
+ SendMessageA(radio1, BM_SETCHECK, BST_CHECKED, 0);
+
+ ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
+ ok(ret == BST_CHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
+ ok(ret == BST_UNCHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
+ ok(ret == BST_UNCHECKED, "got %08x\n", ret);
+
+ SendMessageA(radio2, BM_SETCHECK, BST_CHECKED, 0);
+
+ ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
+ ok(ret == BST_CHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
+ ok(ret == BST_CHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
+ ok(ret == BST_UNCHECKED, "got %08x\n", ret);
+
+ SendMessageA(radio3, BM_SETCHECK, BST_CHECKED, 0);
+
+ ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
+ ok(ret == BST_CHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
+ ok(ret == BST_CHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
+ ok(ret == BST_CHECKED, "got %08x\n", ret);
+
+ GetWindowRect(radio2, &rc);
+ SetCursorPos(rc.left+1, rc.top+1);
+
+ flush_events();
+ flush_sequence();
+
+ log_all_parent_messages++;
+
+ SendMessageA(radio2, BM_CLICK, 0, 0);
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(auto_radio_button_WM_CLICK, "BM_CLICK on auto-radio button", FALSE);
+
+ log_all_parent_messages--;
+
+ ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
+ ok(ret == BST_UNCHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
+ ok(ret == BST_CHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
+ ok(ret == BST_UNCHECKED, "got %08x\n", ret);
+
+ DestroyWindow(parent);
+}
+
/****************** static message test *************************/
static const struct message WmSetFontStaticSeq2[] =
{
@@ -16075,6 +16199,7 @@ START_TEST(msg)
invisible_parent_tests();
test_mdi_messages();
test_button_messages();
+ test_autoradio_messages();
test_static_messages();
test_listbox_messages();
test_combobox_messages();
--
2.9.0

View File

@ -0,0 +1 @@
Fixes: [42010] Move the auto radio button group logic from BM_SETCHECK to WM_LBUTTONUP handler