tinus <o112w8r02@sneakemail.com>
Don't allow selecting disabled menu items
Modified: trunk/reactos/lib/user32/windows/menu.c

Modified: trunk/reactos/lib/user32/windows/menu.c
--- trunk/reactos/lib/user32/windows/menu.c	2005-01-24 09:33:21 UTC (rev 13245)
+++ trunk/reactos/lib/user32/windows/menu.c	2005-01-24 09:41:00 UTC (rev 13246)
@@ -1884,46 +1884,56 @@
 {
   INT i;
   ROSMENUITEMINFO ItemInfo;
+  INT OrigPos;
 
   DPRINT("hwnd=%x menu=%x off=0x%04x\n", WndOwner, MenuInfo, Offset);
 
+  /* Prevent looping */
+  if (0 == MenuInfo->MenuItemCount || 0 == Offset)
+    return;
+  else if (Offset < -1)
+    Offset = -1;
+  else if (Offset > 1)
+    Offset = 1;
+
   MenuInitRosMenuItemInfo(&ItemInfo);
-  if (NO_SELECTED_ITEM != MenuInfo->FocusedItem)
+
+  OrigPos = MenuInfo->FocusedItem;
+  if (OrigPos == NO_SELECTED_ITEM) /* NO_SELECTED_ITEM is not -1 ! */
     {
-      if (1 == MenuInfo->MenuItemCount)
+       OrigPos = 0;
+       i = -1;
+    }
+  else
+    { 
+      i = MenuInfo->FocusedItem; 
+    }
+
+  do
+    {
+      /* Step */
+      i += Offset;
+      /* Clip and wrap around */
+      if (i < 0)
         {
-          MenuCleanupRosMenuItemInfo(&ItemInfo);
-          return;
+          i = MenuInfo->MenuItemCount - 1;
         }
-      else
+      else if (i >= MenuInfo->MenuItemCount)
         {
-          for (i = MenuInfo->FocusedItem + Offset;
-               0 <= i && i < MenuInfo->MenuItemCount;
-               i += Offset)
-            {
-              if (MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo) &&
-                  0 == (ItemInfo.fType & MF_SEPARATOR))
-                {
-                  MenuSelectItem(WndOwner, MenuInfo, i, TRUE, NULL);
-                  MenuCleanupRosMenuItemInfo(&ItemInfo);
-                  return;
-                }
-            }
+          i = 0;
         }
-    }
-
-  for (i = (0 < Offset) ? 0 : MenuInfo->MenuItemCount - 1;
-       0 <= i && i < MenuInfo->MenuItemCount; i += Offset)
-    {
+      /* If this is a good candidate; */
       if (MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo) &&
-          0 == (ItemInfo.fType & MF_SEPARATOR))
+          0 == (ItemInfo.fType & MF_SEPARATOR) &&
+          0 == (ItemInfo.fState & (MFS_DISABLED | MFS_GRAYED)) )
         {
           MenuSelectItem(WndOwner, MenuInfo, i, TRUE, NULL);
           MenuCleanupRosMenuItemInfo(&ItemInfo);
           return;
         }
-    }
+    } while (i != OrigPos);
 
+  /* Not found */
   MenuCleanupRosMenuItemInfo(&ItemInfo);
 }
 
@@ -2276,15 +2286,19 @@
           return FALSE;
         }
 
-      if (MenuInfo.FocusedItem != Index)
-        {
-          MenuSwitchTracking(Mt, &MenuInfo, Index);
-        }
+      if (!(Item.fType & MF_SEPARATOR) &&
+          !(Item.fState & (MFS_DISABLED | MFS_GRAYED)) )
+	{
+          if (MenuInfo.FocusedItem != Index)
+            {
+              MenuSwitchTracking(Mt, &MenuInfo, Index);
+            }
 
-      /* If the popup menu is not already "popped" */
-      if (0 == (Item.fState & MF_MOUSESELECT))
-        {
-          Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
+          /* If the popup menu is not already "popped" */
+          if (0 == (Item.fState & MF_MOUSESELECT))
+            {
+              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
+            }
         }
 
       MenuCleanupRosMenuItemInfo(&Item);
@@ -2422,6 +2436,7 @@
 {
   UINT Index;
   ROSMENUINFO MenuInfo;
+  ROSMENUITEMINFO ItemInfo;
 
   if (NULL != PtMenu)
     {
@@ -2454,8 +2469,15 @@
     }
   else if (MenuInfo.FocusedItem != Index)
     {
-      MenuSwitchTracking(Mt, &MenuInfo, Index);
-      Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
+	MenuInitRosMenuItemInfo(&ItemInfo);
+	if (MenuGetRosMenuItemInfo(MenuInfo.Self, Index, &ItemInfo) &&
+           !(ItemInfo.fType & MF_SEPARATOR) &&
+           !(ItemInfo.fState & (MFS_DISABLED | MFS_GRAYED)) )
+	{
+	    MenuSwitchTracking(Mt, &MenuInfo, Index);
+	    Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
+	}
+	MenuCleanupRosMenuItemInfo(&ItemInfo);
     }
 
   return TRUE;
@@ -4026,9 +4048,9 @@
   BOOL res = FALSE;
   mi.hbmpItem = (HBITMAP)0;
 
-  // while we could just pass 'lpmii' to win32k, we make a copy so that
-  // if a bad user passes bad data, we crash his process instead of the
-  // entire kernel
+  /* while we could just pass 'lpmii' to win32k, we make a copy so that
+     if a bad user passes bad data, we crash his process instead of the
+     entire kernel */
 
   if((lpmii->cbSize == sizeof(MENUITEMINFOW)) || 
      (lpmii->cbSize == sizeof(MENUITEMINFOW) - sizeof(HBITMAP)))