[PATCH 1/6] win32u: Move NtUserDrawCaptionTemp implementation from user32.

Jacek Caban wine at gitlab.winehq.org
Thu Jun 16 18:56:41 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
---
 dlls/user32/nonclient.c      | 185 +----------------------------------
 dlls/user32/user32.spec      |   2 +-
 dlls/win32u/defwnd.c         | 111 ++++++++++++++++++++-
 dlls/win32u/gdiobj.c         |   1 +
 dlls/win32u/win32u.spec      |   2 +-
 dlls/win32u/win32u_private.h |   2 +
 dlls/win32u/wrappers.c       |   7 ++
 include/ntuser.h             |   2 +
 8 files changed, 127 insertions(+), 185 deletions(-)

diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c
index b803c99d43b..73d5b6449de 100644
--- a/dlls/user32/nonclient.c
+++ b/dlls/user32/nonclient.c
@@ -87,99 +87,12 @@ static void adjust_window_rect( RECT *rect, DWORD style, BOOL menu, DWORD exStyl
 }
 
 
-static HICON NC_IconForWindow( HWND hwnd )
-{
-    HICON hIcon = 0;
-    WND *wndPtr = WIN_GetPtr( hwnd );
-
-    if (wndPtr && wndPtr != WND_OTHER_PROCESS && wndPtr != WND_DESKTOP)
-    {
-        hIcon = wndPtr->hIconSmall;
-        if (!hIcon) hIcon = wndPtr->hIcon;
-        WIN_ReleasePtr( wndPtr );
-    }
-    if (!hIcon) hIcon = (HICON) GetClassLongPtrW( hwnd, GCLP_HICONSM );
-    if (!hIcon) hIcon = (HICON) GetClassLongPtrW( hwnd, GCLP_HICON );
-
-    /* If there is no icon specified and this is not a modal dialog,
-     * get the default one.
-     */
-    if (!hIcon && !(GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_DLGMODALFRAME))
-        hIcon = LoadImageW(0, (LPCWSTR)IDI_WINLOGO, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
-                           GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR | LR_SHARED);
-    return hIcon;
-}
-
-/* Draws the bar part(ie the big rectangle) of the caption */
-static void NC_DrawCaptionBar (HDC hdc, const RECT *rect, DWORD dwStyle, 
-                               BOOL active, BOOL gradient)
-{
-    if (gradient)
-    {
-        TRIVERTEX vertices[4];
-        DWORD colLeft = 
-            GetSysColor (active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION);
-        DWORD colRight = 
-            GetSysColor (active ? COLOR_GRADIENTACTIVECAPTION 
-                                : COLOR_GRADIENTINACTIVECAPTION);
-        int buttonsAreaSize = GetSystemMetrics(SM_CYCAPTION) - 1;
-        static GRADIENT_RECT mesh[] = {{0, 1}, {1, 2}, {2, 3}};
-
-        vertices[0].Red   = vertices[1].Red   = GetRValue (colLeft) << 8;
-        vertices[0].Green = vertices[1].Green = GetGValue (colLeft) << 8;
-        vertices[0].Blue  = vertices[1].Blue  = GetBValue (colLeft) << 8;
-        vertices[0].Alpha = vertices[1].Alpha = 0xff00;
-        vertices[2].Red   = vertices[3].Red   = GetRValue (colRight) << 8;
-        vertices[2].Green = vertices[3].Green = GetGValue (colRight) << 8;
-        vertices[2].Blue  = vertices[3].Blue  = GetBValue (colRight) << 8;
-        vertices[2].Alpha = vertices[3].Alpha = 0xff00;
-
-        if ((dwStyle & WS_SYSMENU)
-            && ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX)))
-            buttonsAreaSize += 2 * (GetSystemMetrics(SM_CXSIZE) + 1);
-
-        /* area behind icon; solid filled with left color */
-        vertices[0].x = rect->left;
-        vertices[0].y = rect->top;
-        if (dwStyle & WS_SYSMENU)
-            vertices[1].x = min (rect->left + GetSystemMetrics(SM_CXSMICON), rect->right);
-        else
-            vertices[1].x = vertices[0].x;
-        vertices[1].y = rect->bottom;
-
-        /* area behind text; gradient */
-        vertices[2].x = max (vertices[1].x, rect->right - buttonsAreaSize);
-        vertices[2].y = rect->top;
-
-        /* area behind buttons; solid filled with right color */
-        vertices[3].x = rect->right;
-        vertices[3].y = rect->bottom;
-
-        GdiGradientFill (hdc, vertices, 4, mesh, 3, GRADIENT_FILL_RECT_H);
-    }
-    else
-        FillRect (hdc, rect, GetSysColorBrush (active ?
-                  COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
-}
-
 /***********************************************************************
  *		DrawCaption (USER32.@) Draws a caption bar
- *
- * PARAMS
- *     hwnd   [I]
- *     hdc    [I]
- *     lpRect [I]
- *     uFlags [I]
- *
- * RETURNS
- *     Success:
- *     Failure:
  */
-
-BOOL WINAPI
-DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
+BOOL WINAPI DrawCaption( HWND hwnd, HDC hdc, const RECT *rect, UINT flags )
 {
-    return DrawCaptionTempW (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x103F);
+    return NtUserDrawCaptionTemp( hwnd, hdc, rect, 0, 0, NULL, flags & 0x103f );
 }
 
 
@@ -194,109 +107,19 @@ BOOL WINAPI DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
     BOOL ret = FALSE;
 
     if (!(uFlags & DC_TEXT) || !str)
-        return DrawCaptionTempW( hwnd, hdc, rect, hFont, hIcon, NULL, uFlags );
+        return NtUserDrawCaptionTemp( hwnd, hdc, rect, hFont, hIcon, NULL, uFlags );
 
     len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
     if ((strW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
     {
         MultiByteToWideChar( CP_ACP, 0, str, -1, strW, len );
-        ret = DrawCaptionTempW (hwnd, hdc, rect, hFont, hIcon, strW, uFlags);
+        ret = NtUserDrawCaptionTemp( hwnd, hdc, rect, hFont, hIcon, strW, uFlags );
         HeapFree( GetProcessHeap (), 0, strW );
     }
     return ret;
 }
 
 
-/***********************************************************************
- *		DrawCaptionTempW (USER32.@)
- */
-BOOL WINAPI DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
-                              HICON hIcon, LPCWSTR str, UINT uFlags)
-{
-    RECT   rc = *rect;
-
-    TRACE("(%p,%p,%p,%p,%p,%s,%08x)\n",
-          hwnd, hdc, rect, hFont, hIcon, debugstr_w(str), uFlags);
-
-    /* drawing background */
-    if (uFlags & DC_INBUTTON) {
-        FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
-
-        if (uFlags & DC_ACTIVE) {
-            HBRUSH hbr = SelectObject (hdc, SYSCOLOR_Get55AABrush());
-            PatBlt (hdc, rc.left, rc.top,
-                      rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
-            SelectObject (hdc, hbr);
-        }
-    }
-    else {
-        DWORD style = GetWindowLongW (hwnd, GWL_STYLE);
-        NC_DrawCaptionBar (hdc, &rc, style, uFlags & DC_ACTIVE, uFlags & DC_GRADIENT);
-    }
-
-
-    /* drawing icon */
-    if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
-        POINT pt;
-
-        pt.x = rc.left + 2;
-        pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
-
-        if (!hIcon) hIcon = NC_IconForWindow(hwnd);
-        NtUserDrawIconEx( hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
-                          GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL );
-        rc.left = pt.x + GetSystemMetrics( SM_CXSMICON );
-    }
-
-    /* drawing text */
-    if (uFlags & DC_TEXT) {
-        HFONT hOldFont;
-        WCHAR text[128];
-
-        if (uFlags & DC_INBUTTON)
-            SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
-        else if (uFlags & DC_ACTIVE)
-            SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
-        else
-            SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
-
-        SetBkMode (hdc, TRANSPARENT);
-
-        if (hFont)
-            hOldFont = SelectObject (hdc, hFont);
-        else {
-            NONCLIENTMETRICSW nclm;
-            HFONT hNewFont;
-            nclm.cbSize = sizeof(NONCLIENTMETRICSW);
-            SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
-            hNewFont = CreateFontIndirectW ((uFlags & DC_SMALLCAP) ?
-                &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
-            hOldFont = SelectObject (hdc, hNewFont);
-        }
-
-        if (!str)
-        {
-            if (!GetWindowTextW( hwnd, text, ARRAY_SIZE( text ))) text[0] = 0;
-            str = text;
-        }
-        rc.left += 2;
-        DrawTextW( hdc, str, -1, &rc, ((uFlags & 0x4000) ? DT_CENTER : DT_LEFT) |
-                   DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_END_ELLIPSIS );
-
-        if (hFont)
-            SelectObject (hdc, hOldFont);
-        else
-            DeleteObject (SelectObject (hdc, hOldFont));
-    }
-
-    /* drawing focus ??? */
-    if (uFlags & 0x2000)
-        FIXME("undocumented flag (0x2000)!\n");
-
-    return FALSE;
-}
-
-
 /***********************************************************************
  *		AdjustWindowRect (USER32.@)
  */
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index d0262a004f1..bed557ba67e 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -186,7 +186,7 @@
 @ stdcall DrawAnimatedRects(long long ptr ptr)
 @ stdcall DrawCaption(long long ptr long)
 @ stdcall DrawCaptionTempA(long long ptr long long str long)
-@ stdcall DrawCaptionTempW(long long ptr long long wstr long)
+@ stdcall DrawCaptionTempW(long long ptr long long wstr long) NtUserDrawCaptionTemp
 @ stdcall DrawEdge(long ptr long long)
 @ stdcall DrawFocusRect(long ptr)
 @ stub DrawFrame
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c
index b438b6d5275..e3025e68d02 100644
--- a/dlls/win32u/defwnd.c
+++ b/dlls/win32u/defwnd.c
@@ -322,6 +322,24 @@ static BOOL set_window_text( HWND hwnd, const void *text, BOOL ansi )
     return TRUE;
 }
 
+static int get_window_text( HWND hwnd, WCHAR *str, int count )
+{
+    int ret;
+
+    if (is_current_process_window( hwnd ))
+    {
+        /* FIXME: use packed send message */
+        ret = send_message( hwnd, WM_GETTEXT, count, (LPARAM)str );
+    }
+    else
+    {
+        /* when window belongs to other process, don't send a message */
+        ret = NtUserInternalGetWindowText( hwnd, str, count );
+    }
+
+    return ret;
+}
+
 static HICON get_window_icon( HWND hwnd, WPARAM type )
 {
     HICON ret;
@@ -1411,8 +1429,7 @@ static void draw_nc_caption( HDC hdc, RECT *rect, HWND hwnd, DWORD  style,
         }
     }
 
-    /* FIXME: use packed send message */
-    len = send_message( hwnd, WM_GETTEXT, ARRAY_SIZE( buffer ), (LPARAM)buffer );
+    len = get_window_text( hwnd, buffer, ARRAY_SIZE( buffer ));
     if (len)
     {
         NONCLIENTMETRICSW nclm;
@@ -1436,6 +1453,96 @@ static void draw_nc_caption( HDC hdc, RECT *rect, HWND hwnd, DWORD  style,
     }
 }
 
+/***********************************************************************
+ *           NtUserDrawCaptionTemp   (win32u.@)
+ */
+BOOL WINAPI NtUserDrawCaptionTemp( HWND hwnd, HDC hdc, const RECT *rect, HFONT font,
+                                   HICON icon, const WCHAR *str, UINT flags )
+{
+    RECT rc = *rect;
+
+    TRACE( "(%p,%p,%p,%p,%p,%s,%08x)\n", hwnd, hdc, rect, font, icon, debugstr_w(str), flags );
+
+    /* drawing background */
+    if (flags & DC_INBUTTON)
+    {
+        fill_rect( hdc, &rc, get_sys_color_brush( COLOR_3DFACE ));
+
+        if (flags & DC_ACTIVE) {
+            HBRUSH hbr = NtGdiSelectBrush( hdc, get_55aa_brush() );
+            NtGdiPatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 0xfa0089 );
+            NtGdiSelectBrush( hdc, hbr );
+        }
+    }
+    else
+    {
+        DWORD style = get_window_long( hwnd, GWL_STYLE );
+        draw_caption_bar( hdc, &rc, style, flags & DC_ACTIVE, flags & DC_GRADIENT );
+    }
+
+    /* drawing icon */
+    if ((flags & DC_ICON) && !(flags & DC_SMALLCAP))
+    {
+        POINT pt;
+
+        pt.x = rc.left + 2;
+        pt.y = (rc.bottom + rc.top - get_system_metrics( SM_CYSMICON )) / 2;
+
+        if (!icon) icon = get_nc_icon_for_window( hwnd );
+        NtUserDrawIconEx( hdc, pt.x, pt.y, icon, get_system_metrics( SM_CXSMICON ),
+                          get_system_metrics( SM_CYSMICON ), 0, 0, DI_NORMAL );
+        rc.left = pt.x + get_system_metrics( SM_CXSMICON );
+    }
+
+    /* drawing text */
+    if (flags & DC_TEXT)
+    {
+        HFONT prev_font;
+        WCHAR text[128];
+        DWORD color;
+
+        if (flags & DC_INBUTTON)
+            color = COLOR_BTNTEXT;
+        else if (flags & DC_ACTIVE)
+            color = COLOR_CAPTIONTEXT;
+        else
+            color = COLOR_INACTIVECAPTIONTEXT;
+        NtGdiGetAndSetDCDword( hdc, NtGdiSetTextColor, get_sys_color( color ), NULL );
+        NtGdiGetAndSetDCDword( hdc, NtGdiSetBkMode, TRANSPARENT, NULL );
+
+        if (font)
+            prev_font = NtGdiSelectFont( hdc, font );
+        else
+        {
+            NONCLIENTMETRICSW nclm;
+            HFONT new_font;
+            LOGFONTW *lf;
+            nclm.cbSize = sizeof(NONCLIENTMETRICSW);
+            NtUserSystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &nclm, 0 );
+            lf = (flags & DC_SMALLCAP) ? &nclm.lfSmCaptionFont : &nclm.lfCaptionFont;
+            new_font = NtGdiHfontCreate( &lf, sizeof(lf), 0, 0, NULL );
+            prev_font = NtGdiSelectFont( hdc, new_font );
+        }
+
+        if (!str)
+        {
+            if (!get_window_text( hwnd, text, ARRAY_SIZE( text ))) text[0] = 0;
+            str = text;
+        }
+        rc.left += 2;
+        DrawTextW( hdc, str, -1, &rc, ((flags & 0x4000) ? DT_CENTER : DT_LEFT) |
+                   DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_END_ELLIPSIS );
+
+        if (font)
+            NtGdiSelectFont( hdc, prev_font );
+        else
+            NtGdiDeleteObjectApp( NtGdiSelectFont( hdc, prev_font ));
+    }
+
+    if (flags & 0x2000) FIXME( "undocumented flag (0x2000)!\n" );
+    return FALSE;
+}
+
 /* Paint the non-client area for windows */
 static void nc_paint( HWND hwnd, HRGN clip )
 {
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c
index da2e78be2dd..9d95d3cf94a 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -1159,6 +1159,7 @@ static struct unix_funcs unix_funcs =
     NtUserDestroyWindow,
     NtUserDispatchMessage,
     NtUserDragDetect,
+    NtUserDrawCaptionTemp,
     NtUserDrawIconEx,
     NtUserDrawMenuBarTemp,
     NtUserEmptyClipboard,
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index 6f9dc0e921b..7087e04653f 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -849,7 +849,7 @@
 @ stub NtUserDragObject
 @ stub NtUserDrawAnimatedRects
 @ stub NtUserDrawCaption
-@ stub NtUserDrawCaptionTemp
+@ stdcall NtUserDrawCaptionTemp(long long ptr long long wstr long)
 @ stdcall NtUserDrawIconEx(long long long long long long long long long)
 @ stdcall NtUserDrawMenuBarTemp(long long ptr long long)
 @ stub NtUserDwmGetRemoteSessionOcclusionEvent
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h
index dc62f6846a5..6536518c604 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -215,6 +215,8 @@ struct unix_funcs
     BOOL     (WINAPI *pNtUserDestroyWindow)( HWND hwnd );
     LRESULT  (WINAPI *pNtUserDispatchMessage)( const MSG *msg );
     BOOL     (WINAPI *pNtUserDragDetect)( HWND hwnd, int x, int y );
+    BOOL     (WINAPI *pNtUserDrawCaptionTemp)( HWND hwnd, HDC hdc, const RECT *rect, HFONT font,
+                                               HICON icon, const WCHAR *str, UINT flags );
     BOOL     (WINAPI *pNtUserDrawIconEx)( HDC hdc, INT x0, INT y0, HICON icon, INT width,
                                           INT height, UINT istep, HBRUSH hbr, UINT flags );
     DWORD    (WINAPI *pNtUserDrawMenuBarTemp)( HWND hwnd, HDC hdc, RECT *rect, HMENU handle, HFONT font );
diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c
index ed4337eae84..b451e57e3b1 100644
--- a/dlls/win32u/wrappers.c
+++ b/dlls/win32u/wrappers.c
@@ -861,6 +861,13 @@ BOOL WINAPI NtUserDragDetect( HWND hwnd, int x, int y )
     return unix_funcs->pNtUserDragDetect( hwnd, x, y );
 }
 
