Sync to trunk head (r42241)
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / menu.c
index e99168e..3ff3890 100644 (file)
@@ -95,7 +95,7 @@ UserMenuInfo(
 { \
   if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
            (MenuItem)->Text.Length) { \
-    RtlFreeUnicodeString(&(MenuItem)->Text); \
+    ExFreePoolWithTag((MenuItem)->Text.Buffer, TAG_STRING); \
   } \
 }
 
@@ -206,27 +206,9 @@ IntGetMenuObject(HMENU hMenu)
 }
 
 BOOL FASTCALL
-IntFreeMenuItem(PMENU_OBJECT Menu, PMENU_ITEM MenuItem,
-                BOOL RemoveFromList, BOOL bRecurse)
+IntFreeMenuItem(PMENU_OBJECT Menu, PMENU_ITEM MenuItem, BOOL bRecurse)
 {
    FreeMenuText(MenuItem);
-   if(RemoveFromList)
-   {
-      PMENU_ITEM CurItem = Menu->MenuItemList;
-      while(CurItem)
-      {
-         if (CurItem->Next == MenuItem)
-         {
-            CurItem->Next = MenuItem->Next;
-            break;
-         }
-         else
-         {
-            CurItem = CurItem->Next;
-         }
-      }
-      Menu->MenuInfo.MenuItemCount--;
-   }
    if(bRecurse && MenuItem->hSubMenu)
    {
       PMENU_OBJECT SubMenu;
@@ -248,7 +230,7 @@ IntRemoveMenuItem(PMENU_OBJECT Menu, UINT uPosition, UINT uFlags,
                   BOOL bRecurse)
 {
    PMENU_ITEM PrevMenuItem, MenuItem;
-   if(IntGetMenuItemByFlag(Menu, uPosition, uFlags, &MenuItem,
+   if(IntGetMenuItemByFlag(Menu, uPosition, uFlags, &Menu, &MenuItem,
                            &PrevMenuItem) > -1)
    {
       if(MenuItem)
@@ -259,7 +241,8 @@ IntRemoveMenuItem(PMENU_OBJECT Menu, UINT uPosition, UINT uFlags,
          {
             Menu->MenuItemList = MenuItem->Next;
          }
-         return IntFreeMenuItem(Menu, MenuItem, TRUE, bRecurse);
+         Menu->MenuInfo.MenuItemCount--;
+         return IntFreeMenuItem(Menu, MenuItem, bRecurse);
       }
    }
    return FALSE;
@@ -274,7 +257,7 @@ IntDeleteMenuItems(PMENU_OBJECT Menu, BOOL bRecurse)
    while(CurItem)
    {
       NextItem = CurItem->Next;
-      IntFreeMenuItem(Menu, CurItem, FALSE, bRecurse);
+      IntFreeMenuItem(Menu, CurItem, bRecurse);
       CurItem = NextItem;
       res++;
    }
@@ -314,12 +297,13 @@ IntDestroyMenuObject(PMENU_OBJECT Menu,
             Window = UserGetWindowObject(Menu->MenuInfo.Wnd);
             if (Window)
             {
-               Window->IDMenu = 0;
+               Window->Wnd->IDMenu = 0;
             }
          }
-         ObmDeleteObject(Menu->MenuInfo.Self, otMenu);
+//         UserDereferenceObject(Menu);
+         BOOL ret = UserDeleteObject(Menu->MenuInfo.Self, otMenu);
          ObDereferenceObject(WindowStation);
-         return TRUE;
+         return ret;
       }
    }
    return FALSE;
@@ -329,8 +313,9 @@ PMENU_OBJECT FASTCALL
 IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
 {
    PMENU_OBJECT Menu;
+   PPROCESSINFO CurrentWin32Process;
 
-   Menu = (PMENU_OBJECT)ObmCreateObject(
+   Menu = (PMENU_OBJECT)UserCreateObject(
              gHandleTable, Handle,
              otMenu, sizeof(MENU_OBJECT));
 
@@ -346,8 +331,7 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
    Menu->MenuInfo.fMask = 0; /* not used */
    Menu->MenuInfo.dwStyle = 0; /* FIXME */
    Menu->MenuInfo.cyMax = 0; /* default */
-   Menu->MenuInfo.hbrBack =
-      NtGdiCreateSolidBrush(RGB(192, 192, 192), 0); /* FIXME: default background color */
+   Menu->MenuInfo.hbrBack = NULL; /* no brush */
    Menu->MenuInfo.dwContextHelpID = 0; /* default */
    Menu->MenuInfo.dwMenuData = 0; /* default */
    Menu->MenuInfo.Self = *Handle;
@@ -363,7 +347,8 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
    Menu->MenuItemList = NULL;
 
    /* Insert menu item into process menu handle list */
-   InsertTailList(&PsGetCurrentProcessWin32Process()->MenuListHead, &Menu->ListEntry);
+   CurrentWin32Process = PsGetCurrentProcessWin32Process();
+   InsertTailList(&CurrentWin32Process->MenuListHead, &Menu->ListEntry);
 
    return Menu;
 }
@@ -402,7 +387,7 @@ IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
             NewMenuItem->Text.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, MenuItem->Text.MaximumLength, TAG_STRING);
             if(!NewMenuItem->Text.Buffer)
             {
-               ExFreePool(NewMenuItem);
+               ExFreePoolWithTag(NewMenuItem, TAG_MENUITEM);
                break;
             }
             RtlCopyUnicodeString(&NewMenuItem->Text, &MenuItem->Text);
@@ -433,13 +418,14 @@ IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
 PMENU_OBJECT FASTCALL
 IntCloneMenu(PMENU_OBJECT Source)
 {
+   PPROCESSINFO CurrentWin32Process;
    HANDLE hMenu;
    PMENU_OBJECT Menu;
 
    if(!Source)
       return NULL;
 
-   Menu = (PMENU_OBJECT)ObmCreateObject(
+   Menu = (PMENU_OBJECT)UserCreateObject(
              gHandleTable, &hMenu,
              otMenu, sizeof(MENU_OBJECT));
 
@@ -467,7 +453,8 @@ IntCloneMenu(PMENU_OBJECT Source)
    Menu->MenuItemList = NULL;
 
    /* Insert menu item into process menu handle list */
-   InsertTailList(&PsGetCurrentProcessWin32Process()->MenuListHead, &Menu->ListEntry);
+   CurrentWin32Process = PsGetCurrentProcessWin32Process();
+   InsertTailList(&CurrentWin32Process->MenuListHead, &Menu->ListEntry);
 
    IntCloneMenuItems(Menu, Source);
 
@@ -515,20 +502,6 @@ IntGetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi)
    return TRUE;
 }
 
-
-BOOL FASTCALL
-IntIsMenu(HMENU hMenu)
-{
-   PMENU_OBJECT Menu;
-
-   if((Menu = UserGetMenuObject(hMenu)))
-   {
-      return TRUE;
-   }
-   return FALSE;
-}
-
-
 BOOL FASTCALL
 IntSetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi)
 {
@@ -566,7 +539,8 @@ IntSetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi)
 
 int FASTCALL
 IntGetMenuItemByFlag(PMENU_OBJECT Menu, UINT uSearchBy, UINT fFlag,
-                     PMENU_ITEM *MenuItem, PMENU_ITEM *PrevMenuItem)
+                     PMENU_OBJECT *SubMenu, PMENU_ITEM *MenuItem,
+                     PMENU_ITEM *PrevMenuItem)
 {
    PMENU_ITEM PrevItem = NULL;
    PMENU_ITEM CurItem = Menu->MenuItemList;
@@ -611,18 +585,24 @@ IntGetMenuItemByFlag(PMENU_OBJECT Menu, UINT uSearchBy, UINT fFlag,
                *MenuItem = CurItem;
             if(PrevMenuItem)
                *PrevMenuItem = PrevItem;
+            if(SubMenu)
+                *SubMenu = Menu;
+
             return p;
          }
-         else if (0 != (CurItem->fType & MF_POPUP))
+         else
          {
-            Menu = UserGetMenuObject(CurItem->hSubMenu);
-            if (NULL != Menu)
+            if(CurItem->fType & MF_POPUP)
             {
-               ret = IntGetMenuItemByFlag(Menu, uSearchBy, fFlag,
-                                          MenuItem, PrevMenuItem);
-               if (-1 != ret)
+               PMENU_OBJECT NewMenu = UserGetMenuObject(CurItem->hSubMenu);
+               if(NewMenu)
                {
-                  return ret;
+                   ret = IntGetMenuItemByFlag(NewMenu, uSearchBy, fFlag,
+                                              SubMenu, MenuItem, PrevMenuItem);
+                   if(ret != -1)
+                   {
+                      return ret;
+                   }
                }
             }
          }
@@ -643,56 +623,25 @@ IntInsertMenuItemToList(PMENU_OBJECT Menu, PMENU_ITEM MenuItem, int pos)
    UINT npos = 0;
 
    CurItem = Menu->MenuItemList;
-   if(pos <= -1)
-   {
-      while(CurItem)
-      {
-         LastItem = CurItem;
-         CurItem = CurItem->Next;
-         npos++;
-      }
-   }
-   else
+   while(CurItem && (pos != 0))
    {
-      while(CurItem && (pos > 0))
-      {
-         LastItem = CurItem;
-         CurItem = CurItem->Next;
-         pos--;
-         npos++;
-      }
+      LastItem = CurItem;
+      CurItem = CurItem->Next;
+      pos--;
+      npos++;
    }
 
-   if(CurItem)
+   if(LastItem)
    {
-      if(LastItem)
-      {
-         /* insert the item before CurItem */
-         MenuItem->Next = LastItem->Next;
-         LastItem->Next = MenuItem;
-      }
-      else
-      {
-         /* insert at the beginning */
-         Menu->MenuItemList = MenuItem;
-         MenuItem->Next = CurItem;
-      }
+      /* insert the item after LastItem */
+      LastItem->Next = MenuItem;
    }
    else
    {
-      if(LastItem)
-      {
-         /* append item */
-         LastItem->Next = MenuItem;
-         MenuItem->Next = NULL;
-      }
-      else
-      {
-         /* insert first item */
-         Menu->MenuItemList = MenuItem;
-         MenuItem->Next = NULL;
-      }
+      /* insert at the beginning */
+      Menu->MenuItemList = MenuItem;
    }
+   MenuItem->Next = CurItem;
    Menu->MenuInfo.MenuItemCount++;
 
    return npos;
@@ -922,6 +871,7 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
 {
    int pos = (int)uItem;
    PMENU_ITEM MenuItem;
+   PMENU_OBJECT SubMenu = NULL;
 
    if (MAX_MENU_ITEMS <= MenuObject->MenuInfo.MenuItemCount)
    {
@@ -931,6 +881,7 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
 
    if (fByPosition)
    {
+      SubMenu = MenuObject;
       /* calculate position */
       if(MenuObject->MenuInfo.MenuItemCount < pos)
       {
@@ -939,8 +890,16 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
    }
    else
    {
-      pos = IntGetMenuItemByFlag(MenuObject, uItem, MF_BYCOMMAND, NULL, NULL);
+      pos = IntGetMenuItemByFlag(MenuObject, uItem, MF_BYCOMMAND, &SubMenu, NULL, NULL);
+   }
+   if (SubMenu == NULL)
+   {
+       /* default to last position of menu */
+      SubMenu = MenuObject;
+      pos = MenuObject->MenuInfo.MenuItemCount;
    }
+
+
    if (pos < -1)
    {
       pos = -1;
@@ -963,16 +922,16 @@ IntInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition,
    RtlInitUnicodeString(&MenuItem->Text, NULL);
    MenuItem->hbmpItem = (HBITMAP)0;
 
-   if (! IntSetMenuItemInfo(MenuObject, MenuItem, ItemInfo))
+   if(!IntSetMenuItemInfo(SubMenu, MenuItem, ItemInfo))
    {
-      ExFreePool(MenuItem);
+      ExFreePoolWithTag(MenuItem, TAG_MENUITEM);
       return FALSE;
    }
 
    /* Force size recalculation! */
    MenuObject->MenuInfo.Height = 0;
 
-   pos = IntInsertMenuItemToList(MenuObject, MenuItem, pos);
+   pos = IntInsertMenuItemToList(SubMenu, MenuItem, pos);
 
    DPRINT("IntInsertMenuItemToList = %i\n", pos);
 
@@ -983,7 +942,7 @@ UINT FASTCALL
 IntEnableMenuItem(PMENU_OBJECT MenuObject, UINT uIDEnableItem, UINT uEnable)
 {
    PMENU_ITEM MenuItem;
-   UINT res = IntGetMenuItemByFlag(MenuObject, uIDEnableItem, uEnable, &MenuItem, NULL);
+   UINT res = IntGetMenuItemByFlag(MenuObject, uIDEnableItem, uEnable, NULL, &MenuItem, NULL);
    if(!MenuItem || (res == (UINT)-1))
    {
       return (UINT)-1;
@@ -993,29 +952,18 @@ IntEnableMenuItem(PMENU_OBJECT MenuObject, UINT uIDEnableItem, UINT uEnable)
 
    if(uEnable & MF_DISABLED)
    {
-      if(!(MenuItem->fState & MF_DISABLED))
-         MenuItem->fState |= MF_DISABLED;
-      if(uEnable & MF_GRAYED)
-      {
-         if(!(MenuItem->fState & MF_GRAYED))
-            MenuItem->fState |= MF_GRAYED;
-      }
+      MenuItem->fState |= MF_DISABLED;
+      MenuItem->fState |= uEnable & MF_GRAYED;
    }
    else
    {
       if(uEnable & MF_GRAYED)
       {
-         if(!(MenuItem->fState & MF_GRAYED))
-            MenuItem->fState |= MF_GRAYED;
-         if(!(MenuItem->fState & MF_DISABLED))
-            MenuItem->fState |= MF_DISABLED;
+         MenuItem->fState |= (MF_GRAYED | MF_DISABLED);
       }
       else
       {
-         if(MenuItem->fState & MF_DISABLED)
-            MenuItem->fState ^= MF_DISABLED;
-         if(MenuItem->fState & MF_GRAYED)
-            MenuItem->fState ^= MF_GRAYED;
+         MenuItem->fState &= ~(MF_DISABLED | MF_GRAYED);
       }
    }
 
@@ -1064,6 +1012,7 @@ IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax)
          }
          mii.fState = CurItem->fState;
          mii.fType = CurItem->fType;
+         mii.wID = CurItem->wID;
          mii.hbmpChecked = CurItem->hbmpChecked;
          mii.hbmpItem = CurItem->hbmpItem;
          mii.hbmpUnchecked = CurItem->hbmpUnchecked;
@@ -1129,7 +1078,7 @@ IntCheckMenuItem(PMENU_OBJECT MenuObject, UINT uIDCheckItem, UINT uCheck)
    PMENU_ITEM MenuItem;
    int res = -1;
 
-   if((IntGetMenuItemByFlag(MenuObject, uIDCheckItem, uCheck, &MenuItem, NULL) < 0) || !MenuItem)
+   if((IntGetMenuItemByFlag(MenuObject, uIDCheckItem, uCheck, NULL, &MenuItem, NULL) < 0) || !MenuItem)
    {
       return -1;
    }
@@ -1137,13 +1086,11 @@ IntCheckMenuItem(PMENU_OBJECT MenuObject, UINT uIDCheckItem, UINT uCheck)
    res = (DWORD)(MenuItem->fState & MF_CHECKED);
    if(uCheck & MF_CHECKED)
    {
-      if(!(MenuItem->fState & MF_CHECKED))
-         MenuItem->fState |= MF_CHECKED;
+      MenuItem->fState |= MF_CHECKED;
    }
    else
    {
-      if(MenuItem->fState & MF_CHECKED)
-         MenuItem->fState ^= MF_CHECKED;
+      MenuItem->fState &= ~MF_CHECKED;
    }
 
    return (DWORD)res;
@@ -1154,7 +1101,7 @@ IntHiliteMenuItem(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject,
                   UINT uItemHilite, UINT uHilite)
 {
    PMENU_ITEM MenuItem;
-   BOOL res = IntGetMenuItemByFlag(MenuObject, uItemHilite, uHilite, &MenuItem, NULL);
+   BOOL res = IntGetMenuItemByFlag(MenuObject, uItemHilite, uHilite, NULL, &MenuItem, NULL);
    if(!MenuItem || !res)
    {
       return FALSE;
@@ -1162,13 +1109,11 @@ IntHiliteMenuItem(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject,
 
    if(uHilite & MF_HILITE)
    {
-      if(!(MenuItem->fState & MF_HILITE))
-         MenuItem->fState |= MF_HILITE;
+      MenuItem->fState |= MF_HILITE;
    }
    else
    {
-      if(MenuItem->fState & MF_HILITE)
-         MenuItem->fState ^= MF_HILITE;
+      MenuItem->fState &= ~MF_HILITE;
    }
 
    /* FIXME - update the window's menu */
@@ -1186,8 +1131,7 @@ UserSetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT uItem, UINT fByPos)
    {
       while(MenuItem)
       {
-         if(MenuItem->fState & MFS_DEFAULT)
-            MenuItem->fState ^= MFS_DEFAULT;
+         MenuItem->fState &= ~MFS_DEFAULT;
          MenuItem = MenuItem->Next;
       }
       return TRUE;
@@ -1200,14 +1144,12 @@ UserSetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT uItem, UINT fByPos)
       {
          if(pos == uItem)
          {
-            if(!(MenuItem->fState & MFS_DEFAULT))
-               MenuItem->fState |= MFS_DEFAULT;
+            MenuItem->fState |= MFS_DEFAULT;
             ret = TRUE;
          }
          else
          {
-            if(MenuItem->fState & MFS_DEFAULT)
-               MenuItem->fState ^= MFS_DEFAULT;
+            MenuItem->fState &= ~MFS_DEFAULT;
          }
          pos++;
          MenuItem = MenuItem->Next;
@@ -1219,14 +1161,12 @@ UserSetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT uItem, UINT fByPos)
       {
          if(!ret && (MenuItem->wID == uItem))
          {
-            if(!(MenuItem->fState & MFS_DEFAULT))
-               MenuItem->fState |= MFS_DEFAULT;
+            MenuItem->fState |= MFS_DEFAULT;
             ret = TRUE;
          }
          else
          {
-            if(MenuItem->fState & MFS_DEFAULT)
-               MenuItem->fState ^= MFS_DEFAULT;
+            MenuItem->fState &= ~MFS_DEFAULT;
          }
          MenuItem = MenuItem->Next;
       }
@@ -1253,7 +1193,7 @@ IntGetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT fByPos, UINT gmdiFlags,
          if(!(gmdiFlags & GMDI_USEDISABLED) && (MenuItem->fState & MFS_DISABLED))
             break;
 
-         if(fByPos & MF_BYPOSITION)
+         if(fByPos)
             res = x;
          else
             res = MenuItem->wID;
@@ -1311,14 +1251,14 @@ co_IntExitTracking(PWINDOW_OBJECT Window, PMENU_OBJECT Menu, BOOL Popup,
 
 INT FASTCALL
 IntTrackMenu(PMENU_OBJECT Menu, PWINDOW_OBJECT Window, INT x, INT y,
-             RECT lprect)
+             RECTL lprect)
 {
    return 0;
 }
 
 BOOL FASTCALL
 co_IntTrackPopupMenu(PMENU_OBJECT Menu, PWINDOW_OBJECT Window,
-                     UINT Flags, POINT *Pos, UINT MenuPos, RECT *ExcludeRect)
+                     UINT Flags, POINT *Pos, UINT MenuPos, RECTL *ExcludeRect)
 {
    co_IntInitTracking(Window, Menu, TRUE, Flags);
 
@@ -1327,11 +1267,11 @@ co_IntTrackPopupMenu(PMENU_OBJECT Menu, PWINDOW_OBJECT Window,
 }
 
 BOOL FASTCALL
-IntSetMenuItemRect(PMENU_OBJECT Menu, UINT Item, BOOL fByPos, RECT *rcRect)
+IntSetMenuItemRect(PMENU_OBJECT Menu, UINT Item, BOOL fByPos, RECTL *rcRect)
 {
    PMENU_ITEM mi;
    if(IntGetMenuItemByFlag(Menu, Item, (fByPos ? MF_BYPOSITION : MF_BYCOMMAND),
-                           &mi, NULL) > -1)
+                           NULL, &mi, NULL) > -1)
    {
       mi->Rect = *rcRect;
       return TRUE;
@@ -1344,7 +1284,7 @@ IntSetMenuItemRect(PMENU_OBJECT Menu, UINT Item, BOOL fByPos, RECT *rcRect)
  * Internal function. Called when the process is destroyed to free the remaining menu handles.
 */
 BOOL FASTCALL
-IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process)
+IntCleanupMenus(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
 {
    PEPROCESS CurrentProcess;
    PLIST_ENTRY LastHead = NULL;
@@ -1372,6 +1312,146 @@ IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process)
    return TRUE;
 }
 
+VOID APIENTRY
+co_InflateRect(RECTL *rect, int dx, int dy)
+{
+    rect->left -= dx;
+    rect->top -= dy;
+    rect->right += dx;
+    rect->bottom += dy;
+}
+
+BOOLEAN APIENTRY
+intGetTitleBarInfo(PWINDOW_OBJECT pWindowObject, PTITLEBARINFO bti)
+{
+
+    DWORD dwStyle = 0;
+    DWORD dwExStyle = 0;
+    BOOLEAN retValue = TRUE;
+
+    if (bti->cbSize == sizeof(TITLEBARINFO))
+    {
+        RtlZeroMemory(&bti->rgstate[0],sizeof(DWORD)*(CCHILDREN_TITLEBAR+1));
+
+        bti->rgstate[0] = STATE_SYSTEM_FOCUSABLE;
+
+        dwStyle = pWindowObject->Wnd->style;
+        dwExStyle = pWindowObject->Wnd->ExStyle;
+
+        bti->rcTitleBar.top  = 0;
+        bti->rcTitleBar.left = 0;
+        bti->rcTitleBar.right  = pWindowObject->Wnd->rcWindow.right - pWindowObject->Wnd->rcWindow.left;
+        bti->rcTitleBar.bottom = pWindowObject->Wnd->rcWindow.bottom - pWindowObject->Wnd->rcWindow.top;
+
+        /* is it iconiced ? */ 
+        if ((dwStyle & WS_ICONIC)!=WS_ICONIC)
+        {
+            /* Remove frame from rectangle */
+            if (HAS_THICKFRAME( dwStyle, dwExStyle ))
+            {
+                /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXFRAME) and UserGetSystemMetrics(SM_CYFRAME) */
+                co_InflateRect( &bti->rcTitleBar, -UserGetSystemMetrics(SM_CXFRAME), -UserGetSystemMetrics(SM_CYFRAME) );
+            }
+            else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
+            {
+                /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXDLGFRAME) and UserGetSystemMetrics(SM_CYDLGFRAME) */
+                co_InflateRect( &bti->rcTitleBar, -UserGetSystemMetrics(SM_CXDLGFRAME), -UserGetSystemMetrics(SM_CYDLGFRAME));
+            }
+            else if (HAS_THINFRAME( dwStyle, dwExStyle))
+            {
+                /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXBORDER) and UserGetSystemMetrics(SM_CYBORDER) */
+                co_InflateRect( &bti->rcTitleBar, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER) );
+            }
+
+            /* We have additional border information if the window
+             * is a child (but not an MDI child) */
+            if ( (dwStyle & WS_CHILD)  &&
+                 ((dwExStyle & WS_EX_MDICHILD) == 0 ) )
+            {
+                if (dwExStyle & WS_EX_CLIENTEDGE)
+                {
+                    /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXEDGE) and UserGetSystemMetrics(SM_CYEDGE) */
+                    co_InflateRect (&bti->rcTitleBar, -UserGetSystemMetrics(SM_CXEDGE), -UserGetSystemMetrics(SM_CYEDGE));
+                }
+
+                if (dwExStyle & WS_EX_STATICEDGE)
+                {
+                    /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXBORDER) and UserGetSystemMetrics(SM_CYBORDER) */
+                    co_InflateRect (&bti->rcTitleBar, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER));
+                }
+            }
+        }
+
+        bti->rcTitleBar.top += pWindowObject->Wnd->rcWindow.top;
+        bti->rcTitleBar.left += pWindowObject->Wnd->rcWindow.left;
+        bti->rcTitleBar.right += pWindowObject->Wnd->rcWindow.left;
+
+        bti->rcTitleBar.bottom = bti->rcTitleBar.top;
+        if (dwExStyle & WS_EX_TOOLWINDOW)
+        {
+            /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CYSMCAPTION) */
+            bti->rcTitleBar.bottom += UserGetSystemMetrics(SM_CYSMCAPTION);
+        }
+        else 
+        {
+            /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CYCAPTION) and UserGetSystemMetrics(SM_CXSIZE) */
+            bti->rcTitleBar.bottom += UserGetSystemMetrics(SM_CYCAPTION);
+            bti->rcTitleBar.left += UserGetSystemMetrics(SM_CXSIZE);
+        }
+
+        if (dwStyle & WS_CAPTION) 
+        {
+            bti->rgstate[1] = STATE_SYSTEM_INVISIBLE;
+            if (dwStyle & WS_SYSMENU) 
+            {
+                if (!(dwStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX))) 
+                {
+                    bti->rgstate[2] = STATE_SYSTEM_INVISIBLE;
+                    bti->rgstate[3] = STATE_SYSTEM_INVISIBLE;
+                }
+                else 
+                {
+                    if (!(dwStyle & WS_MINIMIZEBOX))
+                    {
+                        bti->rgstate[2] = STATE_SYSTEM_UNAVAILABLE;
+                    }
+                    if (!(dwStyle & WS_MAXIMIZEBOX))
+                    {
+                        bti->rgstate[3] = STATE_SYSTEM_UNAVAILABLE;
+                    }
+                }
+
+                if (!(dwExStyle & WS_EX_CONTEXTHELP))
+                {
+                    bti->rgstate[4] = STATE_SYSTEM_INVISIBLE;
+                }
+                if (pWindowObject->Wnd->pcls->style & CS_NOCLOSE)
+                {
+                    bti->rgstate[5] = STATE_SYSTEM_UNAVAILABLE;
+                }
+            }
+            else 
+            {
+                bti->rgstate[2] = STATE_SYSTEM_INVISIBLE;
+                bti->rgstate[3] = STATE_SYSTEM_INVISIBLE;
+                bti->rgstate[4] = STATE_SYSTEM_INVISIBLE;
+                bti->rgstate[5] = STATE_SYSTEM_INVISIBLE;
+            }
+        }
+        else
+        {
+            bti->rgstate[0] |= STATE_SYSTEM_INVISIBLE;
+        }
+    }
+    else
+    {
+        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        retValue = FALSE;
+    }
+
+    return retValue;
+}
+
 /* FUNCTIONS *****************************************************************/
 
 
