#define NDEBUG
#include <debug.h>
+PMENU_OBJECT FASTCALL
+IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu);
+
+
/* STATIC FUNCTION ***********************************************************/
PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu)
{
- PMENU_OBJECT Menu = (PMENU_OBJECT)UserGetObject(&gHandleTable, hMenu, otMenu);
+ PMENU_OBJECT Menu;
+
+ if (!hMenu)
+ {
+ SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+ return NULL;
+ }
+
+ Menu = (PMENU_OBJECT)UserGetObject(&gHandleTable, hMenu, otMenu);
if (!Menu)
{
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
Menu->MenuInfo.dwStyle = 0; /* FIXME */
Menu->MenuInfo.cyMax = 0; /* default */
Menu->MenuInfo.hbrBack =
- NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */
+ NtGdiCreateSolidBrush(RGB(192, 192, 192), 0); /* FIXME: default background color */
Menu->MenuInfo.dwContextHelpID = 0; /* default */
Menu->MenuInfo.dwMenuData = 0; /* default */
Menu->MenuInfo.Self = *Handle;
pos = IntInsertMenuItemToList(MenuObject, MenuItem, pos);
- return pos >= 0;
+ DPRINT("IntInsertMenuItemToList = %i\n", pos);
+
+ return (pos >= 0);
}
UINT FASTCALL
if(!(Menu = UserGetMenuObject(hMenu)))
{
- RETURN(0);
+ RETURN( FALSE);
}
+ /* Try to copy the whole MENUITEMINFOW structure */
Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, sizeof(MENUITEMINFOW));
- if (! NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status))
{
- SetLastNtError(Status);
- RETURN( FALSE);
+ if (sizeof(MENUITEMINFOW) != ItemInfo.cbSize
+ && FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != ItemInfo.cbSize)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ RETURN( FALSE);
+ }
+ RETURN( IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo));
}
- if (ItemInfo.cbSize != sizeof(MENUITEMINFOW))
+
+ /* Try to copy without last field (not present in older versions) */
+ Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, FIELD_OFFSET(MENUITEMINFOW, hbmpItem));
+ if (NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( FALSE);
+ if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != ItemInfo.cbSize)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ RETURN( FALSE);
+ }
+ ItemInfo.hbmpItem = (HBITMAP)0;
+ RETURN( IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo));
}
- RETURN( IntInsertMenuItem(Menu, uItem, fByPosition, &ItemInfo));
+ SetLastNtError(Status);
+ RETURN( FALSE);
CLEANUP:
DPRINT("Leave NtUserInsertMenuItem, ret=%i\n",_ret_);
/*
- * @unimplemented
+ * @implemented
*/
BOOL STDCALL
NtUserGetMenuBarInfo(
LONG idItem,
PMENUBARINFO pmbi)
{
- UNIMPLEMENTED
+ BOOL Res = TRUE;
+ PMENU_OBJECT MenuObject;
+ PMENU_ITEM mi;
+ PWINDOW_OBJECT WindowObject;
+ HMENU hMenu;
+ POINT Offset;
+ RECT Rect;
+ MENUBARINFO kmbi;
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserGetMenuBarInfo\n");
+ UserEnterShared();
+
+ if (!(WindowObject = UserGetWindowObject(hwnd)))
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ RETURN(FALSE);
+ }
+
+ hMenu = (HMENU)WindowObject->IDMenu;
+
+ if (!(MenuObject = UserGetMenuObject(hMenu)))
+ {
+ SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+ RETURN(FALSE);
+ }
+
+ if (pmbi->cbSize != sizeof(MENUBARINFO))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ RETURN(FALSE);
+ }
+
+ kmbi.cbSize = sizeof(MENUBARINFO);
+ kmbi.fBarFocused = FALSE;
+ kmbi.fFocused = FALSE;
+ kmbi.hwndMenu = NULL;
+
+ switch (idObject)
+ {
+ case OBJID_MENU:
+ {
+ PMENU_OBJECT SubMenuObject;
+ kmbi.hMenu = hMenu;
+ if (idItem) /* Non-Zero-Based. */
+ {
+ if (IntGetMenuItemByFlag(MenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+ kmbi.rcBar = mi->Rect;
+ else
+ {
+ Res = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ /* If items is zero we assume info for the menu itself. */
+ if (!(IntGetClientOrigin(WindowObject, &Offset)))
+ {
+ Res = FALSE;
+ break;
+ }
+ Rect.left = Offset.x;
+ Rect.right = Offset.x + MenuObject->MenuInfo.Width;
+ Rect.top = Offset.y;
+ Rect.bottom = Offset.y + MenuObject->MenuInfo.Height;
+ kmbi.rcBar = Rect;
+ DPRINT("Rect top = %d bottom = %d left = %d right = %d \n",
+ Rect.top, Rect.bottom, Rect.left, Rect.right);
+ }
+ if (idItem)
+ {
+ if (idItem-1 == MenuObject->MenuInfo.FocusedItem)
+ kmbi.fFocused = TRUE;
+ }
+ if (MenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
+ kmbi.fBarFocused = TRUE;
+ SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
+ if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
+ DPRINT("OBJID_MENU, idItem = %d\n",idItem);
+ break;
+ }
+ case OBJID_CLIENT:
+ {
+ PMENU_OBJECT SubMenuObject, XSubMenuObject;
+ SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
+ if(SubMenuObject) kmbi.hMenu = SubMenuObject->MenuInfo.Self;
+ else
+ {
+ Res = FALSE;
+ DPRINT1("OBJID_CLIENT, No SubMenu!\n");
+ break;
+ }
+ if (idItem)
+ {
+ if (IntGetMenuItemByFlag(SubMenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+ kmbi.rcBar = mi->Rect;
+ else
+ {
+ Res = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ PWINDOW_OBJECT SubWinObj;
+ if (!(SubWinObj = UserGetWindowObject(SubMenuObject->MenuInfo.Wnd)))
+ {
+ Res = FALSE;
+ break;
+ }
+ if (!(IntGetClientOrigin(SubWinObj, &Offset)))
+ {
+ Res = FALSE;
+ break;
+ }
+ Rect.left = Offset.x;
+ Rect.right = Offset.x + SubMenuObject->MenuInfo.Width;
+ Rect.top = Offset.y;
+ Rect.bottom = Offset.y + SubMenuObject->MenuInfo.Height;
+ kmbi.rcBar = Rect;
+ }
+ if (idItem)
+ {
+ if (idItem-1 == SubMenuObject->MenuInfo.FocusedItem)
+ kmbi.fFocused = TRUE;
+ }
+ if (SubMenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
+ kmbi.fBarFocused = TRUE;
+ XSubMenuObject = UserGetMenuObject(SubMenuObject->MenuItemList->hSubMenu);
+ if (XSubMenuObject) kmbi.hwndMenu = XSubMenuObject->MenuInfo.Wnd;
+ DPRINT("OBJID_CLIENT, idItem = %d\n",idItem);
+ break;
+ }
+ case OBJID_SYSMENU:
+ {
+ PMENU_OBJECT SysMenuObject, SubMenuObject;
+ if(!(SysMenuObject = IntGetSystemMenu(WindowObject, FALSE, FALSE)))
+ {
+ Res = FALSE;
+ break;
+ }
+ kmbi.hMenu = SysMenuObject->MenuInfo.Self;
+ if (idItem)
+ {
+ if (IntGetMenuItemByFlag(SysMenuObject, idItem-1, MF_BYPOSITION, &mi, NULL) > -1)
+ kmbi.rcBar = mi->Rect;
+ else
+ {
+ Res = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ PWINDOW_OBJECT SysWinObj;
+ if (!(SysWinObj = UserGetWindowObject(SysMenuObject->MenuInfo.Wnd)))
+ {
+ Res = FALSE;
+ break;
+ }
+ if (!(IntGetClientOrigin(SysWinObj, &Offset)))
+ {
+ Res = FALSE;
+ break;
+ }
+ Rect.left = Offset.x;
+ Rect.right = Offset.x + SysMenuObject->MenuInfo.Width;
+ Rect.top = Offset.y;
+ Rect.bottom = Offset.y + SysMenuObject->MenuInfo.Height;
+ kmbi.rcBar = Rect;
+ }
+ if (idItem)
+ {
+ if (idItem-1 == SysMenuObject->MenuInfo.FocusedItem)
+ kmbi.fFocused = TRUE;
+ }
+ if (SysMenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
+ kmbi.fBarFocused = TRUE;
+ SubMenuObject = UserGetMenuObject(SysMenuObject->MenuItemList->hSubMenu);
+ if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
+ DPRINT("OBJID_SYSMENU, idItem = %d\n",idItem);
+ break;
+ }
+ default:
+ Res = FALSE;
+ DPRINT1("Unknown idObject = %d, idItem = %d\n",idObject,idItem);
+ }
+ if (Res)
+ {
+ NTSTATUS Status = MmCopyToCaller(pmbi, &kmbi, sizeof(MENUBARINFO));
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN(FALSE);
+ }
+ }
+ RETURN(Res);
- return 0;
+CLEANUP:
+ DPRINT("Leave NtUserGetMenuBarInfo, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
LPRECT lprcItem)
{
ROSMENUINFO mi;
- ROSMENUITEMINFO mii;
HWND referenceHwnd;
- LPPOINT lpPoints;
- LPRECT lpRect = NULL;
- POINT FromOffset;
- LONG XMove, YMove;
- ULONG i;
+ RECT Rect;
NTSTATUS Status;
PMENU_OBJECT Menu;
- PWINDOW_OBJECT ReferenceWnd;
+ PMENU_ITEM MenuItem;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserGetMenuItemRect\n");
RETURN(FALSE);
}
- if(!UserMenuItemInfo(Menu, uItem, MF_BYPOSITION, &mii, FALSE))
- RETURN( FALSE);
-
+ if (IntGetMenuItemByFlag(Menu, uItem, MF_BYPOSITION, &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;
+ referenceHwnd = mi.Wnd; /* Okay we found it, so now what do we do? */
}
if (lprcItem == NULL)
RETURN( FALSE);
- *lpRect = mii.Rect;
- lpPoints = (LPPOINT)lpRect;
-
- ReferenceWnd = UserGetWindowObject(referenceHwnd);
- if (!ReferenceWnd || !UserGetClientOrigin(ReferenceWnd, &FromOffset))
- {
- RETURN( FALSE);
- }
-
- XMove = FromOffset.x;
- YMove = FromOffset.y;
-
- for (i = 0; i < 2; i++)
- {
- lpPoints[i].x += XMove;
- lpPoints[i].y += YMove;
- }
- Status = MmCopyToCaller(lprcItem, lpPoints, sizeof(POINT));
+ Status = MmCopyToCaller(lprcItem, &Rect, sizeof(RECT));
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
return( FALSE);
}
if (sizeof(MENUITEMINFOW) != Size
- && sizeof(MENUITEMINFOW) - sizeof(HBITMAP) != Size
+ && FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != Size
&& sizeof(ROSMENUITEMINFO) != Size)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
}
/* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
set/get hbmpItem */
- if (sizeof(MENUITEMINFOW) - sizeof(HBITMAP) == Size
+ if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) == Size
&& 0 != (ItemInfo.fMask & MIIM_BITMAP))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);