[ros-diffs] [jimtabor] 23221: -Part 1 -Win32k and User32 - Menu.c: Made set menu items selective masking. Setting masks fixed the garbage going into the item structure. Now right justify menu bar works. There are some more cosmetic issues left to do. I have those ready next week or so. Running wine menu test fail due to exception in kernel32 IsBadStringPtrA&W isbad.c. Funny? Does PSEH work in user mode? The string test is needed. Misc fixed, some restructuring and Wine ports. Please let me know if it breaks something.

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Sat Jul 22 07:28:45 CEST 2006


Author: jimtabor
Date: Sat Jul 22 09:28:44 2006
New Revision: 23221

URL: http://svn.reactos.org/svn/reactos?rev=23221&view=rev
Log:
-Part 1
-Win32k and User32
  - Menu.c: Made set menu items selective masking. Setting masks fixed the garbage going into the item structure. Now right justify menu bar works. There are some more cosmetic issues left to do. I have those ready next week or so. Running wine menu test fail due to exception in kernel32 IsBadStringPtrA&W isbad.c. Funny? Does PSEH work in user mode? The string test is needed. Misc fixed, some restructuring and Wine ports. Please let me know if it breaks something.

Modified:
    trunk/reactos/dll/win32/user32/windows/menu.c
    trunk/reactos/subsystems/win32/win32k/ntuser/menu.c

Modified: trunk/reactos/dll/win32/user32/windows/menu.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/menu.c?rev=23221&r1=23220&r2=23221&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/menu.c (original)
+++ trunk/reactos/dll/win32/user32/windows/menu.c Sat Jul 22 09:28:44 2006
@@ -1,34 +1,12 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- *  Partly based on Wine code
- *  Copyright 1993 Martin Ayotte
- *  Copyright 1994 Alexandre Julliard
- *  Copyright 1997 Morten Welinder
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
 /* $Id$
  *
+ * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
- * FILE:            lib/user32/windows/menu.c
+ * FILE:            user32/windows/menu.c
  * PURPOSE:         Menus
- * PROGRAMMER:      Casper S. Hornstrup (chorns at users.sourceforge.net)
- * UPDATE HISTORY:
- *      09-05-2001  CSH  Created
+ *
+ * PROGRAMMERS:     Casper S. Hornstrup
+ *                  James Tabor
  */
 
 /* INCLUDES ******************************************************************/
@@ -62,6 +40,7 @@
 	(0 != ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
 
 #define IS_MAGIC_ITEM(Bmp)   ((int) Bmp <12)
+#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
 
 #define MENU_ITEM_HBMP_SPACE (5)
 #define MENU_BAR_ITEMS_SPACE (12)
@@ -155,7 +134,7 @@
 /***********************************************************************
  *           MenuSetRosMenuInfo
  *
- * Set full information about menu
+ * Set full information about menu      
  */
 static BOOL FASTCALL
 MenuSetRosMenuInfo(PROSMENUINFO MenuInfo)
@@ -186,13 +165,16 @@
 static BOOL FASTCALL
 MenuGetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo)
 {
+  UINT Save_Mask = ItemInfo->fMask; /* Save the org mask bits. */
+  
   if (ItemInfo->dwTypeData != NULL)
     {
       HeapFree(GetProcessHeap(), 0, ItemInfo->dwTypeData);
     }
+  
 
   ItemInfo->fMask = MIIM_BITMAP | MIIM_CHECKMARKS | MIIM_DATA | MIIM_FTYPE
-                    | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE;
+             | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE;
   ItemInfo->dwTypeData = NULL;
 
   if (! NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, FALSE))
@@ -217,14 +199,14 @@
           return FALSE;
         }
     }
-
+  ItemInfo->fMask =  Save_Mask;
   return TRUE;
 }
 
 /***********************************************************************
  *           MenuSetRosMenuItemInfo
  *
- * Set full information about a menu item
+ * Set selected information about a menu item, need to set the mask bits.
  */
 static BOOL FASTCALL
 MenuSetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo)
@@ -236,10 +218,6 @@
   {
     ItemInfo->cch = strlenW(ItemInfo->dwTypeData);
   }
-  ItemInfo->fMask = MIIM_BITMAP | MIIM_CHECKMARKS | MIIM_DATA | MIIM_FTYPE
-                    | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE;
-
-
   Ret = NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, TRUE);
 
   return Ret;
@@ -368,10 +346,11 @@
             /* fall through */
           case (INT_PTR) HBMMENU_MBAR_RESTORE:
           case (INT_PTR) HBMMENU_MBAR_MINIMIZE:
+          case (INT_PTR) HBMMENU_MBAR_CLOSE:
           case (INT_PTR) HBMMENU_MBAR_MINIMIZE_D:
-          case (INT_PTR) HBMMENU_MBAR_CLOSE:
           case (INT_PTR) HBMMENU_MBAR_CLOSE_D:
             /* FIXME: Why we need to subtract these magic values? */
+            /* to make them smaller than the menu bar? */
             Size->cx = GetSystemMetrics(SM_CXSIZE) - 2;
             Size->cy = GetSystemMetrics(SM_CYSIZE) - 4;
             return;
