Added some more menu functions

svn path=/trunk/; revision=5424
This commit is contained in:
Thomas Bluemel 2003-08-05 19:50:57 +00:00
parent 6295a1f99b
commit 0c3a60aa71
3 changed files with 223 additions and 124 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: menu.c,v 1.16 2003/08/05 15:41:03 weiden Exp $
/* $Id: menu.c,v 1.17 2003/08/05 19:50:57 weiden Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/menu.c
@ -476,7 +476,7 @@ CheckMenuRadioItem(HMENU hmenu,
HMENU STDCALL
CreateMenu(VOID)
{
return NtUserCreateMenu();
return NtUserCreateMenu();
}
@ -486,14 +486,8 @@ CreateMenu(VOID)
HMENU STDCALL
CreatePopupMenu(VOID)
{
HMENU hMenu;
PPOPUP_MENU Menu;
hMenu = CreateMenu();
Menu = MenuGetMenu(hMenu);
Menu->Flags |= MF_POPUP;
return (HMENU)Menu;
/* FIXME - add MF_POPUP style */
return NtUserCreateMenu();
}
@ -505,19 +499,7 @@ DeleteMenu(HMENU hMenu,
UINT uPosition,
UINT uFlags)
{
PMENUITEM Item;
Item = MenuFindItem(&hMenu, &uPosition, uFlags);
if (Item == NULL)
{
return(FALSE);
}
if (Item->TypeData & MF_POPUP)
{
DestroyMenu(Item->SubMenu);
}
RemoveMenu(hMenu, uPosition, uFlags | MF_BYPOSITION);
return(TRUE);
return NtUserDeleteMenu(hMenu, uPosition, uFlags);
}
VOID
@ -600,12 +582,13 @@ EndMenu(VOID)
/*
* @implemented
* @unimplemented
*/
HMENU STDCALL
GetMenu(HWND hWnd)
{
return((HMENU)GetWindowLong(hWnd, GWL_ID));
UNIMPLEMENTED;
return (HWND)0;
}
@ -683,37 +666,26 @@ GetMenuDefaultItem(HMENU hMenu,
/*
* @unimplemented
* @implemented
*/
WINBOOL STDCALL
GetMenuInfo(HMENU hmenu,
LPMENUINFO lpcmi)
{
PPOPUP_MENU Menu;
Menu = MenuGetMenu(hmenu);
if (lpcmi->fMask & MIM_BACKGROUND)
{
lpcmi->hbrBack = Menu->hbrBack;
}
if (lpcmi->fMask & MIM_HELPID)
{
lpcmi->dwContextHelpID = Menu->HelpId;
}
if (lpcmi->fMask & MIM_MAXHEIGHT)
{
lpcmi->cyMax = Menu->cyMax;
}
if (lpcmi->fMask & MIM_MENUDATA)
{
lpcmi->dwMenuData = Menu->MenuData;
}
if (lpcmi->fMask & MIM_STYLE)
{
lpcmi->dwStyle = Menu->Style;
}
return(TRUE);
MENUINFO mi;
BOOL res = FALSE;
if(!lpcmi || (lpcmi->cbSize != sizeof(MENUINFO)))
return FALSE;
RtlZeroMemory(&mi, sizeof(MENUINFO));
mi.cbSize = sizeof(MENUINFO);
mi.fMask = lpcmi->fMask;
res = NtUserMenuInfo(hmenu, &mi, FALSE);
memcpy(lpcmi, &mi, sizeof(MENUINFO));
return res;
}
@ -734,18 +706,20 @@ UINT STDCALL
GetMenuItemID(HMENU hMenu,
int nPos)
{
PMENUITEM Item;
Item = MenuFindItem(&hMenu, &nPos, MF_BYPOSITION);
if (Item == NULL)
{
return(0);
}
if (Item->TypeData & MF_POPUP)
{
return(-1);
}
return(Item->Id);
MENUITEMINFOW mii;
mii.cbSize = sizeof(MENUITEMINFOW);
mii.fMask = MIIM_ID | MIIM_SUBMENU;
if(!NtUserMenuItemInfo(hMenu, nPos, MF_BYPOSITION, &mii, FALSE))
{
return -1;
}
if(mii.hSubMenu) return -1;
if(mii.wID == 0) return -1;
return mii.wID;
}
@ -795,7 +769,7 @@ GetMenuItemRect(HWND hWnd,
/*
* @unimplemented
* @implemented
*/
UINT
STDCALL
@ -804,8 +778,29 @@ GetMenuState(
UINT uId,
UINT uFlags)
{
UNIMPLEMENTED;
return 0;
MENUITEMINFOW mii;
mii.cbSize = sizeof(MENUITEMINFOW);
mii.fMask = MIIM_STATE | MIIM_TYPE | MIIM_SUBMENU;
if(NtUserMenuItemInfo(hMenu, uId, uFlags, &mii, FALSE))
{
UINT nSubItems = 0;
if(mii.hSubMenu)
{
nSubItems = (UINT)NtUserBuildMenuItemList(mii.hSubMenu, NULL, 0, 0);
/* FIXME - ported from wine, does that work (0xff)? */
if(GetLastError() != ERROR_INVALID_HANDLE)
return (nSubItems << 8) | ((mii.fState | mii.fType) & 0xff);
return (UINT)-1; /* Invalid submenu */
}
/* FIXME - ported from wine, does that work? */
return (mii.fType | mii.fState);
}
return (UINT)-1;
}
@ -844,7 +839,7 @@ GetMenuStringW(
/*
* @unimplemented
* @implemented
*/
HMENU
STDCALL
@ -852,7 +847,13 @@ GetSubMenu(
HMENU hMenu,
int nPos)
{
UNIMPLEMENTED;
MENUITEMINFOW mi;
mi.cbSize = sizeof(MENUITEMINFO);
mi.fMask = MIIM_SUBMENU;
if(NtUserMenuItemInfo(hMenu, (UINT)nPos, MF_BYPOSITION, &mi, FALSE))
{
return mi.hSubMenu;
}
return (HMENU)0;
}
@ -890,7 +891,7 @@ InsertMenuA(
/*
* @unimplemented
* @implemented
*/
WINBOOL
STDCALL
@ -933,7 +934,7 @@ InsertMenuItemA(
/*
* @unimplemented
* @implemented
*/
WINBOOL
STDCALL
@ -960,7 +961,7 @@ InsertMenuItemW(
(MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData)
{
len = lstrlenW(lpmii->dwTypeData);
DbgPrint("InsertMenuItemW() len = %d\n", len);
mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR));
if(!mi.dwTypeData)
{
@ -970,11 +971,6 @@ InsertMenuItemW(
memcpy(&mi.dwTypeData, &lpmii->dwTypeData, len);
CleanHeap = TRUE;
mi.cch = len;
DbgPrint("InsertMenuItemW() Text = %ws\n", (PWSTR)mi.dwTypeData);
}
else
{
DbgPrint("InsertMenuItemW() No Text\n");
}
res = NtUserInsertMenuItem(hMenu, uItem, fByPosition, &mi);
@ -1003,15 +999,15 @@ InsertMenuW(
/*
* @unimplemented
* @implemented
*/
WINBOOL
STDCALL
IsMenu(
HMENU hMenu)
{
UNIMPLEMENTED;
return FALSE;
DWORD ret = NtUserBuildMenuItemList(hMenu, NULL, 0, 0);
return ((ret != -1) && (GetLastError() != ERROR_INVALID_HANDLE));
}
@ -1202,7 +1198,7 @@ SetMenu(HWND hWnd,
/*
* @unimplemented
* @implemented
*/
WINBOOL
STDCALL
@ -1211,13 +1207,12 @@ SetMenuDefaultItem(
UINT uItem,
UINT fByPos)
{
UNIMPLEMENTED;
return FALSE;
return NtUserSetMenuDefaultItem(hMenu, uItem, fByPos);
}
/*
* @unimplemented
* @implemented
*/
WINBOOL
STDCALL
@ -1225,8 +1220,13 @@ SetMenuInfo(
HMENU hmenu,
LPCMENUINFO lpcmi)
{
UNIMPLEMENTED;
return FALSE;
MENUINFO mi;
BOOL res = FALSE;
if(lpcmi->cbSize != sizeof(MENUINFO))
return res;
memcpy(&mi, lpcmi, sizeof(MENUINFO));
return NtUserMenuInfo(hmenu, &mi, TRUE);
}
@ -1317,7 +1317,7 @@ TrackPopupMenuEx(
/*
* @unimplemented
* @implemented
*/
WINBOOL
STDCALL
@ -1329,14 +1329,21 @@ SetMenuContextHelpId(HMENU hmenu,
/*
* @unimplemented
* @implemented
*/
DWORD
STDCALL
GetMenuContextHelpId(HMENU hmenu)
{
UNIMPLEMENTED;
return(0);
MENUINFO mi;
mi.cbSize = sizeof(MENUINFO);
mi.fMask = MIM_HELPID;
if(NtUserMenuInfo(hmenu, &mi, FALSE))
{
return mi.dwContextHelpID;
}
return 0;
}

View file

@ -30,12 +30,8 @@ typedef struct _MENU_OBJECT
int MenuItemCount;
FAST_MUTEX MenuItemsLock;
PMENU_ITEM MenuItemList;
MENUINFO MenuInfo;
BOOL RtoL;
DWORD dwStyle;
UINT cyMax;
HBRUSH hbrBack;
DWORD dwContextHelpID;
ULONG_PTR dwMenuData;
} MENU_OBJECT, *PMENU_OBJECT;
NTSTATUS FASTCALL
@ -211,4 +207,5 @@ NtUserTrackPopupMenuEx(
#endif /* __WIN32K_MENU_H */
/* EOF */
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: menu.c,v 1.8 2003/08/05 15:41:03 weiden Exp $
/* $Id: menu.c,v 1.9 2003/08/05 19:50:57 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -85,6 +85,7 @@
ExFreePool((MenuItem).dwTypeData); \
(MenuItem).dwTypeData = 0; \
(MenuItem).cch = 0; \
DbgPrint("FreeMenuText(): Deleted menu text\n"); \
} \
}
@ -145,9 +146,9 @@ W32kGetMenuObject(HMENU hMenu)
WindowStation->HandleTable, hMenu, otMenu,
(PVOID*)&MenuObject);
if (!NT_SUCCESS(Status))
{
return(NULL);
}
{
return NULL;
}
return MenuObject;
}
@ -157,6 +158,40 @@ W32kReleaseMenuObject(PMENU_OBJECT MenuObject)
ObmDereferenceObject(MenuObject);
}
BOOL FASTCALL
W32kFreeMenuItem(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem,
BOOL RemoveFromList, BOOL bRecurse)
{
if(MenuItem)
{
FreeMenuText(MenuItem->MenuItem);
if(RemoveFromList)
{
/* FIXME - Remove from List */
MenuObject->MenuItemCount--;
}
}
return FALSE;
}
UINT FASTCALL
W32kDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse)
{
UINT res = 0;
PMENU_ITEM NextItem;
PMENU_ITEM CurItem = MenuObject->MenuItemList;
while(CurItem)
{
NextItem = CurItem->Next;
W32kFreeMenuItem(MenuObject, CurItem, FALSE, bRecurse);
CurItem = NextItem;
res++;
}
MenuObject->MenuItemCount = 0;
MenuObject->MenuItemList = NULL;
return res;
}
BOOL FASTCALL
W32kDestroyMenuObject(PMENU_OBJECT MenuObject)
{
@ -164,8 +199,7 @@ W32kDestroyMenuObject(PMENU_OBJECT MenuObject)
{
/* remove all menu items */
ExAcquireFastMutexUnsafe (&MenuObject->MenuItemsLock);
//RemoveEntryList(&MenuObject->MenuItemsHead);
// FIXME Delete entries
W32kDeleteMenuItems(MenuObject, FALSE); /* do not destroy submenus */
ExReleaseFastMutexUnsafe (&MenuObject->MenuItemsLock);
W32kReleaseMenuObject(MenuObject);
@ -192,14 +226,15 @@ W32kCreateMenu(PHANDLE Handle)
MenuObject->Self = *Handle;
MenuObject->RtoL = FALSE; /* default */
MenuObject->dwStyle = 0; /* FIXME */
MenuObject->cyMax = 0; /* default */
MenuObject->hbrBack = W32kGetSysColorBrush(COLOR_MENU); /*default background color */
MenuObject->dwContextHelpID = 0; /* default */
MenuObject->dwMenuData = 0; /* default */
MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */
MenuObject->MenuInfo.fMask = 0; /* not used */
MenuObject->MenuInfo.dwStyle = 0; /* FIXME */
MenuObject->MenuInfo.cyMax = 0; /* default */
MenuObject->MenuInfo.hbrBack = W32kGetSysColorBrush(COLOR_MENU); /*default background color */
MenuObject->MenuInfo.dwContextHelpID = 0; /* default */
MenuObject->MenuInfo.dwMenuData = 0; /* default */
MenuObject->MenuItemCount = 0;
//InitializeListHead(&MenuObject->MenuItemsHead);
MenuObject->MenuItemList = NULL;
ExInitializeFastMutex(&MenuObject->MenuItemsLock);
@ -222,7 +257,7 @@ W32kSetMenuContextHelpId(PMENU_OBJECT MenuObject, DWORD dwContextHelpId)
{
if(MenuObject)
{
MenuObject->dwContextHelpID = dwContextHelpId;
MenuObject->MenuInfo.dwContextHelpID = dwContextHelpId;
return TRUE;
}
return FALSE;
@ -234,15 +269,15 @@ W32kGetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi)
if(MenuObject)
{
if(lpmi->fMask & MIM_BACKGROUND)
lpmi->hbrBack = MenuObject->hbrBack;
lpmi->hbrBack = MenuObject->MenuInfo.hbrBack;
if(lpmi->fMask & MIM_HELPID)
lpmi->dwContextHelpID = MenuObject->dwContextHelpID;
lpmi->dwContextHelpID = MenuObject->MenuInfo.dwContextHelpID;
if(lpmi->fMask & MIM_MAXHEIGHT)
lpmi->cyMax = MenuObject->cyMax;
lpmi->cyMax = MenuObject->MenuInfo.cyMax;
if(lpmi->fMask & MIM_MENUDATA)
lpmi->dwMenuData = MenuObject->dwMenuData;
lpmi->dwMenuData = MenuObject->MenuInfo.dwMenuData;
if(lpmi->fMask & MIM_STYLE)
lpmi->dwStyle = MenuObject->dwStyle;
lpmi->dwStyle = MenuObject->MenuInfo.dwStyle;
return TRUE;
}
return FALSE;
@ -254,15 +289,15 @@ W32kSetMenuInfo(PMENU_OBJECT MenuObject, LPMENUINFO lpmi)
if(MenuObject)
{
if(lpmi->fMask & MIM_BACKGROUND)
MenuObject->hbrBack = lpmi->hbrBack;
MenuObject->MenuInfo.hbrBack = lpmi->hbrBack;
if(lpmi->fMask & MIM_HELPID)
MenuObject->dwContextHelpID = lpmi->dwContextHelpID;
MenuObject->MenuInfo.dwContextHelpID = lpmi->dwContextHelpID;
if(lpmi->fMask & MIM_MAXHEIGHT)
MenuObject->cyMax = lpmi->cyMax;
MenuObject->MenuInfo.cyMax = lpmi->cyMax;
if(lpmi->fMask & MIM_MENUDATA)
lpmi->dwMenuData = MenuObject->dwMenuData;
MenuObject->MenuInfo.dwMenuData = lpmi->dwMenuData;
if(lpmi->fMask & MIM_STYLE)
lpmi->dwStyle = MenuObject->dwStyle;
MenuObject->MenuInfo.dwStyle = lpmi->dwStyle;
if(lpmi->fMask & MIM_APPLYTOSUBMENUS)
{
/* FIXME */
@ -318,6 +353,7 @@ W32kGetMenuItemByFlag(PMENU_OBJECT MenuObject, UINT uSearchBy, UINT fFlag, PMENU
return -1;
}
int FASTCALL
W32kInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
{
@ -382,7 +418,7 @@ W32kInsertMenuItemToList(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, int pos)
}
BOOL FASTCALL
W32kSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPMENUITEMINFOW lpmii)
W32kSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPCMENUITEMINFOW lpmii)
{
if(!MenuItem || !MenuObject || !lpmii)
{
@ -454,7 +490,7 @@ W32kSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, LPMENUITEMINFO
BOOL FASTCALL
W32kInsertMenuItem(PMENU_OBJECT MenuObject, UINT uItem, WINBOOL fByPosition,
LPMENUITEMINFOW lpmii)
LPCMENUITEMINFOW lpmii)
{
int pos = (int)uItem;
PMENU_ITEM MenuItem;
@ -608,9 +644,57 @@ W32kHiliteMenuItem(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject,
MenuItem->MenuItem.fState ^= MF_HILITE;
}
/* FIXME - update the window's menu */
return TRUE;
}
BOOL FASTCALL
W32kSetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT uItem, UINT fByPos)
{
BOOL ret = FALSE;
PMENU_ITEM MenuItem = MenuObject->MenuItemList;
if(fByPos)
{
UINT pos = 0;
while(MenuItem)
{
if(pos == uItem)
{
if(!(MenuItem->MenuItem.fState & MFS_DEFAULT))
MenuItem->MenuItem.fState |= MFS_DEFAULT;
ret = TRUE;
}
else
{
if(MenuItem->MenuItem.fState & MFS_DEFAULT)
MenuItem->MenuItem.fState ^= MFS_DEFAULT;
}
pos++;
MenuItem = MenuItem->Next;
}
}
else
{
while(MenuItem)
{
if(!ret && (MenuItem->MenuItem.wID == uItem))
{
if(!(MenuItem->MenuItem.fState & MFS_DEFAULT))
MenuItem->MenuItem.fState |= MFS_DEFAULT;
ret = TRUE;
}
else
{
if(MenuItem->MenuItem.fState & MFS_DEFAULT)
MenuItem->MenuItem.fState ^= MFS_DEFAULT;
}
MenuItem = MenuItem->Next;
}
}
return ret;
}
/* FUNCTIONS *****************************************************************/
@ -850,7 +934,7 @@ NtUserGetMenuItemRect(
/*
* @unimplemented
* @implemented
*/
BOOL STDCALL
NtUserHiliteMenuItem(
@ -997,7 +1081,7 @@ NtUserSetMenuContextHelpId(
/*
* @unimplemented
* @implemented
*/
BOOL STDCALL
NtUserSetMenuDefaultItem(
@ -1005,9 +1089,20 @@ NtUserSetMenuDefaultItem(
UINT uItem,
UINT fByPos)
{
UNIMPLEMENTED
BOOL res = FALSE;
PMENU_OBJECT MenuObject;
MenuObject = W32kGetMenuObject(hMenu);
if(!MenuObject)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
res = W32kSetMenuDefaultItem(MenuObject, uItem, fByPos);
ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
W32kReleaseMenuObject(MenuObject);
return 0;
return res;
}