Merge trunk HEAD (r46369)
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 24 Mar 2010 00:00:51 +0000 (00:00 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 24 Mar 2010 00:00:51 +0000 (00:00 +0000)
(part 5/x)

svn path=/branches/ros-amd64-bringup/; revision=46379

21 files changed:
1  2 
reactos/dll/win32/advapi32/reg/reg.c
reactos/dll/win32/advapi32/service/sctrl.c
reactos/dll/win32/gdi32/objects/region.c
reactos/dll/win32/kernel32/except/except.c
reactos/dll/win32/kernel32/kernel32.pspec
reactos/dll/win32/kernel32/misc/dllmain.c
reactos/dll/win32/kernel32/misc/stubs.c
reactos/dll/win32/kernel32/process/procsup.c
reactos/dll/win32/kernel32/thread/thread.c
reactos/dll/win32/rpcrt4/rpc_transport.c
reactos/dll/win32/shell32/shell32_main.c
reactos/dll/win32/shell32/shellord.c
reactos/dll/win32/syssetup/install.c
reactos/dll/win32/user32/include/user32p.h
reactos/dll/win32/user32/windows/dialog.c
reactos/dll/win32/user32/windows/menu.c
reactos/dll/win32/user32/windows/message.c
reactos/dll/win32/user32/windows/nonclient.c
reactos/dll/win32/user32/windows/spy.c
reactos/dll/win32/user32/windows/window.c
reactos/dll/win32/ws2_32_new/inc/ws2_32p.h

Simple merge
@@@ -379,25 -448,52 +448,52 @@@ ScServiceDispatcher(HANDLE hPipe
              return FALSE;
          }
  
 -            /* Execute command */
 -            switch (ControlPacket->dwControl)
 -            {
 -                case SERVICE_CONTROL_START:
 -                    TRACE("Start command - recieved SERVICE_CONTROL_START\n");
+         lpServiceName = &ControlPacket->szArguments[0];
+         TRACE("Service: %S\n", lpServiceName);
+         lpService = ScLookupServiceByServiceName(lpServiceName);
+         if (lpService != NULL)
+         {
-                 if (ScStartService(ControlPacket) == ERROR_SUCCESS)
 +        /* Execute command */
 +        switch (ControlPacket->dwControl)
 +        {
 +            case SERVICE_CONTROL_START:
 +                TRACE("Start command - recieved SERVICE_CONTROL_START\n");
 -                        dwRunningServices++;
 -                    break;
+                     dwError = ScStartService(lpService, ControlPacket);
+                     if (dwError == ERROR_SUCCESS)
 +                    dwRunningServices++;
 +                break;
  
 -                case SERVICE_CONTROL_STOP:
 -                    TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n");
 +            case SERVICE_CONTROL_STOP:
 +                TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n");
-                 if (ScControlService(ControlPacket) == ERROR_SUCCESS)
+                     dwError = ScControlService(lpService, ControlPacket);
+                     if (dwError == ERROR_SUCCESS)
 -                        dwRunningServices--;
 -                    break;
 +                    dwRunningServices--;
 +                break;
  
 -                default:
 -                    TRACE("Command %lu received", ControlPacket->dwControl);
 +            default:
 +                TRACE("Command %lu received", ControlPacket->dwControl);
-                 ScControlService(ControlPacket);
-                 continue;
+                     dwError = ScControlService(lpService, ControlPacket);
+                     break;
 -            }
++        }
+         }
+         else
+         {
+             dwError = ERROR_SERVICE_DOES_NOT_EXIST;
+         }
+         ReplyPacket.dwError = dwError;
+         /* Send the reply packet */
+         bResult = WriteFile(hPipe,
+                             &ReplyPacket,
+                             sizeof(ReplyPacket),
+                             &Count,
+                             NULL);
+         if (bResult == FALSE)
+         {
+             ERR("Pipe write failed (Error: %lu)\n", GetLastError());
+             return FALSE;
          }
  
          if (dwRunningServices == 0)
@@@ -631,9 -727,18 +727,18 @@@ SetServiceStatus(SERVICE_STATUS_HANDLE 
      TRACE("SetServiceStatus() called\n");
      TRACE("hServiceStatus %lu\n", hServiceStatus);
  
 -        /* Call to services.exe using RPC */
 -        dwError = RSetServiceStatus((RPC_SERVICE_STATUS_HANDLE)hServiceStatus,
 -                                    lpServiceStatus);
+     RpcTryExcept
+     {
 +    /* Call to services.exe using RPC */
 +    dwError = RSetServiceStatus((RPC_SERVICE_STATUS_HANDLE)hServiceStatus,
 +                                lpServiceStatus);
+     }
+     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+     {
+         dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+     }
+     RpcEndExcept;
      if (dwError != ERROR_SUCCESS)
      {
          ERR("ScmrSetServiceStatus() failed (Error %lu)\n", dwError);
@@@ -220,13 -275,14 +282,14 @@@ UnhandledExceptionFilter(struct _EXCEPT
     LONG RetValue;
     HANDLE DebugPort = NULL;
     NTSTATUS ErrCode;
 -   ULONG ErrorParameters[4];
 +   ULONG_PTR ErrorParameters[4];
     ULONG ErrorResponse;
+    PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
  
-    if ((NTSTATUS)ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
-        ExceptionInfo->ExceptionRecord->NumberParameters >= 2)
+    if ((NTSTATUS)ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
+        ExceptionRecord->NumberParameters >= 2)
     {
-       switch(ExceptionInfo->ExceptionRecord->ExceptionInformation[0])
+       switch(ExceptionRecord->ExceptionInformation[0])
        {
        case EXCEPTION_WRITE_FAULT:
           /* Change the protection on some write attempts, some InstallShield setups
  @ stdcall GetConsoleKeyboardLayoutNameW(ptr)
  @ stdcall GetConsoleMode(long ptr)
  @ stdcall GetConsoleNlsMode(long ptr)
 +;@ stdcall GetConsoleOriginalTitleA ; Win 7
 +;@ stdcall GetConsoleOriginalTitleW ; Win 7
  @ stdcall GetConsoleOutputCP()
- @ stub GetConsoleProcessList ; missing in XP SP3, present in Win 7
+ @ stdcall GetConsoleProcessList(ptr long) ; missing in XP SP3
  @ stdcall GetConsoleScreenBufferInfo(long ptr)
 +;@ stdcall GetConsoleScreenBufferInfoEx ; Win 7
  @ stdcall GetConsoleSelectionInfo(ptr)
  @ stdcall GetConsoleTitleA(ptr long)
  @ stdcall GetConsoleTitleW(ptr long)
Simple merge
Simple merge
  
  LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
  
+ WINE_DEFAULT_DEBUG_CHANNEL(menu);
  /* internal popup menu window messages */
 -#define MM_SETMENUHANDLE      (WM_USER + 0)
 -#define MM_GETMENUHANDLE      (WM_USER + 1)
 +#define MM_SETMENUHANDLE (WM_USER + 0)
 +#define MM_GETMENUHANDLE (WM_USER + 1)
  
+ /* internal flags for menu tracking */
+ #define TF_ENDMENU              0x10000
+ #define TF_SUSPENDPOPUP         0x20000
+ #define TF_SKIPREMOVE           0x40000
+ #define ITEM_PREV             -1
+ #define ITEM_NEXT              1
  /* Internal MenuTrackMenu() flags */
  #define TPM_INTERNAL          0xF0000000
- #define TPM_ENTERIDLEEX               0x80000000              /* set owner window for WM_ENTERIDLE */
  #define TPM_BUTTONDOWN                0x40000000              /* menu was clicked before tracking */
  #define TPM_POPUPMENU           0x20000000              /* menu is a popup menu */
  
@@@ -276,85 -267,171 +267,171 @@@ MenuCleanupAllRosMenuItemInfo(PROSMENUI
    HeapFree(GetProcessHeap(), 0, ItemInfo);
  }
  
  /***********************************************************************
-  *           MenuLoadBitmaps
+  *           MenuInitSysMenuPopup
   *
-  * Load the arrow bitmap. We can't do this from MenuInit since user32
-  * can also be used (and thus initialized) from text-mode.
+  * Grey the appropriate items in System menu.
   */
- static void FASTCALL
- MenuLoadBitmaps(VOID)
+ void FASTCALL MenuInitSysMenuPopup(HMENU hmenu, DWORD style, DWORD clsStyle, LONG HitTest )
  {
-   /* Load system buttons bitmaps */
-   if (NULL == BmpSysMenu)
+     BOOL gray;
+     UINT DefItem;
+     #if 0
+     MENUITEMINFOW mii;
+     #endif
+     gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
+     EnableMenuItem( hmenu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
+     gray = ((style & WS_MAXIMIZE) != 0);
+     EnableMenuItem( hmenu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
+     gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
+     EnableMenuItem( hmenu, SC_MINIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
+     gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
+     EnableMenuItem( hmenu, SC_MAXIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
+     gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
+     EnableMenuItem( hmenu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
+     gray = (clsStyle & CS_NOCLOSE) != 0;
+     /* The menu item must keep its state if it's disabled */
+     if(gray)
+         EnableMenuItem( hmenu, SC_CLOSE, MF_GRAYED);
+     /* Set default menu item */
+     if(style & WS_MINIMIZE) DefItem = SC_RESTORE;
+     else if(HitTest == HTCAPTION) DefItem = ((style & (WS_MAXIMIZE | WS_MINIMIZE)) ? SC_RESTORE : SC_MAXIMIZE);
+     else DefItem = SC_CLOSE;
+ #if 0
+     mii.cbSize = sizeof(MENUITEMINFOW);
+     mii.fMask |= MIIM_STATE;
+     if((DefItem != SC_CLOSE) && GetMenuItemInfoW(hmenu, DefItem, FALSE, &mii) &&
+        (mii.fState & (MFS_GRAYED | MFS_DISABLED))) DefItem = SC_CLOSE;
+ #endif
+     SetMenuDefaultItem(hmenu, DefItem, MF_BYCOMMAND);
+ }
+ /******************************************************************************
+  *
+  *   UINT MenuGetStartOfNextColumn(
+  *     PROSMENUINFO MenuInfo)
+  *
+  *****************************************************************************/
+ static UINT MenuGetStartOfNextColumn(
+     PROSMENUINFO MenuInfo)
 -{
 +    {
-       BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
+     PROSMENUITEMINFO MenuItems;
+     UINT i;
+     i = MenuInfo->FocusedItem;
+     if ( i == NO_SELECTED_ITEM )
+         return i;
+     if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0)
+         return NO_SELECTED_ITEM;
+     for (i++ ; i < MenuInfo->MenuItemCount; i++)
+         if (0 != (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK)))
+             return i;
+     return NO_SELECTED_ITEM;
 -}
 +    }
- }
  
- /***********************************************************************
-  *           MenuGetBitmapItemSize
+ /******************************************************************************
   *
-  * Get the size of a bitmap item.
-  */
- static void FASTCALL
- MenuGetBitmapItemSize(PROSMENUITEMINFO lpitem, SIZE *Size, HWND WndOwner)
+  *   UINT MenuGetStartOfPrevColumn(
+  *     PROSMENUINFO MenuInfo)
+  *
+  *****************************************************************************/
+ static UINT FASTCALL MenuGetStartOfPrevColumn(
+     PROSMENUINFO MenuInfo)
  {
-   BITMAP Bm;
-   HBITMAP Bmp = lpitem->hbmpItem;
+     PROSMENUITEMINFO MenuItems;
+     UINT i;
+     if (!MenuInfo->FocusedItem || MenuInfo->FocusedItem == NO_SELECTED_ITEM)
+         return NO_SELECTED_ITEM;
  
-   Size->cx = Size->cy = 0;
+     if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0)
+         return NO_SELECTED_ITEM;
  
-   /* check if there is a magic menu item associated with this item */
-   if (IS_MAGIC_BITMAP(Bmp))
+     /* Find the start of the column */
+     for (i = MenuInfo->FocusedItem;
+          0 != i && 0 == (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK));
+          --i)
      {
-       switch((INT_PTR) Bmp)
+         ; /* empty */
+     }
+     if (i == 0)
 -    {
 +        {
-             case (INT_PTR)HBMMENU_CALLBACK:
-             {
-                 MEASUREITEMSTRUCT measItem;
-                 measItem.CtlType = ODT_MENU;
-                 measItem.CtlID = 0;
-                 measItem.itemID = lpitem->wID;
-                 measItem.itemWidth = lpitem->Rect.right - lpitem->Rect.left;
-                 measItem.itemHeight = lpitem->Rect.bottom - lpitem->Rect.top;
-                 measItem.itemData = lpitem->dwItemData;
-                 SendMessageW( WndOwner, WM_MEASUREITEM, lpitem->wID, (LPARAM)&measItem);
-                 Size->cx = measItem.itemWidth;
-                 Size->cy = measItem.itemHeight;
-                 return;
+         MenuCleanupAllRosMenuItemInfo(MenuItems);
+         return NO_SELECTED_ITEM;
 -    }
 +            }
+     for (--i; 0 != i; --i)
+         if (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))
              break;
  
-           case (INT_PTR) HBMMENU_SYSTEM:
-             if (0 != lpitem->dwItemData)
+     MenuCleanupAllRosMenuItemInfo(MenuItems);
+     TRACE("ret %d.\n", i );
+     return i;
+ }
+ /***********************************************************************
+  *           MenuFindSubMenu
+  *
+  * Find a Sub menu. Return the position of the submenu, and modifies
+  * *hmenu in case it is found in another sub-menu.
+  * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
+  */
+ static UINT FASTCALL MenuFindSubMenu(HMENU *hmenu, HMENU hSubTarget )
 -{
 +              {
-                 Bmp = (HBITMAP)(ULONG_PTR) lpitem->dwItemData;
-                 break;
+     ROSMENUINFO menu;
+     UINT i;
+     ROSMENUITEMINFO item;
+     if (((*hmenu)==(HMENU)0xffff) ||
+           (!MenuGetRosMenuInfo(&menu, *hmenu)))
+         return NO_SELECTED_ITEM;
+     MenuInitRosMenuItemInfo(&item);
+     for (i = 0; i < menu.MenuItemCount; i++) {
+         if (! MenuGetRosMenuItemInfo(menu.Self, i, &item))
+         {
+             MenuCleanupRosMenuItemInfo(&item);
+             return NO_SELECTED_ITEM;
 -        }
 +              }
-             /* 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_D:
-           case (INT_PTR) HBMMENU_POPUP_CLOSE:
-           case (INT_PTR) HBMMENU_POPUP_RESTORE:
-           case (INT_PTR) HBMMENU_POPUP_MAXIMIZE:
-           case (INT_PTR) HBMMENU_POPUP_MINIMIZE:
-             /* 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;
+         if (!(item.fType & MF_POPUP)) continue;
+         if (item.hSubMenu == hSubTarget) {
+             MenuCleanupRosMenuItemInfo(&item);
+             return i;
+         }
+         else  {
+             HMENU hsubmenu = item.hSubMenu;
+             UINT pos = MenuFindSubMenu(&hsubmenu, hSubTarget );
+             if (pos != NO_SELECTED_ITEM) {
+                 *hmenu = hsubmenu;
+                 return pos;
 -           }
++    }
          }
      }
+     MenuCleanupRosMenuItemInfo(&item);
+     return NO_SELECTED_ITEM;
+ }
  
-   if (GetObjectW(Bmp, sizeof(BITMAP), &Bm))
+ /***********************************************************************
+  *           MenuLoadBitmaps
+  *
+  * Load the arrow bitmap. We can't do this from MenuInit since user32
+  * can also be used (and thus initialized) from text-mode.
+  */
+ static void FASTCALL
+ MenuLoadBitmaps(VOID)
 -{
++    {
+   /* Load system buttons bitmaps */
+   if (NULL == BmpSysMenu)
      {
-       Size->cx = Bm.bmWidth;
-       Size->cy = Bm.bmHeight;
+       BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
      }
  }
  
@@@ -427,70 -639,63 +639,63 @@@ static void FASTCALL MenuGetBitmapItemS
   *
   * Draw a bitmap item.
   */
- static void FASTCALL
- MenuDrawBitmapItem(HDC Dc, PROSMENUITEMINFO Item, const RECT *Rect,
+ static void FASTCALL MenuDrawBitmapItem(HDC hdc, PROSMENUITEMINFO lpitem, const RECT *rect,
                      HMENU hmenu, HWND WndOwner, UINT odaction, BOOL MenuBar)
  {
-   BITMAP Bm;
-   DWORD Rop;
-   HDC DcMem;
-   HBITMAP Bmp;
-   int w = Rect->right - Rect->left;
-   int h = Rect->bottom - Rect->top;
-   int BmpXoffset = 0;
-   int Left, Top;
-   HBITMAP hbmpToDraw = (HBITMAP) Item->hbmpItem;
-   Bmp = hbmpToDraw;
+     BITMAP bm;
+     DWORD rop;
+     HDC hdcMem;
+     HBITMAP bmp;
+     int w = rect->right - rect->left;
+     int h = rect->bottom - rect->top;
+     int bmp_xoffset = 0;
+     int left, top;
+     HBITMAP hbmToDraw = lpitem->hbmpItem;
+     bmp = hbmToDraw;
  
 -    /* Check if there is a magic menu item associated with this item */
 +  /* Check if there is a magic menu item associated with this item */
-   if (IS_MAGIC_BITMAP(hbmpToDraw))
+     if (IS_MAGIC_BITMAP(hbmToDraw))
      {
-       UINT Flags = 0;
+         UINT flags = 0;
 -        RECT r;
 +      RECT r;
  
-       r = *Rect;
-       switch ((INT_PTR)hbmpToDraw)
+       r = *rect;
+       switch ((INT_PTR)hbmToDraw)
          {
 -        case (INT_PTR)HBMMENU_SYSTEM:
 +          case (INT_PTR) HBMMENU_SYSTEM:
-             if (NULL != Item->dwTypeData)
+             if (lpitem->dwTypeData)
 -            {
 +              {
-                 Bmp = (HBITMAP)Item->dwTypeData;
-                 if (! GetObjectW(Bmp, sizeof(BITMAP), &Bm))
-                   {
-                     return;
+                 bmp = (HBITMAP)lpitem->dwTypeData;
+                 if (!GetObjectW( bmp, sizeof(bm), &bm )) return;
 -            }
 +                  }
-               }
              else
 -            {
 +              {
                  if (!BmpSysMenu) BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
-                 Bmp = BmpSysMenu;
-                 if (! GetObjectW(Bmp, sizeof(BITMAP), &Bm))
-                   {
-                     return;
-                   }
+                 bmp = BmpSysMenu;
+                 if (! GetObjectW(bmp, sizeof(bm), &bm)) return;
                  /* only use right half of the bitmap */
-                 BmpXoffset = Bm.bmWidth / 2;
-                 Bm.bmWidth -= BmpXoffset;
+                 bmp_xoffset = bm.bmWidth / 2;
+                 bm.bmWidth -= bmp_xoffset;
 -            }
 +              }
              goto got_bitmap;
 -        case (INT_PTR)HBMMENU_MBAR_RESTORE:
 +          case (INT_PTR) HBMMENU_MBAR_RESTORE:
-             Flags = DFCS_CAPTIONRESTORE;
+             flags = DFCS_CAPTIONRESTORE;
              break;
 -        case (INT_PTR)HBMMENU_MBAR_MINIMIZE:
 +          case (INT_PTR) HBMMENU_MBAR_MINIMIZE:
              r.right += 1;
-             Flags = DFCS_CAPTIONMIN;
+             flags = DFCS_CAPTIONMIN;
              break;
 -        case (INT_PTR)HBMMENU_MBAR_MINIMIZE_D:
 +          case (INT_PTR) HBMMENU_MBAR_MINIMIZE_D:
              r.right += 1;
-             Flags = DFCS_CAPTIONMIN | DFCS_INACTIVE;
+             flags = DFCS_CAPTIONMIN | DFCS_INACTIVE;
              break;
 -        case (INT_PTR)HBMMENU_MBAR_CLOSE:
 +          case (INT_PTR) HBMMENU_MBAR_CLOSE:
-             Flags = DFCS_CAPTIONCLOSE;
+             flags = DFCS_CAPTIONCLOSE;
              break;
 -        case (INT_PTR)HBMMENU_MBAR_CLOSE_D:
 +          case (INT_PTR) HBMMENU_MBAR_CLOSE_D:
-             Flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE;
+             flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE;
              break;
 -        case (INT_PTR)HBMMENU_CALLBACK:
 +          case (INT_PTR) HBMMENU_CALLBACK:
              {
                  DRAWITEMSTRUCT drawItem;
                  POINT origorg;
              return;
          }
        InflateRect(&r, -1, -1);
-       if (0 != (Item->fState & MF_HILITE))
+       if (0 != (lpitem->fState & MF_HILITE))
 -      {
 +        {
-           Flags |= DFCS_PUSHED;
+           flags |= DFCS_PUSHED;
 -      }
 +        }
-       DrawFrameControl(Dc, &r, DFC_CAPTION, Flags);
+       DrawFrameControl(hdc, &r, DFC_CAPTION, flags);
        return;
      }
  
-   if (NULL == Bmp || ! GetObjectW(Bmp, sizeof(BITMAP), &Bm))
-     {
-       return;
-     }
+     if (!bmp || !GetObjectW( bmp, sizeof(bm), &bm )) return;
  
- got_bitmap:
-   DcMem = CreateCompatibleDC(Dc);
-   SelectObject(DcMem, Bmp);
 got_bitmap:
+     hdcMem = CreateCompatibleDC( hdc );
+     SelectObject( hdcMem, bmp );
  
-   /* handle fontsize > bitmap_height */
-   Top = (Bm.bmHeight < h) ? Rect->top + (h - Bm.bmHeight) / 2 : Rect->top;
-   Left = Rect->left;
-   Rop= ((Item->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmpToDraw)) ? NOTSRCCOPY : SRCCOPY;
-   if ((Item->fState & MF_HILITE) && Item->hbmpItem)
-     {
-       SetBkColor(Dc, GetSysColor(COLOR_HIGHLIGHT));
-     }
-   BitBlt(Dc, Left, Top, w, h, DcMem, BmpXoffset, 0, Rop);
-   DeleteDC(DcMem);
+     /* handle fontsize > bitmap_height */
+     top = (h>bm.bmHeight) ? rect->top+(h-bm.bmHeight)/2 : rect->top;
+     left=rect->left;
+     rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmToDraw)) ? NOTSRCCOPY : SRCCOPY;
+     if ((lpitem->fState & MF_HILITE) && lpitem->hbmpItem)
+         SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
+     BitBlt( hdc, left, top, w, h, hdcMem, bmp_xoffset, 0, rop );
+     DeleteDC( hdcMem );
+ }
+ /***********************************************************************
+  *           MenuCalcItemSize
+  *
+  * Calculate the size of the menu item and store it in lpitem->rect.
+  */
+ static void FASTCALL MenuCalcItemSize( HDC hdc, PROSMENUITEMINFO lpitem, PROSMENUINFO MenuInfo, HWND hwndOwner,
+                  INT orgX, INT orgY, BOOL menuBar)
 -{
++    {
+     WCHAR *p;
+     UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
+     INT itemheight = 0;
+     TRACE("dc=%x owner=%x (%d,%d)\n", hdc, hwndOwner, orgX, orgY);
+     MenuCharSize.cx = GdiGetCharDimensions( hdc, NULL, &MenuCharSize.cy );
+     SetRect( &lpitem->Rect, orgX, orgY, orgX, orgY );
+     if (lpitem->fType & MF_OWNERDRAW)
+     {
+         MEASUREITEMSTRUCT mis;
+         mis.CtlType    = ODT_MENU;
+         mis.CtlID      = 0;
+         mis.itemID     = lpitem->wID;
+         mis.itemData   = lpitem->dwItemData;
+         mis.itemHeight = HIWORD( GetDialogBaseUnits());
+         mis.itemWidth  = 0;
+         SendMessageW( hwndOwner, WM_MEASUREITEM, 0, (LPARAM)&mis );
+         /* Tests reveal that Windows ( Win95 thru WinXP) adds twice the average
+          * width of a menufont character to the width of an owner-drawn menu. 
+          */
+         lpitem->Rect.right += mis.itemWidth + 2 * MenuCharSize.cx;
+         if (menuBar) {
+             /* under at least win95 you seem to be given a standard
+                height for the menu and the height value is ignored */
+             lpitem->Rect.bottom += GetSystemMetrics(SM_CYMENUSIZE);
+         } else
+             lpitem->Rect.bottom += mis.itemHeight;
+         TRACE("id=%04lx size=%dx%d\n",
+                 lpitem->wID, mis.itemWidth, mis.itemHeight);
 -        return;
++      return;
+     }
+     if (lpitem->fType & MF_SEPARATOR)
+     {
+         lpitem->Rect.bottom += SEPARATOR_HEIGHT;
+         if( !menuBar)
+             lpitem->Rect.right += check_bitmap_width +  MenuCharSize.cx;
+         return;
+     }
+     lpitem->dxTab = 0;
+     if (lpitem->hbmpItem)
+     {
+         SIZE size;
+         if (!menuBar) {
+             MenuGetBitmapItemSize(lpitem, &size, hwndOwner );
+             /* Keep the size of the bitmap in callback mode to be able
+              * to draw it correctly */
+             lpitem->Rect.right = lpitem->Rect.left + size.cx;
+             if (MenuInfo->maxBmpSize.cx < abs(size.cx) +  MENU_ITEM_HBMP_SPACE ||
+                 MenuInfo->maxBmpSize.cy < abs(size.cy))
+             {
+                 MenuInfo->maxBmpSize.cx = abs(size.cx) + MENU_ITEM_HBMP_SPACE;
+                 MenuInfo->maxBmpSize.cy = abs(size.cy);
 -            }
++    }
+             MenuSetRosMenuInfo(MenuInfo);
+             itemheight = size.cy + 2;
+             if( !(MenuInfo->dwStyle & MNS_NOCHECK))
+                 lpitem->Rect.right += 2 * check_bitmap_width;
+             lpitem->Rect.right += 4 + MenuCharSize.cx;
+             lpitem->dxTab = lpitem->Rect.right;
+             lpitem->Rect.right += check_bitmap_width;
+         } else /* hbmpItem & MenuBar */ {
+             MenuGetBitmapItemSize(lpitem, &size, hwndOwner );
+             lpitem->Rect.right  += size.cx;
+             if( lpitem->lpstr) lpitem->Rect.right  += 2;
+             itemheight = size.cy;
+             /* Special case: Minimize button doesn't have a space behind it. */
+             if (lpitem->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE ||
+                 lpitem->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE_D)
+             lpitem->Rect.right -= 1;
 -        }
++}
+     }
+     else if (!menuBar) {
+         if( !(MenuInfo->dwStyle & MNS_NOCHECK))
+              lpitem->Rect.right += check_bitmap_width;
+         lpitem->Rect.right += 4 + MenuCharSize.cx;
+         lpitem->dxTab = lpitem->Rect.right;
+         lpitem->Rect.right += check_bitmap_width;
+     }
+     /* it must be a text item - unless it's the system menu */
+     if (!(lpitem->fType & MF_SYSMENU) && lpitem->lpstr) {
+         HFONT hfontOld = NULL;
+         RECT rc = lpitem->Rect;
+         LONG txtheight, txtwidth;
+         if ( lpitem->fState & MFS_DEFAULT ) {
+             hfontOld = SelectObject( hdc, hMenuFontBold );
+         }
+         if (menuBar) {
+             txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc,
+                     DT_SINGLELINE|DT_CALCRECT); 
+             lpitem->Rect.right  += rc.right - rc.left;
+             itemheight = max( max( itemheight, txtheight),
+                     GetSystemMetrics( SM_CYMENU) - 1);
+             lpitem->Rect.right +=  2 * MenuCharSize.cx;
+         } else {
+             if ((p = strchrW( lpitem->dwTypeData, '\t' )) != NULL) {
+                 RECT tmprc = rc;
+                 LONG tmpheight;
+                 int n = (int)( p - lpitem->dwTypeData);
+                 /* Item contains a tab (only meaningful in popup menus) */
+                 /* get text size before the tab */
+                 txtheight = DrawTextW( hdc, lpitem->dwTypeData, n, &rc,
+                         DT_SINGLELINE|DT_CALCRECT);
+                 txtwidth = rc.right - rc.left;
+                 p += 1; /* advance past the Tab */
+                 /* get text size after the tab */
+                 tmpheight = DrawTextW( hdc, p, -1, &tmprc,
+                         DT_SINGLELINE|DT_CALCRECT);
+                 lpitem->dxTab += txtwidth;
+                 txtheight = max( txtheight, tmpheight);
+                 txtwidth += MenuCharSize.cx + /* space for the tab */
+                     tmprc.right - tmprc.left; /* space for the short cut */
+             } else {
+                 txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc,
+                         DT_SINGLELINE|DT_CALCRECT);
+                 txtwidth = rc.right - rc.left;
+                 lpitem->dxTab += txtwidth;
+             }
+             lpitem->Rect.right  += 2 + txtwidth;
+             itemheight = max( itemheight,
+                                   max( txtheight + 2, MenuCharSize.cy + 4));
+         }
+         if (hfontOld) SelectObject (hdc, hfontOld);
+     } else if( menuBar) {
+         itemheight = max( itemheight, GetSystemMetrics(SM_CYMENU)-1);
+     }
+     lpitem->Rect.bottom += itemheight;
+     TRACE("(%ld,%ld)-(%ld,%ld)\n", lpitem->Rect.left, lpitem->Rect.top, lpitem->Rect.right, lpitem->Rect.bottom);
+ }
+ /***********************************************************************
+  *           MenuPopupMenuCalcSize
+  *
+  * Calculate the size of a popup menu.
+  */
+ static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner)
+ {
+     ROSMENUITEMINFO lpitem;
+     HDC hdc;
+     int start, i;
+     int orgX, orgY, maxX, maxTab, maxTabWidth;
+     MenuInfo->Width = MenuInfo->Height = 0;
+     if (MenuInfo->MenuItemCount == 0)
+     {
+         MenuSetRosMenuInfo(MenuInfo);
+         return;
+     }
+     hdc = GetDC(NULL);
+     SelectObject( hdc, hMenuFont );
+     start = 0;
+     maxX = 2 + 1;
+     MenuInfo->maxBmpSize.cx = 0;
+     MenuInfo->maxBmpSize.cy = 0;
+     MenuInitRosMenuItemInfo(&lpitem);
+     while (start < MenuInfo->MenuItemCount)
+     {
+       orgX = maxX;
+       orgY = 2;
+       maxTab = maxTabWidth = 0;
+       /* Parse items until column break or end of menu */
+       for (i = start; i < MenuInfo->MenuItemCount; i++)
+       {
+           if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i, &lpitem))
+           {
+               MenuCleanupRosMenuItemInfo(&lpitem);
+               MenuSetRosMenuInfo(MenuInfo);
+               return;
+           }
+           if (i != start &&
+                (lpitem.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
+           MenuCalcItemSize(hdc, &lpitem, MenuInfo, WndOwner, orgX, orgY, FALSE);
+           if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &lpitem))
+           {
+               MenuCleanupRosMenuItemInfo(&lpitem);
+               MenuSetRosMenuInfo(MenuInfo);
+               return;
+           }
+ // Not sure here,, The patch from wine removes this.
+ //        if ((lpitem.fType & MF_MENUBARBREAK) != 0)
+ //        {
+ //              OrgX++;
+ //        }
+           maxX = max(maxX, lpitem.Rect.right);
+           orgY = lpitem.Rect.bottom;
+           if ((lpitem.lpstr) && lpitem.dxTab )
+             {
+               maxTab = max( maxTab, lpitem.dxTab );
+               maxTabWidth = max(maxTabWidth, lpitem.Rect.right - lpitem.dxTab);
+           }
+         }
+         /* Finish the column (set all items to the largest width found) */
+         maxX = max( maxX, maxTab + maxTabWidth );
+         while (start < i)
+         {
+             if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &lpitem))
+             {
+                 lpitem.Rect.right = maxX;
+                 if ((lpitem.lpstr) && 0 != lpitem.dxTab)
+                 {
+                     lpitem.dxTab = maxTab;
+                 }
+                 MenuSetRosMenuItemInfo(MenuInfo->Self, start, &lpitem);
+             }
+             start++;
+           }
+         MenuInfo->Height = max(MenuInfo->Height, orgY);
+     }
+     MenuInfo->Width  = maxX;
+     /* space for 3d border */
+     MenuInfo->Height += 2;
+     MenuInfo->Width += 2;
+     MenuCleanupRosMenuItemInfo(&lpitem);
+     MenuSetRosMenuInfo(MenuInfo);
+     ReleaseDC( 0, hdc );
+ }
+ /***********************************************************************
+  *           MenuMenuBarCalcSize
+  *
+  * FIXME: Word 6 implements its own MDI and its own 'close window' bitmap
+  * height is off by 1 pixel which causes lengthy window relocations when
+  * active document window is maximized/restored.
+  *
+  * Calculate the size of the menu bar.
+  */
+ static void FASTCALL MenuMenuBarCalcSize( HDC hdc, LPRECT lprect,
+                                           PROSMENUINFO MenuInfo, HWND hwndOwner )
+ {
+     ROSMENUITEMINFO ItemInfo;
+     int start, i, orgX, orgY, maxY, helpPos;
+     if ((lprect == NULL) || (MenuInfo == NULL)) return;
+     if (MenuInfo->MenuItemCount == 0) return;
+     TRACE("left=%ld top=%ld right=%ld bottom=%ld\n", lprect->left, lprect->top, lprect->right, lprect->bottom);
+     MenuInfo->Width = lprect->right - lprect->left;
+     MenuInfo->Height = 0;
+     maxY = lprect->top + 1;
+     start = 0;
+     helpPos = -1;
+     MenuInfo->maxBmpSize.cx = 0;
+     MenuInfo->maxBmpSize.cy = 0;
+     MenuInitRosMenuItemInfo(&ItemInfo);
+     while (start < MenuInfo->MenuItemCount)
+     {
+         if (! MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo))
+         {
+             MenuCleanupRosMenuItemInfo(&ItemInfo);
+             return;
+         }
+         orgX = lprect->left;
+         orgY = maxY;
+         /* Parse items until line break or end of menu */
+         for (i = start; i < MenuInfo->MenuItemCount; i++)
+           {
+             if ((helpPos == -1) && (ItemInfo.fType & MF_RIGHTJUSTIFY)) helpPos = i;
+             if ((i != start) &&
+                (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
+             TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", orgX, orgY);
+             MenuCalcItemSize(hdc, &ItemInfo, MenuInfo, hwndOwner, orgX, orgY, TRUE);
+             if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo))
+             {
+                 MenuCleanupRosMenuItemInfo(&ItemInfo);
+                 return;
+             }
+             if (ItemInfo.Rect.right > lprect->right)
+             {
+                 if (i != start) break;
+                 else ItemInfo.Rect.right = lprect->right;
+             }
+             maxY = max( maxY, ItemInfo.Rect.bottom );
+             orgX = ItemInfo.Rect.right;
+             if (i + 1 < MenuInfo->MenuItemCount)
+             {
+                 if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i + 1, &ItemInfo))
+                 {
+                     MenuCleanupRosMenuItemInfo(&ItemInfo);
+                     return;
+                 }
+             }
+       }
+ /* 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)
+         {
+             if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo))
+             {
+                 ItemInfo.Rect.bottom = maxY;
+                 MenuSetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo);
+             }
+             start++;
+         }
+ #else
+         start = i; /* This works! */
+ #endif
+     }
+     lprect->bottom = maxY;
+     MenuInfo->Height = lprect->bottom - lprect->top;
+     MenuSetRosMenuInfo(MenuInfo);
+     if (helpPos != -1)
+     {
+       /* Flush right all items between the MF_RIGHTJUSTIFY and */
+       /* the last item (if several lines, only move the last line) */
+       if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->MenuItemCount - 1, &ItemInfo))
+       {
+           MenuCleanupRosMenuItemInfo(&ItemInfo);
+           return;
+       }
+       orgY = ItemInfo.Rect.top;
+       orgX = lprect->right;
+       for (i = MenuInfo->MenuItemCount - 1; helpPos <= i; i--)
+         {
+           if (i < helpPos)
+           {
+               break;                          /* done */
+           }
+           if (ItemInfo.Rect.top != orgY)
+           {
+               break;                          /* Other line */
+           }
+           if (orgX <= ItemInfo.Rect.right)
+           {
+               break;                          /* Too far right already */
+           }
+           ItemInfo.Rect.left += orgX - ItemInfo.Rect.right;
+           ItemInfo.Rect.right = orgX;
+           orgX = ItemInfo.Rect.left;
+           MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo);
+           if (helpPos + 1 <= i &&
+               ! MenuGetRosMenuItemInfo(MenuInfo->Self, i - 1, &ItemInfo))
+             {
+                 MenuCleanupRosMenuItemInfo(&ItemInfo);
+                 return;
+             }
+         }
+     }
+     MenuCleanupRosMenuItemInfo(&ItemInfo);
  }
  
  /***********************************************************************
   *
   * Draw a single menu item.
   */
