From: Jacek Caban jacek@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, ¶ms, 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 {