@@ -1379,7 +1459,7 @@ IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process)
  * @implemented
  */
 DWORD
-STDCALL
+APIENTRY
 NtUserBuildMenuItemList(
    HMENU hMenu,
    VOID* Buffer,
@@ -1419,7 +1499,7 @@ CLEANUP:
 /*
  * @implemented
  */
-DWORD STDCALL
+DWORD APIENTRY
 NtUserCheckMenuItem(
    HMENU hMenu,
    UINT uIDCheckItem,
@@ -1449,6 +1529,7 @@ HMENU FASTCALL UserCreateMenu(BOOL PopupMenu)
 {
    PWINSTATION_OBJECT WinStaObject;
    HANDLE Handle;
+   PMENU_OBJECT Menu;
    NTSTATUS Status;
    PEPROCESS CurrentProcess = PsGetCurrentProcess();
 
@@ -1471,14 +1552,15 @@ HMENU FASTCALL UserCreateMenu(BOOL PopupMenu)
           SetLastNtError(Status);
           return (HMENU)0;
        }
-       IntCreateMenu(&Handle, !PopupMenu);
+       Menu = IntCreateMenu(&Handle, !PopupMenu);
        ObDereferenceObject(WinStaObject);
    }
    else
    {
-       IntCreateMenu(&Handle, !PopupMenu);
+       Menu = IntCreateMenu(&Handle, !PopupMenu);
    }
 
+   if (Menu) UserDereferenceObject(Menu);
    return (HMENU)Handle;
 }
 
