win32u: Move NtUserDrawCaptionTemp implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
This commit is contained in:
Jacek Caban 2022-06-16 19:52:44 +02:00 committed by Alexandre Julliard
parent 0b07bb8566
commit 67e39efb75
8 changed files with 128 additions and 185 deletions

View file

@ -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.@)
*/

View file

@ -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

View file

@ -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,97 @@ 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 )
{

View file

@ -1159,6 +1159,7 @@ static struct unix_funcs unix_funcs =
NtUserDestroyWindow,
NtUserDispatchMessage,
NtUserDragDetect,
NtUserDrawCaptionTemp,
NtUserDrawIconEx,
NtUserDrawMenuBarTemp,
NtUserEmptyClipboard,

View file

@ -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

View file

@ -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 );

View file

@ -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 )
{

View file

@ -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 );