@@ -422,9 +401,9 @@
       switch ((INT_PTR)hbmpToDraw)
         {
           case (INT_PTR) HBMMENU_SYSTEM:
-            if (NULL != Item->hbmpItem)
+            if (NULL != Item->dwTypeData)
               {
-                Bmp = Item->hbmpItem;
+                Bmp = (HBITMAP)Item->dwTypeData;
                 if (! GetObjectW(Bmp, sizeof(BITMAP), &Bm))
                   {
                     return;
@@ -432,6 +411,7 @@
               }
             else
               {
+                if (!BmpSysMenu) BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
                 Bmp = BmpSysMenu;
                 if (! GetObjectW(Bmp, sizeof(BITMAP), &Bm))
                   {
@@ -514,8 +494,8 @@
   /* handle fontsize > bitmap_height */
   Top = (Bm.bmHeight < h) ? Rect->top + (h - Bm.bmHeight) / 2 : Rect->top;
   Left = Rect->left;
-  Rop = (0 != (Item->fState & MF_HILITE) && ! IS_MAGIC_ITEM(Item->hbmpItem)) ? NOTSRCCOPY : SRCCOPY;
-  if (0 != (Item->fState & MF_HILITE) && IS_BITMAP_ITEM(Item->fType))
+  Rop= ((Item->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmpToDraw)) ? NOTSRCCOPY : SRCCOPY;
+  if ((Item->fState & MF_HILITE) && Item->hbmpItem)
     {
       SetBkColor(Dc, GetSysColor(COLOR_HIGHLIGHT));
     }
@@ -545,7 +525,6 @@
           UserDrawSysMenuButton(Wnd, Dc, &Rect,
                                 Item->fState & (MF_HILITE | MF_MOUSESELECT));
 	}
-
       return;
     }
 
@@ -587,7 +566,9 @@
       SetBkColor(Dc, GetSysColor(bkgnd));
     }
 
-  if (0 != (Item->fType & MF_OWNERDRAW))
+  Rect = Item->Rect;
+
+  if (Item->fType & MF_OWNERDRAW)
     {
       /*
       ** Experimentation under Windows reveals that an owner-drawn
@@ -620,7 +601,7 @@
       dis.itemAction = Action; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
       dis.hwndItem   = (HWND) MenuInfo->Self;
       dis.hDC        = Dc;
-      dis.rcItem     = Item->Rect;
+      dis.rcItem     = Rect;
       DPRINT("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, "
 	      "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", Wnd,
 	      dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem,
@@ -648,171 +629,157 @@
                                      Item->Rect.right, Item->Rect.bottom);
 
   if (MenuBar && 0 != (Item->fType & MF_SEPARATOR))
-    {
-      return;
-    }
-
-  Rect = Item->Rect;
-
-  if (0 == (Item->fType & MF_OWNERDRAW))
-    {
-      if (Item->fState & MF_HILITE)
-        {
-          if (flat_menu)
-            {
-              InflateRect (&Rect, -1, -1);
-              FillRect(Dc, &Rect, GetSysColorBrush(COLOR_MENUHILIGHT));
-              InflateRect (&Rect, 1, 1);
-              FrameRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT));
-            }
-          else
-            {
-              if (MenuBar)
-                {
-                  DrawEdge(Dc, &Rect, BDR_SUNKENOUTER, BF_RECT);
-                }
-              else
-                {
-                  FillRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT));
-                }
-            }
-        }
-      else
-        {
-          FillRect(Dc, &Rect, GetSysColorBrush(bkgnd));
-        }
-    }
+  {
+     return;
+  }
+
+  if (Item->fState & MF_HILITE)
+  {
+    if (flat_menu)
+    {
+       InflateRect (&Rect, -1, -1);
+       FillRect(Dc, &Rect, GetSysColorBrush(COLOR_MENUHILIGHT));
+       InflateRect (&Rect, 1, 1);
+       FrameRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT));
+    }
+    else
+    {
+       if (MenuBar)
+       {
+          DrawEdge(Dc, &Rect, BDR_SUNKENOUTER, BF_RECT);
+       }
+       else
+       {
+          FillRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT));
+       }
+    }
+  }
+  else
+  {
+     FillRect(Dc, &Rect, GetSysColorBrush(bkgnd));
+  }
 
   SetBkMode(Dc, TRANSPARENT);
 
-  if (0 == (Item->fType & MF_OWNERDRAW))
-    {
-      /* vertical separator */
-      if (! MenuBar && 0 != (Item->fType & MF_MENUBARBREAK))
-        {
-          HPEN oldPen;
-          RECT rc = Rect;
-          rc.top = 3;
-          rc.bottom = Height - 3;
-          if (flat_menu)
-          {
-             oldPen = SelectObject( Dc, GetSysColorPen(COLOR_BTNSHADOW) );
-             MoveToEx( Dc, rc.left, rc.top, NULL );
-             LineTo( Dc, rc.left, rc.bottom );
-             SelectObject( Dc, oldPen );
-          }
-          else
-             DrawEdge(Dc, &rc, EDGE_ETCHED, BF_LEFT);
-        }
-
-      /* horizontal separator */
-      if (0 != (Item->fType & MF_SEPARATOR))
-        {
-          HPEN oldPen;
-          RECT rc = Rect;
-          rc.left++;
-          rc.right--;
-          rc.top += SEPARATOR_HEIGHT / 2;
-          if (flat_menu)
-          {
-             oldPen = SelectObject( Dc, GetSysColorPen(COLOR_BTNSHADOW) );
-             MoveToEx( Dc, rc.left, rc.top, NULL );
-             LineTo( Dc, rc.right, rc.top );
-             SelectObject( Dc, oldPen );
-          }
-          else
-             DrawEdge(Dc, &rc, EDGE_ETCHED, BF_TOP);
-	  return;
-        }
-    }
+  /* vertical separator */
+  if (! MenuBar && 0 != (Item->fType & MF_MENUBARBREAK))
+  {
+    HPEN oldPen;
+    RECT rc = Rect;
+    rc.top = 3;
+    rc.bottom = Height - 3;
+    if (flat_menu)
+    {
+       oldPen = SelectObject( Dc, GetSysColorPen(COLOR_BTNSHADOW) );
+       MoveToEx( Dc, rc.left, rc.top, NULL );
+       LineTo( Dc, rc.left, rc.bottom );
+       SelectObject( Dc, oldPen );
+    }
+    else
+       DrawEdge(Dc, &rc, EDGE_ETCHED, BF_LEFT);
+  }
+
+  /* horizontal separator */
+  if (0 != (Item->fType & MF_SEPARATOR))
+  {
+    HPEN oldPen;
+    RECT rc = Rect;
+    rc.left++;
+    rc.right--;
+    rc.top += SEPARATOR_HEIGHT / 2;
+    if (flat_menu)
+    {
+       oldPen = SelectObject( Dc, GetSysColorPen(COLOR_BTNSHADOW) );
+       MoveToEx( Dc, rc.left, rc.top, NULL );
+       LineTo( Dc, rc.right, rc.top );
+       SelectObject( Dc, oldPen );
+    }
+    else
+       DrawEdge(Dc, &rc, EDGE_ETCHED, BF_TOP);
+    return;
+  }
 
 #if 0
   /* helper lines for debugging */
+  /* This is a very good test tool when hacking menus! (JT) 07/16/2006 */
   FrameRect(Dc, &Rect, GetStockObject(BLACK_BRUSH));
-  SelectObject(Dc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME));
+  SelectObject(Dc, GetSysColorPen(COLOR_WINDOWFRAME));
   MoveToEx(Dc, Rect.left, (Rect.top + Rect.bottom) / 2, NULL);
   LineTo(Dc, Rect.right, (Rect.top + Rect.bottom) / 2);
 #endif
 
   if (! MenuBar)
