user32: Add BM_SETSTATE/BM_SETCHECK message tests for a button, make them pass under Wine.

Dmitry Timoshkov dmitry at codeweavers.com
Wed Apr 21 06:29:55 CDT 2010


---
 dlls/user32/button.c    |   29 +++++---
 dlls/user32/tests/msg.c |  178 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 180 insertions(+), 27 deletions(-)

diff --git a/dlls/user32/button.c b/dlls/user32/button.c
index 0aefe1b..8066e9e 100644
--- a/dlls/user32/button.c
+++ b/dlls/user32/button.c
@@ -503,9 +503,8 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
         state = get_button_state( hWnd );
         if ((btn_type == BS_RADIOBUTTON) || (btn_type == BS_AUTORADIOBUTTON))
         {
-            if (wParam) style |= WS_TABSTOP;
-            else style &= ~WS_TABSTOP;
-            SetWindowLongW( hWnd, GWL_STYLE, style );
+            if (wParam) WIN_SetStyle( hWnd, WS_TABSTOP, 0 );
+            else WIN_SetStyle( hWnd, 0, WS_TABSTOP );
         }
         if ((state & 3) != wParam)
         {
@@ -522,15 +521,10 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
     case BM_SETSTATE:
         state = get_button_state( hWnd );
         if (wParam)
-        {
-            if (state & BUTTON_HIGHLIGHTED) break;
             set_button_state( hWnd, state | BUTTON_HIGHLIGHTED );
-        }
         else
-        {
-            if (!(state & BUTTON_HIGHLIGHTED)) break;
             set_button_state( hWnd, state & ~BUTTON_HIGHLIGHTED );
-        }
+
         paint_button( hWnd, btn_type, ODA_SELECT );
         break;
 
@@ -1066,8 +1060,6 @@ static void UB_Paint( HWND hwnd, HDC hDC, UINT action )
     LONG state = get_button_state( hwnd );
     HWND parent;
 
-    if (action == ODA_SELECT) return;
-
     GetClientRect( hwnd, &rc);
 
     if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont );
@@ -1084,7 +1076,20 @@ static void UB_Paint( HWND hwnd, HDC hDC, UINT action )
         ((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS)))
         DrawFocusRect( hDC, &rc );
 
-    BUTTON_NOTIFY_PARENT( hwnd, BN_PAINT );
+    switch (action)
+    {
+    case ODA_FOCUS:
+        BUTTON_NOTIFY_PARENT( hwnd, (state & BUTTON_HASFOCUS) ? BN_SETFOCUS : BN_KILLFOCUS );
+        break;
+
+    case ODA_SELECT:
+        BUTTON_NOTIFY_PARENT( hwnd, (state & BUTTON_HIGHLIGHTED) ? BN_HILITE : BN_UNHILITE );
+        break;
+
+    default:
+        BUTTON_NOTIFY_PARENT( hwnd, BN_PAINT );
+        break;
+    }
 }
 
 
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 714e57f..087b6c6 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -20,7 +20,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#define _WIN32_WINNT 0x0501 /* For WM_CHANGEUISTATE,QS_RAWINPUT */
+#define _WIN32_WINNT 0x0600 /* For WM_CHANGEUISTATE,QS_RAWINPUT,WM_DWMxxxx */
+#define WINVER 0x0600 /* for WM_GETTITLEBARINFOEX */
 
 #include <assert.h>
 #include <stdarg.h>
@@ -5256,6 +5257,65 @@ static const struct message WmSetStyleOwnerdrawSeq[] =
     { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000010e4 },
     { 0 }
 };
