From 86f9c8b1f6f8f5eb00c848e22b80a043726c6d8e Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 16 Jun 2022 22:33:26 +0200 Subject: [PATCH] win32u: Move NtUserGetTitleBarInfo implementation from user32. Signed-off-by: Jacek Caban --- 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 0bcbbe54548..3eb7ce7883b 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -33,28 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(nonclient); #define SC_ABOUTWINE (SC_SCREENSAVE+1) - /* 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 ) { @@ -164,42 +142,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; @@ -306,70 +248,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 2de4834be54..b67f4de2dd9 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -2514,3 +2514,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 );