-    {
-      INT y = Rect.top + Rect.bottom;
-      UINT CheckBitmapWidth = GetSystemMetrics(SM_CXMENUCHECK);
-      UINT CheckBitmapHeight = GetSystemMetrics(SM_CYMENUCHECK);
-
-      if (0 == (Item->fType & MF_OWNERDRAW))
-        {
-          /* Draw the check mark
-           *
-           * FIXME:
-           * Custom checkmark bitmaps are monochrome but not always 1bpp.
-           */
-          HBITMAP bm = 0 != (Item->fState & MF_CHECKED) ? Item->hbmpChecked : Item->hbmpUnchecked;
-          if (NULL != bm)  /* we have a custom bitmap */
-            {
-              HDC DcMem = CreateCompatibleDC(Dc);
-              SelectObject(DcMem, bm);
-              BitBlt(Dc, Rect.left, (y - CheckBitmapHeight) / 2,
-                     CheckBitmapWidth, CheckBitmapHeight,
-                     DcMem, 0, 0, SRCCOPY);
-              DeleteDC(DcMem);
-            }
-          else if (0 != (Item->fState & MF_CHECKED))  /* standard bitmaps */
-            {
-              RECT r;
-              HBITMAP bm = CreateBitmap(CheckBitmapWidth, CheckBitmapHeight, 1, 1, NULL);
-              HDC DcMem = CreateCompatibleDC(Dc);
-              SelectObject(DcMem, bm);
-              SetRect( &r, 0, 0, CheckBitmapWidth, CheckBitmapHeight);
-              DrawFrameControl(DcMem, &r, DFC_MENU,
-                               0 != (Item->fType & MFT_RADIOCHECK) ?
-                               DFCS_MENUBULLET : DFCS_MENUCHECK);
-              BitBlt(Dc, Rect.left, (y - r.bottom) / 2, r.right, r.bottom,
-                     DcMem, 0, 0, SRCCOPY );
-              DeleteDC(DcMem);
-              DeleteObject(bm);
-            }
-            if (Item->hbmpItem)
-            {
-              MenuDrawBitmapItem(Dc, Item, &Rect, MenuInfo->Self, WndOwner, Action, MenuBar);
-            }
-        }
-
-      /* Draw the popup-menu arrow */
-      if (0 != (Item->fType & MF_POPUP))
-        {
-          HDC DcMem = CreateCompatibleDC(Dc);
-          HBITMAP OrigBitmap;
-
-          OrigBitmap = SelectObject(DcMem, StdMnArrow);
-          BitBlt(Dc, Rect.right - ArrowBitmapWidth - 1,
-                 (y - ArrowBitmapHeight) / 2,
-                 ArrowBitmapWidth, ArrowBitmapHeight,
-                 DcMem, 0, 0, SRCCOPY);
-          SelectObject(DcMem, OrigBitmap);
-          DeleteDC(DcMem);
-        }
-
-      Rect.left += CheckBitmapWidth;
-      Rect.right -= ArrowBitmapWidth;
-    }
-  else 
- /* Draw the item text or bitmap */
-  if (Item->hbmpItem && !(Item->fType & MF_OWNERDRAW)) //IS_BITMAP_ITEM(Item->fType))
-    {
-      MenuDrawBitmapItem(Dc, Item, &Rect, MenuInfo->Self, WndOwner, Action, MenuBar);
-    }
-
-  /* Done for owner-drawn */
-  if (0 != (Item->fType & MF_OWNERDRAW))
-    {
-      return;
-    }
+  {
+     INT y = Rect.top + Rect.bottom;
+     RECT Rc = Rect;
+     UINT CheckBitmapWidth = GetSystemMetrics(SM_CXMENUCHECK);
+     UINT CheckBitmapHeight = GetSystemMetrics(SM_CYMENUCHECK);
+     int checked = FALSE;
+     /* Draw the check mark
+      *
+      * FIXME:
+      * Custom checkmark bitmaps are monochrome but not always 1bpp.
+      */
+     if( !(MenuInfo->dwStyle & MNS_NOCHECK)) 
+     {
+        HBITMAP bm = 0 != (Item->fState & MF_CHECKED) ? Item->hbmpChecked : Item->hbmpUnchecked;
+        if (NULL != bm)  /* we have a custom bitmap */
+        {
+           HDC DcMem = CreateCompatibleDC(Dc);
+           SelectObject(DcMem, bm);
+           BitBlt(Dc, Rc.left, (y - CheckBitmapHeight) / 2,
+                  CheckBitmapWidth, CheckBitmapHeight,
+                  DcMem, 0, 0, SRCCOPY);
+           DeleteDC(DcMem);
+           checked = TRUE;
+        }
+        else if (0 != (Item->fState & MF_CHECKED))  /* standard bitmaps */
+        {
+           RECT r;
+           HBITMAP bm = CreateBitmap(CheckBitmapWidth, CheckBitmapHeight, 1, 1, NULL);
+           HDC DcMem = CreateCompatibleDC(Dc);
+           SelectObject(DcMem, bm);
+           SetRect( &r, 0, 0, CheckBitmapWidth, CheckBitmapHeight);
+           DrawFrameControl(DcMem, &r, DFC_MENU,
+                            0 != (Item->fType & MFT_RADIOCHECK) ?
+                                 DFCS_MENUBULLET : DFCS_MENUCHECK);
+           BitBlt(Dc, Rc.left, (y - r.bottom) / 2, r.right, r.bottom,
+                  DcMem, 0, 0, SRCCOPY );
+           DeleteDC(DcMem);
+           DeleteObject(bm);
+           checked = TRUE;
+        }
+     }
+     if ((Item->hbmpItem)&& !( checked && (MenuInfo->dwStyle & MNS_CHECKORBMP)))
+     {
+        MenuDrawBitmapItem(Dc, Item, &Rect, MenuInfo->Self, WndOwner, Action, MenuBar);
+     }
+     /* Draw the popup-menu arrow */
+     if (0 != (Item->fType & MF_POPUP))
+     {
+        HDC DcMem = CreateCompatibleDC(Dc);
+        HBITMAP OrigBitmap;
+
+        OrigBitmap = SelectObject(DcMem, StdMnArrow);
+        BitBlt(Dc, Rect.right - ArrowBitmapWidth - 1,
+              (y - ArrowBitmapHeight) / 2,
+               ArrowBitmapWidth, ArrowBitmapHeight,
+               DcMem, 0, 0, SRCCOPY);
+        SelectObject(DcMem, OrigBitmap);
+        DeleteDC(DcMem);
+     }
+     Rect.left += CheckBitmapWidth;
+     Rect.right -= ArrowBitmapWidth;
+  }
+  else if (Item->hbmpItem) /* Draw the bitmap */
+  {
+     MenuDrawBitmapItem(Dc, Item, &Rect, MenuInfo->Self, WndOwner, Action, MenuBar);
+  }
  
   /* No bitmap - process text if present */
-  else if ( !(Item->fType & MF_SYSMENU) && IS_STRING_ITEM(Item->fType))
-    {
-      register int i;
+  if (Item->Text)
+  {
+      register int i = 0;
       HFONT FontOld = NULL;
 
       UINT uFormat = MenuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE
@@ -833,14 +800,18 @@
           Rect.left += MenuInfo->maxBmpSize.cx;
           Rect.right -= MenuInfo->maxBmpSize.cx;
         }
+
       Text = (PWCHAR) Item->dwTypeData;
-      for (i = 0; L'\0' != Text[i]; i++)
+      if(Text)
+      {
+        for (i = 0; L'\0' != Text[i]; i++)
         {
           if (L'\t' == Text[i] || L'\b' == Text[i])
             {
               break;
             }
         }
+      }
 
       if (0 != (Item->fState & MF_GRAYED))
 	{
@@ -887,7 +858,7 @@
         {
           SelectObject(Dc, FontOld);
         }
-    }
+  }
 }
 
 /***********************************************************************
@@ -1032,7 +1003,7 @@
       MENUITEMINFOW mii;
 
       mii.cbSize = sizeof(mii);
-      mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE;
+      mii.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE;
       mii.fType = GET_DWORD(res);
       res += sizeof(DWORD);
       mii.fState = GET_DWORD(res);
@@ -1065,8 +1036,6 @@
 	}
       else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR))
 	{
-	  DbgPrint("WARN: Converting NULL menu item %04x, type %04x to SEPARATOR\n",
-	      mii.wID, mii.fType);
 	  mii.fType |= MF_SEPARATOR;
 	}
     InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
@@ -1209,9 +1178,12 @@
                  INT OrgX, INT OrgY, BOOL MenuBar)
 {
   PWCHAR p;
+  SIZE MenuCharSize;
   UINT CheckBitmapWidth = GetSystemMetrics(SM_CXMENUCHECK);
 
   DPRINT("dc=%x owner=%x (%d,%d)\n", Dc, WndOwner, OrgX, OrgY);
+
+  MenuCharSize.cx = GdiGetCharDimensions( Dc, NULL, &MenuCharSize.cy );
 
   SetRect(&ItemInfo->Rect, OrgX, OrgY, OrgX, OrgY);
 
@@ -1235,16 +1207,13 @@
    /* Tests reveal that Windows ( Win95 thru WinXP) adds twice the average
     * width of a menufont character to the width of an owner-drawn menu.
     */
