From 4604c4554007165e84d4dc44db215975923e2ba2 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 15 Apr 2022 00:54:36 +0200 Subject: [PATCH] win32u: Move NtUserGetSystemMenu implementation from user32. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/user32/controls.h | 1 + dlls/user32/defwnd.c | 6 ++--- dlls/user32/mdi.c | 4 ++-- dlls/user32/menu.c | 45 ++---------------------------------- dlls/user32/nonclient.c | 8 +++---- dlls/user32/user32.spec | 2 +- dlls/user32/user_main.c | 1 + dlls/win32u/class.c | 2 +- dlls/win32u/gdiobj.c | 1 + dlls/win32u/menu.c | 43 ++++++++++++++++++++++++++++++++++ dlls/win32u/ntuser_private.h | 2 ++ dlls/win32u/win32u.spec | 2 +- dlls/win32u/win32u_private.h | 1 + dlls/win32u/wrappers.c | 6 +++++ include/ntuser.h | 1 + 15 files changed, 70 insertions(+), 55 deletions(-) diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h index 6e6d7b7d214..1e5b1082d50 100644 --- a/dlls/user32/controls.h +++ b/dlls/user32/controls.h @@ -120,6 +120,7 @@ extern void MENU_TrackMouseMenuBar( HWND hwnd, INT ht, POINT pt ) DECLSPEC_HIDDE extern void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar ) DECLSPEC_HIDDEN; extern UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd ) DECLSPEC_HIDDEN; extern void MENU_EndMenu(HWND) DECLSPEC_HIDDEN; +extern HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu ) DECLSPEC_HIDDEN; /* nonclient area */ extern LRESULT NC_HandleNCPaint( HWND hwnd , HRGN clip) DECLSPEC_HIDDEN; diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index a885690ea82..047822d00d6 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -246,16 +246,16 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa /* Track system popup if click was in the caption area. */ if (hitcode==HTCAPTION || hitcode==HTSYSMENU) - TrackPopupMenu(GetSystemMenu(hwnd, FALSE), + TrackPopupMenu( NtUserGetSystemMenu(hwnd, FALSE), TPM_LEFTBUTTON | TPM_RIGHTBUTTON, - pt.x, pt.y, 0, hwnd, NULL); + pt.x, pt.y, 0, hwnd, NULL ); } break; case WM_POPUPSYSTEMMENU: /* This is an undocumented message used by the windows taskbar to display the system menu of windows that belong to other processes. */ - TrackPopupMenu( GetSystemMenu(hwnd, FALSE), TPM_LEFTBUTTON|TPM_RIGHTBUTTON, + TrackPopupMenu( NtUserGetSystemMenu(hwnd, FALSE), TPM_LEFTBUTTON|TPM_RIGHTBUTTON, (short)LOWORD(lParam), (short)HIWORD(lParam), 0, hwnd, NULL ); return 0; diff --git a/dlls/user32/mdi.c b/dlls/user32/mdi.c index 1b06143d4cf..e6a391e03c3 100644 --- a/dlls/user32/mdi.c +++ b/dlls/user32/mdi.c @@ -217,7 +217,7 @@ static BOOL is_close_enabled(HWND hwnd, HMENU hSysMenu) { if (GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE) return FALSE; - if (!hSysMenu) hSysMenu = GetSystemMenu(hwnd, FALSE); + if (!hSysMenu) hSysMenu = NtUserGetSystemMenu( hwnd, FALSE ); if (hSysMenu) { UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); @@ -835,7 +835,7 @@ static BOOL MDI_AugmentFrameMenu( HWND frame, HWND hChild ) if (!menu) return FALSE; /* create a copy of sysmenu popup and insert it into frame menu bar */ - if (!(hSysPopup = GetSystemMenu(hChild, FALSE))) + if (!(hSysPopup = NtUserGetSystemMenu( hChild, FALSE ))) { TRACE("child %p doesn't have a system menu\n", hChild); return FALSE; diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 761718182b5..2e9121598fa 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -387,7 +387,7 @@ static HMENU MENU_CopySysPopup(BOOL mdi) * However, the real system menu handle is sometimes seen in the * WM_MENUSELECT parameters (and Word 6 likes it this way). */ -static HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu ) +HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu ) { HMENU hMenu; @@ -3925,47 +3925,6 @@ HMENU WINAPI CreateMenu(void) } -/********************************************************************** - * GetSystemMenu (USER32.@) - */ -HMENU WINAPI GetSystemMenu( HWND hWnd, BOOL bRevert ) -{ - WND *wndPtr = WIN_GetPtr( hWnd ); - HMENU retvalue = 0; - - if (wndPtr == WND_DESKTOP) return 0; - if (wndPtr == WND_OTHER_PROCESS) - { - if (IsWindow( hWnd )) FIXME( "not supported on other process window %p\n", hWnd ); - } - else if (wndPtr) - { - if (wndPtr->hSysMenu && bRevert) - { - NtUserDestroyMenu( wndPtr->hSysMenu ); - wndPtr->hSysMenu = 0; - } - - if(!wndPtr->hSysMenu && (wndPtr->dwStyle & WS_SYSMENU) ) - wndPtr->hSysMenu = MENU_GetSysMenu( hWnd, 0 ); - - if( wndPtr->hSysMenu ) - { - POPUPMENU *menu; - retvalue = GetSubMenu(wndPtr->hSysMenu, 0); - - /* Store the dummy sysmenu handle to facilitate the refresh */ - /* of the close button if the SC_CLOSE item change */ - menu = MENU_GetMenu(retvalue); - if ( menu ) - menu->hSysMenuOwner = wndPtr->hSysMenu; - } - WIN_ReleasePtr( wndPtr ); - } - return bRevert ? 0 : retvalue; -} - - /******************************************************************* * SetSystemMenu (USER32.@) */ @@ -4024,7 +3983,7 @@ BOOL WINAPI GetMenuBarInfo( HWND hwnd, LONG idObject, LONG idItem, PMENUBARINFO hmenu = GetMenu(hwnd); break; case OBJID_SYSMENU: - hmenu = GetSystemMenu(hwnd, FALSE); + hmenu = NtUserGetSystemMenu( hwnd, FALSE ); break; default: return FALSE; diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c index a2b5a82a5e6..003ecb7e5e5 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -916,7 +916,7 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, DWORD style, UINT state; /* Go get the sysmenu */ - hSysMenu = GetSystemMenu(hwnd, FALSE); + hSysMenu = NtUserGetSystemMenu(hwnd, FALSE); state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* Draw a grayed close button if disabled or if SC_CLOSE is not there */ @@ -1213,7 +1213,7 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam ) BOOL pressed = TRUE; UINT state; DWORD wndStyle = GetWindowLongW( hwnd, GWL_STYLE); - HMENU hSysMenu = GetSystemMenu(hwnd, FALSE); + HMENU hSysMenu = NtUserGetSystemMenu(hwnd, FALSE); void (*paintButton)(HWND, HDC, BOOL, BOOL); @@ -1291,7 +1291,7 @@ static void NC_TrackCloseButton (HWND hwnd, WPARAM wParam, LPARAM lParam) MSG msg; HDC hdc; BOOL pressed = TRUE; - HMENU hSysMenu = GetSystemMenu(hwnd, FALSE); + HMENU hSysMenu = NtUserGetSystemMenu(hwnd, FALSE); UINT state; if(hSysMenu == 0) @@ -1508,7 +1508,7 @@ LRESULT NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam ) case HTSYSMENU: { - HMENU hSysMenu = GetSystemMenu(hwnd, FALSE); + 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 */ diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 0697bcfa841..8bccdab69c6 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -381,7 +381,7 @@ @ stdcall GetSubMenu(long long) @ stdcall GetSysColor(long) @ stdcall GetSysColorBrush(long) -@ stdcall GetSystemMenu(long long) +@ stdcall GetSystemMenu(long long) NtUserGetSystemMenu @ stdcall GetSystemMetrics(long) @ stdcall GetSystemMetricsForDpi(long long) @ stdcall GetTabbedTextExtentA(long str long long ptr) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index babd5f95e55..358177d33d2 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -166,6 +166,7 @@ static const struct user_callbacks user_funcs = ImmTranslateMessage, SetSystemMenu, free_win_ptr, + MENU_GetSysMenu, MENU_IsMenuActive, notify_ime, post_dde_message, diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index c52fcad6025..64ac48cad19 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -66,7 +66,7 @@ static pthread_mutex_t winproc_lock = PTHREAD_MUTEX_INITIALIZER; static struct list class_list = LIST_INIT( class_list ); -static HINSTANCE user32_module; +HINSTANCE user32_module = 0; /* find an existing winproc for a given function and type */ /* FIXME: probably should do something more clever than a linear search */ diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index ad04ba7ff78..6cc63800201 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1176,6 +1176,7 @@ static struct unix_funcs unix_funcs = NtUserGetMessage, NtUserGetPriorityClipboardFormat, NtUserGetQueueStatus, + NtUserGetSystemMenu, NtUserGetUpdateRect, NtUserGetUpdateRgn, NtUserGetUpdatedClipboardFormats, diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index 67abac37037..0da21675e68 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -1029,6 +1029,49 @@ static HMENU get_sub_menu( HMENU handle, INT pos ) return submenu; } +/********************************************************************** + * NtUserGetSystemMenu (win32u.@) + */ +HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert ) +{ + WND *win = get_win_ptr( hwnd ); + HMENU retvalue = 0; + + if (win == WND_DESKTOP || !win) return 0; + if (win == WND_OTHER_PROCESS) + { + if (is_window( hwnd )) FIXME( "not supported on other process window %p\n", hwnd ); + return 0; + } + + if (win->hSysMenu && revert) + { + NtUserDestroyMenu( win->hSysMenu ); + win->hSysMenu = 0; + } + + if (!win->hSysMenu && (win->dwStyle & WS_SYSMENU) && user_callbacks) + win->hSysMenu = user_callbacks->get_sys_menu( hwnd, 0 ); + + if (win->hSysMenu) + { + POPUPMENU *menu; + retvalue = get_sub_menu( win->hSysMenu, 0 ); + + /* Store the dummy sysmenu handle to facilitate the refresh */ + /* of the close button if the SC_CLOSE item change */ + menu = grab_menu_ptr( retvalue ); + if (menu) + { + menu->hSysMenuOwner = win->hSysMenu; + release_menu_ptr( menu ); + } + } + + release_win_ptr( win ); + return revert ? 0 : retvalue; +} + /********************************************************************** * NtUserSetMenuDefaultItem (win32u.@) */ diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 29e6b4eaf3e..acc3fdf6290 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -39,6 +39,7 @@ struct user_callbacks BOOL (WINAPI *pImmTranslateMessage)(HWND, UINT, WPARAM, LPARAM); BOOL (WINAPI *pSetSystemMenu)( HWND hwnd, HMENU menu ); void (CDECL *free_win_ptr)( struct tagWND *win ); + HMENU (CDECL *get_sys_menu)( HWND hwnd, HMENU popup ); HWND (CDECL *is_menu_active)(void); void (CDECL *notify_ime)( HWND hwnd, UINT param ); BOOL (CDECL *post_dde_message)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD dest_tid, @@ -289,6 +290,7 @@ extern void spy_exit_message( INT flag, HWND hwnd, UINT msg, LRESULT lreturn, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; /* class.c */ +extern HINSTANCE user32_module DECLSPEC_HIDDEN; WNDPROC alloc_winproc( WNDPROC func, BOOL ansi ) DECLSPEC_HIDDEN; WINDOWPROC *get_winproc_ptr( WNDPROC handle ) DECLSPEC_HIDDEN; BOOL is_winproc_unicode( WNDPROC proc, BOOL def_val ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 43db8421bb8..d94324b1290 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -994,7 +994,7 @@ @ stub NtUserGetScrollBarInfo @ stub NtUserGetSharedWindowData @ stdcall -syscall NtUserGetSystemDpiForProcess(long) -@ stub NtUserGetSystemMenu +@ stdcall NtUserGetSystemMenu(long long) @ stdcall -syscall NtUserGetThreadDesktop(long) @ stub NtUserGetThreadState @ stub NtUserGetTitleBarInfo diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 5a0787afca7..c40d2cb2a6f 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -238,6 +238,7 @@ struct unix_funcs BOOL (WINAPI *pNtUserGetMessage)( MSG *msg, HWND hwnd, UINT first, UINT last ); INT (WINAPI *pNtUserGetPriorityClipboardFormat)( UINT *list, INT count ); DWORD (WINAPI *pNtUserGetQueueStatus)( UINT flags ); + HMENU (WINAPI *pNtUserGetSystemMenu)( HWND hwnd, BOOL revert ); BOOL (WINAPI *pNtUserGetUpdateRect)( HWND hwnd, RECT *rect, BOOL erase ); INT (WINAPI *pNtUserGetUpdateRgn)( HWND hwnd, HRGN hrgn, BOOL erase ); BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size ); diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 9a87bccbb7a..e3e0781bdde 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -951,6 +951,12 @@ BOOL WINAPI NtUserGetMessage( MSG *msg, HWND hwnd, UINT first, UINT last ) return unix_funcs->pNtUserGetMessage( msg, hwnd, first, last ); } +HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert ) +{ + if (!unix_funcs) return 0; + return unix_funcs->pNtUserGetSystemMenu( hwnd, revert ); +} + BOOL WINAPI NtUserGetUpdateRect( HWND hwnd, RECT *rect, BOOL erase ) { if (!unix_funcs) return FALSE; diff --git a/include/ntuser.h b/include/ntuser.h index dfa9f53a187..d11cffb8950 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -557,6 +557,7 @@ HANDLE WINAPI NtUserGetProp( HWND hwnd, const WCHAR *str ); ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ); DWORD WINAPI NtUserGetQueueStatus( UINT flags ); ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process ); +HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert ); HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ); INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ); BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size );