- static void FASTCALL
- MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND WndOwner, HDC Dc,
-                  PROSMENUITEMINFO Item, UINT Height, BOOL MenuBar, UINT Action)
+ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND WndOwner, HDC hdc,
+                  PROSMENUITEMINFO lpitem, UINT Height, BOOL menuBar, UINT odaction)
  {
-   RECT Rect;
+     RECT rect;
 -    PWCHAR Text;
 -    BOOL flat_menu = FALSE;
 -    int bkgnd;
 -    PWND Wnd = ValidateHwnd(hWnd);
 +  PWCHAR Text;
 +  BOOL flat_menu = FALSE;
 +  int bkgnd;
 +  PWND Wnd = ValidateHwnd(hWnd);
  
 -    if (!Wnd)
 +  if (!Wnd)
        return;
  
-   if (0 != (Item->fType & MF_SYSMENU))
+     if (lpitem->fType & MF_SYSMENU)
      {
 -        if ( (Wnd->style & WS_MINIMIZE))
 +      if ( (Wnd->style & WS_MINIMIZE))
          {
-           UserGetInsideRectNC(Wnd, &Rect);
-           UserDrawSysMenuButton(hWnd, Dc, &Rect,
-                                 Item->fState & (MF_HILITE | MF_MOUSESELECT));
+           UserGetInsideRectNC(Wnd, &rect);
+           UserDrawSysMenuButton(hWnd, hdc, &rect,
+                                 lpitem->fState & (MF_HILITE | MF_MOUSESELECT));
 -          }
 -        return;
 +      }
 +      return;
      }
  
      SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