-      ItemInfo->Rect.right += mis.itemWidth + 2 * 
-                                     GdiGetCharDimensions( Dc, NULL, NULL );
+      ItemInfo->Rect.right += mis.itemWidth + 2 *  MenuCharSize.cx;
+
       if (MenuBar)
         {
-          ItemInfo->Rect.right += MENU_BAR_ITEMS_SPACE;
-
           /* under at least win95 you seem to be given a standard
              height for the menu and the height value is ignored */
-
-          ItemInfo->Rect.bottom += GetSystemMetrics(SM_CYMENU) - 1;
+            ItemInfo->Rect.bottom += GetSystemMetrics(SM_CYMENUSIZE);
         }
       else
         {
@@ -1252,21 +1221,18 @@
         }
 
       DPRINT("id=%04x size=%dx%d\n", ItemInfo->wID, mis.itemWidth, mis.itemHeight);
-      /* Fall through to get check/arrow width calculation. */
+      return;
     }
 
   if (0 != (ItemInfo->fType & MF_SEPARATOR))
     {
       ItemInfo->Rect.bottom += SEPARATOR_HEIGHT;
+      if( !MenuBar)
+            ItemInfo->Rect.right += ArrowBitmapWidth +  MenuCharSize.cx;
       return;
     }
 
-  if (0 != (ItemInfo->fType & MF_OWNERDRAW))
-    {
-      return;
-    }
-
-  if (ItemInfo->hbmpItem) //IS_BITMAP_ITEM(ItemInfo->fType))
+  if (ItemInfo->hbmpItem)
     {
       SIZE Size;
 
@@ -1289,7 +1255,6 @@
         {
             ItemInfo->Rect.right += ArrowBitmapWidth;
         }
-
       }
       else
       {
@@ -1309,7 +1274,7 @@
     }
 
   /* it must be a text item - unless it's the system menu */
-  if (0 == (ItemInfo->fType & MF_SYSMENU) && IS_STRING_ITEM(ItemInfo->fType))
+  if (0 == (ItemInfo->fType & MF_SYSMENU) && ItemInfo->Text)
     {
       SIZE Size;
 
@@ -1372,7 +1337,7 @@
   Start = 0;
   MaxX = 2 + 1;
 
-  MenuInitRosMenuItemInfo(&ItemInfo);
+  MenuInitRosMenuItemInfo(&ItemInfo);  
   while (Start < MenuInfo->MenuItemCount)
     {
       OrgX = MaxX;
@@ -1394,7 +1359,6 @@
             {
               break;
             }
-
           MenuCalcItemSize(Dc, &ItemInfo, MenuInfo, WndOwner, OrgX, OrgY, FALSE);
           if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo))
             {
@@ -1409,7 +1373,7 @@
             }
           MaxX = max(MaxX, ItemInfo.Rect.right);
           OrgY = ItemInfo.Rect.bottom;
-          if (IS_STRING_ITEM(ItemInfo.fType) && 0 != ItemInfo.XTab)
+          if ((ItemInfo.Text) && 0 != ItemInfo.XTab)
 	    {
               MaxTab = max(MaxTab, ItemInfo.XTab);
               MaxTabWidth = max(MaxTabWidth, ItemInfo.Rect.right - ItemInfo.XTab);
@@ -1423,7 +1387,7 @@
           if (MenuGetRosMenuItemInfo(MenuInfo->Self, Start, &ItemInfo))
             {
               ItemInfo.Rect.right = MaxX;
-              if (IS_STRING_ITEM(ItemInfo.fType) && 0 != ItemInfo.XTab)
+              if ((ItemInfo.Text) && 0 != ItemInfo.XTab)
                 {
                   ItemInfo.XTab = MaxTab;
                 }
@@ -1476,6 +1440,7 @@
   MaxY = Rect->top + 1;
   Start = 0;
   HelpPos = -1;
+
   MenuInitRosMenuItemInfo(&ItemInfo);
   while (Start < MenuInfo->MenuItemCount)
     {
@@ -1502,6 +1467,7 @@
 
           DPRINT("calling MENU_CalcItemSize org=(%d, %d)\n", OrgX, OrgY);
           MenuCalcItemSize(Dc, &ItemInfo, MenuInfo, WndOwner, OrgX, OrgY, TRUE);
+          
           if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo))
             {
               MenuCleanupRosMenuItemInfo(&ItemInfo);
@@ -1531,7 +1497,8 @@
             }
 	}
 
-/* FIXME: Is this really needed? */
+/* FIXME: Is this really needed? */ /*NO! it is not needed, why make the
+HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */
 #if 0
       /* Finish the line (set all items to the largest height found) */
       while (Start < i)
@@ -1544,7 +1511,7 @@
           Start++;
         }
 #else
-     Start = i;
+     Start = i; /* This works! */
 #endif
     }
 
@@ -1731,7 +1698,9 @@
 
       SendMessageW(Wnd, WM_INITMENU, (WPARAM)Menu, 0);
 
-      if (MenuGetRosMenuInfo(&MenuInfo, Menu) && 0 == MenuInfo.Height)
+      MenuGetRosMenuInfo(&MenuInfo, Menu);
+      
+      if (0 == MenuInfo.Height)
         {
           /* app changed/recreated menu bar entries in WM_INITMENU
              Recalculate menu sizes else clicks will not work */
@@ -1739,6 +1708,15 @@
                        SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
 
         }
+    /* This makes the menus of applications built with Delphi work.
+     * It also enables menus to be displayed in more than one window,
+     * but there are some bugs left that need to be fixed in this case.
+     */
+      if(MenuInfo.Self == Menu)
+      {
+         MenuInfo.Wnd = Wnd;
+         MenuSetRosMenuInfo(&MenuInfo);
+      }
     }
 
   return TRUE;
@@ -1771,6 +1749,7 @@
       MenuInitRosMenuItemInfo(&ItemInfo);
       if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo))
         {
+          ItemInfo.fMask |= MIIM_STATE;
           ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
           MenuSetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo);
         }
@@ -1936,12 +1915,12 @@
 
   SelectObject(Dc, hMenuFont);
   MenuInitRosMenuItemInfo(&ItemInfo);
-
   /* Clear previous highlighted item */
   if (NO_SELECTED_ITEM != MenuInfo->FocusedItem)
     {
       if (MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
         {
+          ItemInfo.fMask |= MIIM_STATE;
           ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
           MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
         }
@@ -1959,6 +1938,7 @@
         {
           if (0 == (ItemInfo.fType & MF_SEPARATOR))
             {
+              ItemInfo.fMask |= MIIM_STATE;
               ItemInfo.fState |= MF_HILITE;
               MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
               MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc,
@@ -1993,7 +1973,6 @@
             }
         }
     }
-
   MenuCleanupRosMenuItemInfo(&ItemInfo);
   ReleaseDC(MenuInfo->Wnd, Dc);
 }
@@ -2113,7 +2092,7 @@
   }
   #if 0
   mii.cbSize = sizeof(MENUITEMINFOW);
-  mii.fMask = MIIM_STATE;
+  mii.fMask |= MIIM_STATE;
   if((DefItem != SC_CLOSE) && GetMenuItemInfoW(Menu, DefItem, FALSE, &mii) &&
      (mii.fState & (MFS_GRAYED | MFS_DISABLED)))
   {
@@ -2188,7 +2167,7 @@
         }
 
       SelectObject(Dc, hMenuFont);
