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 );
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/controls.h | 1 - dlls/user32/defwnd.c | 15 ---------- dlls/user32/nonclient.c | 52 --------------------------------- dlls/win32u/defwnd.c | 64 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 68 deletions(-)
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h index 3fadcc113c0..a0047d6183d 100644 --- a/dlls/user32/controls.h +++ b/dlls/user32/controls.h @@ -123,7 +123,6 @@ extern LRESULT NC_HandleNCMouseMove( HWND hwnd, WPARAM wParam, LPARAM lParam ) D extern LRESULT NC_HandleNCMouseLeave( HWND hwnd ) DECLSPEC_HIDDEN; extern LRESULT NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam) DECLSPEC_HIDDEN; extern LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; -extern LRESULT NC_HandleSetCursor( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
/* scrollbar */
diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index 57e12d8e00b..fd6c44dd29b 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -225,21 +225,6 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa case WM_CTLCOLOR: return (LRESULT)DEFWND_ControlColor( (HDC)wParam, HIWORD(lParam) );
- case WM_SETCURSOR: - if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) - { - /* with the exception of the border around a resizable wnd, - * give the parent first chance to set the cursor */ - if ((LOWORD(lParam) < HTSIZEFIRST) || (LOWORD(lParam) > HTSIZELAST)) - { - HWND parent = GetParent( hwnd ); - if (parent != GetDesktopWindow() && - SendMessageW( parent, WM_SETCURSOR, wParam, lParam )) return TRUE; - } - } - NC_HandleSetCursor( hwnd, wParam, lParam ); - break; - case WM_SYSCOMMAND: return NC_HandleSysCommand( hwnd, wParam, lParam );
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c index 73d5b6449de..cc31e1b2f2f 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -236,58 +236,6 @@ LRESULT NC_HandleNCMouseLeave(HWND hwnd) return 0; }
-/*********************************************************************** - * NC_HandleSetCursor - * - * Handle a WM_SETCURSOR message. Called from DefWindowProc(). - */ -LRESULT NC_HandleSetCursor( HWND hwnd, WPARAM wParam, LPARAM lParam ) -{ - hwnd = WIN_GetFullHandle( (HWND)wParam ); - - switch((short)LOWORD(lParam)) - { - case HTERROR: - { - WORD msg = HIWORD( lParam ); - if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) || - (msg == WM_RBUTTONDOWN) || (msg == WM_XBUTTONDOWN)) - MessageBeep(0); - } - break; - - case HTCLIENT: - { - HCURSOR hCursor = (HCURSOR)GetClassLongPtrW(hwnd, GCLP_HCURSOR); - if(hCursor) { - NtUserSetCursor(hCursor); - return TRUE; - } - return FALSE; - } - - case HTLEFT: - case HTRIGHT: - return (LRESULT)NtUserSetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZEWE ) ); - - case HTTOP: - case HTBOTTOM: - return (LRESULT)NtUserSetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENS ) ); - - case HTTOPLEFT: - case HTBOTTOMRIGHT: - return (LRESULT)NtUserSetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENWSE ) ); - - case HTTOPRIGHT: - case HTBOTTOMLEFT: - return (LRESULT)NtUserSetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENESW ) ); - } - - /* Default cursor: arrow */ - return (LRESULT)NtUserSetCursor( LoadCursorA( 0, (LPSTR)IDC_ARROW ) ); -} - -
/*********************************************************************** * NC_TrackScrollBar diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index e3025e68d02..a385d581d3a 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -414,6 +414,55 @@ static HICON set_window_icon( HWND hwnd, WPARAM type, HICON icon ) return ret; }
+static LRESULT handle_set_cursor( HWND hwnd, WPARAM wparam, LPARAM lparam ) +{ + UINT cursor_id = IDC_ARROW; + HCURSOR cursor; + + hwnd = get_full_window_handle( (HWND)wparam ); + + switch((short)LOWORD( lparam )) + { + case HTERROR: + { + WORD msg = HIWORD( lparam ); + if (msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN || + msg == WM_RBUTTONDOWN || msg == WM_XBUTTONDOWN) + message_beep( 0 ); + } + break; + + case HTCLIENT: + cursor = (HCURSOR)get_class_long_ptr( hwnd, GCLP_HCURSOR, FALSE ); + if (!cursor) return FALSE; + NtUserSetCursor( cursor ); + return TRUE; + + case HTLEFT: + case HTRIGHT: + cursor_id = IDC_SIZEWE; + break; + + case HTTOP: + case HTBOTTOM: + cursor_id = IDC_SIZENS; + break; + + case HTTOPLEFT: + case HTBOTTOMRIGHT: + cursor_id = IDC_SIZENWSE; + break; + + case HTTOPRIGHT: + case HTBOTTOMLEFT: + cursor_id = IDC_SIZENESW; + } + + cursor = LoadImageW( 0, MAKEINTRESOURCEW( cursor_id ), IMAGE_CURSOR, + 0, 0, LR_SHARED | LR_DEFAULTSIZE ); + return (LRESULT)NtUserSetCursor( cursor ); +} + static LONG handle_window_pos_changing( HWND hwnd, WINDOWPOS *winpos ) { LONG style = get_window_long( hwnd, GWL_STYLE ); @@ -2306,6 +2355,21 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, result = (LRESULT)get_window_icon( hwnd, wparam ); break;
+ case WM_SETCURSOR: + if (get_window_long( hwnd, GWL_STYLE ) & WS_CHILD) + { + /* with the exception of the border around a resizable window, + * give the parent first chance to set the cursor */ + if ((LOWORD( lparam ) < HTSIZEFIRST) || (LOWORD( lparam ) > HTSIZELAST)) + { + HWND parent = get_parent( hwnd ); + if (parent != get_desktop_window() && + send_message( parent, WM_SETCURSOR, wparam, lparam )) return TRUE; + } + } + handle_set_cursor( hwnd, wparam, lparam ); + break; + case WM_SYSCOMMAND: result = handle_sys_command( hwnd, wparam, lparam ); break;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117143
Your paranoid android.
=== debian11 (32 bit report) ===
user32: msg.c:6881: Test failed: SetFocus(hwnd) on a button: 5: the msg 0x0135 was expected, but got msg 0x030f instead msg.c:6881: Test failed: SetFocus(hwnd) on a button: 7: the msg 0x8000 was expected, but got msg 0x0086 instead msg.c:6881: Test failed: SetFocus(hwnd) on a button: 8: the msg sequence is not complete: expected 0000 - actual 0006 win.c:11770: Test succeeded inside todo block: child should be topmost win.c:11773: Test failed: grandchild should be topmost win.c:11781: Test failed: child should NOT be topmost win.c:11784: Test succeeded inside todo block: grandchild should NOT be topmost win.c:11787: Test failed: 007200BA: expected NOT topmost win.c:11606: Test succeeded inside todo block: 5: hwnd 014F0052 is still topmost
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/controls.h | 1 - dlls/user32/defwnd.c | 6 ----- dlls/user32/nonclient.c | 51 ----------------------------------------- dlls/win32u/defwnd.c | 48 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 58 deletions(-)
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h index a0047d6183d..639b9f2214e 100644 --- a/dlls/user32/controls.h +++ b/dlls/user32/controls.h @@ -121,7 +121,6 @@ extern HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu ) DECLSPEC_HIDDEN; /* nonclient area */ extern LRESULT NC_HandleNCMouseMove( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; extern LRESULT NC_HandleNCMouseLeave( HWND hwnd ) DECLSPEC_HIDDEN; -extern LRESULT NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam) DECLSPEC_HIDDEN; extern LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
/* scrollbar */ diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index fd6c44dd29b..45f1842714f 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -175,12 +175,6 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa iF10Key = iMenuSysKey = 0; break;
- case WM_LBUTTONDBLCLK: - return NC_HandleNCLButtonDblClk( hwnd, HTCLIENT, lParam ); - - case WM_NCLBUTTONDBLCLK: - return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam ); - case WM_RBUTTONUP: { POINT pt; diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c index cc31e1b2f2f..3844d42adba 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -260,57 +260,6 @@ static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt ) }
-/*********************************************************************** - * NC_HandleNCLButtonDblClk - * - * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc(). - */ -LRESULT NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam ) -{ - /* - * if this is an icon, send a restore since we are handling - * a double click - */ - if (IsIconic(hwnd)) - { - SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, lParam ); - return 0; - } - - switch(wParam) /* Hit test */ - { - case HTCAPTION: - /* stop processing if WS_MAXIMIZEBOX is missing */ - if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_MAXIMIZEBOX) - SendMessageW( hwnd, WM_SYSCOMMAND, - IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, lParam ); - break; - - case HTSYSMENU: - { - HMENU hSysMenu = NtUserGetSystemMenu(hwnd, FALSE); - UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); - - /* If the close item of the sysmenu is disabled or not present do nothing */ - if ((state & (MF_DISABLED | MF_GRAYED)) || (state == 0xFFFFFFFF)) - break; - - SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, lParam ); - break; - } - - case HTHSCROLL: - SendMessageW( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam ); - break; - - case HTVSCROLL: - SendMessageW( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam ); - break; - } - return 0; -} - - /*********************************************************************** * NC_HandleSysCommand * diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index a385d581d3a..105bb9744ec 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -2168,6 +2168,48 @@ static LRESULT handle_nc_rbutton_down( HWND hwnd, WPARAM wparam, LPARAM lparam ) return 0; }
+static LRESULT handle_nc_button_dbl_click( HWND hwnd, WPARAM wparam, LPARAM lparam ) +{ + /*if this is an icon, send a restore since we are handling a double click */ + if (is_iconic(hwnd)) + { + send_message( hwnd, WM_SYSCOMMAND, SC_RESTORE, lparam ); + return 0; + } + + switch (wparam) /* Hit test */ + { + case HTCAPTION: + /* stop processing if WS_MAXIMIZEBOX is missing */ + if (get_window_long( hwnd, GWL_STYLE ) & WS_MAXIMIZEBOX) + send_message( hwnd, WM_SYSCOMMAND, + is_zoomed( hwnd ) ? SC_RESTORE : SC_MAXIMIZE, lparam ); + break; + + case HTSYSMENU: + { + HMENU hSysMenu = NtUserGetSystemMenu( hwnd, FALSE ); + UINT state = get_menu_state( hSysMenu, SC_CLOSE, MF_BYCOMMAND ); + + /* If the close item of the sysmenu is disabled or not present do nothing */ + if ((state & (MF_DISABLED | MF_GRAYED)) || state == 0xffffffff) + break; + + send_message( hwnd, WM_SYSCOMMAND, SC_CLOSE, lparam ); + break; + } + + case HTHSCROLL: + send_message( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lparam ); + break; + + case HTVSCROLL: + send_message( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lparam ); + break; + } + return 0; +} + LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) { LRESULT result = 0; @@ -2219,6 +2261,12 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, case WM_NCRBUTTONDOWN: return handle_nc_rbutton_down( hwnd, wparam, lparam );
+ case WM_LBUTTONDBLCLK: + return handle_nc_button_dbl_click( hwnd, HTCLIENT, lparam ); + + case WM_NCLBUTTONDBLCLK: + return handle_nc_button_dbl_click( hwnd, wparam, lparam ); + case WM_CONTEXTMENU: if (get_window_long( hwnd, GWL_STYLE ) & WS_CHILD) send_message( get_parent( hwnd ), msg, (WPARAM)hwnd, lparam );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117144
Your paranoid android.
=== debian11 (32 bit WoW report) ===
user32: menu.c:2324: Test failed: test 25
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/nonclient.c | 20 -------------------- 1 file changed, 20 deletions(-)
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c index 3844d42adba..7a742e1a429 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -31,8 +31,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(nonclient);
-#define SC_ABOUTWINE (SC_SCREENSAVE+1) - /* Some useful macros */ #define HAS_DLGFRAME(style,exStyle) \ (((exStyle) & WS_EX_DLGMODALFRAME) || \ @@ -291,24 +289,6 @@ LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) WinExec( "taskman.exe", SW_SHOWNORMAL ); break;
- case SC_SCREENSAVE: - if (wParam == SC_ABOUTWINE) - { - HMODULE hmodule = LoadLibraryA( "shell32.dll" ); - if (hmodule) - { - BOOL (WINAPI *aboutproc)(HWND, LPCSTR, LPCSTR, HICON); - extern const char * CDECL wine_get_version(void); - char app[256]; - - sprintf( app, "Wine %s", wine_get_version() ); - aboutproc = (void *)GetProcAddress( hmodule, "ShellAboutA" ); - if (aboutproc) aboutproc( hwnd, app, NULL, 0 ); - FreeLibrary( hmodule ); - } - } - break; - case SC_HOTKEY: case SC_ARRANGE: case SC_NEXTWINDOW:
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/nonclient.c | 12 ------------ dlls/win32u/defwnd.c | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c index 7a742e1a429..d972930b10b 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -265,16 +265,11 @@ static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt ) */ LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) { - TRACE("hwnd %p WM_SYSCOMMAND %Ix %Ix\n", hwnd, wParam, lParam ); - if (!NtUserMessageCall( hwnd, WM_SYSCOMMAND, wParam, lParam, 0, NtUserDefWindowProc, FALSE )) return 0;
switch (wParam & 0xfff0) { - case SC_CLOSE: - return SendMessageW( hwnd, WM_CLOSE, 0, 0 ); - case SC_VSCROLL: case SC_HSCROLL: { @@ -288,13 +283,6 @@ LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) case SC_TASKLIST: WinExec( "taskman.exe", SW_SHOWNORMAL ); break; - - case SC_HOTKEY: - case SC_ARRANGE: - case SC_NEXTWINDOW: - case SC_PREVWINDOW: - FIXME("unimplemented WM_SYSCOMMAND %04Ix!\n", wParam); - break; } return 0; } diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index 105bb9744ec..9cb46c1c78b 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -892,6 +892,8 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam )
static LRESULT handle_sys_command( HWND hwnd, WPARAM wparam, LPARAM lparam ) { + TRACE( "hwnd %p WM_SYSCOMMAND %lx %lx\n", hwnd, wparam, lparam ); + if (!is_window_enabled( hwnd )) return 0;
if (call_hooks( WH_CBT, HCBT_SYSCOMMAND, wparam, lparam, TRUE )) @@ -917,6 +919,13 @@ static LRESULT handle_sys_command( HWND hwnd, WPARAM wparam, LPARAM lparam ) NtUserShowWindow( hwnd, SW_MAXIMIZE ); break;
+ case SC_CLOSE: + return send_message( hwnd, WM_CLOSE, 0, 0 ); + + case SC_VSCROLL: + case SC_HSCROLL: + return 1; /* FIXME: handle on client side */ + case SC_MOUSEMENU: track_mouse_menu_bar( hwnd, wparam & 0x000F, (short)LOWORD(lparam), (short)HIWORD(lparam) ); break; @@ -930,6 +939,16 @@ static LRESULT handle_sys_command( HWND hwnd, WPARAM wparam, LPARAM lparam ) NtUserShowWindow( hwnd, SW_RESTORE ); break;
+ case SC_TASKLIST: + return 1; /* FIXME: handle on client side */ + + case SC_HOTKEY: + case SC_ARRANGE: + case SC_NEXTWINDOW: + case SC_PREVWINDOW: + FIXME( "unimplemented WM_SYSCOMMAND %04lx\n", wparam ); + break; + default: return 1; /* handle on client side */ }
From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/nonclient.c | 125 ---------------------------------------- dlls/user32/user32.spec | 2 +- dlls/win32u/defwnd.c | 73 +++++++++++++++++++++++ dlls/win32u/syscall.c | 1 + dlls/win32u/win32u.spec | 2 +- dlls/wow64win/syscall.h | 1 + dlls/wow64win/user.c | 8 +++ include/ntuser.h | 1 + 8 files changed, 86 insertions(+), 127 deletions(-)
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c index d972930b10b..ece63dea4a8 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -31,28 +31,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(nonclient);
- /* Some useful macros */ -#define HAS_DLGFRAME(style,exStyle) \ - (((exStyle) & WS_EX_DLGMODALFRAME) || \ - (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME))) - -#define HAS_THICKFRAME(style,exStyle) \ - (((style) & WS_THICKFRAME) && \ - !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME)) - -#define HAS_THINFRAME(style) \ - (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP))) - -#define HAS_BIGFRAME(style,exStyle) \ - (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \ - ((exStyle) & WS_EX_DLGMODALFRAME)) - -#define HAS_STATICOUTERFRAME(style,exStyle) \ - (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \ - WS_EX_STATICEDGE) - -#define HAS_MENU(hwnd,style) ((((style) & (WS_CHILD | WS_POPUP)) != WS_CHILD) && GetMenu(hwnd)) -
static void adjust_window_rect( RECT *rect, DWORD style, BOOL menu, DWORD exStyle, NONCLIENTMETRICSW *ncm ) { @@ -162,42 +140,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH AdjustWindowRectExForDpi( LPRECT rect, DWORD style }
-/*********************************************************************** - * NC_GetInsideRect - * - * Get the 'inside' rectangle of a window, i.e. the whole window rectangle - * but without the borders (if any). - */ -static void NC_GetInsideRect( HWND hwnd, enum coords_relative relative, RECT *rect, - DWORD style, DWORD ex_style ) -{ - WIN_GetRectangles( hwnd, relative, rect, NULL ); - - /* Remove frame from rectangle */ - if (HAS_THICKFRAME( style, ex_style )) - { - InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) ); - } - else if (HAS_DLGFRAME( style, ex_style )) - { - InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME)); - } - else if (HAS_THINFRAME( style )) - { - InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) ); - } - - /* We have additional border information if the window - * is a child (but not an MDI child) */ - if ((style & WS_CHILD) && !(ex_style & WS_EX_MDICHILD)) - { - if (ex_style & WS_EX_CLIENTEDGE) - InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE)); - if (ex_style & WS_EX_STATICEDGE) - InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER)); - } -} - LRESULT NC_HandleNCMouseMove(HWND hwnd, WPARAM wParam, LPARAM lParam) { RECT rect; @@ -286,70 +228,3 @@ LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) } return 0; } - -/*********************************************************************** - * GetTitleBarInfo (USER32.@) - * TODO: Handle STATE_SYSTEM_PRESSED - */ -BOOL WINAPI GetTitleBarInfo(HWND hwnd, PTITLEBARINFO tbi) { - DWORD dwStyle; - DWORD dwExStyle; - - TRACE("(%p %p)\n", hwnd, tbi); - - if(!tbi) { - SetLastError(ERROR_NOACCESS); - return FALSE; - } - - if(tbi->cbSize != sizeof(TITLEBARINFO)) { - TRACE("Invalid TITLEBARINFO size: %ld\n", tbi->cbSize); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - dwStyle = GetWindowLongW(hwnd, GWL_STYLE); - dwExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE); - NC_GetInsideRect(hwnd, COORDS_SCREEN, &tbi->rcTitleBar, dwStyle, dwExStyle); - - tbi->rcTitleBar.bottom = tbi->rcTitleBar.top; - if(dwExStyle & WS_EX_TOOLWINDOW) - tbi->rcTitleBar.bottom += GetSystemMetrics(SM_CYSMCAPTION); - else { - tbi->rcTitleBar.bottom += GetSystemMetrics(SM_CYCAPTION); - tbi->rcTitleBar.left += GetSystemMetrics(SM_CXSIZE); - } - - ZeroMemory(tbi->rgstate, sizeof(tbi->rgstate)); - /* Does the title bar always have STATE_SYSTEM_FOCUSABLE? - * Under XP it seems to - */ - tbi->rgstate[0] = STATE_SYSTEM_FOCUSABLE; - if(dwStyle & WS_CAPTION) { - tbi->rgstate[1] = STATE_SYSTEM_INVISIBLE; - if(dwStyle & WS_SYSMENU) { - if(!(dwStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX))) { - tbi->rgstate[2] = STATE_SYSTEM_INVISIBLE; - tbi->rgstate[3] = STATE_SYSTEM_INVISIBLE; - } - else { - if(!(dwStyle & WS_MINIMIZEBOX)) - tbi->rgstate[2] = STATE_SYSTEM_UNAVAILABLE; - if(!(dwStyle & WS_MAXIMIZEBOX)) - tbi->rgstate[3] = STATE_SYSTEM_UNAVAILABLE; - } - if(!(dwExStyle & WS_EX_CONTEXTHELP)) - tbi->rgstate[4] = STATE_SYSTEM_INVISIBLE; - if(GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE) - tbi->rgstate[5] = STATE_SYSTEM_UNAVAILABLE; - } - else { - tbi->rgstate[2] = STATE_SYSTEM_INVISIBLE; - tbi->rgstate[3] = STATE_SYSTEM_INVISIBLE; - tbi->rgstate[4] = STATE_SYSTEM_INVISIBLE; - tbi->rgstate[5] = STATE_SYSTEM_INVISIBLE; - } - } - else - tbi->rgstate[0] |= STATE_SYSTEM_INVISIBLE; - return TRUE; -} diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index bed557ba67e..90ddad761f0 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -389,7 +389,7 @@ @ stdcall GetTaskmanWindow () @ stdcall GetThreadDesktop(long) NtUserGetThreadDesktop @ stdcall GetThreadDpiAwarenessContext() -@ stdcall GetTitleBarInfo(long ptr) +@ stdcall GetTitleBarInfo(long ptr) NtUserGetTitleBarInfo @ stdcall GetTopWindow(long) @ stdcall GetTouchInputInfo(long long ptr long) @ stdcall GetUpdateRect(long ptr long) NtUserGetUpdateRect diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index 9cb46c1c78b..c4eb9b76287 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -2512,3 +2512,76 @@ LRESULT desktop_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
return default_window_proc( hwnd, msg, wparam, lparam, FALSE ); } + +/*********************************************************************** + * NtUserGetTitleBarInfo (win32u.@) + */ +BOOL WINAPI NtUserGetTitleBarInfo( HWND hwnd, TITLEBARINFO *info ) +{ + DWORD style, ex_style; + + TRACE( "(%p %p)\n", hwnd, info ); + + if (!info) + { + SetLastError( ERROR_NOACCESS ); + return FALSE; + } + + if (info->cbSize != sizeof(TITLEBARINFO)) + { + TRACE( "Invalid TITLEBARINFO size: %d\n", info->cbSize ); + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + style = get_window_long( hwnd, GWL_STYLE ); + ex_style = get_window_long( hwnd, GWL_EXSTYLE ); + get_inside_rect( hwnd, COORDS_SCREEN, &info->rcTitleBar, style, ex_style ); + + info->rcTitleBar.bottom = info->rcTitleBar.top; + if (ex_style & WS_EX_TOOLWINDOW) + info->rcTitleBar.bottom += get_system_metrics( SM_CYSMCAPTION ); + else + { + info->rcTitleBar.bottom += get_system_metrics( SM_CYCAPTION ); + info->rcTitleBar.left += get_system_metrics( SM_CXSIZE ); + } + + memset( info->rgstate, 0, sizeof(info->rgstate) ); + info->rgstate[0] = STATE_SYSTEM_FOCUSABLE; + + if (style & WS_CAPTION) + { + info->rgstate[1] = STATE_SYSTEM_INVISIBLE; + if (style & WS_SYSMENU) + { + if (!(style & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX))) + { + info->rgstate[2] = STATE_SYSTEM_INVISIBLE; + info->rgstate[3] = STATE_SYSTEM_INVISIBLE; + } + else + { + if (!(style & WS_MINIMIZEBOX)) + info->rgstate[2] = STATE_SYSTEM_UNAVAILABLE; + if (!(style & WS_MAXIMIZEBOX)) + info->rgstate[3] = STATE_SYSTEM_UNAVAILABLE; + } + if (!(ex_style & WS_EX_CONTEXTHELP)) + info->rgstate[4] = STATE_SYSTEM_INVISIBLE; + if (get_class_long( hwnd, GCL_STYLE, FALSE ) & CS_NOCLOSE ) + info->rgstate[5] = STATE_SYSTEM_UNAVAILABLE; + } + else + { + info->rgstate[2] = STATE_SYSTEM_INVISIBLE; + info->rgstate[3] = STATE_SYSTEM_INVISIBLE; + info->rgstate[4] = STATE_SYSTEM_INVISIBLE; + info->rgstate[5] = STATE_SYSTEM_INVISIBLE; + } + } + else + info->rgstate[0] |= STATE_SYSTEM_INVISIBLE; + return TRUE; +} diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index 6bbdfc66f50..ffb1529e03f 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -147,6 +147,7 @@ static void * const syscalls[] = NtUserGetProp, NtUserGetSystemDpiForProcess, NtUserGetThreadDesktop, + NtUserGetTitleBarInfo, NtUserGetWindowRgnEx, NtUserInitializeClientPfnArrays, NtUserInternalGetWindowText, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 7087e04653f..8d8f46705b8 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -997,7 +997,7 @@ @ stdcall NtUserGetSystemMenu(long long) @ stdcall -syscall NtUserGetThreadDesktop(long) @ stub NtUserGetThreadState -@ stub NtUserGetTitleBarInfo +@ stdcall -syscall NtUserGetTitleBarInfo(long ptr) @ stub NtUserGetTopLevelWindow @ stub NtUserGetTouchInputInfo @ stub NtUserGetTouchValidationStatus diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 27e1ba76c56..e1364c2811e 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -134,6 +134,7 @@ SYSCALL_ENTRY( NtUserGetProp ) \ SYSCALL_ENTRY( NtUserGetSystemDpiForProcess ) \ SYSCALL_ENTRY( NtUserGetThreadDesktop ) \ + SYSCALL_ENTRY( NtUserGetTitleBarInfo ) \ SYSCALL_ENTRY( NtUserGetWindowRgnEx ) \ SYSCALL_ENTRY( NtUserInitializeClientPfnArrays ) \ SYSCALL_ENTRY( NtUserInternalGetWindowText ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 6208c939310..08b8fb6f2a0 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -850,3 +850,11 @@ NTSTATUS WINAPI wow64_NtUserLockWindowUpdate( UINT *args )
return NtUserLockWindowUpdate( hwnd ); } + +NTSTATUS WINAPI wow64_NtUserGetTitleBarInfo( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + TITLEBARINFO *info = get_ptr( &args ); + + return NtUserGetTitleBarInfo( hwnd, info ); +} diff --git a/include/ntuser.h b/include/ntuser.h index 5abe9b9a3cb..76d0387eed7 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -609,6 +609,7 @@ DWORD WINAPI NtUserGetQueueStatus( UINT flags ); ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process ); HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert ); HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ); +BOOL WINAPI NtUserGetTitleBarInfo( HWND hwnd, TITLEBARINFO *info ); INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ); BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size ); BOOL WINAPI NtUserGetUpdateRect( HWND hwnd, RECT *rect, BOOL erase );
Huw Davies (@huw) commented about dlls/user32/nonclient.c:
{
HMODULE hmodule = LoadLibraryA( "shell32.dll" );
if (hmodule)
{
BOOL (WINAPI *aboutproc)(HWND, LPCSTR, LPCSTR, HICON);
extern const char * CDECL wine_get_version(void);
char app[256];
sprintf( app, "Wine %s", wine_get_version() );
aboutproc = (void *)GetProcAddress( hmodule, "ShellAboutA" );
if (aboutproc) aboutproc( hwnd, app, NULL, 0 );
FreeLibrary( hmodule );
}
}
break;
We probably want to remove the item (and the separator above it) from the SYSMENU then ;-)
Also, there are a couple of work-arounds for it in the menu tests that could also go away.
Huw Davies (@huw) commented about dlls/win32u/defwnd.c:
+/***********************************************************************
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) {
Left over K&R brace.
Huw Davies (@huw) commented about dlls/win32u/defwnd.c:
return 0;
}
+static LRESULT handle_nc_button_dbl_click( HWND hwnd, WPARAM wparam, LPARAM lparam ) +{
- /*if this is an icon, send a restore since we are handling a double click */
Missing space after the `/*`.
On Fri Jun 17 06:44:16 2022 +0000, Huw Davies wrote:
We probably want to remove the item (and the separator above it) from the SYSMENU then ;-) Also, there are a couple of work-arounds for it in the menu tests that could also go away.
Oh, right. Thinking more about it, once we have SC_TASKLIST converted, it should be easy enough to convert this one as well that we might as well keep it. I will push v2 without this patch and with other comments addressed.