-     bkgnd = (MenuBar && flat_menu) ? COLOR_MENUBAR : COLOR_MENU;
+     bkgnd = (menuBar && flat_menu) ? COLOR_MENUBAR : COLOR_MENU;
 -  
 -    /* Setup colors */
 +
 +  /* Setup colors */
  
-   if (0 != (Item->fState & MF_HILITE))
+     if (lpitem->fState & MF_HILITE)
      {
-       if (MenuBar && !flat_menu)
-         {
-           SetTextColor(Dc, GetSysColor(COLOR_MENUTEXT));
-           SetBkColor(Dc, GetSysColor(COLOR_MENU));
-         }
+         if(menuBar && !flat_menu) {
+             SetTextColor(hdc, GetSysColor(COLOR_MENUTEXT));
+             SetBkColor(hdc, GetSysColor(COLOR_MENU));
+         } else {
+             if (lpitem->fState & MF_GRAYED)
+                 SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
 -            else
 +      else
-         {
-           if (0 != (Item->fState & MF_GRAYED))
-             {
-               SetTextColor(Dc, GetSysColor(COLOR_GRAYTEXT));
+                 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
+             SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
 -        }
 -    }
 -    else
 +            }
-           else
-             {
-               SetTextColor(Dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
 +            }
-           SetBkColor(Dc, GetSysColor(COLOR_HIGHLIGHT));
-         }
-     }
 +  else
      {
-       if (0 != (Item->fState & MF_GRAYED))
-         {
-           SetTextColor(Dc, GetSysColor(COLOR_GRAYTEXT));
-         }
+         if (lpitem->fState & MF_GRAYED)
+             SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
 -        else
 +      else
-         {
-           SetTextColor(Dc, GetSysColor(COLOR_MENUTEXT));
+             SetTextColor( hdc, GetSysColor( COLOR_MENUTEXT ) );
+         SetBkColor( hdc, GetSysColor( bkgnd ) );
 -    }
 +        }
-       SetBkColor(Dc, GetSysColor(bkgnd));
-     }
  
-   Rect = Item->Rect;
+     rect = lpitem->Rect;
  
