Static control [01/10]: Support text style flags

Michael Kaufmann hallo at michael-kaufmann.ch
Wed Jan 11 16:15:21 CST 2006


I've completely reviewed and partially rewritten the static control.
It's the most basic control, and I think nobody has worked on it for a
while, despite the fact that it's one of the most basic controls and
that it has changed quite a bit in Windows XP.

The patches have been carefully tested; I hope that there won't be any
issues.

My first patch is against CVS, the other patches must be applied in the
proper order.

Changelog for the first patch:
- Support DT_END_ELLIPSIS, DT_PATH_ELLIPSIS and DT_WORD_ELLIPSIS
- Paint simple text without prefixes (SS_SIMPLE | SS_NOPREFIX) with the 
ExtTextOut function like the native control does
- Gray text color: Only for non-simple static controls


-------------- next part --------------
Index: dlls/user/static.c
===================================================================
RCS file: /home/wine/wine/dlls/user/static.c,v
retrieving revision 1.12
diff -u -r1.12 static.c
--- dlls/user/static.c	10 Jan 2006 20:15:47 -0000	1.12
+++ dlls/user/static.c	11 Jan 2006 21:23:49 -0000
@@ -29,13 +29,9 @@
  * TODO:
  *
  *   Styles
- *   - SS_EDITCONTROL
- *   - SS_ENDELLIPSIS
- *   - SS_PATHELLIPSIS
  *   - SS_REALSIZECONTROL
  *   - SS_REALSIZEIMAGE
  *   - SS_RIGHTJUST
- *   - SS_WORDELLIPSIS
  *
  *   Notifications
  *   - STN_DISABLE
@@ -254,6 +250,20 @@
     }
 }
 
+static HBRUSH STATIC_SendWmCtlColorStatic(HWND hwnd, HDC hdc)
+{
+    HBRUSH hBrush = (HBRUSH) SendMessageW( GetParent(hwnd),
+                    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,
+                                        (WPARAM)hdc, (LPARAM)hwnd);
+    }
+    return hBrush;
+}
+
 static VOID STATIC_InitColours(void)
 {
     color_3ddkshadow  = GetSysColor(COLOR_3DDKSHADOW);
@@ -504,7 +514,7 @@
 {
     RECT rc;
     HBRUSH hBrush;
-    HFONT hFont;
+    HFONT hFont, hOldFont = NULL;
     WORD wFormat;
     INT len;
     WCHAR *text;
@@ -538,28 +548,56 @@
     }
 
     if (style & SS_NOPREFIX)
-	wFormat |= DT_NOPREFIX;
-    if ((style & SS_CENTERIMAGE) && (style & SS_TYPEMASK) != SS_SIMPLE)
-        wFormat |= DT_SINGLELINE | DT_VCENTER;
-
-    if ((hFont = (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET ))) SelectObject( hdc, hFont );
-
-    if ((style & SS_NOPREFIX) || ((style & SS_TYPEMASK) != SS_SIMPLE))
-    {
-        hBrush = (HBRUSH)SendMessageW( GetParent(hwnd), WM_CTLCOLORSTATIC,
-				       (WPARAM)hdc, (LPARAM)hwnd );
-        if (!hBrush) /* did the app forget to call defwindowproc ? */
-            hBrush = (HBRUSH)DefWindowProcW(GetParent(hwnd), WM_CTLCOLORSTATIC,
-					    (WPARAM)hdc, (LPARAM)hwnd);
+        wFormat |= DT_NOPREFIX;
+    
+    if ((style & SS_TYPEMASK) != SS_SIMPLE)
+    {
+        if (style & SS_CENTERIMAGE)
+            wFormat |= DT_SINGLELINE | DT_VCENTER;
+        if (style & SS_EDITCONTROL)
+            wFormat |= DT_EDITCONTROL;
+        if (style & SS_ENDELLIPSIS)
+            wFormat |= DT_SINGLELINE | DT_END_ELLIPSIS;
+        if (style & SS_PATHELLIPSIS)
+            wFormat |= DT_SINGLELINE | DT_PATH_ELLIPSIS;
+        if (style & SS_WORDELLIPSIS)
+            wFormat |= DT_SINGLELINE | DT_WORD_ELLIPSIS;
+    }
+
+    if ((hFont = (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET )))
+        hOldFont = (HFONT)SelectObject( hdc, hFont );
+
+    /* 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 (!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 );
-    DrawTextW( hdc, text, -1, &rc, wFormat );
+    
+    if (((style & SS_TYPEMASK) == SS_SIMPLE) && (style & SS_NOPREFIX))
+    {
+        /* Windows uses the faster ExtTextOut() to draw the text and
+           to paint the whole client rectangle with the text background
+           color. Reference: "Static Controls" by Kyle Marsh, 1992 */
+        ExtTextOutW( hdc, rc.left, rc.top, ETO_CLIPPED | ETO_OPAQUE,
+                     &rc, text, len, NULL );
+    }
+    else
+    {
+        DrawTextW( hdc, text, -1, &rc, wFormat );
+    }
+    
     HeapFree( GetProcessHeap(), 0, text );
+    
+    if (hFont)
+        SelectObject( hdc, hOldFont );
 }
 
 static void STATIC_PaintRectfn( HWND hwnd, HDC hdc, DWORD style )


More information about the wine-patches mailing list