[PATCH 11/13] win32u: Move NtUserGetSystemMenu implementation from user32.

Jacek Caban wine at gitlab.winehq.org
Mon May 2 05:44:44 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

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


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



More information about the wine-devel mailing list