-   if (Item->fType & MF_OWNERDRAW)
+     if (lpitem->fType & MF_OWNERDRAW)
      {
 -        /*
 -        ** Experimentation under Windows reveals that an owner-drawn
 -        ** menu is given the rectangle which includes the space it requested
 -        ** in its response to WM_MEASUREITEM _plus_ width for a checkmark
 -        ** and a popup-menu arrow.  This is the value of lpitem->rect.
 -        ** Windows will leave all drawing to the application except for
 -        ** the popup-menu arrow.  Windows always draws that itself, after
 -        ** the menu owner has finished drawing.
 -        */
 -        DRAWITEMSTRUCT dis;
 -
 -        dis.CtlType   = ODT_MENU;
 -        dis.CtlID     = 0;
 +      /*
 +      ** Experimentation under Windows reveals that an owner-drawn
 +      ** menu is given the rectangle which includes the space it requested
 +      ** in its response to WM_MEASUREITEM _plus_ width for a checkmark
 +      ** and a popup-menu arrow.  This is the value of lpitem->rect.
 +      ** Windows will leave all drawing to the application except for
 +      ** the popup-menu arrow.  Windows always draws that itself, after
 +      ** the menu owner has finished drawing.
 +      */
 +      DRAWITEMSTRUCT dis;
 +
 +      dis.CtlType   = ODT_MENU;
 +      dis.CtlID     = 0;
-       dis.itemID    = Item->wID;
-       dis.itemData  = (DWORD)Item->dwItemData;
+         dis.itemID    = lpitem->wID;
+         dis.itemData  = (DWORD)lpitem->dwItemData;
 -        dis.itemState = 0;
 +      dis.itemState = 0;
-       if (0 != (Item->fState & MF_CHECKED))
-         {
-           dis.itemState |= ODS_CHECKED;
-         }
-       if (0 != (Item->fState & MF_GRAYED))
-         {
-           dis.itemState |= ODS_GRAYED | ODS_DISABLED;
-         }
-       if (0 != (Item->fState & MF_HILITE))
-         {
-           dis.itemState |= ODS_SELECTED;
-         }
-       dis.itemAction = Action; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
+         if (lpitem->fState & MF_CHECKED) dis.itemState |= ODS_CHECKED;
+         if (lpitem->fState & MF_GRAYED)  dis.itemState |= ODS_GRAYED | ODS_DISABLED;
+         if (lpitem->fState & MF_HILITE)  dis.itemState |= ODS_SELECTED;
+         dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
 -        dis.hwndItem   = (HWND) MenuInfo->Self;
 +      dis.hwndItem   = (HWND) MenuInfo->Self;
-       dis.hDC        = Dc;
-       dis.rcItem     = Rect;
+         dis.hDC        = hdc;
+         dis.rcItem     = rect;
 -        TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, "
 -              "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", hWnd,
 -              dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem,
 -              dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right,
 -              dis.rcItem.bottom);
 -        SendMessageW(WndOwner, WM_DRAWITEM, 0, (LPARAM) &dis);
 -        /* Draw the popup-menu arrow */
 +      TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, "
 +            "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", hWnd,
 +            dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem,
 +            dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right,
 +            dis.rcItem.bottom);
 +      SendMessageW(WndOwner, WM_DRAWITEM, 0, (LPARAM) &dis);
 +      /* Draw the popup-menu arrow */
-       if (0 != (Item->fType & MF_POPUP))
+         if (lpitem->fType & MF_POPUP)
 -        {
 -            RECT rectTemp;
 +      {
 +           RECT rectTemp;
-            CopyRect(&rectTemp, &Rect);
+             CopyRect(&rectTemp, &rect);
 -            rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
 +           rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
-            DrawFrameControl(Dc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
+             DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
 -        }
 -        return;
 +      }
 +      return;
      }
  
-   TRACE("rect={%ld,%ld,%ld,%ld}\n", Item->Rect.left, Item->Rect.top,
-                                      Item->Rect.right, Item->Rect.bottom);
-   if (MenuBar && 0 != (Item->fType & MF_SEPARATOR))
-   {
-      return;
-   }
+     if (menuBar && (lpitem->fType & MF_SEPARATOR)) return;
  
-   if (Item->fState & MF_HILITE)
+     if (lpitem->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));
 -        if (flat_menu)
 -        {
+             InflateRect (&rect, -1, -1);
+             FillRect(hdc, &rect, GetSysColorBrush(COLOR_MENUHILIGHT));
+             InflateRect (&rect, 1, 1);
+             FrameRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT));
 -        }
 -        else
 -        {
 +    }
 +    else
 +    {
-        if (MenuBar)
-        {
-           DrawEdge(Dc, &Rect, BDR_SUNKENOUTER, BF_RECT);
-        }
+             if(menuBar)
+                 DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT);
 -            else
 +       else
-        {
-           FillRect(Dc, &Rect, GetSysColorBrush(COLOR_HIGHLIGHT));
+                 FillRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT));
 -        }
 +       }
      }
-   }
 -    else
 +  else
-   {
-      FillRect(Dc, &Rect, GetSysColorBrush(bkgnd));
-   }
+         FillRect( hdc, &rect, GetSysColorBrush(bkgnd) );
  
-   SetBkMode(Dc, TRANSPARENT);
+     SetBkMode( hdc, TRANSPARENT );
  
 -    /* vertical separator */
 +  /* vertical separator */
-   if (! MenuBar && 0 != (Item->fType & MF_MENUBARBREAK))
+     if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
 -    {
 -        HPEN oldPen;
 +  {
 +    HPEN oldPen;
-     RECT rc = Rect;
+         RECT rc = rect;
 -        rc.left -= 3;
 -        rc.top = 3;
 -        rc.bottom = Height - 3;
 -        if (flat_menu)
 -        {
 +    rc.left -= 3;
 +    rc.top = 3;
 +    rc.bottom = Height - 3;
 +    if (flat_menu)
 +    {
-        oldPen = SelectObject( Dc, GetStockObject(DC_PEN) );
-        SetDCPenColor(Dc, GetSysColor(COLOR_BTNSHADOW));
-        MoveToEx( Dc, rc.left, rc.top, NULL );
-        LineTo( Dc, rc.left, rc.bottom );
-        SelectObject( Dc, oldPen );
+             oldPen = SelectObject( hdc, GetStockObject(DC_PEN) );
+             SetDCPenColor(hdc, GetSysColor(COLOR_BTNSHADOW));
+             MoveToEx( hdc, rc.left, rc.top, NULL );
+             LineTo( hdc, rc.left, rc.bottom );
+             SelectObject( hdc, oldPen );
 -        }
 -        else
 -            DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT);
      }
-        DrawEdge(Dc, &rc, EDGE_ETCHED, BF_LEFT);
 +    else
++            DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT);
 +  }
  
 -    /* horizontal separator */
 +  /* horizontal separator */
-   if (0 != (Item->fType & MF_SEPARATOR))
+     if (lpitem->fType & MF_SEPARATOR)
 -    {
 -        HPEN oldPen;
 +  {
 +    HPEN oldPen;
-     RECT rc = Rect;
+         RECT rc = rect;
 -        rc.left++;
 -        rc.right--;
 -        rc.top += SEPARATOR_HEIGHT / 2;
 -        if (flat_menu)
 -        {
 +    rc.left++;
 +    rc.right--;
 +    rc.top += SEPARATOR_HEIGHT / 2;
 +    if (flat_menu)
 +    {
-        oldPen = SelectObject( Dc, GetStockObject(DC_PEN) );
-        SetDCPenColor(Dc, GetSysColor(COLOR_BTNSHADOW));
-        MoveToEx( Dc, rc.left, rc.top, NULL );
-        LineTo( Dc, rc.right, rc.top );
-        SelectObject( Dc, oldPen );
+             oldPen = SelectObject( hdc, GetStockObject(DC_PEN) );
+             SetDCPenColor( hdc, GetSysColor(COLOR_BTNSHADOW));
+             MoveToEx( hdc, rc.left, rc.top, NULL );
+             LineTo( hdc, rc.right, rc.top );
+             SelectObject( hdc, oldPen );
 -        }
 -        else
 -            DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP);
 -        return;
      }
-        DrawEdge(Dc, &rc, EDGE_ETCHED, BF_TOP);
 +    else
++            DrawEdge (hdc, &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 */
 +  /* 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, GetStockObject(DC_PEN));
-   SetDCPenColor(Dc, GetSysColor(COLOR_WINDOWFRAME));
-   MoveToEx(Dc, Rect.left, (Rect.top + Rect.bottom) / 2, NULL);
-   LineTo(Dc, Rect.right, (Rect.top + Rect.bottom) / 2);
+     FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
+     SelectObject(hdc, GetStockObject(DC_PEN));
+     SetDCPenColor(hdc, GetSysColor(COLOR_WINDOWFRAME));
+     MoveToEx(hdc, rect.left, (rect.top + rect.bottom) / 2, NULL);
+     LineTo(hdc, rect.right, (rect.top + rect.bottom) / 2);
  #endif
  
-   if (! MenuBar)
+     if (!menuBar)
 -    {
 +  {
-      INT y = Rect.top + Rect.bottom;
-      RECT Rc = Rect;
-      UINT CheckBitmapWidth = GetSystemMetrics(SM_CXMENUCHECK);
-      UINT CheckBitmapHeight = GetSystemMetrics(SM_CYMENUCHECK);
+         HBITMAP bm;
+         INT y = rect.top + rect.bottom;
+         RECT rc = rect;
 -        int checked = FALSE;
 +     int checked = FALSE;
+         UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
+         UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK );
 -        /* Draw the check mark
 -         *
 -         * FIXME:
 -         * Custom checkmark bitmaps are monochrome but not always 1bpp.
 -         */
 +     /* Draw the check mark
 +      *
 +      * FIXME:
 +      * Custom checkmark bitmaps are monochrome but not always 1bpp.
 +      */
-      if( !(MenuInfo->dwStyle & MNS_NOCHECK))
+         if( !(MenuInfo->dwStyle & MNS_NOCHECK)) {
+             bm = (lpitem->fState & MF_CHECKED) ? lpitem->hbmpChecked : 
+                 lpitem->hbmpUnchecked;
+             if (bm)  /* we have a custom bitmap */
 -            {
 +     {
-         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);
+                 HDC hdcMem = CreateCompatibleDC( hdc );
+                 SelectObject( hdcMem, bm );
+                 BitBlt( hdc, rc.left, (y - check_bitmap_height) / 2,
+                         check_bitmap_width, check_bitmap_height,
+                         hdcMem, 0, 0, SRCCOPY );
+                 DeleteDC( hdcMem );
 -                checked = TRUE;
 -            }
 +           checked = TRUE;
 +        }
-         else if (0 != (Item->fState & MF_CHECKED))  /* standard bitmaps */
+             else if (lpitem->fState & MF_CHECKED) /* standard bitmaps */
 -            {
 +        {
-            RECT rectTemp;
-            CopyRect(&rectTemp, &Rect);
-            rectTemp.right = rectTemp.left + GetSystemMetrics(SM_CXMENUCHECK);
-            DrawFrameControl(Dc, &rectTemp, DFC_MENU,
-                             0 != (Item->fType & MFT_RADIOCHECK) ?
+                 RECT r;
+                 CopyRect(&r, &rect);
+                 r.right = r.left + GetSystemMetrics(SM_CXMENUCHECK);
+                 DrawFrameControl( hdc, &r, DFC_MENU,
+                                  (lpitem->fType & MFT_RADIOCHECK) ?
                                   DFCS_MENUBULLET : DFCS_MENUCHECK);
 -                checked = TRUE;
 -            }
 +           checked = TRUE;
          }
-      if (Item->hbmpItem)
 +     }
 -        {
 -            RECT bmpRect;
+         if ( lpitem->hbmpItem )
-        CopyRect(&bmpRect, &Rect);
 +     {
 +       RECT bmpRect;
 -            if (!(MenuInfo->dwStyle & MNS_CHECKORBMP) && !(MenuInfo->dwStyle & MNS_NOCHECK))
+             CopyRect(&bmpRect, &rect);
-          bmpRect.left += CheckBitmapWidth + 2;
 +       if (!(MenuInfo->dwStyle & MNS_CHECKORBMP) && !(MenuInfo->dwStyle & MNS_NOCHECK))
 -            if (!(checked && (MenuInfo->dwStyle & MNS_CHECKORBMP)))
 -            {
 -                bmpRect.right = bmpRect.left + MenuInfo->maxBmpSize.cx;
+                 bmpRect.left += check_bitmap_width + 2;
-          MenuDrawBitmapItem(Dc, Item, &bmpRect, MenuInfo->Self, WndOwner, Action, MenuBar);
 +       if (!(checked && (MenuInfo->dwStyle & MNS_CHECKORBMP)))
 +       {
 +         bmpRect.right = bmpRect.left + MenuInfo->maxBmpSize.cx;
 -            }
 -        }
 -        /* Draw the popup-menu arrow */
+                 MenuDrawBitmapItem(hdc, lpitem, &bmpRect, MenuInfo->Self, WndOwner, odaction, menuBar);
-      if (0 != (Item->fType & MF_POPUP))
 +       }
 +     }
 +     /* Draw the popup-menu arrow */
 -        {
 -            RECT rectTemp;
+         if (lpitem->fType & MF_POPUP)
-            CopyRect(&rectTemp, &Rect);
 +     {
 +           RECT rectTemp;
 -            rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
+             CopyRect(&rectTemp, &rect);
-            DrawFrameControl(Dc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
 +           rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
 -        }
+             DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
-      Rect.left += 4;
 +     }
 -        if( !(MenuInfo->dwStyle & MNS_NOCHECK))
+         rect.left += 4;
-         Rect.left += CheckBitmapWidth;
-      Rect.right -= CheckBitmapWidth;
 +     if( !(MenuInfo->dwStyle & MNS_NOCHECK))
 -    }
+             rect.left += check_bitmap_width;
+         rect.right -= check_bitmap_width;
-   else if (Item->hbmpItem) /* Draw the bitmap */
-   {
-      MenuDrawBitmapItem(Dc, Item, &Rect, MenuInfo->Self, WndOwner, Action, MenuBar);
 +  }
 -    }
+     else if( lpitem->hbmpItem)
+     { /* Draw the bitmap */
+         MenuDrawBitmapItem(hdc, lpitem, &rect, MenuInfo->Self, WndOwner, odaction, menuBar);
 +  }
  
-   /* No bitmap - process text if present */
-   if (Item->Text)
+     /* process text if present */
+     if (lpitem->lpstr)
 -    {
 -        register int i = 0;
 +  {
 +      register int i = 0;
-       HFONT FontOld = NULL;
+         HFONT hfontOld = 0;
  
-       UINT uFormat = MenuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE
+         UINT uFormat = menuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE
 -                       : DT_LEFT | DT_VCENTER | DT_SINGLELINE;
 +                     : DT_LEFT | DT_VCENTER | DT_SINGLELINE;
  
 -        if(MenuInfo->dwStyle & MNS_CHECKORBMP)
 +      if(MenuInfo->dwStyle & MNS_CHECKORBMP)
-              Rect.left += max(0, MenuInfo->maxBmpSize.cx - GetSystemMetrics(SM_CXMENUCHECK));
+              rect.left += max(0, MenuInfo->maxBmpSize.cx - GetSystemMetrics(SM_CXMENUCHECK));
 -        else
 +      else
-              Rect.left += MenuInfo->maxBmpSize.cx;
+              rect.left += MenuInfo->maxBmpSize.cx;
  
-       if (0 != (Item->fState & MFS_DEFAULT))
+         if ( lpitem->fState & MFS_DEFAULT )
          {
-           FontOld = SelectObject(Dc, hMenuFontBold);
+             hfontOld = SelectObject(hdc, hMenuFontBold);
          }
  
-       if (MenuBar)
-         {
-           Rect.left += MENU_BAR_ITEMS_SPACE / 2;
-           Rect.right -= MENU_BAR_ITEMS_SPACE / 2;
+         if (menuBar) {
+             rect.left += MENU_BAR_ITEMS_SPACE / 2;
+             rect.right -= MENU_BAR_ITEMS_SPACE / 2;
          }
  
-       Text = (PWCHAR) Item->dwTypeData;
+         Text = (PWCHAR) lpitem->dwTypeData;
 -        if(Text)
 -        {
 -            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])
-             {
+                 if (Text[i] == L'\t' || Text[i] == L'\b')
 -                    break;
 -        }
 +              break;
 +            }
-         }
-       }
  
