[PATCH 3/5] win32u: Move NtUserGetSystemMenu implementation from user32.

Jacek Caban wine at gitlab.winehq.org
Mon Jun 27 05:18:36 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

---
 dlls/user32/controls.h       |   6 --
 dlls/user32/menu.c           | 124 ---------------------------------
 dlls/user32/user_main.c      |   8 ++-
 dlls/win32u/menu.c           | 129 ++++++++++++++++++++++++++++++++++-
 dlls/win32u/ntuser_private.h |   1 -
 include/ntuser.h             |   7 ++
 6 files changed, 140 insertions(+), 135 deletions(-)

diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index 639b9f2214e..48127ca6bb2 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -112,12 +112,6 @@ extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ) DECLSPEC_HIDDEN;
 /* desktop */
 extern BOOL update_wallpaper( const WCHAR *wallpaper, const WCHAR *pattern ) DECLSPEC_HIDDEN;
 
-/* menu controls */
-extern void MENU_TrackMouseMenuBar( HWND hwnd, INT ht, POINT pt ) DECLSPEC_HIDDEN;
-extern void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar ) DECLSPEC_HIDDEN;
-extern void MENU_EndMenu(HWND) DECLSPEC_HIDDEN;
-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;
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 52dc6369e3a..07be830eed3 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -42,15 +42,10 @@
 #include <stdarg.h>
 #include <string.h>
 
-#define OEMRESOURCE
-
 #include "windef.h"
 #include "winbase.h"
 #include "wingdi.h"
 #include "winnls.h"
-#include "wine/server.h"
-#include "wine/exception.h"
-#include "win.h"
 #include "controls.h"
 #include "user_private.h"
 #include "wine/debug.h"
@@ -58,15 +53,6 @@
 WINE_DEFAULT_DEBUG_CHANNEL(menu);
 
 
