[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