[Win32k]
authorJames Tabor <james.tabor@reactos.org>
Mon, 26 May 2014 01:26:45 +0000 (01:26 +0000)
committerJames Tabor <james.tabor@reactos.org>
Mon, 26 May 2014 01:26:45 +0000 (01:26 +0000)
- Fix G/SetSystemMenu. Move code into menu.c.
- Add loading for MDI system menu.

svn path=/trunk/; revision=63455

reactos/win32ss/include/ntuser.h
reactos/win32ss/user/ntuser/menu.c
reactos/win32ss/user/ntuser/menu.h
reactos/win32ss/user/ntuser/window.c
reactos/win32ss/user/user32/windows/menu.c

index fb39f5a..20813bb 100644 (file)
@@ -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
 {
index a155c9f..c802832 100644 (file)
@@ -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:
index 0a63e49..dffc55a 100644 (file)
@@ -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);
index b5386d7..de3b4bd 100644 (file)
@@ -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)
index 5298c6c..37f241c 100644 (file)
@@ -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);
 }
 
 /*