-       if (0 != (Item->fState & MF_GRAYED))
+         if(lpitem->fState & MF_GRAYED)
 -        {
 +      {
-           if (0 == (Item->fState & MF_HILITE))
+             if (!(lpitem->fState & MF_HILITE) )
 -            {
 +          {
-               ++Rect.left; ++Rect.top; ++Rect.right; ++Rect.bottom;
-               SetTextColor(Dc, RGB(0xff, 0xff, 0xff));
-               DrawTextW(Dc, Text, i, &Rect, uFormat);
-               --Rect.left; --Rect.top; --Rect.right; --Rect.bottom;
+                 ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
+                 SetTextColor(hdc, RGB(0xff, 0xff, 0xff));
+                 DrawTextW( hdc, Text, i, &rect, uFormat );
+                 --rect.left; --rect.top; --rect.right; --rect.bottom;
 -              }
 +          }
-           SetTextColor(Dc, RGB(0x80, 0x80, 0x80));
+             SetTextColor(hdc, RGB(0x80, 0x80, 0x80));
          }
  
-       DrawTextW(Dc, Text, i, &Rect, uFormat);
+         DrawTextW( hdc, Text, i, &rect, uFormat);
  
 -        /* paint the shortcut text */
 +      /* paint the shortcut text */
-       if (! MenuBar && L'\0' != Text[i])  /* There's a tab or flush-right char */
+         if (!menuBar && L'\0' != Text[i])  /* There's a tab or flush-right char */
          {
 -            if (L'\t' == Text[i])
 +          if (L'\t' == Text[i])
              {
-               Rect.left = Item->XTab;
+                 rect.left = lpitem->dxTab;
 -                uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
 +              uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
              }
 -            else
 +          else
              {
-               Rect.right = Item->XTab;
+                 rect.right = lpitem->dxTab;
 -                uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE;
 +              uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE;
              }
  
-           if (0 != (Item->fState & MF_GRAYED))
+             if (lpitem->fState & MF_GRAYED)
              {
-               if (0 == (Item->fState & MF_HILITE))
+                 if (!(lpitem->fState & MF_HILITE) )
                  {
-                   ++Rect.left; ++Rect.top; ++Rect.right; ++Rect.bottom;
-                   SetTextColor(Dc, RGB(0xff, 0xff, 0xff));
-                   DrawTextW(Dc, Text + i + 1, -1, &Rect, uFormat);
-                   --Rect.left; --Rect.top; --Rect.right; --Rect.bottom;
+                     ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
+                     SetTextColor(hdc, RGB(0xff, 0xff, 0xff));
+                     DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat);
+                     --rect.left; --rect.top; --rect.right; --rect.bottom;
                  }
-               SetTextColor(Dc, RGB(0x80, 0x80, 0x80));
+                 SetTextColor(hdc, RGB(0x80, 0x80, 0x80));
 -              }
 +          }
-           DrawTextW(Dc, Text + i + 1, -1, &Rect, uFormat);
+           DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat );
          }
  
-       if (NULL != FontOld)
-         {
-           SelectObject(Dc, FontOld);
+         if (hfontOld)
+           SelectObject (hdc, hfontOld);
 -    }
 -}
 +        }
 +  }
- }
  
  /***********************************************************************
   *           MenuDrawPopupMenu
   *
   * Paint a popup menu.
   */
- static void FASTCALL
- MenuDrawPopupMenu(HWND Wnd, HDC Dc, HMENU Menu)
+ static void FASTCALL MenuDrawPopupMenu(HWND hwnd, HDC hdc, HMENU hmenu )
  {
-   HBRUSH PrevBrush = NULL;
-   HPEN PrevPen;
-   RECT Rect;
-   ROSMENUINFO MenuInfo;
-   ROSMENUITEMINFO ItemInfo;
-   UINT u;
+     HBRUSH hPrevBrush = 0;
+     RECT rect;
  
-   TRACE("wnd=%x dc=%x menu=%x\n", Wnd, Dc, Menu);
+     TRACE("wnd=%p dc=%p menu=%p\n", hwnd, hdc, hmenu);
  
-   GetClientRect(Wnd, &Rect);
+     GetClientRect( hwnd, &rect );
  
-   if (NULL != (PrevBrush = SelectObject(Dc, GetSysColorBrush(COLOR_MENU)))
-       && NULL != SelectObject(Dc, hMenuFont))
+     if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) ))
+         && (SelectObject( hdc, hMenuFont)))
      {
-       Rectangle(Dc, Rect.left, Rect.top, Rect.right, Rect.bottom);
+         HPEN hPrevPen;
+         Rectangle( hdc, rect.left, rect.top, rect.right, rect.bottom );
  
-       PrevPen = SelectObject(Dc, GetStockObject(NULL_PEN));
-       if (NULL != PrevPen)
+         hPrevPen = SelectObject( hdc, GetStockObject( NULL_PEN ) );
+         if ( hPrevPen )
          {
 -            BOOL flat_menu = FALSE;
 +          BOOL flat_menu = FALSE;
+             ROSMENUINFO MenuInfo;
+             ROSMENUITEMINFO ItemInfo;
  
 -            SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
 -            if (flat_menu)
 +          SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
 +          if (flat_menu)
-              FrameRect(Dc, &Rect, GetSysColorBrush(COLOR_BTNSHADOW));
+                FrameRect(hdc, &rect, GetSysColorBrush(COLOR_BTNSHADOW));
 -            else
 +          else
-              DrawEdge(Dc, &Rect, EDGE_RAISED, BF_RECT);
+                DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT);
  
 -            /* draw menu items */
 +          /* draw menu items */
-           if (MenuGetRosMenuInfo(&MenuInfo, Menu) && 0 != MenuInfo.MenuItemCount)
+             if (MenuGetRosMenuInfo(&MenuInfo, hmenu) && MenuInfo.MenuItemCount)
              {
 -                              MenuInitRosMenuItemInfo(&ItemInfo);
+                 UINT u;
+                 
 +              MenuInitRosMenuItemInfo(&ItemInfo);
  
 -                for (u = 0; u < MenuInfo.MenuItemCount; u++)
 +              for (u = 0; u < MenuInfo.MenuItemCount; u++)
                  {
 -                    if (MenuGetRosMenuItemInfo(MenuInfo.Self, u, &ItemInfo))
 +                  if (MenuGetRosMenuItemInfo(MenuInfo.Self, u, &ItemInfo))
                      {
-                       MenuDrawMenuItem(Wnd, &MenuInfo, MenuInfo.WndOwner, Dc, &ItemInfo,
+                         MenuDrawMenuItem(hwnd, &MenuInfo, MenuInfo.WndOwner, hdc, &ItemInfo,
 -                        MenuInfo.Height, FALSE, ODA_DRAWENTIRE);
 +                                     MenuInfo.Height, FALSE, ODA_DRAWENTIRE);
                      }
                  }
  
 -                MenuCleanupRosMenuItemInfo(&ItemInfo);
 -            }
 +            MenuCleanupRosMenuItemInfo(&ItemInfo);
 +          }
-       }
-       else
-         {
-           SelectObject(Dc, PrevBrush);
+          } else
+          {
+              SelectObject( hdc, hPrevBrush );
 -         }
 +      }
      }
  }
  
- LRESULT WINAPI
- PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
+ /***********************************************************************
+  *           MenuDrawMenuBar
+  *
+  * Paint a menu bar. Returns the height of the menu bar.
+  * called from [windows/nonclient.c]
+  */
+ UINT MenuDrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd,
+                          BOOL suppress_draw)
  {
-   TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam);
+     ROSMENUINFO lppop;
+     HFONT hfontOld = 0;
+     HMENU hMenu = GetMenu(hwnd);
  
-   switch(Message)
+     if (! MenuGetRosMenuInfo(&lppop, hMenu) || lprect == NULL)
      {
-     case WM_CREATE:
-       {
-         CREATESTRUCTA *cs = (CREATESTRUCTA *) lParam;
-         SetWindowLongPtrA(Wnd, 0, (LONG_PTR)cs->lpCreateParams);
-         return 0;
-       }
+         return GetSystemMetrics(SM_CYMENU);
+     }
  
-     case WM_MOUSEACTIVATE:  /* We don't want to be activated */
-       return MA_NOACTIVATE;
+     if (suppress_draw)
+     {
+         hfontOld = SelectObject(hDC, hMenuFont);
  
-     case WM_PAINT:
-       {
-         PAINTSTRUCT ps;
-         BeginPaint(Wnd, &ps);
-         MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrA(Wnd, 0));
-         EndPaint(Wnd, &ps);
-         return 0;
-       }
+         MenuMenuBarCalcSize(hDC, lprect, &lppop, hwnd);
  
-     case WM_PRINTCLIENT:
-       {
-         MenuDrawPopupMenu( Wnd, (HDC)wParam,
-                                 (HMENU)GetWindowLongPtrW( Wnd, 0 ) );
-         return 0;
-       }
+         lprect->bottom = lprect->top + lppop.Height;
  
-     case WM_ERASEBKGND:
-       return 1;
+         if (hfontOld) SelectObject( hDC, hfontOld);
+         return lppop.Height;
+     }
 -      else
++      else
+         return DrawMenuBarTemp(hwnd, hDC, lprect, hMenu, NULL);
+ }
  
-     case WM_DESTROY:
-       /* zero out global pointer in case resident popup window was destroyed. */
-       if (Wnd == TopPopup)
+ /***********************************************************************
+  *           MenuShowPopup
+  *
+  * Display a popup menu.
+  */
+ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
+                               INT x, INT y, INT xanchor, INT yanchor )
 -{
 +        {
-           TopPopup = NULL;
-         }
-       break;
+     ROSMENUINFO MenuInfo;
+     ROSMENUITEMINFO ItemInfo;
+     UINT width, height;
+     POINT pt;
+     HMONITOR monitor;
+     MONITORINFO info;
  
-     case WM_SHOWWINDOW:
-       if (0 != wParam)
-         {
-           if (0 == GetWindowLongPtrA(Wnd, 0))
-             {
-               OutputDebugStringA("no menu to display\n");
-             }
-         }
-       else
-         {
-           SetWindowLongPtrA(Wnd, 0, 0);
-         }
-       break;
+     TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
+           hwndOwner, hmenu, id, x, y, xanchor, yanchor);
+     if (! MenuGetRosMenuInfo(&MenuInfo, hmenu)) return FALSE;
+     if (MenuInfo.FocusedItem != NO_SELECTED_ITEM)
+     {
+         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);
 -        }
++      }
+         MenuCleanupRosMenuItemInfo(&ItemInfo);
+         MenuInfo.FocusedItem = NO_SELECTED_ITEM;
+     }
+     /* store the owner for DrawItem */
+     MenuInfo.WndOwner = hwndOwner;
+     MenuSetRosMenuInfo(&MenuInfo);
+     MenuPopupMenuCalcSize(&MenuInfo, hwndOwner);
+     /* adjust popup menu pos so that it fits within the desktop */
+     width = MenuInfo.Width + GetSystemMetrics(SM_CXBORDER);
+     height = MenuInfo.Height + GetSystemMetrics(SM_CYBORDER);
+     /* FIXME: should use item rect */
+     pt.x = x;
+     pt.y = y;
+     monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST );
+     info.cbSize = sizeof(info);
+     GetMonitorInfoW( monitor, &info );
+     if( flags & TPM_RIGHTALIGN ) x -= width;
+     if( flags & TPM_CENTERALIGN ) x -= width / 2;
+     if( flags & TPM_BOTTOMALIGN ) y -= height;
+     if( flags & TPM_VCENTERALIGN ) y -= height / 2;
+     if( x + width > info.rcWork.right)
+     {
+         if( xanchor && x >= width - xanchor )
+             x -= width - xanchor;
+         if( x + width > info.rcWork.right)
+             x = info.rcWork.right - width;
 -    }
