win32u: Move menu handle management from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-03-25 12:19:05 +01:00 committed by Alexandre Julliard
parent af915de212
commit 27c0b997f0
17 changed files with 108 additions and 109 deletions

View File

@ -124,6 +124,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 void free_menu_items( void *ptr ) DECLSPEC_HIDDEN;
/* nonclient area */
extern LRESULT NC_HandleNCPaint( HWND hwnd , HRGN clip) DECLSPEC_HIDDEN;

View File

@ -240,7 +240,7 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
WND *wndPtr;
if (dlgInfo->hUserFont) DeleteObject( dlgInfo->hUserFont );
if (dlgInfo->hMenu) DestroyMenu( dlgInfo->hMenu );
if (dlgInfo->hMenu) NtUserDestroyMenu( dlgInfo->hMenu );
HeapFree( GetProcessHeap(), 0, dlgInfo );
wndPtr = WIN_GetPtr( hwnd );

View File

@ -639,7 +639,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
if (!hwnd)
{
if (hUserFont) DeleteObject( hUserFont );
if (hMenu) DestroyMenu( hMenu );
if (hMenu) NtUserDestroyMenu( hMenu );
if (disabled_owner) EnableWindow( disabled_owner, TRUE );
return 0;
}

View File

@ -3337,7 +3337,7 @@ static void EDIT_WM_ContextMenu(EDITSTATE *es, INT x, INT y)
if (cmd)
EDIT_ContextMenuCommand(es, cmd);
DestroyMenu(menu);
NtUserDestroyMenu(menu);
}

View File

@ -887,7 +887,7 @@ static BOOL MDI_AugmentFrameMenu( HWND frame, HWND hChild )
(UINT_PTR)hSysPopup, (LPSTR)hSysMenuBitmap))
{
TRACE("not inserted\n");
DestroyMenu(hSysPopup);
NtUserDestroyMenu( hSysPopup );
return FALSE;
}

View File