+static const struct message WmSetStateButtonSeq[] =
+{
+    { BM_SETSTATE, sent },
+    { WM_CTLCOLORBTN, sent|parent },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetStateStaticSeq[] =
+{
+    { BM_SETSTATE, sent },
+    { WM_CTLCOLORSTATIC, sent|parent },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetStateUserSeq[] =
+{
+    { BM_SETSTATE, sent },
+    { WM_CTLCOLORBTN, sent|parent },
+    { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_HILITE) },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetStateOwnerdrawSeq[] =
+{
+    { BM_SETSTATE, sent },
+    { WM_CTLCOLORBTN, sent|parent },
+    { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000120e4 },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmClearStateButtonSeq[] =
+{
+    { BM_SETSTATE, sent },
+    { WM_CTLCOLORBTN, sent|parent },
+    { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_UNHILITE) },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmClearStateOwnerdrawSeq[] =
+{
+    { BM_SETSTATE, sent },
+    { WM_CTLCOLORBTN, sent|parent },
+    { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000020e4 },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetCheckIgnoredSeq[] =
+{
+    { BM_SETCHECK, sent },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetCheckStaticSeq[] =
+{
+    { BM_SETCHECK, sent },
+    { WM_CTLCOLORSTATIC, sent|parent },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
 
 static WNDPROC old_button_proc;
 
@@ -5272,7 +5332,8 @@ static LRESULT CALLBACK button_hook_proc(HWND hwnd, UINT message, WPARAM wParam,
     case WM_SYNCPAINT:
         break;
     case BM_SETSTATE:
-	ok(GetCapture() == hwnd, "GetCapture() = %p\n", GetCapture());
+        if (GetCapture())
+            ok(GetCapture() == hwnd, "GetCapture() = %p\n", GetCapture());
         /* fall through */
     default:
         msg.hwnd = hwnd;
@@ -5316,29 +5377,43 @@ static void test_button_messages(void)
 	const struct message *setfocus;
 	const struct message *killfocus;
 	const struct message *setstyle;
+	const struct message *setstate;
+	const struct message *clearstate;
+	const struct message *setcheck;
     } button[] = {
 	{ BS_PUSHBUTTON, DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON,
-	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq },
+	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq,
+          WmSetStateButtonSeq, WmSetStateButtonSeq, WmSetCheckIgnoredSeq },
 	{ BS_DEFPUSHBUTTON, DLGC_BUTTON | DLGC_DEFPUSHBUTTON,
-	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq },
+	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq,
+          WmSetStateButtonSeq, WmSetStateButtonSeq, WmSetCheckIgnoredSeq },
 	{ BS_CHECKBOX, DLGC_BUTTON,
-	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq },
+	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
 	{ BS_AUTOCHECKBOX, DLGC_BUTTON,
-	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq },
+	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
 	{ BS_RADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON,
-	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq },
+	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
 	{ BS_3STATE, DLGC_BUTTON,
-	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq },
+	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
 	{ BS_AUTO3STATE, DLGC_BUTTON,
-	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq },
+	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
 	{ BS_GROUPBOX, DLGC_STATIC,
-	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq },
+	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckIgnoredSeq },
 	{ BS_USERBUTTON, DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON,
-	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleUserSeq },
+	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleUserSeq,
+          WmSetStateUserSeq, WmClearStateButtonSeq, WmSetCheckIgnoredSeq },
 	{ BS_AUTORADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON,
-	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq },
+	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
 	{ BS_OWNERDRAW, DLGC_BUTTON,
-	  WmSetFocusOwnerdrawSeq, WmKillFocusOwnerdrawSeq, WmSetStyleOwnerdrawSeq }
+	  WmSetFocusOwnerdrawSeq, WmKillFocusOwnerdrawSeq, WmSetStyleOwnerdrawSeq,
+          WmSetStateOwnerdrawSeq, WmClearStateOwnerdrawSeq, WmSetCheckIgnoredSeq },
     };
     unsigned int i;
     HWND hwnd, parent;
@@ -5365,7 +5440,7 @@ static void test_button_messages(void)
     for (i = 0; i < sizeof(button)/sizeof(button[0]); i++)
     {
         MSG msg;
-        DWORD style;
+        DWORD style, state;
 
         trace("button style %08x\n", button[i].style);
 
@@ -5414,7 +5489,80 @@ static void test_button_messages(void)
         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);
+        ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
+
+        state = SendMessage(hwnd, BM_GETSTATE, 0, 0);
+        ok(state == 0, "expected state 0, got %04x\n", state);
+
+        flush_sequence();
+
+        SendMessage(hwnd, BM_SETSTATE, TRUE, 0);
+        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].setstate, "BM_SETSTATE/TRUE on a button", FALSE);
+
+        state = SendMessage(hwnd, BM_GETSTATE, 0, 0);
+        ok(state == 0x0004, "expected state 0x0004, got %04x\n", state);
+
+        style = GetWindowLongA(hwnd, GWL_STYLE);
+        style &= ~(WS_CHILD | BS_NOTIFY | WS_VISIBLE);
+        ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
+
+        flush_sequence();
+
+        SendMessage(hwnd, BM_SETSTATE, FALSE, 0);
+        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].clearstate, "BM_SETSTATE/FALSE on a button", FALSE);
+
+        state = SendMessage(hwnd, BM_GETSTATE, 0, 0);
+        ok(state == 0, "expected state 0, got %04x\n", state);
+
+        style = GetWindowLongA(hwnd, GWL_STYLE);
+        style &= ~(WS_CHILD | BS_NOTIFY | WS_VISIBLE);
+        ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
+
+        state = SendMessage(hwnd, BM_GETCHECK, 0, 0);
+        ok(state == BST_UNCHECKED, "expected BST_UNCHECKED, got %04x\n", state);
+
+        flush_sequence();
+
+        SendMessage(hwnd, BM_SETCHECK, BST_UNCHECKED, 0);
+        SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */
+        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+        ok_sequence(WmSetCheckIgnoredSeq, "BM_SETCHECK on a button", FALSE);
+
+        state = SendMessage(hwnd, BM_GETCHECK, 0, 0);
+        ok(state == BST_UNCHECKED, "expected BST_UNCHECKED, got %04x\n", state);
+
+        style = GetWindowLongA(hwnd, GWL_STYLE);
+        style &= ~(WS_CHILD | BS_NOTIFY | WS_VISIBLE);
+        ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
+
+        flush_sequence();
+
+        SendMessage(hwnd, BM_SETCHECK, BST_CHECKED, 0);
+        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].setcheck, "BM_SETCHECK on a button", FALSE);
+
+        state = SendMessage(hwnd, BM_GETCHECK, 0, 0);
+        if (button[i].style == BS_PUSHBUTTON ||
+            button[i].style == BS_DEFPUSHBUTTON ||
+            button[i].style == BS_GROUPBOX ||
+            button[i].style == BS_USERBUTTON ||
+            button[i].style == BS_OWNERDRAW)
+            ok(state == BST_UNCHECKED, "expected check 0, got %04x\n", state);
+        else
+            ok(state == BST_CHECKED, "expected check 1, got %04x\n", state);
+
+        style = GetWindowLongA(hwnd, GWL_STYLE);
+        style &= ~(WS_CHILD | BS_NOTIFY | WS_VISIBLE);
+        if (button[i].style == BS_RADIOBUTTON ||
+            button[i].style == BS_AUTORADIOBUTTON)
+            ok(style == (button[i].style | WS_TABSTOP), "expected style %04x | WS_TABSTOP got %04x\n", button[i].style, style);
+        else
+            ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
 
         log_all_parent_messages--;
 
-- 
1.7.0.2




More information about the wine-patches mailing list