++}
+     if( x < info.rcWork.left ) x = info.rcWork.left;
+     if( y + height > info.rcWork.bottom)
 -    {
++{
+         if( yanchor && y >= height + yanchor )
+             y -= height + yanchor;
+         if( y + height > info.rcWork.bottom)
+             y = info.rcWork.bottom - height;
+     }
+     if( y < info.rcWork.top ) y = info.rcWork.top;
+     /* NOTE: In Windows, top menu popup is not owned. */
+     MenuInfo.Wnd = CreateWindowExW( 0, POPUPMENU_CLASS_ATOMW, NULL,
+                                   WS_POPUP, x, y, width, height,
+                                   hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
+                                  (LPVOID) MenuInfo.Self);
+     if ( !MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo)) return FALSE;
+     if (!top_popup) {
+         top_popup = MenuInfo.Wnd;
+         top_popup_hmenu = hmenu;
+     }
+     /* Display the window */
+     SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0,
+                   SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+     UpdateWindow( MenuInfo.Wnd );
+     return TRUE;
+ }
+ /***********************************************************************
+  *           MenuSelectItem
+  */
+ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIndex,
+                                     BOOL sendMenuSelect, HMENU topmenu)
+ {
+     ROSMENUITEMINFO ItemInfo;
+     ROSMENUINFO TopMenuInfo;
+     HDC hdc;
+     TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, hmenu, wIndex, sendMenuSelect);
+      if (!hmenu || !hmenu->MenuItemCount || !hmenu->Wnd) return;
+     if (hmenu->FocusedItem == wIndex) return;
+     if (hmenu->Flags & MF_POPUP) hdc = GetDC(hmenu->Wnd);
+     else hdc = GetDCEx(hmenu->Wnd, 0, DCX_CACHE | DCX_WINDOW);
+     if (!top_popup) {
+         top_popup = hmenu->Wnd;
+         top_popup_hmenu = hmenu->Self;
+     }
+     SelectObject( hdc, hMenuFont );
+     MenuInitRosMenuItemInfo(&ItemInfo);
+      /* Clear previous highlighted item */
+     if (hmenu->FocusedItem != NO_SELECTED_ITEM)
+     {
+         if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo))
+         {
+             ItemInfo.fMask |= MIIM_STATE;
+             ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
+             MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
+         }
+         MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, &ItemInfo,
+                        hmenu->Height, ! (hmenu->Flags & MF_POPUP),
+                        ODA_SELECT);
+     }
+     /* Highlight new item (if any) */
+     hmenu->FocusedItem = wIndex;
+     MenuSetRosMenuInfo(hmenu);
+     if (hmenu->FocusedItem != NO_SELECTED_ITEM)
+     {
+         if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo))
+         {
+             if (!(ItemInfo.fType & MF_SEPARATOR))
+             {
+                 ItemInfo.fMask |= MIIM_STATE;
+                 ItemInfo.fState |= MF_HILITE;
+                 MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
+                 MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc,
+                                &ItemInfo, hmenu->Height, ! (hmenu->Flags & MF_POPUP),
+                                ODA_SELECT);
+             }
+             if (sendMenuSelect)
+             {
+                 SendMessageW(hwndOwner, WM_MENUSELECT,
+                            MAKELONG(ItemInfo.fType & MF_POPUP ? wIndex : ItemInfo.wID,
+                                     ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT |
+                                     (hmenu->Flags & MF_SYSMENU)), (LPARAM) hmenu->Self);
+             }
+         }
+     }
+     else if (sendMenuSelect) {
+         if(topmenu) {
+             int pos;
+             pos = MenuFindSubMenu(&topmenu, hmenu->Self);
+             if (pos != NO_SELECTED_ITEM)
+             {
+                 if (MenuGetRosMenuInfo(&TopMenuInfo, topmenu)
+                     && MenuGetRosMenuItemInfo(topmenu, pos, &ItemInfo))
+                 {
+                     SendMessageW(hwndOwner, WM_MENUSELECT,
+                                MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState
+                                              | MF_MOUSESELECT
+                                              | (TopMenuInfo.Flags & MF_SYSMENU)),
+                                (LPARAM) topmenu);
+                 }
+             }
+         }
+     }
+     MenuCleanupRosMenuItemInfo(&ItemInfo);
+     ReleaseDC(hmenu->Wnd, hdc);
+ }
+ /***********************************************************************
+  *           MenuMoveSelection
+  *
+  * Moves currently selected item according to the Offset parameter.
+  * If there is no selection then it should select the last item if
+  * Offset is ITEM_PREV or the first item if Offset is ITEM_NEXT.
+  */
+ static void FASTCALL
+ MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset)
+ {
+   INT i;
+   ROSMENUITEMINFO ItemInfo;
+   INT OrigPos;
+   TRACE("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);
+   OrigPos = MenuInfo->FocusedItem;
+   if (OrigPos == NO_SELECTED_ITEM) /* NO_SELECTED_ITEM is not -1 ! */
+     {
+        OrigPos = 0;
+        i = -1;
+     }
+   else
+     {
+       i = MenuInfo->FocusedItem;
+     }
+   do
+     {
+       /* Step */
+       i += Offset;
+       /* Clip and wrap around */
+       if (i < 0)
+         {
+           i = MenuInfo->MenuItemCount - 1;
+         }
+       else if (i >= MenuInfo->MenuItemCount)
+         {
+           i = 0;
+         }
+       /* If this is a good candidate; */
+       if (MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo) &&
+           0 == (ItemInfo.fType & MF_SEPARATOR))
+         {
+           MenuSelectItem(WndOwner, MenuInfo, i, TRUE, NULL);
+           MenuCleanupRosMenuItemInfo(&ItemInfo);
+           return;
+         }
+     } while (i != OrigPos);
+   /* Not found */
+   MenuCleanupRosMenuItemInfo(&ItemInfo);
+ }
+ LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
+ {
+   TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam);
+   switch(Message)
+     {
+     case WM_CREATE:
+       {
+         CREATESTRUCTA *cs = (CREATESTRUCTA *) lParam;
 -        SetWindowLongPtrA(Wnd, 0, (LONG) cs->lpCreateParams);
++        SetWindowLongPtrA(Wnd, 0, (LONG_PTR)cs->lpCreateParams);
+         return 0;
+       }
+     case WM_MOUSEACTIVATE:  /* We don't want to be activated */
+       return MA_NOACTIVATE;
+     case WM_PAINT:
+       {
+         PAINTSTRUCT ps;
+         BeginPaint(Wnd, &ps);
+         MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrA(Wnd, 0));
+         EndPaint(Wnd, &ps);
+         return 0;
+       }
+     case WM_PRINTCLIENT:
+       {
+         MenuDrawPopupMenu( Wnd, (HDC)wParam,
+                                 (HMENU)GetWindowLongPtrW( Wnd, 0 ) );
+         return 0;
+       }
+     case WM_ERASEBKGND:
+       return 1;
+     case WM_DESTROY:
+       /* zero out global pointer in case resident popup window was destroyed. */
+       if (Wnd == top_popup)
+         {
+           top_popup = NULL;
+           top_popup_hmenu = NULL;
+         }
+       break;
+     case WM_SHOWWINDOW:
+       if (0 != wParam)
+         {
+           if (0 == GetWindowLongPtrA(Wnd, 0))
+             {
+               OutputDebugStringA("no menu to display\n");
+             }
+         }
+       else
+         {
+           SetWindowLongPtrA(Wnd, 0, 0);
+         }
+       break;
  
      case MM_SETMENUHANDLE:
        SetWindowLongPtrA(Wnd, 0, wParam);
@@@ -1187,69 -1951,68 +1951,68 @@@ PopupMenuWndProcW(HWND Wnd, UINT Messag
   */
  static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
  {
 -    WORD flags, id = 0;
 -    HMENU hSubMenu;
 -    LPCSTR str;
 -    BOOL end = FALSE;
 +  WORD flags, id = 0;
 +  HMENU hSubMenu;
 +  LPCSTR str;
 +  BOOL end = FALSE;
  
 -    do
 -    {
 -        flags = GET_WORD(res);
 +  do
 +  {
 +    flags = GET_WORD(res);
  
 -        /* remove MF_END flag before passing it to AppendMenu()! */
 -        end = (flags & MF_END);
 -        if(end) flags ^= MF_END;
 +    /* remove MF_END flag before passing it to AppendMenu()! */
 +    end = (flags & MF_END);
 +    if(end) flags ^= MF_END;
  
 -        res += sizeof(WORD);
 -        if(!(flags & MF_POPUP))
 -        {
 -            id = GET_WORD(res);
 -            res += sizeof(WORD);
 -        }
 -        str = res;
 -        if(!unicode)
 -            res += strlen(str) + 1;
 -        else
 -            res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
 -        if (flags & MF_POPUP)
 -        {
 -            hSubMenu = CreatePopupMenu();
 -            if(!hSubMenu) return NULL;
 -            if(!(res = MENU_ParseResource(res, hSubMenu, unicode)))
 -                return NULL;
 -            if(!unicode)
 -                AppendMenuA(hMenu, flags, (UINT)hSubMenu, str);
 -            else
 -                AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str);
 -        }
 -        else  /* Not a popup */
 -        {
 -            if(!unicode)
 -            {
 +    res += sizeof(WORD);
 +    if(!(flags & MF_POPUP))
 +    {
 +      id = GET_WORD(res);
 +      res += sizeof(WORD);
 +    }
 +    str = res;
 +    if(!unicode)
 +      res += strlen(str) + 1;
 +    else
 +      res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
 +    if (flags & MF_POPUP)
 +    {
 +      hSubMenu = CreatePopupMenu();
 +      if(!hSubMenu) return NULL;
 +      if(!(res = MENU_ParseResource(res, hSubMenu, unicode)))
 +        return NULL;
 +      if(!unicode)
 +        AppendMenuA(hMenu, flags, (UINT_PTR)hSubMenu, str);
 +      else
 +        AppendMenuW(hMenu, flags, (UINT_PTR)hSubMenu, (LPCWSTR)str);
 +    }
 +    else  /* Not a popup */
 +    {
 +      if(!unicode)
 +      {
-       if (*str == 0)
-         flags = MF_SEPARATOR;
+                 if (*str == 0)
+                     flags = MF_SEPARATOR;
 -            }
 -            else
 -            {
 -                if (*(LPCWSTR)str == 0)
 -                    flags = MF_SEPARATOR;
 -            }
 +      }
 +      else
 +      {
 +        if (*(LPCWSTR)str == 0)
 +          flags = MF_SEPARATOR;
 +      }
  
 -            if (flags & MF_SEPARATOR)
 -            {
 -                if (!(flags & (MF_GRAYED | MF_DISABLED)))
 -                    flags |= MF_GRAYED | MF_DISABLED;
 -            }
 +      if (flags & MF_SEPARATOR)
 +      {
 +        if (!(flags & (MF_GRAYED | MF_DISABLED)))
 +          flags |= MF_GRAYED | MF_DISABLED;
 +      }
  
 -            if(!unicode)
 -                AppendMenuA(hMenu, flags, id, *str ? str : NULL);
 -            else
 -                AppendMenuW(hMenu, flags, id,
 +      if(!unicode)
 +        AppendMenuA(hMenu, flags, id, *str ? str : NULL);
 +      else
 +        AppendMenuW(hMenu, flags, id,
                      *(LPCWSTR)str ? (LPCWSTR)str : NULL);
 -        }
 -    } while(!end);
 -    return res;
 +    }
 +  } while(!end);
 +  return res;
  }
  
  
@@@ -2452,8 -2387,8 +2387,8 @@@ MenuHideSubPopups(HWND WndOwner, PROSME
  
    TRACE("owner=%x menu=%x 0x%04x\n", WndOwner, MenuInfo, SendMenuSelect);
  
-   if (NULL != MenuInfo && NULL != TopPopup && NO_SELECTED_ITEM != MenuInfo->FocusedItem)
+   if (NULL != MenuInfo && NULL != top_popup && NO_SELECTED_ITEM != MenuInfo->FocusedItem)
 -  {
 +    {
        MenuInitRosMenuItemInfo(&ItemInfo);
        ItemInfo.fMask |= MIIM_FTYPE | MIIM_STATE;
        if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)
        ItemInfo.fMask |= MIIM_STATE;
        MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
        if (MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu))
 -      {
 +        {
-           MenuHideSubPopups(WndOwner, &SubMenuInfo, FALSE);
+           MenuHideSubPopups(WndOwner, &SubMenuInfo, FALSE, wFlags);
            MenuSelectItem(WndOwner, &SubMenuInfo, NO_SELECTED_ITEM, SendMenuSelect, NULL);
            DestroyWindow(SubMenuInfo.Wnd);
            SubMenuInfo.Wnd = NULL;
            MenuSetRosMenuInfo(&SubMenuInfo);
 -      }
 -  }
+           if (!(wFlags & TPM_NONOTIFY))
+              SendMessageW( WndOwner, WM_UNINITMENUPOPUP, (WPARAM)ItemInfo.hSubMenu,
+                                  MAKELPARAM(0, IS_SYSTEM_MENU(&SubMenuInfo)) );
 +        }
 +    }
  }
  
  /***********************************************************************
@@@ -3202,22 -3061,18 +3061,18 @@@ MenuKeyLeft(MTRACKER* Mt, UINT Flags
   *
   * Handle a VK_RIGHT key event in a menu.
   */