-  /* Space between 2 columns */
-#define MENU_COL_SPACE 4
-
-  /* Margins for popup menus */
-#define MENU_MARGIN 3
-
-  /* (other menu->FocusedItem values give the position of the focused item) */
-#define NO_SELECTED_ITEM  0xffff
-
 #define MENU_ITEM_TYPE(flags) \
   ((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
 
@@ -96,116 +82,6 @@ const struct builtin_class_descr MENU_builtin_class =
 };
 
 
-/***********************************************************************
- *           MENU_GetMenu
- *
- * Validate the given menu handle and returns the menu structure pointer.
- */
-static POPUPMENU *MENU_GetMenu(HMENU hMenu)
-{
-    POPUPMENU *menu = get_user_handle_ptr( hMenu, NTUSER_OBJ_MENU );
-
-    if (menu == OBJ_OTHER_PROCESS)
-    {
-        WARN( "other process menu %p?\n", hMenu);
-        return NULL;
-    }
-    if (menu) release_user_handle_ptr( menu );  /* FIXME! */
-    else WARN("invalid menu handle=%p\n", hMenu);
-    return menu;
-}
-
-/***********************************************************************
- *           MENU_CopySysPopup
- *
- * Return the default system menu.
- */
-static HMENU MENU_CopySysPopup(BOOL mdi)
-{
-    HMENU hMenu = LoadMenuW(user32_module, mdi ? L"SYSMENUMDI" : L"SYSMENU");
-
-    if( hMenu ) {
-        MENUINFO minfo;
-        MENUITEMINFOW miteminfo;
-        POPUPMENU* menu = MENU_GetMenu(hMenu);
-        menu->wFlags |= MF_SYSMENU | MF_POPUP;
-        /* decorate the menu with bitmaps */
-        minfo.cbSize = sizeof( MENUINFO);
-        minfo.dwStyle = MNS_CHECKORBMP;
-        minfo.fMask = MIM_STYLE;
-        SetMenuInfo( hMenu, &minfo);
-        miteminfo.cbSize = sizeof( MENUITEMINFOW);
-        miteminfo.fMask = MIIM_BITMAP;
-        miteminfo.hbmpItem = HBMMENU_POPUP_CLOSE;
-        SetMenuItemInfoW( hMenu, SC_CLOSE, FALSE, &miteminfo);
-        miteminfo.hbmpItem = HBMMENU_POPUP_RESTORE;
-        SetMenuItemInfoW( hMenu, SC_RESTORE, FALSE, &miteminfo);
-        miteminfo.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
-        SetMenuItemInfoW( hMenu, SC_MAXIMIZE, FALSE, &miteminfo);
-        miteminfo.hbmpItem = HBMMENU_POPUP_MINIMIZE;
-        SetMenuItemInfoW( hMenu, SC_MINIMIZE, FALSE, &miteminfo);
-        NtUserSetMenuDefaultItem( hMenu, SC_CLOSE, FALSE );
-    }
-    else
-	ERR("Unable to load default system menu\n" );
-
-    TRACE("returning %p (mdi=%d).\n", hMenu, mdi );
-
-    return hMenu;
-}
-
-
-/**********************************************************************
- *           MENU_GetSysMenu
- *
- * Create a copy of the system menu. System menu in Windows is
- * a special menu bar with the single entry - system menu popup.
- * This popup is presented to the outside world as a "system menu".
- * However, the real system menu handle is sometimes seen in the
- * WM_MENUSELECT parameters (and Word 6 likes it this way).
- */
-HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu )
-{
-    HMENU hMenu;
-
-    TRACE("loading system menu, hWnd %p, hPopupMenu %p\n", hWnd, hPopupMenu);
-    if ((hMenu = CreateMenu()))
-    {
-	POPUPMENU *menu = MENU_GetMenu(hMenu);
-	menu->wFlags = MF_SYSMENU;
-	menu->hWnd = WIN_GetFullHandle( hWnd );
-	TRACE("hWnd %p (hMenu %p)\n", menu->hWnd, hMenu);
-
-	if (!hPopupMenu)
-        {
-            if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
-	        hPopupMenu = MENU_CopySysPopup(TRUE);
-            else
-	        hPopupMenu = MENU_CopySysPopup(FALSE);
-        }
-
-	if (hPopupMenu)
-	{
-            if (GetClassLongW(hWnd, GCL_STYLE) & CS_NOCLOSE)
-                NtUserDeleteMenu( hPopupMenu, SC_CLOSE, MF_BYCOMMAND );
-
-	    InsertMenuW( hMenu, -1, MF_SYSMENU | MF_POPUP | MF_BYPOSITION,
-                         (UINT_PTR)hPopupMenu, NULL );
-
-            menu->items[0].fType = MF_SYSMENU | MF_POPUP;
-            menu->items[0].fState = 0;
-            if ((menu = MENU_GetMenu(hPopupMenu))) menu->wFlags |= MF_SYSMENU;
-
-	    TRACE("hMenu=%p (hPopup %p)\n", hMenu, hPopupMenu );
-	    return hMenu;
-	}
-	NtUserDestroyMenu( hMenu );
-    }
-    ERR("failed to load system menu!\n");
-    return 0;
-}
-
-
 /**********************************************************************
  *         MENU_ParseResource
  *
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c
index 55e72dcf203..038f1f0796f 100644
--- a/dlls/user32/user_main.c
+++ b/dlls/user32/user_main.c
@@ -159,7 +159,6 @@ static const struct user_callbacks user_funcs =
     NtWaitForMultipleObjects,
     SCROLL_DrawNCScrollBar,
     free_win_ptr,
-    MENU_GetSysMenu,
     notify_ime,
     post_dde_message,
     rawinput_update_device_list,
@@ -190,6 +189,12 @@ static NTSTATUS WINAPI User32LoadImage( const struct load_image_params *params,
     return HandleToUlong( ret );
 }
 
+static NTSTATUS WINAPI User32LoadSysMenu( const struct load_sys_menu_params *params, ULONG size )
+{
+    HMENU ret = LoadMenuW( user32_module, params->mdi ? L"SYSMENUMDI" : L"SYSMENU" );
+    return HandleToUlong( ret );
+}
+
 static NTSTATUS WINAPI User32FreeCachedClipboardData( const struct free_cached_data_params *params,
                                                       ULONG size )
 {
@@ -221,6 +226,7 @@ static const void *kernel_callback_table[NtUserCallCount] =
     User32FreeCachedClipboardData,
     User32LoadDriver,
     User32LoadImage,
+    User32LoadSysMenu,
     User32RegisterBuiltinClasses,
     User32RenderSsynthesizedFormat,
 };
diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c
index cf755c57a15..64c832c58a9 100644
--- a/dlls/win32u/menu.c
+++ b/dlls/win32u/menu.c
@@ -1378,6 +1378,129 @@ BOOL WINAPI NtUserSetMenuContextHelpId( HMENU handle, DWORD id )
     return TRUE;
 }
 
+/***********************************************************************
+ *           copy_sys_popup
+ *
+ * Return the default system menu.
+ */
+static HMENU copy_sys_popup( BOOL mdi )
+{
+    struct load_sys_menu_params params;
+    MENUITEMINFOW item_info;
+    MENUINFO menu_info;
+    POPUPMENU *menu;
+    void *ret_ptr;
+    ULONG ret_len;
+    HMENU handle;
+
+    params.mdi = mdi;
+    handle = UlongToHandle( KeUserModeCallback( NtUserLoadSysMenu, &params, sizeof(params),
+                                                &ret_ptr, &ret_len ));
+
+    if (!handle || !(menu = grab_menu_ptr( handle )))
+    {
+        ERR("Unable to load default system menu\n" );
+        return 0;
+    }
+
+    menu->wFlags |= MF_SYSMENU | MF_POPUP;
+    release_menu_ptr( menu );
+
+    /* decorate the menu with bitmaps */
+    menu_info.cbSize = sizeof(MENUINFO);
+    menu_info.dwStyle = MNS_CHECKORBMP;
+    menu_info.fMask = MIM_STYLE;
+    NtUserThunkedMenuInfo( handle, &menu_info );
+    item_info.cbSize = sizeof(MENUITEMINFOW);
+    item_info.fMask = MIIM_BITMAP;
+    item_info.hbmpItem = HBMMENU_POPUP_CLOSE;
+    NtUserThunkedMenuItemInfo( handle, SC_CLOSE, 0, NtUserSetMenuItemInfo, &item_info, NULL );
+    item_info.hbmpItem = HBMMENU_POPUP_RESTORE;
+    NtUserThunkedMenuItemInfo( handle, SC_RESTORE, 0, NtUserSetMenuItemInfo, &item_info, NULL );
+    item_info.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
+    NtUserThunkedMenuItemInfo( handle, SC_MAXIMIZE, 0, NtUserSetMenuItemInfo, &item_info, NULL );
+    item_info.hbmpItem = HBMMENU_POPUP_MINIMIZE;
+    NtUserThunkedMenuItemInfo( handle, SC_MINIMIZE, 0, NtUserSetMenuItemInfo, &item_info, NULL );
+    NtUserSetMenuDefaultItem( handle, SC_CLOSE, FALSE );
+
+    TRACE( "returning %p (mdi=%d).\n", handle, mdi );
+    return handle;
+}
+
+/**********************************************************************
+ *           get_sys_menu
+ *
+ * Create a copy of the system menu. System menu in Windows is
+ * a special menu bar with the single entry - system menu popup.
+ * This popup is presented to the outside world as a "system menu".
+ * However, the real system menu handle is sometimes seen in the
+ * WM_MENUSELECT parameters (and Word 6 likes it this way).
+ */
+static HMENU get_sys_menu( HWND hwnd, HMENU popup_menu )
+{
+    MENUITEMINFOW info;
+    POPUPMENU *menu;
+    HMENU handle;
+
+    TRACE("loading system menu, hwnd %p, popup_menu %p\n", hwnd, popup_menu);
+    if (!(handle = create_menu( FALSE )))
+    {
+        ERR("failed to load system menu!\n");
+        return 0;
+    }
+
+    if (!(menu = grab_menu_ptr( handle )))
+    {
+        NtUserDestroyMenu( handle );
+        return 0;
+    }
+    menu->wFlags = MF_SYSMENU;
+    menu->hWnd = get_full_window_handle( hwnd );
+    release_menu_ptr( menu );
+    TRACE("hwnd %p (handle %p)\n", menu->hWnd, handle);
+
+    if (!popup_menu)
+    {
+        if (get_window_long(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
+            popup_menu = copy_sys_popup(TRUE);
+        else
+            popup_menu = copy_sys_popup(FALSE);
+    }
+    if (!popup_menu)
+    {
+        NtUserDestroyMenu( handle );
+        return 0;
+    }
+
+    if (get_class_long( hwnd, GCL_STYLE, FALSE ) & CS_NOCLOSE)
+        NtUserDeleteMenu(popup_menu, SC_CLOSE, MF_BYCOMMAND);
+
+    info.cbSize = sizeof(info);
+    info.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE | MIIM_SUBMENU;
+    info.fState = 0;
+    info.fType = MF_SYSMENU | MF_POPUP;
+    info.wID = (UINT_PTR)popup_menu;
+    info.hSubMenu = popup_menu;
+
+    NtUserThunkedMenuItemInfo( handle, -1, MF_SYSMENU | MF_POPUP | MF_BYPOSITION,
+                               NtUserInsertMenuItem, &info, NULL );
+
+    if ((menu = grab_menu_ptr( handle )))
+    {
+        menu->items[0].fType = MF_SYSMENU | MF_POPUP;
+        menu->items[0].fState = 0;
+        release_menu_ptr( menu );
+    }
+    if ((menu = grab_menu_ptr(popup_menu)))
+    {
+        menu->wFlags |= MF_SYSMENU;
+        release_menu_ptr( menu );
+    }
+
+    TRACE("handle=%p (hPopup %p)\n", handle, popup_menu );
+    return handle;
+}
+
 /**********************************************************************
  *           NtUserMenuItemFromPoint    (win32u.@)
  */
@@ -1414,8 +1537,8 @@ HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert )
         win->hSysMenu = 0;
     }
 
