Resend (2): Status bar fixes

Michael Kaufmann hallo at michael-kaufmann.ch
Wed Sep 7 06:41:17 CDT 2005


I've fixed some typos in the patch. It's against the current CVS.
Please notify me if there's something wrong with it.

Changelog:
- Redraw immediately upon WM_SETTEXT, WM_SETFONT, SB_SETTEXT, SB_SETICON
- SB_GETRECT: Return FALSE for simple status bars, check the part number
- SB_SETICON: Didn't work for simple status bars (-1 has been casted to 255)
- SB_SETTEXT: Don't redraw normal status bars if the simple text has 
been set and vice versa
- New tests
-------------- next part --------------
Index: dlls/comctl32/status.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/status.c,v
retrieving revision 1.75
diff -u -r1.75 status.c
--- dlls/comctl32/status.c	30 Aug 2005 10:07:17 -0000	1.75
+++ dlls/comctl32/status.c	7 Sep 2005 11:08:29 -0000
@@ -38,6 +38,7 @@
  * 	-- CCS_RIGHT
  * 	-- CCS_TOP
  * 	-- CCS_VERT (defaults to RIGHT)
+ * 	-- WM_SETFONT: Adjust the control size (undocumented)
  */
 
 #include <stdarg.h>
@@ -403,9 +404,10 @@
 STATUSBAR_GetIcon (STATUS_INFO *infoPtr, INT nPart)
 {
     TRACE("%d\n", nPart);
+    
     /* MSDN says: "simple parts are indexed with -1" */
     if ((nPart < -1) || (nPart >= infoPtr->numParts))
-	return 0;
+        return 0;
 
     if (nPart == -1)
         return (infoPtr->part0.hIcon);
@@ -434,9 +436,12 @@
 {
     TRACE("part %d\n", nPart);
     if (infoPtr->simple)
-	*rect = infoPtr->part0.bound;
-    else
+        return FALSE;
+    else {
+        if ((nPart < 0) || (nPart >= infoPtr->numParts))
+            return FALSE;
 	*rect = infoPtr->parts[nPart].bound;
+    }
     return TRUE;
 }
 
@@ -588,20 +593,26 @@
 
     TRACE("setting part %d\n", nPart);
 
-    /* FIXME: MSDN says "if nPart is -1, the status bar is assumed simple" */
+    /* MSDN says "if nPart is -1, the status bar is assumed simple".
+       This means that if the status bar is not simple, the icon
+       is saved in case the status bar type is changed later */
     if (nPart == -1) {
-	if (infoPtr->part0.hIcon == hIcon) /* same as - no redraw */
+	if (infoPtr->part0.hIcon == hIcon) /* same as before - no redraw */
 	    return TRUE;
 	infoPtr->part0.hIcon = hIcon;
-	if (infoPtr->simple)
+	if (infoPtr->simple) {
             InvalidateRect(infoPtr->Self, &infoPtr->part0.bound, FALSE);
+            UpdateWindow(infoPtr->Self);
+        }
     } else {
-	if (infoPtr->parts[nPart].hIcon == hIcon) /* same as - no redraw */
+	if (infoPtr->parts[nPart].hIcon == hIcon) /* same as before - no redraw */
 	    return TRUE;
 
 	infoPtr->parts[nPart].hIcon = hIcon;
-	if (!(infoPtr->simple))
+	if (!(infoPtr->simple)) {
             InvalidateRect(infoPtr->Self, &infoPtr->parts[nPart].bound, FALSE);
+            UpdateWindow(infoPtr->Self);
+        }
     }
     return TRUE;
 }
@@ -734,7 +745,7 @@
     /* MSDN says: "If the parameter is set to SB_SIMPLEID (255), the status
      * window is assumed to be a simple window */
 
