From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@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 );