-    if (!win->hSysMenu && (win->dwStyle & WS_SYSMENU) && user_callbacks)
-        win->hSysMenu = user_callbacks->get_sys_menu( hwnd, 0 );
+    if (!win->hSysMenu && (win->dwStyle & WS_SYSMENU))
+        win->hSysMenu = get_sys_menu( hwnd, 0 );
 
     if (win->hSysMenu)
     {
@@ -1446,7 +1569,7 @@ BOOL WINAPI NtUserSetSystemMenu( HWND hwnd, HMENU menu )
     if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE;
 
     if (win->hSysMenu) NtUserDestroyMenu( win->hSysMenu );
-    win->hSysMenu = user_callbacks ? user_callbacks->get_sys_menu( hwnd, menu ) : NULL;
+    win->hSysMenu = get_sys_menu( hwnd, menu );
     release_win_ptr( win );
     return TRUE;
 }
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h
index eb851f57cdb..a5b77a85396 100644
--- a/dlls/win32u/ntuser_private.h
+++ b/dlls/win32u/ntuser_private.h
@@ -37,7 +37,6 @@ struct user_callbacks
     NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*);
     void (CDECL *draw_nc_scrollbar)( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical );
     void (CDECL *free_win_ptr)( struct tagWND *win );
-    HMENU (CDECL *get_sys_menu)( HWND hwnd, HMENU popup );
     void (CDECL *notify_ime)( HWND hwnd, UINT param );
     BOOL (CDECL *post_dde_message)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD dest_tid,
                                     DWORD type );
diff --git a/include/ntuser.h b/include/ntuser.h
index e1435bc2626..18ddbcaa4a4 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -37,6 +37,7 @@ enum
     NtUserFreeCachedClipboardData,
     NtUserLoadDriver,
     NtUserLoadImage,
+    NtUserLoadSysMenu,
     NtUserRegisterBuiltinClasses,
     NtUserRenderSynthesizedFormat,
     /* win16 hooks */
@@ -187,6 +188,12 @@ struct load_image_params
     UINT flags;
 };
 
+/* NtUserLoadSysMenu params */
+struct load_sys_menu_params
+{
+    BOOL mdi;
+};
+
 /* NtUserRenderSynthesizedFormat params */
 struct render_synthesized_format_params
 {
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/321



More information about the wine-devel mailing list