@ -59,7 +59,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu);
WINE_DECLARE_DEBUG_CHANNEL(accel);
/* Menu item structure */
typedef struct {
typedef struct menu_item {
/* ----------- MENUITEMINFO Stuff ----------- */
UINT fType; /* Item type. */
UINT fState; /* Item state. */
@ -79,32 +79,6 @@ typedef struct {
* bitmap */
} MENUITEM;
/* Popup menu structure */
typedef struct {
struct user_object obj;
WORD wFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */
WORD Width; /* Width of the whole menu */
WORD Height; /* Height of the whole menu */
UINT nItems; /* Number of items in the menu */
HWND hWnd; /* Window containing the menu */
MENUITEM *items; /* Array of menu items */
UINT FocusedItem; /* Currently focused item */
HWND hwndOwner; /* window receiving the messages for ownerdraw */
BOOL bScrolling; /* Scroll arrows are active */
UINT nScrollPos; /* Current scroll position */
UINT nTotalHeight; /* Total height of menu items inside menu */
RECT items_rect; /* Rectangle within which the items lie. Excludes margins and scroll arrows */
LONG refcount;
/* ------------ MENUINFO members ------ */
DWORD dwStyle; /* Extended menu style */
UINT cyMax; /* max height of the whole menu, 0 is screen height */
HBRUSH hbrBack; /* brush for menu background */
DWORD dwContextHelpID;
ULONG_PTR dwMenuData; /* application defined value */
HMENU hSysMenuOwner; /* Handle to the dummy sys menu holder */
WORD textOffset; /* Offset of text when items have both bitmaps and text */
} POPUPMENU, *LPPOPUPMENU;
/* internal flags for menu tracking */
#define TF_ENDMENU 0x10000
@ -477,7 +451,7 @@ static HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu )
TRACE("hMenu=%p (hPopup %p)\n", hMenu, hPopupMenu );
return hMenu;
}
DestroyMenu( hMenu );
NtUserDestroyMenu( hMenu );
}
ERR("failed to load system menu!\n");
return 0;
@ -2264,7 +2238,7 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
if (!mii.hSubMenu)
return NULL;
if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) {
DestroyMenu(mii.hSubMenu);
NtUserDestroyMenu( mii.hSubMenu );
return NULL;
}
mii.fMask |= MIIM_SUBMENU;
@ -4117,7 +4091,7 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UINT id, UINT flags )
return FALSE;
if (menu->items[pos].fType & MF_POPUP)
DestroyMenu(menu->items[pos].hSubMenu);
NtUserDestroyMenu( menu->items[pos].hSubMenu );
RemoveMenu(menu->obj.handle, pos, flags | MF_BYPOSITION);
release_menu_ptr(menu);
@ -4239,53 +4213,22 @@ BOOL WINAPI SetMenuItemBitmaps( HMENU hMenu, UINT nPos, UINT wFlags,
*/
HMENU WINAPI CreateMenu(void)
{
HMENU hMenu;
LPPOPUPMENU menu;
if (!(menu = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*menu) ))) return 0;
menu->FocusedItem = NO_SELECTED_ITEM;
menu->refcount = 1;
if (!(hMenu = alloc_user_handle( &menu->obj, NTUSER_OBJ_MENU ))) HeapFree( GetProcessHeap(), 0, menu );
TRACE("return %p\n", hMenu );
return hMenu;
return UlongToHandle( NtUserCallNoParam( NtUserCreateMenu ));
}
/**********************************************************************
* DestroyMenu (USER32.@)
*/
BOOL WINAPI DestroyMenu( HMENU hMenu )
void free_menu_items( void *ptr )
{
LPPOPUPMENU lppop;
POPUPMENU *menu = ptr;
MENUITEM *item = menu->items;
int i;
TRACE("(%p)\n", hMenu);
if (!(lppop = free_user_handle( hMenu, NTUSER_OBJ_MENU ))) return FALSE;
if (lppop == OBJ_OTHER_PROCESS) return FALSE;
/* DestroyMenu should not destroy system menu popup owner */
if ((lppop->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && lppop->hWnd)
for (i = menu->nItems; i > 0; i--, item++)
{
NtUserDestroyWindow( lppop->hWnd );
lppop->hWnd = 0;
if (item->fType & MF_POPUP) NtUserDestroyMenu( item->hSubMenu );
MENU_FreeItemData( item );
}
if (lppop->items) /* recursively destroy submenus */
{
int i;
MENUITEM *item = lppop->items;
for (i = lppop->nItems; i > 0; i--, item++)
{
if (item->fType & MF_POPUP) DestroyMenu(item->hSubMenu);
MENU_FreeItemData( item );
}
HeapFree( GetProcessHeap(), 0, lppop->items );
}
HeapFree( GetProcessHeap(), 0, lppop );
return TRUE;
HeapFree( GetProcessHeap(), 0, menu->items );
}
@ -4306,7 +4249,7 @@ HMENU WINAPI GetSystemMenu( HWND hWnd, BOOL bRevert )
{
if (wndPtr->hSysMenu && bRevert)
{
DestroyMenu(wndPtr->hSysMenu);
NtUserDestroyMenu( wndPtr->hSysMenu );
wndPtr->hSysMenu = 0;
}
@ -4339,7 +4282,7 @@ BOOL WINAPI SetSystemMenu( HWND hwnd, HMENU hMenu )
if (wndPtr && wndPtr != WND_OTHER_PROCESS && wndPtr != WND_DESKTOP)
{
if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
if (wndPtr->hSysMenu) NtUserDestroyMenu( wndPtr->hSysMenu );
wndPtr->hSysMenu = MENU_GetSysMenu( hwnd, hMenu );
WIN_ReleasePtr( wndPtr );
return TRUE;
@ -4670,7 +4613,7 @@ HMENU WINAPI LoadMenuIndirectW( LPCVOID template )
if (!(hMenu = CreateMenu())) return 0;
if (!MENU_ParseResource( p, hMenu ))
{
DestroyMenu( hMenu );
NtUserDestroyMenu( hMenu );
return 0;
}
return hMenu;
@ -4680,7 +4623,7 @@ HMENU WINAPI LoadMenuIndirectW( LPCVOID template )
if (!(hMenu = CreateMenu())) return 0;
if (!MENUEX_ParseResource( p, hMenu))
{
DestroyMenu( hMenu );
NtUserDestroyMenu( hMenu );
return 0;
}
return hMenu;

View File

@ -159,7 +159,7 @@
@ stdcall DestroyCaret()
@ stdcall DestroyCursor(long)
@ stdcall DestroyIcon(long)
@ stdcall DestroyMenu(long)
@ stdcall DestroyMenu(long) NtUserDestroyMenu
# @ stub DestroyReasons
@ stdcall DestroyWindow(long) NtUserDestroyWindow
# @ stub DeviceEventWorker

View File

@ -162,7 +162,6 @@ static const struct user_callbacks user_funcs =
AdjustWindowRectEx,
CopyImage,
DestroyCaret,
DestroyMenu,
EndMenu,
HideCaret,
PostMessageW,
@ -174,6 +173,7 @@ static const struct user_callbacks user_funcs =
SetSystemMenu,
ShowCaret,
WaitForInputIdle,
free_menu_items,
free_win_ptr,
MENU_IsMenuActive,
notify_ime,

View File

@ -39,15 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
static DWORD process_layout = ~0u;
/***********************************************************************
* alloc_user_handle
*/
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type )
{
return UlongToHandle( NtUserCallTwoParam( (UINT_PTR)ptr, type, NtUserAllocHandle ));
}
/***********************************************************************
* get_user_handle_ptr
*/
@ -67,15 +58,6 @@ void release_user_handle_ptr( void *ptr )
}
/***********************************************************************
* free_user_handle
*/
void *free_user_handle( HANDLE handle, unsigned int type )
{
return UlongToHandle( NtUserCallTwoParam( HandleToUlong(handle), type, NtUserFreeHandle ));
}
/*******************************************************************
* list_window_children
*
@ -672,7 +654,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
hwnd = NtUserCreateWindowEx( cs->dwExStyle, &class, NULL, NULL, cs->style, cs->x, cs->y,
cs->cx, cs->cy, cs->hwndParent, menu, module,
cs->lpCreateParams, 0, &cbtc, 0, !unicode );
if (!hwnd && menu && menu != cs->hMenu) DestroyMenu( menu );
if (!hwnd && menu && menu != cs->hMenu) NtUserDestroyMenu( menu );
return hwnd;
}

View File

@ -1163,6 +1163,7 @@ static struct unix_funcs unix_funcs =
NtUserCreateWindowEx,
NtUserDeferWindowPosAndBand,
NtUserDestroyCursor,
NtUserDestroyMenu,
NtUserDestroyWindow,
NtUserDispatchMessage,
NtUserDrawIconEx,

View File

@ -27,6 +27,7 @@
#include "ntuser_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(menu);
WINE_DECLARE_DEBUG_CHANNEL(accel);
/* the accelerator user object */
@ -37,6 +38,9 @@ struct accelerator
ACCEL table[1];
};
/* (other menu->FocusedItem values give the position of the focused item) */
#define NO_SELECTED_ITEM 0xffff
/**********************************************************************
* NtUserCopyAcceleratorTable (win32u.@)
*/
@ -112,12 +116,46 @@ HMENU get_menu( HWND hwnd )
return UlongToHandle( get_window_long( hwnd, GWLP_ID ));
}
/* see CreateMenu */
HMENU create_menu(void)
{
POPUPMENU *menu;
HMENU handle;
if (!(menu = calloc( 1, sizeof(*menu) ))) return 0;
menu->FocusedItem = NO_SELECTED_ITEM;
menu->refcount = 1;
if (!(handle = alloc_user_handle( &menu->obj, NTUSER_OBJ_MENU ))) free( menu );
TRACE( "return %p\n", handle );
return handle;
}
/**********************************************************************
* NtUserDestroyMenu (win32u.@)
*/
BOOL WINAPI NtUserDestroyMenu( HMENU menu )
BOOL WINAPI NtUserDestroyMenu( HMENU handle )
{
return user_callbacks && user_callbacks->pDestroyMenu( menu );
POPUPMENU *menu;
TRACE( "(%p)\n", handle );
if (!(menu = free_user_handle( handle, NTUSER_OBJ_MENU ))) return FALSE;
if (menu == OBJ_OTHER_PROCESS) return FALSE;
/* DestroyMenu should not destroy system menu popup owner */
if ((menu->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && menu->hWnd)
{
NtUserDestroyWindow( menu->hWnd );
menu->hWnd = 0;
}
if (menu->items && user_callbacks) /* recursively destroy submenus */
user_callbacks->free_menu_items( menu );
free( menu );
return TRUE;
}
/*******************************************************************

View File

@ -33,7 +33,6 @@ struct user_callbacks
BOOL (WINAPI *pAdjustWindowRectEx)( RECT *, DWORD, BOOL, DWORD );
HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT );
BOOL (WINAPI *pDestroyCaret)(void);
BOOL (WINAPI *pDestroyMenu)( HMENU );
BOOL (WINAPI *pEndMenu)(void);
BOOL (WINAPI *pHideCaret)( HWND hwnd );
BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM );
@ -45,6 +44,7 @@ struct user_callbacks
BOOL (WINAPI *pSetSystemMenu)( HWND hwnd, HMENU menu );
BOOL (WINAPI *pShowCaret)( HWND hwnd );
DWORD (WINAPI *pWaitForInputIdle)( HANDLE, DWORD );
void (CDECL *free_menu_items)( void *ptr );
void (CDECL *free_win_ptr)( struct tagWND *win );
HWND (CDECL *is_menu_active)(void);
void (CDECL *notify_ime)( HWND hwnd, UINT param );
@ -199,6 +199,35 @@ enum builtin_winprocs
NB_BUILTIN_AW_WINPROCS = WINPROC_DESKTOP
};
struct menu_item;
/* FIXME: make it private to menu.c */
typedef struct
{
struct user_object obj;
WORD wFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */
WORD Width; /* Width of the whole menu */
WORD Height; /* Height of the whole menu */
UINT nItems; /* Number of items in the menu */
HWND hWnd; /* Window containing the menu */
struct menu_item *items; /* Array of menu items */
UINT FocusedItem; /* Currently focused item */
HWND hwndOwner; /* window receiving the messages for ownerdraw */
BOOL bScrolling; /* Scroll arrows are active */
UINT nScrollPos; /* Current scroll position */
UINT nTotalHeight; /* Total height of menu items inside menu */
RECT items_rect; /* Rectangle within which the items lie. Excludes margins and scroll arrows */
LONG refcount;
/* ------------ MENUINFO members ------ */
DWORD dwStyle; /* Extended menu style */
UINT cyMax; /* max height of the whole menu, 0 is screen height */
HBRUSH hbrBack; /* brush for menu background */
DWORD dwContextHelpID;
ULONG_PTR dwMenuData; /* application defined value */
HMENU hSysMenuOwner; /* Handle to the dummy sys menu holder */
WORD textOffset; /* Offset of text when items have both bitmaps and text */
} POPUPMENU, *LPPOPUPMENU;
/* FIXME: make it private to class.c */
typedef struct tagWINDOWPROC
{

View File

@ -4623,6 +4623,8 @@ ULONG_PTR WINAPI NtUserCallNoParam( ULONG code )
{
switch(code)
{
case NtUserCreateMenu:
return HandleToUlong( create_menu() );
case NtUserGetDesktopWindow:
return HandleToUlong( get_desktop_window() );
case NtUserGetInputState:
@ -4739,12 +4741,8 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code
case NtUserUnhookWindowsHook:
return unhook_windows_hook( arg1, (HOOKPROC)arg2 );
/* temporary exports */
case NtUserAllocHandle:
return HandleToUlong( alloc_user_handle( (struct user_object *)arg1, arg2 ));
case NtUserAllocWinProc:
return (UINT_PTR)alloc_winproc( (WNDPROC)arg1, arg2 );
case NtUserFreeHandle:
return (UINT_PTR)free_user_handle( UlongToHandle(arg1), arg2 );
case NtUserGetHandlePtr:
return (UINT_PTR)get_user_handle_ptr( UlongToHandle(arg1), arg2 );
default:

View File

@ -832,7 +832,7 @@
@ stdcall NtUserDestroyCursor(long long)
@ stub NtUserDestroyDCompositionHwndTarget
@ stub NtUserDestroyInputContext
@ stub NtUserDestroyMenu
@ stdcall NtUserDestroyMenu(long)
@ stub NtUserDestroyPalmRejectionDelayZone
@ stdcall NtUserDestroyWindow(long)
@ stub NtUserDisableImmersiveOwner

View File

@ -204,6 +204,7 @@ struct unix_funcs
INT x, INT y, INT cx, INT cy,
UINT flags, UINT unk1, UINT unk2 );
BOOL (WINAPI *pNtUserDestroyCursor)( HCURSOR cursor, ULONG arg );
BOOL (WINAPI *pNtUserDestroyMenu)( HMENU handle );
BOOL (WINAPI *pNtUserDestroyWindow)( HWND hwnd );
LRESULT (WINAPI *pNtUserDispatchMessage)( const MSG *msg );
BOOL (WINAPI *pNtUserDrawIconEx)( HDC hdc, INT x0, INT y0, HICON icon, INT width,
@ -336,6 +337,7 @@ extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECL
extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ) DECLSPEC_HIDDEN;
/* menu.c */
extern HMENU create_menu(void) DECLSPEC_HIDDEN;
extern HMENU get_menu( HWND hwnd ) DECLSPEC_HIDDEN;
/* message.c */

View File

@ -795,6 +795,12 @@ BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg )
return unix_funcs->pNtUserDestroyCursor( cursor, arg );
}
BOOL WINAPI NtUserDestroyMenu( HMENU handle )
{
if (!unix_funcs) return FALSE;
return unix_funcs->pNtUserDestroyMenu( handle );
}
BOOL WINAPI NtUserDestroyWindow( HWND hwnd )
{
if (!unix_funcs) return FALSE;

View File

@ -121,6 +121,7 @@ struct win_hook_params
/* NtUserCallNoParam codes, not compatible with Windows */
enum
{
NtUserCreateMenu,
NtUserGetDesktopWindow,
NtUserGetInputState,
NtUserReleaseCapture,
@ -169,9 +170,7 @@ enum
NtUserSetIconParam,
NtUserUnhookWindowsHook,
/* temporary exports */
NtUserAllocHandle,
NtUserAllocWinProc,
NtUserFreeHandle,
NtUserGetHandlePtr,
};