user32: Add a rudimentary WM_SETFONT message test for the static control, make it pass under Wine. Take 2

Dmitry Timoshkov dmitry at codeweavers.com
Tue Nov 21 05:45:07 CST 2006


Hello,

this is another version of the patch which addresses Alexandre's concerns.

This patch fixes a regression in one of applications I'm working on caused
by the following commit:

http://www.winehq.com/pipermail/wine-cvs/2006-January/020362.html

Changelog:
    user32: Add a rudimentary WM_SETFONT message test for the static
    control, make it pass under Wine.

---
 dlls/user32/static.c    |   37 +++++++++++++------
 dlls/user32/tests/msg.c |   93 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+), 12 deletions(-)

diff --git a/dlls/user32/static.c b/dlls/user32/static.c
index b70754a..1e6c1d9 100644
--- a/dlls/user32/static.c
+++ b/dlls/user32/static.c
@@ -323,13 +323,17 @@ static VOID STATIC_TryPaintFcn(HWND hwnd
 
 static HBRUSH STATIC_SendWmCtlColorStatic(HWND hwnd, HDC hdc)
 {
-    HBRUSH hBrush = (HBRUSH) SendMessageW( GetParent(hwnd),
+    HBRUSH hBrush;
+    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 ? */
     {
         /* FIXME: DefWindowProc should return different colors if a
                   manifest is present */
-        hBrush = (HBRUSH)DefWindowProcW(GetParent(hwnd), WM_CTLCOLORSTATIC,
+        hBrush = (HBRUSH)DefWindowProcW( parent, WM_CTLCOLORSTATIC,
                                         (WPARAM)hdc, (LPARAM)hwnd);
     }
     return hBrush;
@@ -399,6 +403,10 @@ static LRESULT StaticWndProc_common( HWN
         else return unicode ? DefWindowProcW(hwnd, uMsg, wParam, lParam) :
                               DefWindowProcA(hwnd, uMsg, wParam, lParam);
 
+    case WM_ERASEBKGND:
+        /* do all painting in WM_PAINT like Windows does */
+        return 1;
+
     case WM_PRINTCLIENT:
     case WM_PAINT:
         {
@@ -496,7 +504,7 @@ static LRESULT StaticWndProc_common( HWN
         {
             SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, wParam );
             if (LOWORD(lParam))
-                STATIC_TryPaintFcn( hwnd, full_style );
+                RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
         }
         break;
 
@@ -612,7 +620,7 @@ static void STATIC_PaintTextfn( HWND hwn
     HBRUSH hBrush;
     HFONT hFont, hOldFont = NULL;
     WORD wFormat;
-    INT len;
+    INT len, buf_size;
     WCHAR *text;
 
     GetClientRect( hwnd, &rc);
@@ -645,7 +653,7 @@ static void STATIC_PaintTextfn( HWND hwn
 
     if (style & SS_NOPREFIX)
         wFormat |= DT_NOPREFIX;
-    
+
     if ((style & SS_TYPEMASK) != SS_SIMPLE)
     {
         if (style & SS_CENTERIMAGE)
@@ -666,17 +674,22 @@ static void STATIC_PaintTextfn( HWND hwn
     /* SS_SIMPLE controls: WM_CTLCOLORSTATIC is sent, but the returned
                            brush is not used */
     hBrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
-    
+
     if ((style & SS_TYPEMASK) != SS_SIMPLE)
     {
         FillRect( hdc, &rc, hBrush );
         if (!IsWindowEnabled(hwnd)) SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
     }
 
-    if (!(len = SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 ))) return;
-    if (!(text = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return;
-    SendMessageW( hwnd, WM_GETTEXT, len + 1, (LPARAM)text );
-    
+    buf_size = 256;
+    if (!(text = HeapAlloc( GetProcessHeap(), 0, buf_size * sizeof(WCHAR) ))) return;
+
+    while ((len = InternalGetWindowText( hwnd, text, buf_size )) == buf_size - 1)
+    {
+        buf_size *= 2;
+        if (!(text = HeapReAlloc( GetProcessHeap(), 0, text, buf_size * sizeof(WCHAR) ))) return;
+    }
+
     if (((style & SS_TYPEMASK) == SS_SIMPLE) && (style & SS_NOPREFIX))
     {
         /* Windows uses the faster ExtTextOut() to draw the text and
@@ -689,9 +702,9 @@ static void STATIC_PaintTextfn( HWND hwn
     {
         DrawTextW( hdc, text, -1, &rc, wFormat );
     }
-    
+
     HeapFree( GetProcessHeap(), 0, text );
-    
+
     if (hFont)
         SelectObject( hdc, hOldFont );
 }
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 3ddb878..697bd25 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -4212,6 +4212,98 @@ static void test_button_messages(void)
     DestroyWindow(hwnd);
 }
 
+/****************** static message test *************************/
+static const struct message WmSetFontStaticSeq[] =
+{
+    { WM_SETFONT, sent },
+    { WM_PAINT, sent|defwinproc },
+    { WM_ERASEBKGND, sent|defwinproc },
+    { WM_CTLCOLORSTATIC, sent|defwinproc },
+    { 0 }
+};
+
+static WNDPROC old_static_proc;
+
+static LRESULT CALLBACK static_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    static long defwndproc_counter = 0;
+    LRESULT ret;
+    struct message msg;
+
+    trace("static: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
+
+    /* explicitly ignore WM_GETICON message */
+    if (message == WM_GETICON) return 0;
+
+    msg.message = message;
+    msg.flags = sent|wparam|lparam;
+    if (defwndproc_counter) msg.flags |= defwinproc;
+    msg.wParam = wParam;
+    msg.lParam = lParam;
+    add_message(&msg);
+
+
+    defwndproc_counter++;
+    ret = CallWindowProcA(old_static_proc, hwnd, message, wParam, lParam);
+    defwndproc_counter--;
+
+    return ret;
+}
+
+static void subclass_static(void)
+{
+    WNDCLASSA cls;
+
+    if (!GetClassInfoA(0, "static", &cls)) assert(0);
+
+    old_static_proc = cls.lpfnWndProc;
+
+    cls.hInstance = GetModuleHandle(0);
+    cls.lpfnWndProc = static_hook_proc;
+    cls.lpszClassName = "my_static_class";
+    if (!RegisterClassA(&cls)) assert(0);
+}
+
+static void test_static_messages(void)
+{
+    /* FIXME: make as comprehensive as the button message test */
+    static const struct
+    {
+	DWORD style;
+	DWORD dlg_code;
+	const struct message *setfont;
+    } static_ctrl[] = {
+	{ SS_LEFT, DLGC_STATIC,
+	  WmSetFontStaticSeq }
+    };
+    unsigned int i;
+    HWND hwnd;
+    DWORD dlg_code;
+
+    subclass_static();
+
+    for (i = 0; i < sizeof(static_ctrl)/sizeof(static_ctrl[0]); i++)
+    {
+	hwnd = CreateWindowExA(0, "my_static_class", "test", static_ctrl[i].style | WS_POPUP,
+			       0, 0, 50, 14, 0, 0, 0, NULL);
+	ok(hwnd != 0, "Failed to create static window\n");
+
+	dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
+	ok(dlg_code == static_ctrl[i].dlg_code, "%u: wrong dlg_code %08x\n", i, dlg_code);
+
+	ShowWindow(hwnd, SW_SHOW);
+	UpdateWindow(hwnd);
+	SetFocus(0);
+	flush_sequence();
+
+	trace("static style %08x\n", static_ctrl[i].style);
+	SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
+	ok_sequence(static_ctrl[i].setfont, "WM_SETFONT on a static", FALSE);
+
+	DestroyWindow(hwnd);
+    }
+}
+
 /************* painting message test ********************/
 
 void dump_region(HRGN hrgn)
@@ -8132,6 +8224,7 @@ #endif
     invisible_parent_tests();
     test_mdi_messages();
     test_button_messages();
+    test_static_messages();
     test_paint_messages();
     test_interthread_messages();
     test_message_conversion();
-- 
1.4.2






More information about the wine-patches mailing list