-
+      ItemInfo.fMask |= MIIM_STATE;
       ItemInfo.fState |= MF_HILITE;
       MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
       MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->Height,
@@ -2202,8 +2181,8 @@
       ItemInfo.Rect = Rect;
     }
 
+  ItemInfo.fMask |= MIIM_STATE;
   ItemInfo.fState |= MF_MOUSESELECT;
-
   MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
 
   if (IS_SYSTEM_MENU(MenuInfo))
@@ -2264,6 +2243,7 @@
   if (NULL != MenuInfo && NULL != TopPopup && NO_SELECTED_ITEM != MenuInfo->FocusedItem)
     {
       MenuInitRosMenuItemInfo(&ItemInfo);
+      ItemInfo.fMask |= MIIM_FTYPE | MIIM_STATE;
       if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)
           || 0 == (ItemInfo.fType & MF_POPUP)
           || 0 == (ItemInfo.fState & MF_MOUSESELECT))
@@ -2272,6 +2252,7 @@
           return;
         }
       ItemInfo.fState &= ~MF_MOUSESELECT;
+      ItemInfo.fMask |= MIIM_STATE;
       MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
       if (MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu))
         {
@@ -3123,7 +3104,7 @@
           ItemInfo = Items;
           for (i = 0; i < MenuInfo->MenuItemCount; i++, ItemInfo++)
             {
-              if (IS_STRING_ITEM(ItemInfo->fType) && NULL != ItemInfo->dwTypeData)
+              if ((ItemInfo->Text) && NULL != ItemInfo->dwTypeData)
                 {
                   WCHAR *p = (WCHAR *) ItemInfo->dwTypeData - 2;
                   do
@@ -3412,6 +3393,7 @@
                       break;
                   }
                 break;  /* WM_KEYDOWN */
+
               case WM_CHAR:
               case WM_SYSCHAR:
                 {
@@ -3457,7 +3439,9 @@
         }
       else
         {
+          PeekMessageW( &Msg, 0, Msg.message, Msg.message, PM_REMOVE );
           DispatchMessageW(&Msg);
+          continue;
         }
 
       if (! fEndMenu)
@@ -3625,7 +3609,27 @@
 
 }
 
-
+/*
+ *  From MSDN:
+ *  The MFT_BITMAP, MFT_SEPARATOR, and MFT_STRING values cannot be combined 
+ *  with one another. Also MFT_OWNERDRAW. Set fMask to MIIM_TYPE to use fType.
+ *
+ *  Windows 2K/XP: fType is used only if fMask has a value of MIIM_FTYPE.
+ *
+ *  MIIM_TYPE: Retrieves or sets the fType and dwTypeData members. Windows 
+ *  2K/XP: MIIM_TYPE is replaced by  MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING.
+ *  MFT_STRING is replaced by MIIM_STRING. 
+ *  (So, I guess we should use MIIM_STRING only for strings?)
+ *
+ *  MIIM_FTYPE: Windows 2K/Windows XP: Retrieves or sets the fType member.
+ *
+ *  Based on wine, SetMenuItemInfo_common:
+ *  1) set MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP any one with MIIM_TYPE, 
+ *     it will result in a error.
+ *  2) set menu mask to MIIM_FTYPE and MFT_BITMAP ftype it will result in a error.
+ *     These conditions are addressed in Win32k IntSetMenuItemInfo.
+ *
+ */
 static
 BOOL
 FASTCALL
@@ -3636,11 +3640,14 @@
   LPCWSTR NewItem, 
   BOOL Unicode)
 {
+/*
+ * Let us assume MIIM_FTYPE is set and building a new menu item structure.
+ */
   if(Flags & MF_BITMAP)
   {
-    mii->fType |= MFT_BITMAP;
-    mii->fMask |= MIIM_BITMAP;
+    mii->fMask |= MIIM_BITMAP;   /* Use the new way of seting hbmpItem.*/
     mii->hbmpItem = (HBITMAP) NewItem;
+    mii->fType &= ~MFT_BITMAP;  /* just incase, Kill the old way */
   }
   else if(Flags & MF_OWNERDRAW)
   {
@@ -3648,13 +3655,12 @@
     mii->fMask |= MIIM_DATA;
     mii->dwItemData = (DWORD) NewItem;
   }
+  else if (Flags & MF_SEPARATOR)
+  {
+    mii->fType |= MFT_SEPARATOR;
+  }
   else /* Default action MF_STRING. */
   {
-   /*
-    if(mii->dwTypeData != NULL)
-    {
-      HeapFree(GetProcessHeap(),0, mii.dwTypeData);
-    }*/
     /* Item beginning with a backspace is a help item */
     if (NewItem != NULL)
     {
@@ -3677,11 +3683,8 @@
           }
        }
     }
-    else
-    {
-       mii->fType |= MFT_SEPARATOR;
-    }
-    mii->fMask |= MIIM_TYPE;
+    mii->fMask |= MIIM_STRING;
+    mii->fType |= MFT_STRING; /* Zero */
     mii->dwTypeData = (LPWSTR)NewItem;
     if (Unicode)
        mii->cch = (NULL == NewItem ? 0 : strlenW(NewItem));
@@ -3690,29 +3693,40 @@
     mii->hbmpItem = NULL;
   }
 
-  if(Flags & MF_RIGHTJUSTIFY)
+  if(Flags & MF_RIGHTJUSTIFY) /* Same as MF_HELP */
   {
     mii->fType |= MFT_RIGHTJUSTIFY;
   }
+
+  if(Flags & MF_BYPOSITION)
+  {
+    mii->fType |= MF_BYPOSITION;
+  }
+
   if(Flags & MF_MENUBREAK)
   {
     mii->fType |= MFT_MENUBREAK;
   }
-  if(Flags & MF_MENUBARBREAK)
+  else if(Flags & MF_MENUBARBREAK)
   {
     mii->fType |= MFT_MENUBARBREAK;
   }
-  if(Flags & MF_DISABLED)
-  {
-    mii->fState |= MFS_DISABLED;
-  }
+
   if(Flags & MF_GRAYED)
   {
     mii->fState |= MFS_GRAYED;
+    mii->fMask |= MIIM_STATE;
   }
-
-  if ((mii->fType & MF_POPUP) && (Flags & MF_POPUP) && (mii->hSubMenu != (HMENU)IDNewItem))
-    NtUserDestroyMenu( mii->hSubMenu );   /* ModifyMenu() spec */
+  else if(Flags & MF_DISABLED)
+  {
+    mii->fState |= MFS_DISABLED;
+    mii->fMask |= MIIM_STATE;
+  }
+  else /* default state */
+  {
+    mii->fState |= MFS_ENABLED;
+    mii->fMask |= MIIM_STATE;
+  }
 
   if(Flags & MF_POPUP)
   {
@@ -3808,6 +3822,7 @@
       if (0 != (Items[i].fType & MF_MENUBARBREAK)) break;
       if ( i >= idFirst && i <= idLast )
       {
+         Items[i].fMask = MIIM_STATE | MIIM_FTYPE;
          if ( i == idCheck)
          {
              Items[i].fType |= MFT_RADIOCHECK;
@@ -4042,14 +4057,14 @@
       return FALSE;
    }
 
-   if ((mii->fMask & (MIIM_STRING | MIIM_TYPE)) == 0)
+   if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING)))
    {
       /* No text requested, just pass on */
       return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE);
    }
 
    AnsiBuffer = mii->dwTypeData;