@@ -1486,7 +1568,7 @@ HMENU FASTCALL UserCreateMenu(BOOL PopupMenu)
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserDeleteMenu(
    HMENU hMenu,
    UINT uPosition,
@@ -1511,6 +1593,73 @@ CLEANUP:
    END_CLEANUP;
 }
 
+/*
+ * @implemented
+ */
+BOOLEAN APIENTRY
+NtUserGetTitleBarInfo(
+    HWND hwnd,
+    PTITLEBARINFO bti)
+{
+    PWINDOW_OBJECT WindowObject;
+    TITLEBARINFO bartitleinfo;
+    DECLARE_RETURN(BOOLEAN);
+    BOOLEAN retValue = TRUE;
+
+    DPRINT("Enter NtUserGetTitleBarInfo\n");
+    UserEnterExclusive();
+
+    /* Vaildate the windows handle */
+    if (!(WindowObject = UserGetWindowObject(hwnd)))
+    {
+        SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+        retValue = FALSE;
+    }
+
+    _SEH2_TRY
+    {
+        /* Copy our usermode buffer bti to local buffer bartitleinfo */
+        ProbeForRead(bti, sizeof(TITLEBARINFO), 1);
+        RtlCopyMemory(&bartitleinfo, bti, sizeof(TITLEBARINFO));
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Fail copy the data */ 
+        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        retValue = FALSE;
+    }
+    _SEH2_END
+
+    /* Get the tile bar info */ 
+    if (retValue)
+    {
+        retValue = intGetTitleBarInfo(WindowObject, &bartitleinfo);
+        if (retValue)
+        {
+            _SEH2_TRY
+            {
+                /* Copy our buffer to user mode buffer bti */
+                ProbeForWrite(bti, sizeof(TITLEBARINFO), 1);
+                RtlCopyMemory(bti, &bartitleinfo, sizeof(TITLEBARINFO));
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                /* Fail copy the data */ 
+                SetLastWin32Error(ERROR_INVALID_PARAMETER);
+                retValue = FALSE;
+            }
+            _SEH2_END
+        }
+    }
+
+    RETURN( retValue );
+
+CLEANUP:
+    DPRINT("Leave NtUserGetTitleBarInfo, ret=%i\n",_ret_);
+    UserLeave();
+    END_CLEANUP;
+}
+
 
 
 /*
@@ -1537,7 +1686,7 @@ BOOL FASTCALL UserDestroyMenu(HMENU hMenu)
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserDestroyMenu(
    HMENU hMenu)
 {
@@ -1558,7 +1707,7 @@ NtUserDestroyMenu(
       RETURN( FALSE);
    }
 
-   RETURN( IntDestroyMenuObject(Menu, FALSE, TRUE));
+   RETURN( IntDestroyMenuObject(Menu, TRUE, TRUE));
 
 CLEANUP:
    DPRINT("Leave NtUserDestroyMenu, ret=%i\n",_ret_);
@@ -1570,7 +1719,7 @@ CLEANUP:
 /*
  * @implemented
  */
