win32u: Move NtUserGetSystemMenu implementation from user32.

This commit is contained in:
Jacek Caban 2022-04-15 00:54:36 +02:00 committed by Alexandre Julliard
parent fee6acf337
commit e411b98155
6 changed files with 140 additions and 135 deletions

View file

@ -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;

View file

@ -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
*

View file

@ -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,
};

View file

@ -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;
}

View file

@ -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 );

View file

@ -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
{