- static void FASTCALL
- MenuKeyRight(MTRACKER *Mt, UINT Flags)
+ static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags)
  {
-   HMENU MenuTmp;
+     HMENU hmenutmp;
 -    ROSMENUINFO MenuInfo;
 -    ROSMENUINFO CurrentMenuInfo;
 -    UINT NextCol;
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUINFO CurrentMenuInfo;
 +  UINT NextCol;
  
 -    TRACE("MenuKeyRight called, cur %p, top %p.\n",
 +  TRACE("MenuKeyRight called, cur %p, top %p.\n",
           Mt->CurrentMenu, Mt->TopMenu);
  
-   if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu))
-     {
-       return;
-     }
-   if (0 != (MenuInfo.Flags & MF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
+     if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu)) return;
+     if ((MenuInfo.Flags & MF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
      {
        /* If already displaying a popup, try to display sub-popup */
  
          }
  
        /* if subpopup was displayed then we are done */
-       if (MenuTmp != Mt->CurrentMenu)
-         {
-           return;
+       if (hmenutmp != Mt->CurrentMenu) return;
 -    }
 +        }
-     }
  
    if (! MenuGetRosMenuInfo(&CurrentMenuInfo, Mt->CurrentMenu))
      {
   *
   * Menu tracking code.
   */
- static INT FASTCALL
- MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y,
-               HWND Wnd, const RECT *Rect )
+ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
+                             HWND hwnd, const RECT *lprect )
  {
-   MSG Msg;
+     MSG msg;
 -    ROSMENUINFO MenuInfo;
 -    ROSMENUITEMINFO ItemInfo;
 -    BOOL fRemove;
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +  BOOL fRemove;
-   INT ExecutedMenuId = -1;
-   MTRACKER Mt;
-   BOOL EnterIdleSent = FALSE;
-   Mt.TrackFlags = 0;
-   Mt.CurrentMenu = Menu;
-   Mt.TopMenu = Menu;
-   Mt.OwnerWnd = Wnd;
-   Mt.Pt.x = x;
-   Mt.Pt.y = y;
-   TRACE("Menu=%x Flags=0x%08x (%d,%d) Wnd=%x (%ld,%ld)-(%ld,%ld)\n",
-          Menu, Flags, x, y, Wnd, Rect ? Rect->left : 0, Rect ? Rect->top : 0,
-          Rect ? Rect->right : 0, Rect ? Rect->bottom : 0);
-   if (!IsMenu(Menu))
+     INT executedMenuId = -1;
+     MTRACKER mt;
+     BOOL enterIdleSent = FALSE;
+     mt.TrackFlags = 0;
+     mt.CurrentMenu = hmenu;
+     mt.TopMenu = hmenu;
+     mt.OwnerWnd = hwnd;
+     mt.Pt.x = x;
+     mt.Pt.y = y;
+     TRACE("hmenu=%p flags=0x%08x (%d,%d) hwnd=%x (%ld,%ld)-(%ld,%ld)\n",
+          hmenu, wFlags, x, y, hwnd, lprect ? lprect->left : 0, lprect ? lprect->top : 0,
+          lprect ? lprect->right : 0, lprect ? lprect->bottom : 0);
+     if (!IsMenu(hmenu))
 -    {
 +  {
+         WARN("Invalid menu handle %p\n", hmenu);
 -        SetLastError( ERROR_INVALID_MENU_HANDLE );
 -        return FALSE;
 -    }
 +    SetLastError( ERROR_INVALID_MENU_HANDLE );
 +    return FALSE;
 +  }
  
 -    fEndMenu = FALSE;
 +  fEndMenu = FALSE;
-   if (! MenuGetRosMenuInfo(&MenuInfo, Menu))
+     if (! MenuGetRosMenuInfo(&MenuInfo, hmenu))
      {
 -        return FALSE;
 +      return FALSE;
      }
  
-   if (0 != (Flags & TPM_BUTTONDOWN))
+     if (wFlags & TPM_BUTTONDOWN)
      {
 -        /* Get the result in order to start the tracking or not */
 +      /* Get the result in order to start the tracking or not */
-       fRemove = MenuButtonDown(&Mt, Menu, Flags);
+         fRemove = MenuButtonDown( &mt, hmenu, wFlags );
 -        fEndMenu = !fRemove;
 +      fEndMenu = ! fRemove;
      }
  
-   SetCapture(Mt.OwnerWnd);
-   (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, Mt.OwnerWnd);
+     SetCapture(mt.OwnerWnd);
+     (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, mt.OwnerWnd);
  
 -    ERR("MenuTrackMenu 1\n");
 -    while (! fEndMenu)
 +  ERR("MenuTrackMenu 1\n");
 +  while (! fEndMenu)
      {
-       PVOID menu = ValidateHandle(Mt.CurrentMenu, VALIDATE_TYPE_MENU);
+         PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU);
 -        if (!menu) /* sometimes happens if I do a window manager close */
 -           break;
 +      if (!menu) /* sometimes happens if I do a window manager close */
 +         break;
  
 -        /* we have to keep the message in the queue until it's
 -         * clear that menu loop is not over yet. */
 +      /* we have to keep the message in the queue until it's
 +       * clear that menu loop is not over yet. */
  
 -        for (;;)
 +      for (;;)
          {
-           if (PeekMessageW(&Msg, 0, 0, 0, PM_NOREMOVE))
+             if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ))
              {
-               if (! CallMsgFilterW(&Msg, MSGF_MENU))
-                 {
-                   break;
-                 }
+                 if (!CallMsgFilterW( &msg, MSGF_MENU )) break;
 -                /* remove the message from the queue */
 +              /* remove the message from the queue */
-               PeekMessageW(&Msg, 0, Msg.message, Msg.message, PM_REMOVE );
+                 PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
              }
 -            else
 +          else
              {
-               if (! EnterIdleSent)
+                 if (!enterIdleSent)
                  {
-                   HWND Win = (0 != (Flags & TPM_ENTERIDLEEX)
-                               && 0 != (MenuInfo.Flags & MF_POPUP)) ? MenuInfo.Wnd : NULL;
-                   EnterIdleSent = TRUE;
-                   SendMessageW(Mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) Win);
+                   HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL;
+                   enterIdleSent = TRUE;
+                   SendMessageW( mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) win);
                  }
 -                WaitMessage();
 +              WaitMessage();
              }
          }
  
 -        /* check if EndMenu() tried to cancel us, by posting this message */
 +      /* check if EndMenu() tried to cancel us, by posting this message */
-       if (WM_CANCELMODE == Msg.message)
+         if (msg.message == WM_CANCELMODE)
          {
 -            /* we are now out of the loop */
 -            fEndMenu = TRUE;
 +          /* we are now out of the loop */
 +          fEndMenu = TRUE;
  
 -            /* remove the message from the queue */
 +          /* remove the message from the queue */
-           PeekMessageW(&Msg, 0, Msg.message, Msg.message, PM_REMOVE);
+             PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
  
 -            /* break out of internal loop, ala ESCAPE */
 -            break;
 +          /* break out of internal loop, ala ESCAPE */
 +          break;
          }
  
-       TranslateMessage(&Msg);
-       Mt.Pt = Msg.pt;
+         TranslateMessage( &msg );
+         mt.Pt = msg.pt;
  
-       if (Msg.hwnd == MenuInfo.Wnd || WM_TIMER != Msg.message)
-         {
-           EnterIdleSent = FALSE;
-         }
+         if ( (msg.hwnd == MenuInfo.Wnd) || (msg.message!=WM_TIMER) )
+             enterIdleSent=FALSE;
  
 -        fRemove = FALSE;
 +      fRemove = FALSE;
-       if (WM_MOUSEFIRST <= Msg.message && Msg.message <= WM_MOUSELAST)
+         if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
          {
 -            /*
 -             * Use the mouse coordinates in lParam instead of those in the MSG
 -             * struct to properly handle synthetic messages. They are already
 -             * in screen coordinates.
 -             */
 +          /*
 +           * Use the mouse coordinates in lParam instead of those in the MSG
 +           * struct to properly handle synthetic messages. They are already
 +           * in screen coordinates.
 +           */
-           Mt.Pt.x = (short) LOWORD(Msg.lParam);
-           Mt.Pt.y = (short) HIWORD(Msg.lParam);
+             mt.Pt.x = (short)LOWORD(msg.lParam);
+             mt.Pt.y = (short)HIWORD(msg.lParam);
  
 -            /* Find a menu for this mouse event */
 +          /* Find a menu for this mouse event */
-           Menu = MenuPtMenu(Mt.TopMenu, Mt.Pt);
+             hmenu = MenuPtMenu(mt.TopMenu, mt.Pt);
  
-           switch(Msg.message)
+             switch(msg.message)
              {
 -                /* no WM_NC... messages in captured state */
 +              /* no WM_NC... messages in captured state */
  
 -                case WM_RBUTTONDBLCLK:
 -                case WM_RBUTTONDOWN:
 +              case WM_RBUTTONDBLCLK:
 +              case WM_RBUTTONDOWN:
-                 if (0 == (Flags & TPM_RIGHTBUTTON))
-                   {
-                     break;
-                   }
+                      if (!(wFlags & TPM_RIGHTBUTTON)) break;
 -                    /* fall through */
 -                case WM_LBUTTONDBLCLK:
 -                case WM_LBUTTONDOWN:
 -                    /* If the message belongs to the menu, removes it from the queue */
 -                    /* Else, end menu tracking */
 +                /* fall through */
 +              case WM_LBUTTONDBLCLK:
 +              case WM_LBUTTONDOWN:
 +                /* If the message belongs to the menu, removes it from the queue */
 +                /* Else, end menu tracking */
-                 fRemove = MenuButtonDown(&Mt, Menu, Flags);
+                     fRemove = MenuButtonDown(&mt, hmenu, wFlags);
 -                    fEndMenu = !fRemove;
 -                    break;
 +                fEndMenu = ! fRemove;
 +                break;
  
 -                case WM_RBUTTONUP:
 +              case WM_RBUTTONUP:
-                 if (0 == (Flags & TPM_RIGHTBUTTON))
-                   {
-                     break;
-                   }
+                     if (!(wFlags & TPM_RIGHTBUTTON)) break;
 -                    /* fall through */
 -                case WM_LBUTTONUP:
 -                    /* Check if a menu was selected by the mouse */
 +                /* fall through */
 +              case WM_LBUTTONUP:
 +                /* Check if a menu was selected by the mouse */
-                 if (NULL != Menu)
+                     if (hmenu)
 -                    {
 +                  {
-                     ExecutedMenuId = MenuButtonUp(&Mt, Menu, Flags);
+                         executedMenuId = MenuButtonUp( &mt, hmenu, wFlags);
+                         TRACE("executedMenuId %d\n", executedMenuId);
  
-                     /* End the loop if ExecutedMenuId is an item ID */
-                     /* or if the job was done (ExecutedMenuId = 0). */
-                     fEndMenu = fRemove = (-1 != ExecutedMenuId);
+                     /* End the loop if executedMenuId is an item ID */
+                     /* or if the job was done (executedMenuId = 0). */
+                         fEndMenu = fRemove = (executedMenuId != -1);
 -                    }
 +                  }
-                 else
-                   {
                      /* No menu was selected by the mouse */
                      /* if the function was called by TrackPopupMenu, continue
                         with the menu tracking. If not, stop it */
-                     fEndMenu = (0 != (Flags & TPM_POPUPMENU) ? FALSE : TRUE);
-                   }
+                     else
+                         fEndMenu = ((wFlags & TPM_POPUPMENU) ? FALSE : TRUE);
 -                    break;
 +                break;
  
 -                case WM_MOUSEMOVE:
 +              case WM_MOUSEMOVE:
-                 if (Menu)
-                   {
-                     fEndMenu |= ! MenuMouseMove(&Mt, Menu, Flags);
-                   }
-                 break;
+                     /* the selected menu item must be changed every time */
+                     /* the mouse moves. */
  
-           } /* switch(Msg.message) - mouse */
+                     if (hmenu)
+                         fEndMenu |= !MenuMouseMove( &mt, hmenu, wFlags );
+               } /* switch(msg.message) - mouse */
 -          }
 +      }
-       else if (WM_KEYFIRST <= Msg.message && Msg.message <= WM_KEYLAST)
+         else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST))
 -        {
 -            fRemove = TRUE;  /* Keyboard messages are always removed */
 +      {
 +          fRemove = TRUE;  /* Keyboard messages are always removed */
-           switch(Msg.message)
+             switch(msg.message)
              {
-               case WM_SYSKEYDOWN:
 -                case WM_KEYDOWN:
 +              case WM_KEYDOWN:
-                 switch(Msg.wParam)
+                 case WM_SYSKEYDOWN:
+                 switch(msg.wParam)
 -                {
 +                  {
                      case VK_MENU:
 -                        fEndMenu = TRUE;
 -                         break;
+                     case VK_F10:
 +                      fEndMenu = TRUE;
 +                      break;
                      case VK_HOME:
                      case VK_END:
-                       if (MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu))
+                         if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
                          {
-                           MenuSelectItem(Mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM,
-                                          FALSE, 0 );
-                           MenuMoveSelection(Mt.OwnerWnd, &MenuInfo,
-                                             VK_HOME == Msg.wParam ? ITEM_NEXT : ITEM_PREV);
+                             MenuSelectItem(mt.OwnerWnd, &MenuInfo,
+                                     NO_SELECTED_ITEM, FALSE, 0 );
+                             MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
+                                               VK_HOME == msg.wParam ? ITEM_NEXT : ITEM_PREV);
                          }
 -                        break;
 +                      break;
  
                      case VK_UP:
                      case VK_DOWN: /* If on menu bar, pull-down the menu */
-                       if (MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu))
+                         if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
                          {
-                           if (0 == (MenuInfo.Flags & MF_POPUP))
+                             if (!(MenuInfo.Flags & MF_POPUP))
                              {
-                               if (MenuGetRosMenuInfo(&MenuInfo, Mt.TopMenu))
-                                 {
-                                   Mt.CurrentMenu = MenuShowSubPopup(Mt.OwnerWnd, &MenuInfo,
-                                                                     TRUE, Flags);
+                                 if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
+                                     mt.CurrentMenu = MenuShowSubPopup(mt.OwnerWnd, &MenuInfo, TRUE, wFlags);
 -                            }
 -                            else      /* otherwise try to move selection */
 +                                }
-                             }
 +                          else      /* otherwise try to move selection */
-                             {
-                               MenuMoveSelection(Mt.OwnerWnd, &MenuInfo,
-                                             VK_DOWN == Msg.wParam ? ITEM_NEXT : ITEM_PREV);
+                                 MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
+                                        (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT );
 -                        }
 -                        break;
 +                            }
-                         }
 +                      break;
  
                      case VK_LEFT:
-                       MenuKeyLeft(&Mt, Flags);
+                         MenuKeyLeft( &mt, wFlags );
 -                        break;
 +                      break;
  
                      case VK_RIGHT:
-                       MenuKeyRight(&Mt, Flags);
+                         MenuKeyRight( &mt, wFlags );
 -                        break;
 +                      break;
  
                      case VK_ESCAPE:
-                       fEndMenu = MenuKeyEscape(&Mt, Flags);
+                         fEndMenu = MenuKeyEscape(&mt, wFlags);
 -                        break;
 +                      break;
  
                      case VK_F1:
 -                    {
 +                      {
                          HELPINFO hi;
                          hi.cbSize = sizeof(HELPINFO);
                          hi.iContextType = HELPINFO_MENUITEM;
-                         if (MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu))
+                         if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
 -                        {
 +                          {
-                             if (NO_SELECTED_ITEM == MenuInfo.FocusedItem)
-                               {
+                             if (MenuInfo.FocusedItem == NO_SELECTED_ITEM)
                                  hi.iCtrlId = 0;
-                               }
                              else
 -                            {
 +                              {
                                  MenuInitRosMenuItemInfo(&ItemInfo);
                                  if (MenuGetRosMenuItemInfo(MenuInfo.Self,
                                                             MenuInfo.FocusedItem,
                                                             &ItemInfo))
 -                                {
 +                                  {
                                      hi.iCtrlId = ItemInfo.wID;
 -                                }
 +                                  }
                                  else
 -                                {
 +                                  {
                                      hi.iCtrlId = 0;
 -                                }
 +                                  }
                                  MenuCleanupRosMenuItemInfo(&ItemInfo);
 -                            }
 -                        }
 +                              }
 +                          }
-                         hi.hItemHandle = Menu;
+                         hi.hItemHandle = hmenu;
 -                        hi.dwContextId = MenuInfo.dwContextHelpID;
 +                      hi.dwContextId = MenuInfo.dwContextHelpID;
-                       hi.MousePos = Msg.pt;
-                       SendMessageW(Wnd, WM_HELP, 0, (LPARAM) &hi);
+                         hi.MousePos = msg.pt;
+                         SendMessageW(hwnd, WM_HELP, 0, (LPARAM)&hi);
                          break;
 -                    }
 +                      }
  
                      default:
 -                        break;
 -                }
 +                      break;
 +                  }
                  break;  /* WM_KEYDOWN */
  
 -                case WM_CHAR:
 -                case WM_SYSCHAR:
 +              case WM_CHAR:
 +              case WM_SYSCHAR:
                  {
-                   UINT Pos;
+                     UINT pos;
  
-                   if (! MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu))
-                     {
-                       break;
-                     }
-                   if (L'\r' == Msg.wParam || L' ' == Msg.wParam)
+                     if (! MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu)) break;
+                     if (msg.wParam == L'\r' || msg.wParam == L' ')
                      {
-                       ExecutedMenuId = MenuExecFocusedItem(&Mt, &MenuInfo, Flags);
-                       fEndMenu = (ExecutedMenuId != -2);
+                         executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo, wFlags);
+                         fEndMenu = (executedMenuId != -2);
 -                        break;
 +                      break;
                      }
  
 -                    /* Hack to avoid control chars. */
 -                    /* We will find a better way real soon... */
 +                  /* Hack to avoid control chars. */
 +                  /* We will find a better way real soon... */
-                   if (Msg.wParam < 32)
-                     {
-                       break;
-                     }
+                     if (msg.wParam < 32) break;
  
-                   Pos = MenuFindItemByKey(Mt.OwnerWnd, &MenuInfo,
-                                           LOWORD(Msg.wParam), FALSE);
-                   if ((UINT) -2 == Pos)
-                     {
-                       fEndMenu = TRUE;
-                     }
-                   else if ((UINT) -1 == Pos)
-                     {
-                       MessageBeep(0);
-                     }
+                     pos = MenuFindItemByKey(mt.OwnerWnd, &MenuInfo,
+                                           LOWORD(msg.wParam), FALSE);
+                     if (pos == (UINT)-2) fEndMenu = TRUE;
+                     else if (pos == (UINT)-1) MessageBeep(0);
 -                    else
 +                  else
                      {
-                       MenuSelectItem(Mt.OwnerWnd, &MenuInfo, Pos, TRUE, 0);
-                       ExecutedMenuId = MenuExecFocusedItem(&Mt, &MenuInfo, Flags);
-                       fEndMenu = (-2 != ExecutedMenuId);
+                         MenuSelectItem(mt.OwnerWnd, &MenuInfo, pos,
+                             TRUE, 0);
+                         executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo, wFlags);
+                         fEndMenu = (executedMenuId != -2);
                      }
 -                }
 -                break;
 +              }
 +              break;
              }  /* switch(msg.message) - kbd */
          }
 -        else
 +      else
          {
-           PeekMessageW( &Msg, 0, Msg.message, Msg.message, PM_REMOVE );
-           DispatchMessageW(&Msg);
+             PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
+             DispatchMessageW( &msg );
 -            continue;
 +          continue;
          }
  
-       if (! fEndMenu)
-         {
-           fRemove = TRUE;
-         }
+         if (!fEndMenu) fRemove = TRUE;
  
 -        /* finally remove message from the queue */
 +      /* finally remove message from the queue */
  
-       if (fRemove && 0 == (Mt.TrackFlags & TF_SKIPREMOVE))
-         {
-           PeekMessageW(&Msg, 0, Msg.message, Msg.message, PM_REMOVE);
-         }
-       else
-         {
-           Mt.TrackFlags &= ~TF_SKIPREMOVE;
+         if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
+             PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
+         else mt.TrackFlags &= ~TF_SKIPREMOVE;
 -    }
 -    ERR("MenuTrackMenu 2\n");
 +        }
-     }
 +  ERR("MenuTrackMenu 2\n");
  
 -    (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
 -    SetCapture(NULL);  /* release the capture */
 +  (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
 +  SetCapture(NULL);  /* release the capture */
  
 -    /* If dropdown is still painted and the close box is clicked on
 -       then the menu will be destroyed as part of the DispatchMessage above.
 +  /* If dropdown is still painted and the close box is clicked on
 +     then the menu will be destroyed as part of the DispatchMessage above.
-      This will then invalidate the menu handle in Mt.hTopMenu. We should
+        This will then invalidate the menu handle in mt.hTopMenu. We should
 -       check for this first.  */
 +     check for this first.  */
-   if (IsMenu(Mt.TopMenu))
+     if( IsMenu( mt.TopMenu ) )
      {
-       if (IsWindow(Mt.OwnerWnd))
+         if (IsWindow(mt.OwnerWnd))
          {
-           if (MenuGetRosMenuInfo(&MenuInfo, Mt.TopMenu))
+             if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
              {
-               MenuHideSubPopups(Mt.OwnerWnd, &MenuInfo, FALSE);
+                 MenuHideSubPopups(mt.OwnerWnd, &MenuInfo, FALSE, wFlags);
  
-               if (0 != (MenuInfo.Flags & MF_POPUP))
+                 if (MenuInfo.Flags & MF_POPUP)
                  {
 -                    DestroyWindow(MenuInfo.Wnd);
 -                    MenuInfo.Wnd = NULL;
 +                  DestroyWindow(MenuInfo.Wnd);
 +                  MenuInfo.Wnd = NULL;
  
 -                    if (!(MenuInfo.Flags & TPM_NONOTIFY))
 +                  if (!(MenuInfo.Flags & TPM_NONOTIFY))
-                     SendMessageW( Mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)Mt.TopMenu,
+                       SendMessageW( mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.TopMenu,
                                   MAKELPARAM(0, IS_SYSTEM_MENU(&MenuInfo)) );
  
                  }
-               MenuSelectItem(Mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, NULL);
+                 MenuSelectItem( mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, 0 );
              }
  
-           SendMessageW(Mt.OwnerWnd, WM_MENUSELECT, MAKELONG(0, 0xffff), 0);
+             SendMessageW( mt.OwnerWnd, WM_MENUSELECT, MAKEWPARAM(0, 0xffff), 0 );
          }
  
-       if (MenuGetRosMenuInfo(&MenuInfo, Mt.TopMenu))
-         {
 -        /* Reset the variable for hiding menu */
 +          /* Reset the variable for hiding menu */
+         if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
+         {
 -            MenuInfo.TimeToHide = FALSE;
 -            MenuSetRosMenuInfo(&MenuInfo);
 +          MenuInfo.TimeToHide = FALSE;
 +          MenuSetRosMenuInfo(&MenuInfo);
          }
      }
  
 -    /* The return value is only used by TrackPopupMenu */
 +  /* The return value is only used by TrackPopupMenu */
-   if (!(Flags & TPM_RETURNCMD)) return TRUE;
-   if (ExecutedMenuId < 0) ExecutedMenuId = 0;
-   return ExecutedMenuId;
+     if (!(wFlags & TPM_RETURNCMD)) return TRUE;
+     if (executedMenuId == -1) executedMenuId = 0;
+     return executedMenuId;
  }
  
+ /***********************************************************************
+  *           MenuInitTracking
+  */
+ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
+ {
+     ROSMENUINFO MenuInfo;
+     
+     TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu);
+     HideCaret(0);
+     /* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not specified */
+     if (!(wFlags & TPM_NONOTIFY))
+        SendMessageW( hWnd, WM_ENTERMENULOOP, bPopup, 0 );
+     SendMessageW( hWnd, WM_SETCURSOR, (WPARAM)hWnd, HTCAPTION );
+     MenuGetRosMenuInfo(&MenuInfo, hMenu);
+     if (!(wFlags & TPM_NONOTIFY))
+     {
+        SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 );
+        /* If an app changed/recreated menu bar entries in WM_INITMENU
+         * menu sizes will be recalculated once the menu created/shown.
+         */
+        if (!MenuInfo.Height)
+        {
+           /* app changed/recreated menu bar entries in WM_INITMENU
+              Recalculate menu sizes else clicks will not work */
+              SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+                        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 == hMenu)
+     {
+         MenuInfo.Wnd = hWnd;
+         MenuSetRosMenuInfo(&MenuInfo);
+     }
+  
+     return TRUE;
+ }
  /***********************************************************************
   *           MenuExitTracking
   */
- static BOOL FASTCALL
- MenuExitTracking(HWND Wnd)
+ static BOOL FASTCALL MenuExitTracking(HWND hWnd)
  {
-   TRACE("hwnd=%p\n", Wnd);
+     TRACE("hwnd=%p\n", hWnd);
  
-   SendMessageW(Wnd, WM_EXITMENULOOP, 0, 0);
+     SendMessageW( hWnd, WM_EXITMENULOOP, 0, 0 );
 -    ShowCaret(0);
 +  ShowCaret(0);
+     top_popup = 0;
+     top_popup_hmenu = NULL;
 -    return TRUE;
 +  return TRUE;
  }
  
- VOID
- MenuTrackMouseMenuBar(HWND Wnd, ULONG Ht, POINT Pt)
+ /***********************************************************************
+  *           MenuTrackMouseMenuBar
+  *
+  * Menu-bar tracking upon a mouse event. Called from NC_HandleSysCommand().
+  */
+ VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
  {
-   HMENU Menu = (HTSYSMENU == Ht) ? NtUserGetSystemMenu(Wnd, FALSE) : GetMenu(Wnd);
-   UINT Flags = TPM_ENTERIDLEEX | TPM_BUTTONDOWN | TPM_LEFTALIGN | TPM_LEFTBUTTON;
+     HMENU hMenu = (ht == HTSYSMENU) ? NtUserGetSystemMenu( hWnd, FALSE) : GetMenu(hWnd);
+     UINT wFlags = TPM_BUTTONDOWN | TPM_LEFTALIGN | TPM_LEFTBUTTON;
  
-   TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", Wnd, Ht, Pt.x, Pt.y);
+     TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y);
  
-   if (IsMenu(Menu))
+     if (IsMenu(hMenu))
      {
 -        /* map point to parent client coordinates */
 +      /* map point to parent client coordinates */
-       HWND Parent = GetAncestor(Wnd, GA_PARENT );
+         HWND Parent = GetAncestor(hWnd, GA_PARENT );
 -        if (Parent != GetDesktopWindow())
 +      if (Parent != GetDesktopWindow())
          {
-           ScreenToClient(Parent, &Pt);
+             ScreenToClient(Parent, &pt);
          }
  
-       MenuInitTracking(Wnd, Menu, FALSE, Flags);
-       MenuTrackMenu(Menu, Flags, Pt.x, Pt.y, Wnd, NULL);
-       MenuExitTracking(Wnd);
+         MenuInitTracking(hWnd, hMenu, FALSE, wFlags);
+         MenuTrackMenu(hMenu, wFlags, pt.x, pt.y, hWnd, NULL);
+         MenuExitTracking(hWnd);
      }
  }
  
@@@ -4253,7 -4086,25 +4086,25 @@@ EndMenu(VOID
    guii.cbSize = sizeof(GUITHREADINFO);
    if(GetGUIThreadInfo(GetCurrentThreadId(), &guii) && guii.hwndMenuOwner)
    {
-     PostMessageW(guii.hwndMenuOwner, WM_CANCELMODE, 0, 0);
+     if (!fEndMenu &&
+          top_popup &&
+          guii.hwndMenuOwner != top_popup )
+     {
+        ERR("Capture GUI pti hWnd does not match top_popup!\n");
 -    }
++  }
+   }
+   /* if we are in the menu code, and it is active */
+   if (!fEndMenu && top_popup)
+   {
+       /* terminate the menu handling code */
+       fEndMenu = TRUE;
+       /* needs to be posted to wakeup the internal menu handler */
+       /* which will now terminate the menu, in the event that */
+       /* the main window was minimized, or lost focus, so we */
+       /* don't end up with an orphaned menu */
+       PostMessageW( top_popup, WM_CANCELMODE, 0, 0);
    }
    return TRUE;
  }