-UINT STDCALL
+UINT APIENTRY
 NtUserEnableMenuItem(
    HMENU hMenu,
    UINT uIDEnableItem,
@@ -1599,8 +1748,8 @@ CLEANUP:
 /*
  * @implemented
  */
-DWORD STDCALL
-NtUserInsertMenuItem(
+DWORD APIENTRY
+UserInsertMenuItem(
    HMENU hMenu,
    UINT uItem,
    BOOL fByPosition,
@@ -1611,7 +1760,7 @@ NtUserInsertMenuItem(
    ROSMENUITEMINFO ItemInfo;
    DECLARE_RETURN(DWORD);
 
-   DPRINT("Enter NtUserInsertMenuItem\n");
+   DPRINT("Enter UserInsertMenuItem\n");
    UserEnterExclusive();
 
    if(!(Menu = UserGetMenuObject(hMenu)))
@@ -1649,7 +1798,7 @@ NtUserInsertMenuItem(
    RETURN( FALSE);
 
 CLEANUP:
-   DPRINT("Leave NtUserInsertMenuItem, ret=%i\n",_ret_);
+   DPRINT("Leave UserInsertMenuItem, ret=%i\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -1658,7 +1807,7 @@ CLEANUP:
 /*
  * @unimplemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserEndMenu(VOID)
 {
    UNIMPLEMENTED
@@ -1670,7 +1819,7 @@ NtUserEndMenu(VOID)
 /*
  * @implemented
  */
-UINT STDCALL
+UINT APIENTRY
 NtUserGetMenuDefaultItem(
    HMENU hMenu,
    UINT fByPos,
@@ -1700,7 +1849,7 @@ CLEANUP:
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserGetMenuBarInfo(
    HWND hwnd,
    LONG idObject,
@@ -1713,7 +1862,7 @@ NtUserGetMenuBarInfo(
    PWINDOW_OBJECT WindowObject;
    HMENU hMenu;
    POINT Offset;
-   RECT Rect;
+   RECTL Rect;
    MENUBARINFO kmbi;
    DECLARE_RETURN(BOOL);
 
@@ -1726,7 +1875,7 @@ NtUserGetMenuBarInfo(
         RETURN(FALSE);
      }
 
-   hMenu = (HMENU)WindowObject->IDMenu;
+   hMenu = (HMENU)(DWORD_PTR)WindowObject->Wnd->IDMenu;
 
    if (!(MenuObject = UserGetMenuObject(hMenu)))
      {
@@ -1753,7 +1902,7 @@ NtUserGetMenuBarInfo(
          kmbi.hMenu = hMenu;
          if (idItem) /* Non-Zero-Based. */
            {
-              if (IntGetMenuItemByFlag(MenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+              if (IntGetMenuItemByFlag(MenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
                    kmbi.rcBar = mi->Rect;
               else
                 {
@@ -1802,7 +1951,7 @@ NtUserGetMenuBarInfo(
            }
          if (idItem)
            {
-              if (IntGetMenuItemByFlag(SubMenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+              if (IntGetMenuItemByFlag(SubMenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
                    kmbi.rcBar = mi->Rect;
               else
                 {
@@ -1852,7 +2001,7 @@ NtUserGetMenuBarInfo(
          kmbi.hMenu = SysMenuObject->MenuInfo.Self;
          if (idItem)
            {
-              if (IntGetMenuItemByFlag(SysMenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+              if (IntGetMenuItemByFlag(SysMenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
                    kmbi.rcBar = mi->Rect;
               else
                 {
@@ -1916,7 +2065,7 @@ CLEANUP:
 /*
  * @unimplemented
  */
-UINT STDCALL
+UINT APIENTRY
 NtUserGetMenuIndex(
    HMENU hMenu,
    UINT wID)
@@ -1930,16 +2079,17 @@ NtUserGetMenuIndex(
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserGetMenuItemRect(
    HWND hWnd,
    HMENU hMenu,
    UINT uItem,
-   LPRECT lprcItem)
+   PRECTL lprcItem)
 {
    ROSMENUINFO mi;
-   HWND referenceHwnd;
-   RECT Rect;
+   PWINDOW_OBJECT ReferenceWnd;
+   LONG XMove, YMove;
+   RECTL Rect;
    NTSTATUS Status;
    PMENU_OBJECT Menu;
    PMENU_ITEM MenuItem;
@@ -1953,24 +2103,38 @@ NtUserGetMenuItemRect(
       RETURN(FALSE);
    }
 
-   if (IntGetMenuItemByFlag(Menu, uItem, MF_BYPOSITION, &MenuItem, NULL) > -1)
+   if (IntGetMenuItemByFlag(Menu, uItem, MF_BYPOSITION, NULL, &MenuItem, NULL) > -1)
         Rect = MenuItem->Rect;
    else
       RETURN(FALSE);
 
-   referenceHwnd = hWnd;
-
    if(!hWnd)
    {
       if(!UserMenuInfo(Menu, &mi, FALSE))
          RETURN( FALSE);
       if(mi.Wnd == 0)
          RETURN( FALSE);
-      referenceHwnd = mi.Wnd; /* Okay we found it, so now what do we do? */
    }
 
-   if (lprcItem == NULL)
-      RETURN( FALSE);
+   if (lprcItem == NULL) RETURN( FALSE);
+
+   if (!(ReferenceWnd = UserGetWindowObject(mi.Wnd))) RETURN( FALSE);
+
+   if(MenuItem->fType & MF_POPUP)
+   {
+     XMove = ReferenceWnd->Wnd->rcClient.left;
+     YMove = ReferenceWnd->Wnd->rcClient.top;
+   }
+   else
+   {
+     XMove = ReferenceWnd->Wnd->rcWindow.left;
+     YMove = ReferenceWnd->Wnd->rcWindow.top;
+   }
+
+   Rect.left   += XMove;
+   Rect.top    += YMove;
+   Rect.right  += XMove;
+   Rect.bottom += YMove;
 
    Status = MmCopyToCaller(lprcItem, &Rect, sizeof(RECT));
    if (! NT_SUCCESS(Status))
@@ -1990,7 +2154,7 @@ CLEANUP:
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserHiliteMenuItem(
    HWND hWnd,
    HMENU hMenu,
@@ -2014,7 +2178,7 @@ NtUserHiliteMenuItem(
       RETURN(FALSE);
    }
 
-   if(Window->IDMenu == (UINT)hMenu)
+   if(Window->Wnd->IDMenu == (UINT)(UINT_PTR)hMenu)
    {
       RETURN( IntHiliteMenuItem(Window, Menu, uItemHilite, uHilite));
    }
@@ -2089,7 +2253,7 @@ UserMenuInfo(
  * @implemented
  */
 BOOL
-STDCALL
+APIENTRY
 NtUserMenuInfo(
    HMENU hMenu,
    PROSMENUINFO UnsafeMenuInfo,
@@ -2119,7 +2283,7 @@ CLEANUP:
 /*
  * @implemented
  */
-int STDCALL
+int APIENTRY
 NtUserMenuItemFromPoint(
    HWND hWnd,
    HMENU hMenu,
@@ -2145,8 +2309,8 @@ NtUserMenuItemFromPoint(
       RETURN( -1);
    }
 
-   X -= Window->WindowRect.left;
-   Y -= Window->WindowRect.top;
+   X -= Window->Wnd->rcWindow.left;
+   Y -= Window->Wnd->rcWindow.top;
 
    mi = Menu->MenuItemList;
    for (i = 0; NULL != mi; i++)
@@ -2213,7 +2377,7 @@ UserMenuItemInfo(
 
    if (IntGetMenuItemByFlag(Menu, Item,
                             (ByPosition ? MF_BYPOSITION : MF_BYCOMMAND),
-                            &MenuItem, NULL) < 0)
+                            NULL, &MenuItem, NULL) < 0)
    {
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
       return( FALSE);
@@ -2246,7 +2410,7 @@ UserMenuItemInfo(
  * @implemented
  */
 BOOL
-STDCALL
+APIENTRY
 NtUserMenuItemInfo(
    HMENU hMenu,
    UINT Item,
@@ -2278,7 +2442,7 @@ CLEANUP:
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserRemoveMenu(
    HMENU hMenu,
    UINT uPosition,
@@ -2308,7 +2472,7 @@ CLEANUP:
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserSetMenuContextHelpId(
    HMENU hMenu,
    DWORD dwContextHelpId)
@@ -2337,7 +2501,7 @@ CLEANUP:
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserSetMenuDefaultItem(
    HMENU hMenu,
    UINT uItem,
@@ -2366,7 +2530,7 @@ CLEANUP:
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserSetMenuFlagRtoL(
    HMENU hMenu)
 {
@@ -2393,7 +2557,7 @@ CLEANUP:
 /*
  * @unimplemented
  */
-DWORD STDCALL
+DWORD APIENTRY
 NtUserThunkedMenuInfo(
    HMENU hMenu,
    LPCMENUINFO lpcmi)
@@ -2407,7 +2571,7 @@ NtUserThunkedMenuInfo(
 /*
  * @unimplemented
  */
-DWORD STDCALL
+DWORD APIENTRY
 NtUserThunkedMenuItemInfo(
    HMENU hMenu,
    UINT uItem,
@@ -2416,10 +2580,13 @@ NtUserThunkedMenuItemInfo(
    LPMENUITEMINFOW lpmii,
    PUNICODE_STRING lpszCaption)
 {
-   UNIMPLEMENTED
+
    /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
-      if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
-   */
+      if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()   */
+
+   if (bInsert) return UserInsertMenuItem(hMenu, uItem, fByPosition, lpmii);
+
+   UNIMPLEMENTED
    return 0;
 }
 
@@ -2428,7 +2595,7 @@ NtUserThunkedMenuItemInfo(
  * @implemented
  */
 /* NOTE: unused function */
-BOOL STDCALL
+BOOL APIENTRY
 NtUserTrackPopupMenuEx(
    HMENU hMenu,
    UINT fuFlags,