mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-28 04:13:35 +00:00
[Win32k]
- Fix G/SetSystemMenu. Move code into menu.c. - Add loading for MDI system menu. svn path=/trunk/; revision=63455
This commit is contained in:
@@ -345,6 +345,8 @@ typedef struct tagMENULIST
|
||||
#define MNF_DESKTOPMN 0x0040
|
||||
#define MNF_SYSDESKMN 0x0080
|
||||
#define MNF_SYSSUBMENU 0x0100
|
||||
// Hack
|
||||
#define MNF_SYSMENU 0x0200
|
||||
|
||||
typedef struct tagMENU
|
||||
{
|
||||
|
||||
@@ -915,7 +915,7 @@ IntSetMenuItemInfo(PMENU MenuObject, PITEM MenuItem, PROSMENUITEMINFO lpmii, PUN
|
||||
}
|
||||
}
|
||||
|
||||
if( !(MenuObject->fFlags & MNF_SYSDESKMN) &&
|
||||
if( !(MenuObject->fFlags & MNF_SYSMENU) &&
|
||||
!MenuItem->Xlpstr &&
|
||||
!lpmii->dwTypeData &&
|
||||
!(MenuItem->fType & MFT_OWNERDRAW) &&
|
||||
@@ -1430,7 +1430,7 @@ HMENU FASTCALL UserCreateMenu(BOOL PopupMenu)
|
||||
return (HMENU)0;
|
||||
}
|
||||
Menu = IntCreateMenu(&Handle, !PopupMenu);
|
||||
if (Menu->head.rpdesk->rpwinstaParent != WinStaObject)
|
||||
if (Menu && Menu->head.rpdesk->rpwinstaParent != WinStaObject)
|
||||
{
|
||||
ERR("Desktop Window Station does not match Process one!\n");
|
||||
}
|
||||
@@ -1658,6 +1658,183 @@ IntGetMenuItemRect(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PMENU FASTCALL MENU_GetSystemMenu(PWND Window, PMENU Popup)
|
||||
{
|
||||
PMENU Menu, NewMenu = NULL, SysMenu = NULL;
|
||||
HMENU hSysMenu, hNewMenu = NULL;
|
||||
ROSMENUITEMINFO ItemInfoSet = {0};
|
||||
ROSMENUITEMINFO ItemInfo = {0};
|
||||
UNICODE_STRING MenuName;
|
||||
|
||||
hSysMenu = UserCreateMenu(FALSE);
|
||||
if (NULL == hSysMenu)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
SysMenu = IntGetMenuObject(hSysMenu);
|
||||
if (NULL == SysMenu)
|
||||
{
|
||||
UserDestroyMenu(hSysMenu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SysMenu->fFlags |= MNF_SYSMENU;
|
||||
SysMenu->hWnd = Window->head.h;
|
||||
|
||||
if (!Popup)
|
||||
{
|
||||
//hNewMenu = co_IntLoadSysMenuTemplate();
|
||||
//if ( Window->ExStyle & WS_EX_MDICHILD )
|
||||
//{
|
||||
// RtlInitUnicodeString( &MenuName, L"SYSMENUMDI");
|
||||
// hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
|
||||
//}
|
||||
//else
|
||||
{
|
||||
RtlInitUnicodeString( &MenuName, L"SYSMENU");
|
||||
hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
|
||||
//ERR("%wZ\n",&MenuName);
|
||||
}
|
||||
if (!hNewMenu)
|
||||
{
|
||||
ERR("No Menu!!\n");
|
||||
IntReleaseMenuObject(SysMenu);
|
||||
UserDestroyMenu(hSysMenu);
|
||||
return NULL;
|
||||
}
|
||||
Menu = IntGetMenuObject(hNewMenu);
|
||||
if (!Menu)
|
||||
{
|
||||
IntReleaseMenuObject(SysMenu);
|
||||
UserDestroyMenu(hSysMenu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Do the rest in here.
|
||||
|
||||
Menu->fFlags |= MNS_CHECKORBMP | MNF_SYSMENU | MNF_POPUP;
|
||||
|
||||
ItemInfoSet.cbSize = sizeof( MENUITEMINFOW);
|
||||
ItemInfoSet.fMask = MIIM_BITMAP;
|
||||
ItemInfoSet.hbmpItem = HBMMENU_POPUP_CLOSE;
|
||||
IntMenuItemInfo(Menu, SC_CLOSE, FALSE, &ItemInfoSet, TRUE, NULL);
|
||||
ItemInfoSet.hbmpItem = HBMMENU_POPUP_RESTORE;
|
||||
IntMenuItemInfo(Menu, SC_RESTORE, FALSE, &ItemInfoSet, TRUE, NULL);
|
||||
ItemInfoSet.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
|
||||
IntMenuItemInfo(Menu, SC_MAXIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
|
||||
ItemInfoSet.hbmpItem = HBMMENU_POPUP_MINIMIZE;
|
||||
IntMenuItemInfo(Menu, SC_MINIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
|
||||
|
||||
NewMenu = IntCloneMenu(Menu);
|
||||
|
||||
IntReleaseMenuObject(NewMenu);
|
||||
UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
|
||||
|
||||
IntDestroyMenuObject(Menu, FALSE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewMenu = Popup;
|
||||
}
|
||||
if (NewMenu)
|
||||
{
|
||||
NewMenu->fFlags |= MNF_SYSMENU | MNF_POPUP;
|
||||
|
||||
if (Window->pcls->style & CS_NOCLOSE)
|
||||
IntRemoveMenuItem(NewMenu, SC_CLOSE, MF_BYCOMMAND, TRUE);
|
||||
|
||||
ItemInfo.cbSize = sizeof(MENUITEMINFOW);
|
||||
ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU;
|
||||
ItemInfo.fType = 0;
|
||||
ItemInfo.fState = MFS_ENABLED;
|
||||
ItemInfo.dwTypeData = NULL;
|
||||
ItemInfo.cch = 0;
|
||||
ItemInfo.hSubMenu = UserHMGetHandle(NewMenu);
|
||||
IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo, NULL);
|
||||
|
||||
return SysMenu;
|
||||
}
|
||||
ERR("failed to load system menu!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PMENU FASTCALL
|
||||
IntGetSystemMenu(PWND Window, BOOL bRevert)
|
||||
{
|
||||
PMENU Menu;
|
||||
|
||||
if (bRevert)
|
||||
{
|
||||
if (Window->SystemMenu)
|
||||
{
|
||||
Menu = UserGetMenuObject(Window->SystemMenu);
|
||||
if (Menu && !(Menu->fFlags & MNF_SYSDESKMN))
|
||||
{
|
||||
IntDestroyMenuObject(Menu, TRUE, TRUE);
|
||||
Window->SystemMenu = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Menu = Window->SystemMenu ? UserGetMenuObject(Window->SystemMenu) : NULL;
|
||||
if ((!Window->SystemMenu || Menu->fFlags & MNF_SYSDESKMN) && Window->style & WS_SYSMENU)
|
||||
{
|
||||
Menu = MENU_GetSystemMenu(Window, NULL);
|
||||
Window->SystemMenu = Menu ? UserHMGetHandle(Menu) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (Window->SystemMenu)
|
||||
{
|
||||
HMENU hMenu = IntGetSubMenu( Window->SystemMenu, 0);
|
||||
/* Store the dummy sysmenu handle to facilitate the refresh */
|
||||
/* of the close button if the SC_CLOSE item change */
|
||||
Menu = UserGetMenuObject(hMenu);
|
||||
if (Menu)
|
||||
{
|
||||
Menu->spwndNotify = Window;
|
||||
Menu->fFlags |= MNF_SYSSUBMENU;
|
||||
}
|
||||
return Menu;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
IntSetSystemMenu(PWND Window, PMENU Menu)
|
||||
{
|
||||
PMENU OldMenu;
|
||||
|
||||
if (!(Window->style & WS_SYSMENU)) return FALSE;
|
||||
|
||||
if (Window->SystemMenu)
|
||||
{
|
||||
OldMenu = UserGetMenuObject(Window->SystemMenu);
|
||||
if (OldMenu)
|
||||
{
|
||||
OldMenu->fFlags &= ~MNF_SYSMENU;
|
||||
IntDestroyMenuObject(OldMenu, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
OldMenu = MENU_GetSystemMenu(Window, Menu);
|
||||
if (OldMenu)
|
||||
{ // Use spmenuSys too!
|
||||
Window->SystemMenu = UserHMGetHandle(OldMenu);
|
||||
}
|
||||
else
|
||||
Window->SystemMenu = NULL;
|
||||
|
||||
if (Menu && Window != Menu->spwndNotify)
|
||||
{
|
||||
Menu->spwndNotify = Window;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
@@ -1716,6 +1893,107 @@ CLEANUP:
|
||||
END_CLEANUP;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtUserGetSystemMenu
|
||||
*
|
||||
* The NtUserGetSystemMenu function allows the application to access the
|
||||
* window menu (also known as the system menu or the control menu) for
|
||||
* copying and modifying.
|
||||
*
|
||||
* Parameters
|
||||
* hWnd
|
||||
* Handle to the window that will own a copy of the window menu.
|
||||
* bRevert
|
||||
* Specifies the action to be taken. If this parameter is FALSE,
|
||||
* NtUserGetSystemMenu returns a handle to the copy of the window menu
|
||||
* currently in use. The copy is initially identical to the window menu
|
||||
* but it can be modified.
|
||||
* If this parameter is TRUE, GetSystemMenu resets the window menu back
|
||||
* to the default state. The previous window menu, if any, is destroyed.
|
||||
*
|
||||
* Return Value
|
||||
* If the bRevert parameter is FALSE, the return value is a handle to a
|
||||
* copy of the window menu. If the bRevert parameter is TRUE, the return
|
||||
* value is NULL.
|
||||
*
|
||||
* Status
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
HMENU APIENTRY
|
||||
NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
|
||||
{
|
||||
PWND Window;
|
||||
PMENU Menu;
|
||||
DECLARE_RETURN(HMENU);
|
||||
|
||||
TRACE("Enter NtUserGetSystemMenu\n");
|
||||
UserEnterShared();
|
||||
|
||||
if (!(Window = UserGetWindowObject(hWnd)))
|
||||
{
|
||||
RETURN(NULL);
|
||||
}
|
||||
|
||||
if (!(Menu = IntGetSystemMenu(Window, bRevert)))
|
||||
{
|
||||
RETURN(NULL);
|
||||
}
|
||||
|
||||
RETURN(Menu->head.h);
|
||||
|
||||
CLEANUP:
|
||||
TRACE("Leave NtUserGetSystemMenu, ret=%p\n", _ret_);
|
||||
UserLeave();
|
||||
END_CLEANUP;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtUserSetSystemMenu
|
||||
*
|
||||
* Status
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
BOOL APIENTRY
|
||||
NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
|
||||
{
|
||||
BOOL Result = FALSE;
|
||||
PWND Window;
|
||||
PMENU Menu;
|
||||
DECLARE_RETURN(BOOL);
|
||||
|
||||
TRACE("Enter NtUserSetSystemMenu\n");
|
||||
UserEnterExclusive();
|
||||
|
||||
if (!(Window = UserGetWindowObject(hWnd)))
|
||||
{
|
||||
RETURN( FALSE);
|
||||
}
|
||||
|
||||
if (hMenu)
|
||||
{
|
||||
/*
|
||||
* Assign new menu handle and Up the Lock Count.
|
||||
*/
|
||||
if (!(Menu = IntGetMenuObject(hMenu)))
|
||||
{
|
||||
RETURN( FALSE);
|
||||
}
|
||||
|
||||
Result = IntSetSystemMenu(Window, Menu);
|
||||
}
|
||||
else
|
||||
EngSetLastError(ERROR_INVALID_MENU_HANDLE);
|
||||
|
||||
RETURN( Result);
|
||||
|
||||
CLEANUP:
|
||||
TRACE("Leave NtUserSetSystemMenu, ret=%i\n",_ret_);
|
||||
UserLeave();
|
||||
END_CLEANUP;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -1908,7 +2186,7 @@ NtUserGetMenuBarInfo(
|
||||
break;
|
||||
case OBJID_SYSMENU:
|
||||
if (!(pWnd->style & WS_SYSMENU)) RETURN(FALSE);
|
||||
Menu = IntGetSystemMenu(pWnd, FALSE, FALSE);
|
||||
Menu = IntGetSystemMenu(pWnd, FALSE);
|
||||
hMenu = Menu->head.h;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -41,7 +41,7 @@ BOOL FASTCALL
|
||||
IntInsertMenuItem(_In_ PMENU MenuObject, UINT uItem, BOOL fByPosition, PROSMENUITEMINFO ItemInfo, PUNICODE_STRING lpstr);
|
||||
|
||||
PMENU FASTCALL
|
||||
IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu);
|
||||
IntGetSystemMenu(PWND Window, BOOL bRevert);
|
||||
|
||||
UINT FASTCALL IntFindSubMenu(HMENU *hMenu, HMENU hSubTarget );
|
||||
UINT FASTCALL IntGetMenuState( HMENU hMenu, UINT uId, UINT uFlags);
|
||||
|
||||
@@ -895,148 +895,6 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread)
|
||||
}
|
||||
}
|
||||
|
||||
PMENU FASTCALL
|
||||
IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
|
||||
{
|
||||
PMENU Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
|
||||
PTHREADINFO W32Thread;
|
||||
HMENU hNewMenu, hSysMenu;
|
||||
ROSMENUITEMINFO ItemInfoSet = {0};
|
||||
ROSMENUITEMINFO ItemInfo = {0};
|
||||
UNICODE_STRING MenuName;
|
||||
|
||||
if(bRevert)
|
||||
{
|
||||
W32Thread = PsGetCurrentThreadWin32Thread();
|
||||
|
||||
if(!W32Thread->rpdesk)
|
||||
return NULL;
|
||||
|
||||
if(Window->SystemMenu)
|
||||
{
|
||||
Menu = UserGetMenuObject(Window->SystemMenu);
|
||||
if(Menu)
|
||||
{
|
||||
IntDestroyMenuObject(Menu, TRUE, TRUE);
|
||||
Window->SystemMenu = (HMENU)0;
|
||||
}
|
||||
}
|
||||
|
||||
if(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate)
|
||||
{
|
||||
/* Clone system menu */
|
||||
Menu = UserGetMenuObject(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate);
|
||||
if(!Menu)
|
||||
return NULL;
|
||||
|
||||
NewMenu = IntCloneMenu(Menu);
|
||||
if(NewMenu)
|
||||
{ // Use spmenuSys
|
||||
Window->SystemMenu = NewMenu->head.h;
|
||||
NewMenu->fFlags |= MNF_SYSDESKMN;
|
||||
NewMenu->hWnd = Window->head.h;
|
||||
ret = NewMenu;
|
||||
//IntReleaseMenuObject(NewMenu);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hSysMenu = UserCreateMenu(FALSE);
|
||||
if (NULL == hSysMenu)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
SysMenu = IntGetMenuObject(hSysMenu);
|
||||
if (NULL == SysMenu)
|
||||
{
|
||||
UserDestroyMenu(hSysMenu);
|
||||
return NULL;
|
||||
}
|
||||
SysMenu->fFlags |= MNF_SYSDESKMN;
|
||||
SysMenu->hWnd = Window->head.h;
|
||||
//hNewMenu = co_IntLoadSysMenuTemplate();
|
||||
//if ( Window->ExStyle & WS_EX_MDICHILD )
|
||||
//{
|
||||
// RtlInitUnicodeString( &MenuName, L"SYSMENUMDI");
|
||||
// hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
|
||||
//}
|
||||
//else
|
||||
{
|
||||
RtlInitUnicodeString( &MenuName, L"SYSMENU");
|
||||
hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
|
||||
//ERR("%wZ\n",&MenuName);
|
||||
}
|
||||
if(!hNewMenu)
|
||||
{
|
||||
ERR("No Menu!!\n");
|
||||
IntReleaseMenuObject(SysMenu);
|
||||
UserDestroyMenu(hSysMenu);
|
||||
return NULL;
|
||||
}
|
||||
Menu = IntGetMenuObject(hNewMenu);
|
||||
if(!Menu)
|
||||
{
|
||||
IntReleaseMenuObject(SysMenu);
|
||||
UserDestroyMenu(hSysMenu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Do the rest in here.
|
||||
|
||||
Menu->fFlags |= MNS_CHECKORBMP | MNF_SYSDESKMN | MNF_POPUP;
|
||||
|
||||
ItemInfoSet.cbSize = sizeof( MENUITEMINFOW);
|
||||
ItemInfoSet.fMask = MIIM_BITMAP;
|
||||
ItemInfoSet.hbmpItem = HBMMENU_POPUP_CLOSE;
|
||||
IntMenuItemInfo(Menu, SC_CLOSE, FALSE, &ItemInfoSet, TRUE, NULL);
|
||||
ItemInfoSet.hbmpItem = HBMMENU_POPUP_RESTORE;
|
||||
IntMenuItemInfo(Menu, SC_RESTORE, FALSE, &ItemInfoSet, TRUE, NULL);
|
||||
ItemInfoSet.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
|
||||
IntMenuItemInfo(Menu, SC_MAXIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
|
||||
ItemInfoSet.hbmpItem = HBMMENU_POPUP_MINIMIZE;
|
||||
IntMenuItemInfo(Menu, SC_MINIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
|
||||
|
||||
NewMenu = IntCloneMenu(Menu);
|
||||
if(NewMenu)
|
||||
{
|
||||
NewMenu->fFlags |= MNF_SYSDESKMN | MNF_POPUP;
|
||||
// Do not set MNS_CHECKORBMP it breaks menus, also original code destroyed the style anyway.
|
||||
IntReleaseMenuObject(NewMenu);
|
||||
UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
|
||||
|
||||
if (Window->pcls->style & CS_NOCLOSE)
|
||||
IntRemoveMenuItem(NewMenu, SC_CLOSE, MF_BYCOMMAND, TRUE);
|
||||
|
||||
ItemInfo.cbSize = sizeof(MENUITEMINFOW);
|
||||
ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU;
|
||||
ItemInfo.fType = 0;
|
||||
ItemInfo.fState = MFS_ENABLED;
|
||||
ItemInfo.dwTypeData = NULL;
|
||||
ItemInfo.cch = 0;
|
||||
ItemInfo.hSubMenu = NewMenu->head.h;
|
||||
IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo, NULL);
|
||||
|
||||
Window->SystemMenu = SysMenu->head.h;
|
||||
|
||||
ret = SysMenu;
|
||||
}
|
||||
IntDestroyMenuObject(Menu, FALSE, TRUE);
|
||||
}
|
||||
if(RetMenu)
|
||||
return ret;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Window->SystemMenu)
|
||||
return IntGetMenuObject((HMENU)Window->SystemMenu);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL FASTCALL
|
||||
IntIsChildWindow(PWND Parent, PWND BaseWindow)
|
||||
{
|
||||
@@ -1450,32 +1308,6 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
|
||||
return( hWndOldParent);
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
IntSetSystemMenu(PWND Window, PMENU Menu)
|
||||
{
|
||||
PMENU OldMenu;
|
||||
if(Window->SystemMenu)
|
||||
{
|
||||
OldMenu = IntGetMenuObject(Window->SystemMenu);
|
||||
if(OldMenu)
|
||||
{
|
||||
OldMenu->fFlags &= ~ MNF_SYSDESKMN;
|
||||
IntReleaseMenuObject(OldMenu);
|
||||
}
|
||||
}
|
||||
|
||||
if(Menu)
|
||||
{
|
||||
/* FIXME: Check window style, propably return FALSE? */
|
||||
Window->SystemMenu = Menu->head.h;
|
||||
Menu->fFlags |= MNF_SYSDESKMN;
|
||||
}
|
||||
else // Use spmenuSys too!
|
||||
Window->SystemMenu = (HMENU)0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Unlink the window from siblings. children and parent are kept in place. */
|
||||
VOID FASTCALL
|
||||
IntUnlinkWindow(PWND Wnd)
|
||||
@@ -1784,7 +1616,6 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
|
||||
PWND pWnd = NULL;
|
||||
HWND hWnd;
|
||||
PTHREADINFO pti = NULL;
|
||||
PMENU SystemMenu;
|
||||
BOOL MenuChanged;
|
||||
BOOL bUnicodeWindow;
|
||||
|
||||
@@ -2012,22 +1843,13 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
|
||||
if (!(pWnd->style & (WS_CHILD | WS_POPUP)))
|
||||
pWnd->state |= WNDS_SENDSIZEMOVEMSGS;
|
||||
|
||||
/* Create system menu */
|
||||
if ((Cs->style & WS_SYSMENU)) // && (dwStyle & WS_CAPTION) == WS_CAPTION)
|
||||
{
|
||||
SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE);
|
||||
if(SystemMenu)
|
||||
{ // spmenuSys
|
||||
pWnd->SystemMenu = SystemMenu->head.h;
|
||||
IntReleaseMenuObject(SystemMenu);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the window menu */
|
||||
if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
|
||||
{
|
||||
if (Cs->hMenu)
|
||||
if (Cs->hMenu)
|
||||
{
|
||||
IntSetMenu(pWnd, Cs->hMenu, &MenuChanged);
|
||||
}
|
||||
else if (pWnd->pcls->lpszMenuName) // Take it from the parent.
|
||||
{
|
||||
UNICODE_STRING MenuName;
|
||||
@@ -2338,15 +2160,15 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
|
||||
Window->rcWindow.top = Cs->y;
|
||||
Window->rcWindow.right = Cs->x + Size.cx;
|
||||
Window->rcWindow.bottom = Cs->y + Size.cy;
|
||||
/*
|
||||
/*
|
||||
if (0 != (Window->style & WS_CHILD) && ParentWindow)
|
||||
{
|
||||
// ERR("co_UserCreateWindowEx(): Offset rcWindow\n");
|
||||
ERR("co_UserCreateWindowEx(): Offset rcWindow\n");
|
||||
RECTL_vOffsetRect(&Window->rcWindow,
|
||||
ParentWindow->rcClient.left,
|
||||
ParentWindow->rcClient.top);
|
||||
}
|
||||
*/
|
||||
*/
|
||||
/* correct child window coordinates if mirroring on parent is enabled */
|
||||
if (ParentWindow != NULL)
|
||||
{
|
||||
@@ -3679,105 +3501,6 @@ CLEANUP:
|
||||
END_CLEANUP;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtUserGetSystemMenu
|
||||
*
|
||||
* The NtUserGetSystemMenu function allows the application to access the
|
||||
* window menu (also known as the system menu or the control menu) for
|
||||
* copying and modifying.
|
||||
*
|
||||
* Parameters
|
||||
* hWnd
|
||||
* Handle to the window that will own a copy of the window menu.
|
||||
* bRevert
|
||||
* Specifies the action to be taken. If this parameter is FALSE,
|
||||
* NtUserGetSystemMenu returns a handle to the copy of the window menu
|
||||
* currently in use. The copy is initially identical to the window menu
|
||||
* but it can be modified.
|
||||
* If this parameter is TRUE, GetSystemMenu resets the window menu back
|
||||
* to the default state. The previous window menu, if any, is destroyed.
|
||||
*
|
||||
* Return Value
|
||||
* If the bRevert parameter is FALSE, the return value is a handle to a
|
||||
* copy of the window menu. If the bRevert parameter is TRUE, the return
|
||||
* value is NULL.
|
||||
*
|
||||
* Status
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
HMENU APIENTRY
|
||||
NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
|
||||
{
|
||||
PWND Window;
|
||||
PMENU Menu;
|
||||
DECLARE_RETURN(HMENU);
|
||||
|
||||
TRACE("Enter NtUserGetSystemMenu\n");
|
||||
UserEnterShared();
|
||||
|
||||
if (!(Window = UserGetWindowObject(hWnd)))
|
||||
{
|
||||
RETURN(NULL);
|
||||
}
|
||||
|
||||
if (!(Menu = IntGetSystemMenu(Window, bRevert, FALSE)))
|
||||
{
|
||||
RETURN(NULL);
|
||||
}
|
||||
|
||||
RETURN(Menu->head.h);
|
||||
|
||||
CLEANUP:
|
||||
TRACE("Leave NtUserGetSystemMenu, ret=%p\n", _ret_);
|
||||
UserLeave();
|
||||
END_CLEANUP;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtUserSetSystemMenu
|
||||
*
|
||||
* Status
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
BOOL APIENTRY
|
||||
NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
|
||||
{
|
||||
BOOL Result = FALSE;
|
||||
PWND Window;
|
||||
PMENU Menu;
|
||||
DECLARE_RETURN(BOOL);
|
||||
|
||||
TRACE("Enter NtUserSetSystemMenu\n");
|
||||
UserEnterExclusive();
|
||||
|
||||
if (!(Window = UserGetWindowObject(hWnd)))
|
||||
{
|
||||
RETURN( FALSE);
|
||||
}
|
||||
|
||||
if (hMenu)
|
||||
{
|
||||
/*
|
||||
* Assign new menu handle.
|
||||
*/
|
||||
if (!(Menu = UserGetMenuObject(hMenu)))
|
||||
{
|
||||
RETURN( FALSE);
|
||||
}
|
||||
|
||||
Result = IntSetSystemMenu(Window, Menu);
|
||||
}
|
||||
|
||||
RETURN( Result);
|
||||
|
||||
CLEANUP:
|
||||
TRACE("Leave NtUserSetSystemMenu, ret=%i\n",_ret_);
|
||||
UserLeave();
|
||||
END_CLEANUP;
|
||||
}
|
||||
|
||||
// Fixes wine Win test_window_styles and todo tests...
|
||||
static BOOL FASTCALL
|
||||
IntCheckFrameEdge(ULONG Style, ULONG ExStyle)
|
||||
|
||||
@@ -70,10 +70,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu);
|
||||
#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
|
||||
|
||||
#define IS_SYSTEM_MENU(MenuInfo) \
|
||||
(0 == ((MenuInfo)->fFlags & MNF_POPUP) && 0 != ((MenuInfo)->fFlags & MNF_SYSDESKMN))
|
||||
(0 == ((MenuInfo)->fFlags & MNF_POPUP) && 0 != ((MenuInfo)->fFlags & MNF_SYSMENU))
|
||||
|
||||
#define IS_SYSTEM_POPUP(MenuInfo) \
|
||||
(0 != ((MenuInfo)->fFlags & MNF_POPUP) && 0 != ((MenuInfo)->fFlags & MNF_SYSDESKMN))
|
||||
(0 != ((MenuInfo)->fFlags & MNF_POPUP) && 0 != ((MenuInfo)->fFlags & MNF_SYSMENU))
|
||||
|
||||
#define IS_BITMAP_ITEM(flags) (MF_BITMAP == MENU_ITEM_TYPE(flags))
|
||||
|
||||
@@ -902,7 +902,7 @@ static UINT FASTCALL MENU_FindItemByKey(HWND WndOwner, HMENU hmenu,
|
||||
}
|
||||
|
||||
Flags |= menu->fFlags & MNF_POPUP ? MF_POPUP : 0;
|
||||
Flags |= menu->fFlags & MNF_SYSDESKMN ? MF_SYSMENU : 0;
|
||||
Flags |= menu->fFlags & MNF_SYSMENU ? MF_SYSMENU : 0;
|
||||
|
||||
MenuChar = SendMessageW( WndOwner, WM_MENUCHAR,
|
||||
MAKEWPARAM(Key, Flags), (LPARAM) hmenu);
|
||||
@@ -1257,7 +1257,11 @@ static UINT
|
||||
MENU_GetMaxPopupHeight(PROSMENUINFO lppop)
|
||||
{
|
||||
if (lppop->cyMax)
|
||||
{
|
||||
//ERR("MGMaxPH cyMax %d\n",lppop->cyMax);
|
||||
return lppop->cyMax;
|
||||
}
|
||||
//ERR("MGMaxPH SyMax %d\n",GetSystemMetrics(SM_CYSCREEN) - GetSystemMetrics(SM_CYBORDER));
|
||||
return GetSystemMetrics(SM_CYSCREEN) - GetSystemMetrics(SM_CYBORDER);
|
||||
}
|
||||
|
||||
@@ -1844,13 +1848,14 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd
|
||||
/* process text if present */
|
||||
if (lpitem->lpstr)
|
||||
{
|
||||
register int i = 0;
|
||||
int i = 0;
|
||||
HFONT hfontOld = 0;
|
||||
|
||||
UINT uFormat = menuBar ?
|
||||
DT_CENTER | DT_VCENTER | DT_SINGLELINE :
|
||||
DT_LEFT | DT_VCENTER | DT_SINGLELINE;
|
||||
|
||||
if((MenuInfo->dwStyle & MNS_CHECKORBMP))
|
||||
if ((MenuInfo->dwStyle & MNS_CHECKORBMP))
|
||||
rect.left += max(0, (int)(MenuInfo->cxTextAlign - GetSystemMetrics(SM_CXMENUCHECK)));
|
||||
else
|
||||
rect.left += MenuInfo->cxTextAlign;
|
||||
@@ -1861,8 +1866,13 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd
|
||||
}
|
||||
|
||||
if (menuBar) {
|
||||
rect.left += MENU_BAR_ITEMS_SPACE / 2;
|
||||
rect.right -= MENU_BAR_ITEMS_SPACE / 2;
|
||||
if( lpitem->hbmpItem)
|
||||
rect.left += lpitem->maxBmpSize.cx;
|
||||
if( !(lpitem->hbmpItem == HBMMENU_CALLBACK))
|
||||
rect.left += MenuCharSize.cx;
|
||||
rect.right -= MenuCharSize.cx;
|
||||
//rect.left += MENU_BAR_ITEMS_SPACE / 2;
|
||||
//rect.right -= MENU_BAR_ITEMS_SPACE / 2;
|
||||
}
|
||||
|
||||
Text = lpitem->lpstr;
|
||||
@@ -1911,8 +1921,8 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd
|
||||
--rect.left; --rect.top; --rect.right; --rect.bottom;
|
||||
}
|
||||
SetTextColor(hdc, RGB(0x80, 0x80, 0x80));
|
||||
}
|
||||
DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat );
|
||||
}
|
||||
DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat );
|
||||
}
|
||||
|
||||
if (hfontOld)
|
||||
@@ -1961,6 +1971,7 @@ static void FASTCALL MenuDrawPopupMenu(HWND hwnd, HDC hdc, HMENU hmenu )
|
||||
UINT u;
|
||||
MenuInitRosMenuItemInfo(&ItemInfo);
|
||||
|
||||
//for (u = MenuInfo.cItems; u > 0; u--, item++)
|
||||
for (u = 0; u < MenuInfo.cItems; u++)
|
||||
{
|
||||
if (MenuGetRosMenuItemInfo(MenuInfo.Self, u, &ItemInfo))
|
||||
@@ -1972,7 +1983,9 @@ static void FASTCALL MenuDrawPopupMenu(HWND hwnd, HDC hdc, HMENU hmenu )
|
||||
}
|
||||
/* draw scroll arrows */
|
||||
if (MenuInfo.dwArrowsOn)
|
||||
{
|
||||
MENU_DrawScrollArrows(&MenuInfo, hdc);
|
||||
}
|
||||
|
||||
MenuSetRosMenuInfo(&MenuInfo);
|
||||
MenuCleanupRosMenuItemInfo(&ItemInfo);
|
||||
@@ -2013,7 +2026,7 @@ UINT MenuDrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd,
|
||||
if (hfontOld) SelectObject( hDC, hfontOld);
|
||||
return lppop.cyMenu;
|
||||
}
|
||||
else
|
||||
else
|
||||
return DrawMenuBarTemp(hwnd, hDC, lprect, hMenu, NULL);
|
||||
}
|
||||
|
||||
@@ -2185,6 +2198,7 @@ MENU_EnsureMenuItemVisible(PROSMENUINFO lppop, PROSMENUITEMINFO item, HDC hdc)
|
||||
ScrollWindow(lppop->Wnd, 0, nOldPos - lppop->iTop, &rc, &rc);
|
||||
MENU_DrawScrollArrows(lppop, hdc);
|
||||
}
|
||||
MenuSetRosMenuInfo(lppop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2248,7 +2262,7 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
|
||||
WPARAM wParam = MAKEWPARAM( ItemInfo.hSubMenu ? wIndex : ItemInfo.wID,
|
||||
ItemInfo.fType | ItemInfo.fState |
|
||||
(ItemInfo.hSubMenu ? MF_POPUP : 0) |
|
||||
(hmenu->fFlags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
|
||||
(hmenu->fFlags & MNF_SYSMENU ? MF_SYSMENU : 0 ) );
|
||||
|
||||
SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) hmenu->Self);
|
||||
}
|
||||
@@ -2267,7 +2281,7 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
|
||||
{
|
||||
WPARAM wParam = MAKEWPARAM( Pos, ItemInfo.fType | ItemInfo.fState |
|
||||
(ItemInfo.hSubMenu ? MF_POPUP : 0) |
|
||||
(TopMenuInfo.fFlags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
|
||||
(TopMenuInfo.fFlags & MNF_SYSMENU ? MF_SYSMENU : 0 ) );
|
||||
|
||||
SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) topmenu);
|
||||
}
|
||||
@@ -3065,7 +3079,7 @@ MenuExecFocusedItem(MTRACKER *Mt, PROSMENUINFO MenuInfo, UINT Flags)
|
||||
do not send a message to the owner */
|
||||
if (0 == (Flags & TPM_RETURNCMD))
|
||||
{
|
||||
if (0 != (MenuInfo->fFlags & MNF_SYSDESKMN))
|
||||
if (0 != (MenuInfo->fFlags & MNF_SYSMENU))
|
||||
{
|
||||
PostMessageW(Mt->OwnerWnd, WM_SYSCOMMAND, ItemInfo.wID,
|
||||
MAKELPARAM((SHORT) Mt->Pt.x, (SHORT) Mt->Pt.y));
|
||||
@@ -3250,7 +3264,7 @@ MENU_PtMenu(HMENU hMenu, POINT pt)
|
||||
if (ht != HTNOWHERE && ht != HTERROR) ret = hMenu;
|
||||
}
|
||||
else if (ht == HTSYSMENU)
|
||||
ret = NtUserGetSystemMenu(menu->hWnd, FALSE);
|
||||
ret = get_win_sys_menu(menu->hWnd);
|
||||
else if (ht == HTMENU)
|
||||
ret = GetMenu( menu->hWnd );
|
||||
}
|
||||
@@ -3398,7 +3412,7 @@ MenuDoNextMenu(MTRACKER* Mt, UINT Vk, UINT wFlags)
|
||||
else if (0 != (Style & WS_SYSMENU))
|
||||
{
|
||||
/* switch to the system menu */
|
||||
NewMenu = NtUserGetSystemMenu(NewWnd, FALSE);
|
||||
NewMenu = get_win_sys_menu(NewWnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3415,10 +3429,10 @@ MenuDoNextMenu(MTRACKER* Mt, UINT Vk, UINT wFlags)
|
||||
DWORD Style = GetWindowLongPtrW(NewWnd, GWL_STYLE);
|
||||
|
||||
if (0 != (Style & WS_SYSMENU)
|
||||
&& GetSystemMenu(NewWnd, FALSE) == NewMenu)
|
||||
&& get_win_sys_menu(NewWnd) == NewMenu)
|
||||
{
|
||||
/* get the real system menu */
|
||||
NewMenu = NtUserGetSystemMenu(NewWnd, FALSE);
|
||||
NewMenu = get_win_sys_menu(NewWnd);
|
||||
}
|
||||
else if (0 != (Style & WS_CHILD) || GetMenu(NewWnd) != NewMenu)
|
||||
{
|
||||
@@ -4081,7 +4095,7 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
|
||||
|
||||
IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
|
||||
hWnd,
|
||||
MenuInfo.fFlags & MNF_SYSDESKMN ? OBJID_SYSMENU : OBJID_MENU,
|
||||
MenuInfo.fFlags & MNF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU,
|
||||
CHILDID_SELF, 0);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -4108,7 +4122,7 @@ static BOOL FASTCALL MenuExitTracking(HWND hWnd, BOOL bPopup)
|
||||
*/
|
||||
VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
|
||||
{
|
||||
HMENU hMenu = (ht == HTSYSMENU) ? NtUserGetSystemMenu( hWnd, FALSE) : GetMenu(hWnd);
|
||||
HMENU hMenu = (ht == HTSYSMENU) ? get_win_sys_menu( hWnd ) : GetMenu(hWnd);
|
||||
UINT wFlags = TPM_BUTTONDOWN | TPM_LEFTALIGN | TPM_LEFTBUTTON;
|
||||
|
||||
TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y);
|
||||
@@ -4124,6 +4138,8 @@ VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
|
||||
}
|
||||
|
||||
MenuInitTracking(hWnd, hMenu, FALSE, wFlags);
|
||||
/* fetch the window menu again, it may have changed */
|
||||
hMenu = (ht == HTSYSMENU) ? get_win_sys_menu( hWnd ) : GetMenu( hWnd );
|
||||
MenuTrackMenu(hMenu, wFlags, pt.x, pt.y, hWnd, NULL);
|
||||
MenuExitTracking(hWnd, FALSE);
|
||||
}
|
||||
@@ -4155,7 +4171,7 @@ VOID MenuTrackKbdMenuBar(HWND hwnd, UINT wParam, WCHAR wChar)
|
||||
if (!hTrackMenu || IsIconic(hwnd) || wChar == ' ' )
|
||||
{
|
||||
if (!(GetWindowLongPtrW( hwnd, GWL_STYLE ) & WS_SYSMENU)) return;
|
||||
hTrackMenu = NtUserGetSystemMenu(hwnd, FALSE);
|
||||
hTrackMenu = get_win_sys_menu(hwnd);
|
||||
uItem = 0;
|
||||
wParam |= HTSYSMENU; /* prevent item lookup */
|
||||
}
|
||||
@@ -4432,6 +4448,44 @@ MenuCleanup(VOID)
|
||||
}
|
||||
}
|
||||
|
||||
HMENU FASTCALL MENU_LoadSystemMenu(BOOL mdi)
|
||||
{
|
||||
HMENU hmenu = LoadMenuW(User32Instance, L"SYSMENU");
|
||||
|
||||
if (hmenu)
|
||||
{
|
||||
MENUINFO menuinfo = {0};
|
||||
MENUITEMINFOW info = {0};
|
||||
//WCHAR buf[128];
|
||||
|
||||
// removing space for checkboxes from menu
|
||||
menuinfo.cbSize = sizeof(menuinfo);
|
||||
menuinfo.fMask = MIM_STYLE;
|
||||
GetMenuInfo(hmenu, &menuinfo);
|
||||
menuinfo.dwStyle |= MNS_CHECKORBMP;
|
||||
SetMenuInfo(hmenu, &menuinfo);
|
||||
|
||||
// adding bitmaps to menu items
|
||||
info.cbSize = sizeof(info);
|
||||
info.fMask |= MIIM_BITMAP;
|
||||
info.hbmpItem = HBMMENU_POPUP_MINIMIZE;
|
||||
SetMenuItemInfoW(hmenu, SC_MINIMIZE, FALSE, &info);
|
||||
info.hbmpItem = HBMMENU_POPUP_RESTORE;
|
||||
SetMenuItemInfoW(hmenu, SC_RESTORE, FALSE, &info);
|
||||
info.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
|
||||
SetMenuItemInfoW(hmenu, SC_MAXIMIZE, FALSE, &info);
|
||||
info.hbmpItem = HBMMENU_POPUP_CLOSE;
|
||||
SetMenuItemInfoW(hmenu, SC_CLOSE, FALSE, &info);
|
||||
if (mdi)
|
||||
{
|
||||
AppendMenuW(hmenu, MF_SEPARATOR, 0, NULL);
|
||||
//LoadStringW(User32Instance, IDS_MDI_NEXT, buf, sizeof(buf)/sizeof(WCHAR));
|
||||
//AppendMenuW(hmenu, MF_STRING, SC_NEXTWINDOW, buf);
|
||||
}
|
||||
}
|
||||
return hmenu;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI
|
||||
User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||
{
|
||||
@@ -5023,11 +5077,7 @@ GetSystemMenu(
|
||||
HWND hWnd,
|
||||
BOOL bRevert)
|
||||
{
|
||||
HMENU TopMenu;
|
||||
|
||||
TopMenu = NtUserGetSystemMenu(hWnd, bRevert);
|
||||
|
||||
return NULL == TopMenu ? NULL : GetSubMenu(TopMenu, 0);
|
||||
return NtUserGetSystemMenu(hWnd, bRevert);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user