+BOOL WINAPI NtUserDrawCaptionTemp( HWND hwnd, HDC hdc, const RECT *rect, HFONT font,
+                                   HICON icon, const WCHAR *str, UINT flags )
+{
+    if (!unix_funcs) return FALSE;
+    return unix_funcs->pNtUserDrawCaptionTemp( hwnd, hdc, rect, font, icon, str, flags );
+}
+
 BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width,
                               INT height, UINT istep, HBRUSH hbr, UINT flags )
 {
diff --git a/include/ntuser.h b/include/ntuser.h
index 56c920aacdf..5abe9b9a3cb 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -538,6 +538,8 @@ BOOL    WINAPI NtUserDestroyMenu( HMENU menu );
 BOOL    WINAPI NtUserDestroyWindow( HWND hwnd );
 LRESULT WINAPI NtUserDispatchMessage( const MSG *msg );
 BOOL    WINAPI NtUserDragDetect( HWND hwnd, int x, int y );
+BOOL    WINAPI NtUserDrawCaptionTemp( HWND hwnd, HDC hdc, const RECT *rect, HFONT font,
+                                      HICON icon, const WCHAR *str, UINT flags );
 BOOL    WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width,
                                  INT height, UINT istep, HBRUSH hbr, UINT flags );
 DWORD   WINAPI NtUserDrawMenuBarTemp( HWND hwnd, HDC hdc, RECT *rect, HMENU handle, HFONT font );
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/261



More information about the wine-devel mailing list