-    if (nPart == 0x00ff) {
+    if (nPart == SB_SIMPLEID) {
 	part = &infoPtr->part0;
     } else {
 	if (infoPtr->parts && nPart >= 0 && nPart < infoPtr->numParts) {
@@ -785,7 +796,13 @@
 	    Free (part->text);
 	part->text = ntext;
     }
-    InvalidateRect(infoPtr->Self, &part->bound, FALSE);
+    
+    /* Don't redraw normal status bars if the simple text
+       was changed and vice versa */
+    if ((nPart == SB_SIMPLEID) == (infoPtr->simple)) {
+        InvalidateRect(infoPtr->Self, &part->bound, FALSE);
+        UpdateWindow(infoPtr->Self);
+    }
 
     return TRUE;
 }
@@ -1116,8 +1133,10 @@
 {
     infoPtr->hFont = font;
     TRACE("%p\n", infoPtr->hFont);
-    if (redraw)
+    if (redraw) {
         InvalidateRect(infoPtr->Self, NULL, FALSE);
+        UpdateWindow(infoPtr->Self);
+    }
 
     return 0;
 }
@@ -1155,6 +1174,7 @@
     }
 
     InvalidateRect(infoPtr->Self, &part->bound, FALSE);
+    UpdateWindow(infoPtr->Self);
 
     return TRUE;
 }
@@ -1229,9 +1249,13 @@
 StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     STATUS_INFO *infoPtr = (STATUS_INFO *)GetWindowLongPtrW (hwnd, 0);
-    INT nPart = ((INT) wParam) & 0x00ff;
     LRESULT res;
 
+    /* Some messages expect styles in the high word of wParam.
+       Messages that don't expect styles use "-1" as the part number for simple
+       status bars. Messages that expect styles use SB_SIMPLEID which is 0x00ff.
+     */
+
     TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
     if (!infoPtr && msg != WM_CREATE)
         return DefWindowProcW (hwnd, msg, wParam, lParam);
@@ -1241,23 +1265,23 @@
 	    return STATUSBAR_GetBorders (infoPtr, (INT *)lParam);
 
 	case SB_GETICON:
-	    return (LRESULT)STATUSBAR_GetIcon (infoPtr, nPart);
+	    return (LRESULT)STATUSBAR_GetIcon (infoPtr, (INT)wParam);
 
 	case SB_GETPARTS:
 	    return STATUSBAR_GetParts (infoPtr, (INT)wParam, (INT *)lParam);
 
 	case SB_GETRECT:
-	    return STATUSBAR_GetRect (infoPtr, nPart, (LPRECT)lParam);
+	    return STATUSBAR_GetRect (infoPtr, (INT)wParam, (LPRECT)lParam);
 
 	case SB_GETTEXTA:
-	    return STATUSBAR_GetTextA (infoPtr, nPart, (LPSTR)lParam);
+	    return STATUSBAR_GetTextA (infoPtr, (INT)wParam, (LPSTR)lParam);
 
 	case SB_GETTEXTW:
-	    return STATUSBAR_GetTextW (infoPtr, nPart, (LPWSTR)lParam);
+	    return STATUSBAR_GetTextW (infoPtr, (INT)wParam, (LPWSTR)lParam);
 
 	case SB_GETTEXTLENGTHA:
 	case SB_GETTEXTLENGTHW:
-	    return STATUSBAR_GetTextLength (infoPtr, nPart);
+	    return STATUSBAR_GetTextLength (infoPtr, (INT)wParam);
 
 	case SB_GETTIPTEXTA:
 	    return STATUSBAR_GetTipTextA (infoPtr,  LOWORD(wParam), (LPSTR)lParam,  HIWORD(wParam));
@@ -1278,7 +1302,7 @@
 	    return STATUSBAR_SetBkColor (infoPtr, (COLORREF)lParam);
 
 	case SB_SETICON:
-	    return STATUSBAR_SetIcon (infoPtr, nPart, (HICON)lParam);
+	    return STATUSBAR_SetIcon (infoPtr, (INT)wParam, (HICON)lParam);
 
 	case SB_SETMINHEIGHT:
 	    return STATUSBAR_SetMinHeight (infoPtr, (INT)wParam);
@@ -1287,10 +1311,10 @@
 	    return STATUSBAR_SetParts (infoPtr, (INT)wParam, (LPINT)lParam);
 
 	case SB_SETTEXTA:
-	    return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPCWSTR)lParam, FALSE);
+	    return STATUSBAR_SetTextT (infoPtr, (INT)((INT)wParam & 0x00ff), wParam & 0xff00, (LPCWSTR)lParam, FALSE);
 
 	case SB_SETTEXTW:
-	    return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPCWSTR)lParam, TRUE);
+	    return STATUSBAR_SetTextT (infoPtr, (INT)((INT)wParam & 0x00ff), wParam & 0xff00, (LPCWSTR)lParam, TRUE);
 
 	case SB_SETTIPTEXTA:
 	    return STATUSBAR_SetTipTextA (infoPtr, (INT)wParam, (LPSTR)lParam);
Index: dlls/comctl32/tests/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/tests/Makefile.in,v
retrieving revision 1.10
diff -u -r1.10 Makefile.in
--- dlls/comctl32/tests/Makefile.in	27 Aug 2005 09:27:10 -0000	1.10
+++ dlls/comctl32/tests/Makefile.in	7 Sep 2005 11:08:29 -0000
@@ -10,6 +10,7 @@
 	imagelist.c \
 	mru.c \
 	progress.c \
+	status.c \
 	subclass.c \
 	tab.c \
 	treeview.c \
--- /dev/null	2005-09-07 15:00:23.611875680 +0200
+++ dlls/comctl32/tests/status.c	2005-09-07 13:06:42.059369368 +0200
@@ -0,0 +1,375 @@
+/* Unit tests for the status bar control.
+ *
+ * Copyright 2005 Michael Kaufmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "commctrl.h" 
+
+#include "wine/test.h"
+
+
+static HWND hStatusParentWnd, hStatusWnd;
+static char empty_status_text[] = "";
+static char first_status_text[] = "First Status Text";
+static char second_status_text[] = "Second Status Text";
+static char statusTestClass[] = "StatusBarTestClass";
+
+
+LRESULT CALLBACK StatusTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    switch(msg) {
+    
+    case WM_DESTROY:
+        PostQuitMessage(0);
+        break;
+  
+    default:
+        return DefWindowProcA(hWnd, msg, wParam, lParam);
+    }
+    
+    return 0L;
+}
+
+
+static void update_window(HWND hWnd)
+{
+    UpdateWindow(hWnd);
+    ok(!GetUpdateRect(hWnd, NULL, FALSE), "GetUpdateRect must return zero after UpdateWindow\n");    
+}
+
+
+static void init(void)
+{
+    WNDCLASSA wc;
+    INITCOMMONCONTROLSEX icex;
+    RECT rect;
+    
+    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    icex.dwICC   = ICC_BAR_CLASSES;
+    InitCommonControlsEx(&icex);
+  
+    wc.style = CS_HREDRAW | CS_VREDRAW;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = GetModuleHandleA(NULL);
+    wc.hIcon = NULL;
+    wc.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW));
+    wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
+    wc.lpszMenuName = NULL;
+    wc.lpszClassName = statusTestClass;
+    wc.lpfnWndProc = StatusTestWndProc;
+    RegisterClassA(&wc);
+    
+    rect.left = 0;
+    rect.top = 0;
+    rect.right = 300;
+    rect.bottom = 200;
+    assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE));
+    
+    hStatusParentWnd = CreateWindowExA(0, statusTestClass, "Status Bar Test", WS_OVERLAPPEDWINDOW,
+      CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, GetModuleHandleA(NULL), 0);
+    assert(hStatusParentWnd != NULL);
+    
+    hStatusWnd = CreateWindowEx(0, STATUSCLASSNAME, "", WS_CHILD | WS_VISIBLE,
+      0, 0, 0, 0, hStatusParentWnd, NULL, GetModuleHandleA(NULL), 0);
+    assert(hStatusWnd != NULL);
+      
+    ShowWindow(hStatusParentWnd, SW_SHOWNORMAL);
+    ok(GetUpdateRect(hStatusParentWnd, NULL, FALSE), "GetUpdateRect: There should be a region that needs to be updated\n");
+    update_window(hStatusParentWnd);
+}
+
+
+static void cleanup(void)
+{
+    MSG msg;
+    
+    PostMessageA(hStatusParentWnd, WM_CLOSE, 0, 0);
+    while (GetMessageA(&msg,0,0,0)) {
+        TranslateMessage(&msg);
+        DispatchMessageA(&msg);
+    }
+    
+    UnregisterClassA(statusTestClass, GetModuleHandleA(NULL));
+}
+
+
+static HFONT create_some_font(void)
+{
+    return CreateFont(30, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
+      DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
+      DEFAULT_QUALITY, DEFAULT_PITCH, "Arial");
+}
+
+
+static void reset_rect(RECT* rect)
+{
+    rect->left = 0xaa;
+    rect->top = 0xbb;
+    rect->right = 0xcc;
+    rect->bottom = 0xdd;
+}
+
+
+static BOOL is_rect_unchanged(RECT* rect)
+{
+    return ((rect->left == 0xaa) &&
+            (rect->top == 0xbb) &&
+            (rect->right == 0xcc) &&
+            (rect->bottom == 0xdd));
+}
+
+
+static void test_corner_case(BOOL simpleStatusBar)
+{
+    char text[100];
+    RECT rect;
+    HICON icon;
+    
+    /* 0xabff is used in some tests because it has the same
+       low word as SB_SIMPLEID */
+    
+    icon = LoadIcon(NULL, IDI_INFORMATION);
+    ok(icon != NULL, "LoadIcon failed\n");
+    
+    ok(SendMessageA(hStatusWnd, SB_SETTEXT, SB_SIMPLEID, (LPARAM)first_status_text),
+        "SB_SETTEXT failed\n");
+            
+    if (simpleStatusBar)
+    {
+        ok(SendMessageA(hStatusWnd, SB_GETTEXT, 0, (LPARAM)&text),
+            "SB_GETTEXT failed\n");
+    }
+    else
+    {
+        ok(!SendMessageA(hStatusWnd, SB_GETTEXT, 0, (LPARAM)&text),
+            "SB_GETTEXT should have failed: Simple status bar\n");    
+    }
+    ok(!SendMessageA(hStatusWnd, SB_GETTEXT, SB_SIMPLEID, (LPARAM)&text),
+        "SB_GETTEXT should have failed on part SB_SIMPLEID\n");
+    ok(!SendMessageA(hStatusWnd, SB_GETTEXT, -1, (LPARAM)&text),
+        "SB_GETTEXT should have failed on part -1\n");
+    ok(!SendMessageA(hStatusWnd, SB_GETTEXT, 0xabff, (LPARAM)&text),
+        "SB_GETTEXT should have failed on part 0xabff\n");
+    
+    
+    /* Bug in the native status bar: SB_SETICON always returns TRUE, even if
+       the icon has not been set. */
+    
+    /* SB_GETICON and SB_SETICON have been introduced in COMCTL32.DLL version 4.71 */
+    if (SendMessageA(hStatusWnd, SB_SETICON, -1, (LPARAM)NULL))
+    {
+        ok(!SendMessageA(hStatusWnd, SB_SETICON, SB_SIMPLEID, (LPARAM)icon) ||
+           !SendMessageA(hStatusWnd, SB_GETICON, -1, 0),
+            "SB_SETICON should have failed on part SB_SIMPLEID\n");
+        ok(SendMessageA(hStatusWnd, SB_SETICON, -1, (LPARAM)NULL),
+            "SB_SETICON failed\n");  /* Remove the icon */
+        ok(!SendMessageA(hStatusWnd, SB_SETICON, 0xabff, (LPARAM)icon) ||
+           !SendMessageA(hStatusWnd, SB_GETICON, -1, 0),
+            "SB_SETICON should have failed on part 0xabff\n");
+        ok(SendMessageA(hStatusWnd, SB_SETICON, -1, (LPARAM)icon),
+            "SB_SETICON failed\n");
+    
+        ok(SendMessageA(hStatusWnd, SB_GETICON, -1, 0),
+            "SB_GETICON failed\n");
+        ok(!SendMessageA(hStatusWnd, SB_GETICON, SB_SIMPLEID, 0),
+            "SB_GETICON should have failed on part SB_SIMPLEID\n");
+        ok(!SendMessageA(hStatusWnd, SB_GETICON, 0xabff, 0), 
+            "SB_GETICON should have failed on part 0xabff\n");
+    }
+    
+    reset_rect(&rect);
+    if (simpleStatusBar)
+    {
+        ok(!SendMessageA(hStatusWnd, SB_GETRECT, 0, (LPARAM)&rect) && is_rect_unchanged(&rect),
+            "SB_GETRECT should have failed: Simple status bar\n");
+    }
+    else
+    {
+        ok(SendMessageA(hStatusWnd, SB_GETRECT, 0, (LPARAM)&rect) && !is_rect_unchanged(&rect),
+            "SB_GETRECT failed\n");
+    }
+    reset_rect(&rect);
+    ok(!SendMessageA(hStatusWnd, SB_GETRECT, SB_SIMPLEID, (LPARAM)&rect) && is_rect_unchanged(&rect),
+        "SB_GETRECT should have failed on part SB_SIMPLEID\n");
+    reset_rect(&rect);
+    ok(!SendMessageA(hStatusWnd, SB_GETRECT, 0xabff, (LPARAM)&rect) && is_rect_unchanged(&rect),
+        "SB_GETRECT should have failed on part 0xabff\n");
+    reset_rect(&rect);
+    ok(!SendMessageA(hStatusWnd, SB_GETRECT, -1, (LPARAM)&rect) && is_rect_unchanged(&rect),
+        "SB_GETRECT should have failed on part -1\n");
+}
+
+
+static void test_corner_cases(void)
+{
+    /* Simple status bar */
+    SendMessageA(hStatusWnd, SB_SIMPLE, TRUE, 0);
+    test_corner_case(TRUE);
+    
+    /* Normal status bar */
+    SendMessageA(hStatusWnd, SB_SIMPLE, FALSE, 0);
+    test_corner_case(FALSE);
+}
+
+
+/*
+ * Tests if a simple status bar repaints itself immediately when it receives
+ * some specific messages.
+ */
+static void test_redraw_simple_statusbar(void)
+{
+    HICON icon;
+    HFONT font, old_font;
+    
+    /* Initialization */
+    SendMessageA(hStatusWnd, SB_SIMPLE, TRUE, 0);
+    ok(SendMessageA(hStatusWnd, SB_SETTEXT, SB_SIMPLEID, (LPARAM)empty_status_text), "SB_SETTEXT failed\n");
+    update_window(hStatusWnd);
+    
+    /* SB_SETTEXT */
+    ok(SendMessageA(hStatusWnd, SB_SETTEXT, SB_SIMPLEID, (LPARAM)first_status_text), "SB_SETTEXT failed\n");
+    ok(!GetUpdateRect(hStatusWnd, NULL, FALSE), "SB_SETTEXT: The new text should be drawn immediately\n");
+    
+    update_window(hStatusWnd);
+    
+    /* SB_SETICON */
+    icon = LoadIcon(NULL, IDI_INFORMATION);
+    ok(icon != NULL, "LoadIcon failed\n");
+    ok(SendMessageA(hStatusWnd, SB_SETICON, -1, (LPARAM)icon), "SB_SETICON failed\n");
+    ok(!GetUpdateRect(hStatusWnd, NULL, FALSE), "SB_SETICON: The new icon should be drawn immediately\n");
+    
+    update_window(hStatusWnd);
+    
+    /* WM_SETFONT */
+    font = create_some_font();
+    ok(font != NULL, "CreateFont failed\n");
+    old_font = (HFONT)SendMessageA(hStatusWnd, WM_GETFONT, 0, 0);
+    SendMessageA(hStatusWnd, WM_SETFONT, (WPARAM)font, TRUE);
+    ok(!GetUpdateRect(hStatusWnd, NULL, FALSE), "WM_SETFONT: The text should be redrawn immediately\n");
+    
+    SendMessageA(hStatusWnd, WM_SETFONT, (WPARAM)old_font, TRUE);
+    DeleteObject(font);
+}
+
+
+/*
+ * Tests if a normal status bar repaints itself immediately when it receives
+ * some specific messages.
+ */
+static void test_redraw_normal_statusbar(void)
+{
+    INT widths[3];
+    HICON icon;
+    HFONT font, old_font;
+    
+    widths[0] = 50;
+    widths[1] = 100;
+    widths[2] = -1;
+    
+    /* Initialization */
+    SendMessageA(hStatusWnd, SB_SIMPLE, FALSE, 0);
+    ok(SendMessageA(hStatusWnd, SB_SETPARTS, 3, (LPARAM)widths), "SB_SETPARTS failed\n");
+    ok(SendMessageA(hStatusWnd, SB_SETTEXT, 0, (LPARAM)empty_status_text), "SB_SETTEXT failed\n");
+    update_window(hStatusWnd);
+    
+    /* WM_SETTEXT (sets the text of the first part) */
+    ok(SendMessageA(hStatusWnd, WM_SETTEXT, 0, (LPARAM)first_status_text), "WM_SETTEXT failed\n");
+    ok(!GetUpdateRect(hStatusWnd, NULL, FALSE), "WM_SETTEXT: The new text should be drawn immediately\n");
+    
+    update_window(hStatusWnd);
+    
+    /* SB_SETTEXT */
+    ok(SendMessageA(hStatusWnd, SB_SETTEXT, 1, (LPARAM)second_status_text), "SB_SETTEXT failed\n");
+    ok(!GetUpdateRect(hStatusWnd, NULL, FALSE), "SB_SETTEXT: The new text should be drawn immediately\n");
+    
+    update_window(hStatusWnd);
+    
+    /* SB_SETICON */
+    icon = LoadIcon(NULL, IDI_INFORMATION);
+    ok(icon != NULL, "LoadIcon failed\n");
+    ok(SendMessageA(hStatusWnd, SB_SETICON, 2, (LPARAM)icon), "SB_SETICON failed\n");
+    ok(!GetUpdateRect(hStatusWnd, NULL, FALSE), "SB_SETICON: The new icon should be drawn immediately\n");
+    
+    update_window(hStatusWnd);
+    
+    /* WM_SETFONT */
+    font = create_some_font();
+    ok(font != NULL, "CreateFont failed\n");
+    old_font = (HFONT)SendMessageA(hStatusWnd, WM_GETFONT, 0, 0);
+    SendMessageA(hStatusWnd, WM_SETFONT, (WPARAM)font, TRUE);
+    ok(!GetUpdateRect(hStatusWnd, NULL, FALSE), "WM_SETFONT: The text should be redrawn immediately\n");
+    
+    SendMessageA(hStatusWnd, WM_SETFONT, (WPARAM)old_font, TRUE);
+    DeleteObject(font);
+}
+
+
+/*
+ * Tests if a status bar adjusts its size upon WM_SETFONT.
+ */
+static void test_setfont(void)
+{
+    RECT rect, old_rect;
+    HFONT font, old_font;
+
+    /* Initialization */
+    SendMessageA(hStatusWnd, SB_SIMPLE, TRUE, 0);
+    ok(SendMessageA(hStatusWnd, SB_SETTEXT, SB_SIMPLEID, (LPARAM)first_status_text), "SB_SETTEXT failed\n");
+    update_window(hStatusWnd);
+
+    ok(GetWindowRect(hStatusWnd, &old_rect), "GetWindowRect failed\n");
+
+    /* Change the font. The size of the new font is bigger */
+    font = create_some_font();
+    ok(font != NULL, "CreateFont failed\n");
+    old_font = (HFONT)SendMessageA(hStatusWnd, WM_GETFONT, 0, 0);
+    SendMessageA(hStatusWnd, WM_SETFONT, (WPARAM)font, TRUE);
+    ok(GetWindowRect(hStatusWnd, &rect), "GetWindowRect failed\n");
+
+    /* Reset to the old font */
+    SendMessageA(hStatusWnd, WM_SETFONT, (WPARAM)old_font, TRUE);
+    DeleteObject(font);
+
+    todo_wine {
+        ok(rect.bottom - rect.top > old_rect.bottom - old_rect.top,
+            "The status bar should be heigher after a bigger font has been set\n");
+    }
+    ok((rect.left == old_rect.left) && (rect.right == old_rect.right) &&
+        (rect.bottom == old_rect.bottom), "Only the top border of the status bar should move\n");
+
+    /* TODO: Similar tests for status bars with style CCS_TOP, CCS_LEFT, CCS_RIGHT, CCS_VERT */
+}
+
+START_TEST(status)
+{
+    init();
+    
+    test_corner_cases();
+    test_redraw_simple_statusbar();
+    test_redraw_normal_statusbar();
+    test_setfont();
+    
+    cleanup();
+}


More information about the wine-patches mailing list