-   Count = mii->cch;
+   Count = miiW.cch = mii->cch;
    RtlCopyMemory(&miiW, mii, mii->cbSize);
    miiW.dwTypeData = 0;
 
@@ -4061,7 +4076,10 @@
    }
 
    if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO)&miiW, FALSE))
+   {
+      if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
       return FALSE;
+   }
 
    RtlCopyMemory(mii, &miiW, miiW.cbSize);
 
@@ -4073,7 +4091,7 @@
       return TRUE;
    }
 
-   if (IS_STRING_ITEM(miiW.fType))
+   if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType)))
    {
       WideCharToMultiByte(CP_ACP, 0, miiW.dwTypeData, miiW.cch, AnsiBuffer,
                              mii->cch, NULL, NULL);
@@ -4107,7 +4125,7 @@
       return FALSE;
    }
 
-   if ((mii->fMask & (MIIM_STRING | MIIM_TYPE)) == 0)
+   if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING)))
    {
       /* No text requested, just pass on */
       return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE);
@@ -4115,7 +4133,7 @@
 
    String = mii->dwTypeData;
    Count = mii->cch;
-   RtlCopyMemory(&miiW, mii, mii->cbSize);   
+   RtlCopyMemory(&miiW, mii, mii->cbSize);
    miiW.dwTypeData = 0;
 
    if (String)
@@ -4126,9 +4144,12 @@
    }
 
    if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) &miiW, FALSE))
+   {
+      if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
       return FALSE;
-
-   RtlCopyMemory(mii, &miiW, miiW.cbSize); // looks okay to over write user data.
+   }
+   
+   RtlCopyMemory(mii, &miiW, miiW.cbSize); // Okay to over write user data.
 
    if (!String || !Count)
    {
@@ -4138,7 +4159,7 @@
       return TRUE;
    }
 
-   if (IS_STRING_ITEM(miiW.fType))
+   if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType)))
    {
       lstrcpynW( String, miiW.dwTypeData, Count );
    }
