user32: Replicate Windows behavior of WM_SETTEXT handler regarding WM_CTLCOLOR* Fixes bug #25790

Alexander LAW exclusion at gmail.com
Sun Jan 30 03:31:26 CST 2011


---
 dlls/user32/button.c    |   49 +++++++++++++---------
 dlls/user32/tests/msg.c |  105 ++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 123 insertions(+), 31 deletions(-)

diff --git a/dlls/user32/button.c b/dlls/user32/button.c
index b15b36b..6266d13 100644
--- a/dlls/user32/button.c
+++ b/dlls/user32/button.c
@@ -384,26 +384,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 (style & WS_VISIBLE)
+        {
+            HDC hdc = GetDC(hWnd);
+            HBRUSH hbrush;
+            RECT client, rc;
+            HWND parent = GetParent(hWnd);
+            UINT ctlMessage=(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, ctlMessage,
+                                   (WPARAM)hdc, (LPARAM)hWnd);
+            if (!hbrush) /* did the app forget to call DefWindowProc ? */
+            hbrush = (HBRUSH)DefWindowProcW(parent, ctlMessage,
+                                     (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 );
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index ccb4e39..38ed92f 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -5320,6 +5320,61 @@ static const struct message WmSetCheckStaticSeq[] =
     { WM_APP, sent|wparam|lparam, 0, 0 },
     { 0 }
 };
+static const struct message WmSetTextButtonSeq[] =
+{
+    { WM_SETTEXT, sent },
+    { WM_CTLCOLORBTN, sent|parent},
+    { WM_CTLCOLORBTN, sent|parent},
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetTextStaticSeq[] =
+{
+    { WM_SETTEXT, sent },
+    { WM_CTLCOLORSTATIC, sent|parent},
+    { WM_CTLCOLORSTATIC, sent|parent},
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetTextGroupboxSeq[] =
+{
+    { WM_SETTEXT, sent },
+    { WM_CTLCOLORSTATIC, sent|parent},
+    { WM_CTLCOLORSTATIC, sent|parent|optional}, /*Windows sends it, Wine doesn't*/
+    { WM_CTLCOLORSTATIC, sent|parent|optional}, /*Windows sends it, Wine doesn't*/
+    { 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 WmSetTextUserSeq[] =
+{
+    { WM_SETTEXT, sent },
+    { WM_CTLCOLORBTN, sent|parent },
+    { WM_CTLCOLORBTN, sent|parent },
+    { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_PAINT) },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetTextOwnerdrawSeq[] =
+{
+    { WM_SETTEXT, sent },
+    { WM_CTLCOLORBTN, sent|parent},
+    { WM_CTLCOLORBTN, sent|parent},
+    { WM_DRAWITEM, sent|parent },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message WmSetTextInvisibleSeq[] =
+{
+    { WM_SETTEXT, sent },
+    { WM_APP, sent|wparam|lparam, 0, 0 },
+    { WM_PAINT, sent|parent },
+    { 0 }
+};
+
 
 static WNDPROC old_button_proc;
 
@@ -5384,40 +5439,53 @@ static void test_button_messages(void)
 	const struct message *setstate;
 	const struct message *clearstate;
 	const struct message *setcheck;
+	const struct message *settext;
+	const struct message *settextinvisible;
     } button[] = {
 	{ BS_PUSHBUTTON, DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON,
 	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq,
-          WmSetStateButtonSeq, WmSetStateButtonSeq, WmSetCheckIgnoredSeq },
+          WmSetStateButtonSeq, WmSetStateButtonSeq, WmSetCheckIgnoredSeq,
+          WmSetTextButtonSeq, WmSetTextInvisibleSeq },
 	{ BS_DEFPUSHBUTTON, DLGC_BUTTON | DLGC_DEFPUSHBUTTON,
 	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleButtonSeq,
-          WmSetStateButtonSeq, WmSetStateButtonSeq, WmSetCheckIgnoredSeq },
+          WmSetStateButtonSeq, WmSetStateButtonSeq, WmSetCheckIgnoredSeq,
+          WmSetTextButtonSeq, WmSetTextInvisibleSeq },
 	{ BS_CHECKBOX, DLGC_BUTTON,
 	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
-          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq,
+          WmSetTextStaticSeq, WmSetTextInvisibleSeq },
 	{ BS_AUTOCHECKBOX, DLGC_BUTTON,
 	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
-          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq,
+          WmSetTextStaticSeq, WmSetTextInvisibleSeq },
 	{ BS_RADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON,
 	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
-          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq,
+          WmSetTextStaticSeq, WmSetTextInvisibleSeq },
 	{ BS_3STATE, DLGC_BUTTON,
 	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
-          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq,
+          WmSetTextStaticSeq, WmSetTextInvisibleSeq },
 	{ BS_AUTO3STATE, DLGC_BUTTON,
 	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
-          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq,
+          WmSetTextStaticSeq, WmSetTextInvisibleSeq },
 	{ BS_GROUPBOX, DLGC_STATIC,
 	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
-          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckIgnoredSeq },
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckIgnoredSeq,
+          WmSetTextGroupboxSeq, WmSetTextInvisibleSeq },
 	{ BS_USERBUTTON, DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON,
 	  WmSetFocusButtonSeq, WmKillFocusButtonSeq, WmSetStyleUserSeq,
-          WmSetStateUserSeq, WmClearStateButtonSeq, WmSetCheckIgnoredSeq },
+          WmSetStateUserSeq, WmClearStateButtonSeq, WmSetCheckIgnoredSeq,
+          WmSetTextUserSeq, WmSetTextInvisibleSeq },
 	{ BS_AUTORADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON,
 	  WmSetFocusStaticSeq, WmKillFocusStaticSeq, WmSetStyleStaticSeq,
-          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq },
+          WmSetStateStaticSeq, WmSetStateStaticSeq, WmSetCheckStaticSeq,
+          WmSetTextStaticSeq, WmSetTextInvisibleSeq },
 	{ BS_OWNERDRAW, DLGC_BUTTON,
 	  WmSetFocusOwnerdrawSeq, WmKillFocusOwnerdrawSeq, WmSetStyleOwnerdrawSeq,
-          WmSetStateOwnerdrawSeq, WmClearStateOwnerdrawSeq, WmSetCheckIgnoredSeq },
+          WmSetStateOwnerdrawSeq, WmClearStateOwnerdrawSeq, WmSetCheckIgnoredSeq,
+          WmSetTextOwnerdrawSeq, WmSetTextInvisibleSeq },
     };
     unsigned int i;
     HWND hwnd, parent;
@@ -5568,6 +5636,21 @@ static void test_button_messages(void)
         else
             ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
 
+        flush_sequence();
+
+        SendMessage(hwnd, WM_SETTEXT, TRUE, (LPARAM)"caption");
+        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].settext, "SETTEXT on a button", FALSE);
+
+        ShowWindow(hwnd, SW_HIDE);
+        flush_sequence();
+
+        SendMessage(hwnd, WM_SETTEXT, TRUE, (LPARAM)"caption");
+        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].settextinvisible, "SETTEXT on an invisible button", FALSE);
+
         log_all_parent_messages--;
 
 	DestroyWindow(hwnd);
-- 
1.7.1


--------------030706070302090209050305--



More information about the wine-patches mailing list