@@ -4175,10 +4196,9 @@
 {
   ROSMENUINFO MenuInfo;
   ROSMENUITEMINFO mii;
-
+  memset( &mii, 0, sizeof(mii) );
   mii.cbSize = sizeof(MENUITEMINFOW);
-  mii.fMask = MIIM_STATE | MIIM_TYPE | MIIM_SUBMENU;
-  mii.dwTypeData = NULL;
+  mii.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_SUBMENU;
 
   SetLastError(0);
   if(NtUserMenuItemInfo(hMenu, uId, uFlags, &mii, FALSE))
@@ -4220,9 +4240,10 @@
   UINT uFlag)
 {
   MENUITEMINFOA mii;
+  memset( &mii, 0, sizeof(mii) );
   mii.dwTypeData = lpString;
-  mii.fMask = MIIM_STRING;
-  mii.fType = MF_STRING;
+  mii.fMask = MIIM_STRING | MIIM_FTYPE;
+  mii.fType = MFT_STRING;
   mii.cbSize = sizeof(MENUITEMINFOA);
   mii.cch = nMaxCount;
 
@@ -4246,9 +4267,10 @@
   UINT uFlag)
 {
   MENUITEMINFOW miiW;
+  memset( &miiW, 0, sizeof(miiW) );
   miiW.dwTypeData = lpString;
-  miiW.fMask = MIIM_STRING;
-  miiW.fType = MF_STRING;
+  miiW.fMask = MIIM_STRING | MIIM_FTYPE;
+  miiW.fType = MFT_STRING;
   miiW.cbSize = sizeof(MENUITEMINFOW);
   miiW.cch = nMaxCount;
 
@@ -4327,10 +4349,9 @@
   LPCSTR lpNewItem)
 {
   MENUITEMINFOA mii;
+  memset( &mii, 0, sizeof(mii) );
   mii.cbSize = sizeof(MENUITEMINFOA);
-  mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE;
-  mii.fType = 0;
-  mii.fState = MFS_ENABLED;
+  mii.fMask = MIIM_FTYPE;
 
   MenuSetItemData((LPMENUITEMINFOW) &mii,
   		   uFlags,
@@ -4363,12 +4384,21 @@
   if((lpmii->cbSize == sizeof(MENUITEMINFOA)) ||
      (lpmii->cbSize == sizeof(MENUITEMINFOA) - sizeof(HBITMAP)))
   {
-    RtlMoveMemory ( &mi, lpmii, lpmii->cbSize );
-
+    RtlCopyMemory ( &mi, lpmii, lpmii->cbSize );
+
+    if( lpmii->cbSize != sizeof( MENUITEMINFOW)) 
+    {
+       mi.cbSize = sizeof( MENUITEMINFOW);
+       mi.hbmpItem = NULL;
+    }
     /* copy the text string */
-    if((mi.fMask & (MIIM_TYPE | MIIM_STRING)) &&
-      (MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData)
-    {
+    if (((mi.fMask & MIIM_STRING) ||
+        ((mi.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING)))
+          && mi.dwTypeData != NULL)
+    {
+      UINT Count = lpmii->cch;
+      if(!Count) Count++;
+      if (IsBadStringPtrA(lpmii->dwTypeData, Count)) return FALSE;
       Status = RtlCreateUnicodeStringFromAsciiz(&MenuText, (LPSTR)mi.dwTypeData);
       if (!NT_SUCCESS (Status))
       {
@@ -4379,7 +4409,6 @@
       mi.cch = MenuText.Length / sizeof(WCHAR);
       CleanHeap = TRUE;
     }
-
     res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi);
 
     if ( CleanHeap ) RtlFreeUnicodeString ( &MenuText );
@@ -4402,7 +4431,6 @@
   MENUITEMINFOW mi;
   UNICODE_STRING MenuText;
   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
@@ -4411,18 +4439,25 @@
   if((lpmii->cbSize == sizeof(MENUITEMINFOW)) ||
      (lpmii->cbSize == sizeof(MENUITEMINFOW) - sizeof(HBITMAP)))
   {
-    memcpy(&mi, lpmii, lpmii->cbSize);
-
+    RtlCopyMemory(&mi, lpmii, lpmii->cbSize);
+
+    if( lpmii->cbSize != sizeof( MENUITEMINFOW)) 
+    {
+       mi.cbSize = sizeof( MENUITEMINFOW);
+       mi.hbmpItem = NULL;
+    }
     /* copy the text string */
-    if((mi.fMask & (MIIM_TYPE | MIIM_STRING)) &&
-      (MENU_ITEM_TYPE(mi.fType) == MF_STRING) &&
-      mi.dwTypeData != NULL)
-    {
+    if (((mi.fMask & MIIM_STRING) ||
+        ((mi.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING)))
+          && mi.dwTypeData != NULL)
+    {
+      UINT Count = lpmii->cch;
+      if(!Count) Count++;
+      if (IsBadStringPtrW(lpmii->dwTypeData, Count)) return FALSE;
       RtlInitUnicodeString(&MenuText, (PWSTR)lpmii->dwTypeData);
       mi.dwTypeData = MenuText.Buffer;
       mi.cch = MenuText.Length / sizeof(WCHAR);
-    };
-
+    }
     res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi);
   }
   return res;
@@ -4442,10 +4477,9 @@
   LPCWSTR lpNewItem)
 {
   MENUITEMINFOW mii;
+  memset( &mii, 0, sizeof(mii) );
   mii.cbSize = sizeof(MENUITEMINFOW);
-  mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE;
-  mii.fType = 0;
-  mii.fState = MFS_ENABLED;
+  mii.fMask = MIIM_FTYPE;
 
   MenuSetItemData( &mii,
   		   uFlags,
@@ -4581,18 +4615,28 @@
   UINT_PTR uIDNewItem,
   LPCSTR lpNewItem)
 {
+  ROSMENUINFO mi;
+  ROSMENUITEMINFO rmii;
   MENUITEMINFOA mii;
   memset( &mii, 0, sizeof(mii) );
   mii.cbSize = sizeof(MENUITEMINFOA);
-  mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE;
-  mii.fType = 0;
-  mii.fState = MFS_ENABLED;
-
-  if(!GetMenuItemInfoA( hMnu,
-                        uPosition,
-                       (BOOL)(MF_BYPOSITION & uFlags),
-                        &mii)) return FALSE;
-
+  mii.fMask = MIIM_FTYPE;
+
+  if (!MenuGetRosMenuInfo( &mi, hMnu )) return FALSE;
+
+  mi.Height = 0;
+
+  if (!MenuSetRosMenuInfo( &mi )) return FALSE;
+  
+  MenuInitRosMenuItemInfo( &rmii );
+
+  if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE;
+
+  if ((rmii.fType & MF_POPUP) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
+    NtUserDestroyMenu( rmii.hSubMenu );   /* ModifyMenu() spec */
+
+  MenuCleanupRosMenuItemInfo( &rmii );
+  
   MenuSetItemData((LPMENUITEMINFOW) &mii,
   		   uFlags,
   		   uIDNewItem,
@@ -4618,24 +4662,36 @@
   UINT_PTR uIDNewItem,
   LPCWSTR lpNewItem)
 {
+  ROSMENUINFO mi;
+  ROSMENUITEMINFO rmii;  
   MENUITEMINFOW mii;
   memset ( &mii, 0, sizeof(mii) );
   mii.cbSize = sizeof(MENUITEMINFOW);
-  mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE;
-  mii.fState = MFS_ENABLED;
-
-  if(!NtUserMenuItemInfo( hMnu,
-                          uPosition,
-                         (BOOL)(MF_BYPOSITION & uFlags),
-                         (PROSMENUITEMINFO) &mii,
-                          FALSE)) return FALSE;
-
+  mii.fMask = MIIM_FTYPE;
+
+  if (!MenuGetRosMenuInfo( &mi, hMnu )) return FALSE;
+
+  mi.Height = 0; // Force size recalculation.
+
+  if (!MenuSetRosMenuInfo( &mi )) return FALSE;
+
+  MenuInitRosMenuItemInfo( &rmii );
+
+  if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE;
+
+  if ((rmii.fType & MF_POPUP) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
+    NtUserDestroyMenu( rmii.hSubMenu );   /* ModifyMenu() spec */
+
+  MenuCleanupRosMenuItemInfo( &rmii );
+
+  /* Init new data for this menu item */
   MenuSetItemData( &mii,
   		   uFlags,
   		   uIDNewItem,
   		   lpNewItem,
   		   TRUE);
 
+  /* Now, make Win32k IntSetMenuItemInfo handle the changes to this menu item. */
   return SetMenuItemInfoW( hMnu,
                            uPosition,
                            (BOOL)(MF_BYPOSITION & uFlags),
@@ -4714,7 +4770,9 @@
   HBITMAP hBitmapChecked)
 {
   ROSMENUITEMINFO uItem;
-
+  memset ( &uItem, 0, sizeof(uItem) );
+  uItem.fMask = MIIM_STATE | MIIM_BITMAP;
+  
   if(!(NtUserMenuItemInfo(hMenu, uPosition, 
                  (BOOL)(MF_BYPOSITION & uFlags), &uItem, FALSE))) return FALSE;
 
@@ -4746,16 +4804,38 @@
 {
   MENUITEMINFOW MenuItemInfoW;
   UNICODE_STRING UnicodeString;
-  ULONG Result;
+  NTSTATUS Status;
+  ULONG Result = FALSE;
 
   RtlCopyMemory(&MenuItemInfoW, lpmii, min(lpmii->cbSize, sizeof(MENUITEMINFOW)));
 
-  if ((MenuItemInfoW.fMask & (MIIM_TYPE | MIIM_STRING)) &&
-      (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING) &&
-      MenuItemInfoW.dwTypeData != NULL)
+  if( lpmii->cbSize != sizeof( MENUITEMINFOW)) 
   {
-    RtlCreateUnicodeStringFromAsciiz(&UnicodeString,
+     MenuItemInfoW.cbSize = sizeof( MENUITEMINFOW);
+     MenuItemInfoW.hbmpItem = NULL;
+  }
+/*
+ *  MIIM_STRING              == good
+ *  MIIM_TYPE & MFT_STRING   == good
+ *  MIIM_STRING & MFT_STRING == good
+ *  MIIM_STRING & MFT_OWNERSRAW == good
+ */
+  if (((MenuItemInfoW.fMask & MIIM_STRING) ||
+      ((MenuItemInfoW.fMask & MIIM_TYPE) &&
+                           (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING)))
+        && MenuItemInfoW.dwTypeData != NULL)
+  {
+/* cch is ignored when the content of a menu item is set by calling SetMenuItemInfo. */
+    UINT Count = lpmii->cch;
+    if(!Count) Count++;
+    if (IsBadStringPtrA(lpmii->dwTypeData, Count )) return FALSE;
+    Status = RtlCreateUnicodeStringFromAsciiz(&UnicodeString,
                                      (LPSTR)MenuItemInfoW.dwTypeData);
+    if (!NT_SUCCESS (Status))
+    {
+      SetLastError (RtlNtStatusToDosError(Status));
+      return FALSE;
+    }
     MenuItemInfoW.dwTypeData = UnicodeString.Buffer;
     MenuItemInfoW.cch = UnicodeString.Length / sizeof(WCHAR);
   }
@@ -4788,15 +4868,30 @@
   LPCMENUITEMINFOW lpmii)
 {
   MENUITEMINFOW MenuItemInfoW;
+  ULONG Result;
 
   RtlCopyMemory(&MenuItemInfoW, lpmii, min(lpmii->cbSize, sizeof(MENUITEMINFOW)));
-  if (0 != (MenuItemInfoW.fMask & MIIM_STRING))
+
+  if( lpmii->cbSize != sizeof( MENUITEMINFOW)) 
   {
-    MenuItemInfoW.cch = strlenW(MenuItemInfoW.dwTypeData);
+     MenuItemInfoW.cbSize = sizeof( MENUITEMINFOW);
+     MenuItemInfoW.hbmpItem = NULL;
   }
 
-  return NtUserMenuItemInfo(hMenu, uItem, fByPosition,
+  if (((MenuItemInfoW.fMask & MIIM_STRING) ||
+      ((MenuItemInfoW.fMask & MIIM_TYPE) && 
+                           (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING)))
+        && MenuItemInfoW.dwTypeData != NULL)
+  {
+     UINT Count = lpmii->cch;
+     if (!Count) Count++;
+     if (IsBadStringPtrW(lpmii->dwTypeData, Count)) return FALSE;
+     MenuItemInfoW.cch = strlenW(MenuItemInfoW.dwTypeData);
+  }
+  Result = NtUserMenuItemInfo(hMenu, uItem, fByPosition,
                             (PROSMENUITEMINFO)&MenuItemInfoW, TRUE);
+
+  return Result;
 }
 
 /*

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/menu.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/menu.c?rev=23221&r1=23220&r2=23221&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/menu.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/menu.c Sat Jul 22 09:28:44 2006
@@ -302,9 +302,8 @@
             Window = UserGetWindowObject(Menu->MenuInfo.Wnd);
             if (Window)
             {
-               Window->IDMenu = 0;;
+               Window->IDMenu = 0;
             }
-
          }
          ObmDeleteObject(Menu->MenuInfo.Self, otMenu);
          ObDereferenceObject(WindowStation);
@@ -352,7 +351,7 @@
    Menu->MenuItemList = NULL;
 
    /* Insert menu item into process menu handle list */
-   InsertTailList(&PsGetCurrentProcessWin32Process()->MenuListHead, &Menu->ListEntry);
+   InsertTailList(&PsGetWin32Process()->MenuListHead, &Menu->ListEntry);
 
    return Menu;
 }
@@ -456,7 +455,7 @@
    Menu->MenuItemList = NULL;
 
    /* Insert menu item into process menu handle list */
-   InsertTailList(&PsGetCurrentProcessWin32Process()->MenuListHead, &Menu->ListEntry);
+   InsertTailList(&PsGetWin32Process()->MenuListHead, &Menu->ListEntry);
 
    IntCloneMenuItems(Menu, Source);
 
@@ -693,6 +692,10 @@
 {
    NTSTATUS Status;
 
+   if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE))
+   {
+      lpmii->fType = MenuItem->fType;
+   }
    if(lpmii->fMask & MIIM_BITMAP)
    {
       lpmii->hbmpItem = MenuItem->hbmpItem;
@@ -706,10 +709,6 @@
    {
       lpmii->dwItemData = MenuItem->dwItemData;
    }
-   if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE))
-   {
-      lpmii->fType = MenuItem->fType;
-   }
    if(lpmii->fMask & MIIM_ID)
    {
       lpmii->wID = MenuItem->wID;
@@ -722,7 +721,9 @@
    {
       lpmii->hSubMenu = MenuItem->hSubMenu;
    }
-   if (lpmii->fMask & (MIIM_STRING | MIIM_TYPE))
+
+   if ((lpmii->fMask & MIIM_STRING) ||
+      ((lpmii->fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING)))
    {
       if (lpmii->dwTypeData == NULL)
       {
@@ -745,6 +746,7 @@
    {
       lpmii->Rect = MenuItem->Rect;
       lpmii->XTab = MenuItem->XTab;
+      lpmii->Text = MenuItem->Text.Buffer;
    }
 
    return TRUE;
@@ -754,7 +756,7 @@
 IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINFO lpmii)
 {
    PMENU_OBJECT SubMenuObject;
-   UINT fTypeMask = (MFT_BITMAP | MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_OWNERDRAW | MFT_RADIOCHECK | MFT_RIGHTJUSTIFY | MFT_SEPARATOR | MF_POPUP);
+   UINT fTypeMask = (MFT_BITMAP | MFT_MENUBARBREAK | MFT_MENUBREAK | MF_BYPOSITION | MFT_OWNERDRAW | MFT_RADIOCHECK | MFT_RIGHTJUSTIFY | MFT_SEPARATOR | MF_POPUP);
 
    if(!MenuItem || !MenuObject || !lpmii)
    {
@@ -762,36 +764,61 @@
    }
    if( lpmii->fType & ~fTypeMask)
    {
-     DPRINT("IntSetMenuItemInfo invalid fType flags %x\n", lpmii->fType & ~fTypeMask);
+     DbgPrint("IntSetMenuItemInfo invalid fType flags %x\n", lpmii->fType & ~fTypeMask);
      lpmii->fMask &= ~(MIIM_TYPE | MIIM_FTYPE);
    }
-   if(lpmii->fMask & MIIM_BITMAP)
-   {
-      MenuItem->hbmpItem = lpmii->hbmpItem;
-   }
-   if(lpmii->fMask & MIIM_CHECKMARKS)
-   {
-      MenuItem->hbmpChecked = lpmii->hbmpChecked;
-      MenuItem->hbmpUnchecked = lpmii->hbmpUnchecked;
-   }
-   if(lpmii->fMask & MIIM_DATA)
-   {
-      MenuItem->dwItemData = lpmii->dwItemData;
-   }
-   if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE))
-   {
+   if(lpmii->fMask &  MIIM_TYPE)
+   {
+      if(lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP))
+      {
+         DbgPrint("IntSetMenuItemInfo: Invalid combination of fMask bits used\n");
+         /* this does not happen on Win9x/ME */
+         SetLastNtError( ERROR_INVALID_PARAMETER);
+         return FALSE;
+      }
       /*
        * Delete the menu item type when changing type from
        * MF_STRING.
        */
       if (MenuItem->fType != lpmii->fType &&
-            MENU_ITEM_TYPE(MenuItem->fType) == MF_STRING)
+            MENU_ITEM_TYPE(MenuItem->fType) == MFT_STRING)
       {
          FreeMenuText(MenuItem);
          RtlInitUnicodeString(&MenuItem->Text, NULL);
       }
-      MenuItem->fType &= ~MENU_ITEM_TYPE(MenuItem->fType);
-      MenuItem->fType |= MENU_ITEM_TYPE(lpmii->fType);
+      if(lpmii->fType & MFT_BITMAP)
+      {
+//         if(lpmii->hbmpItem) 
+           MenuItem->hbmpItem = lpmii->hbmpItem;
+//         else
+//         { /* Win 9x/Me stuff */
+//           MenuItem->hbmpItem = (HBITMAP)lpmii->dwTypeData;
+//         }
+      }
+      MenuItem->fType |= lpmii->fType;
+   }
+   if (lpmii->fMask & MIIM_FTYPE )
+   {
+      if(( lpmii->fType & MFT_BITMAP))
+      {
+         DbgPrint("IntSetMenuItemInfo: Can not use FTYPE and MFT_BITMAP.\n");
+         SetLastNtError( ERROR_INVALID_PARAMETER);
+         return FALSE;
+      }
+      MenuItem->fType |= lpmii->fType;
+   }
+   if(lpmii->fMask & MIIM_BITMAP)
+   {
+         MenuItem->hbmpItem = lpmii->hbmpItem;
+   }
+   if(lpmii->fMask & MIIM_CHECKMARKS)
+   {
+      MenuItem->hbmpChecked = lpmii->hbmpChecked;
+      MenuItem->hbmpUnchecked = lpmii->hbmpUnchecked;
+   }
+   if(lpmii->fMask & MIIM_DATA)
+   {
+      MenuItem->dwItemData = lpmii->dwItemData;
    }
    if(lpmii->fMask & MIIM_ID)
    {
@@ -829,8 +856,9 @@
          MenuItem->fType &= ~MF_POPUP;
       }
    }
-   if ((lpmii->fMask & (MIIM_TYPE | MIIM_STRING)) &&
-         (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING))
+
+   if ((lpmii->fMask & MIIM_STRING) ||
+      ((lpmii->fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING)))
    {
       FreeMenuText(MenuItem);
 
@@ -870,6 +898,7 @@
    {
       MenuItem->Rect = lpmii->Rect;
       MenuItem->XTab = lpmii->XTab;
+      lpmii->Text = MenuItem->Text.Buffer; /* Send back new allocated string or zero */
    }
 
    return TRUE;




More information about the Ros-diffs mailing list