2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: menu.c,v 1.17 2003/08/18 14:09:13 weiden Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
24 * FILE: subsys/win32k/ntuser/menu.c
25 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
27 * 07/30/2003 CSH Created
29 /* INCLUDES ******************************************************************/
31 #include <ddk/ntddk.h>
32 #include <win32k/win32k.h>
33 #include <napi/win32.h>
34 #include <include/menu.h>
35 #include <include/error.h>
36 #include <include/winsta.h>
37 #include <include/object.h>
38 #include <include/guicheck.h>
39 #include <include/window.h>
40 #include <include/color.h>
45 /* INTERNAL ******************************************************************/
47 /* maximum number of menu items a menu can contain */
48 #define MAX_MENU_ITEMS (0x4000)
51 #define MIIM_STRING (0x00000040)
54 #define MIIM_BITMAP (0x00000080)
57 #define MIIM_FTYPE (0x00000100)
61 #define UpdateMenuItemState(state, change) \
63 if((change) & MFS_DISABLED) { \
64 if(!((state) & MFS_DISABLED)) (state) |= MFS_DISABLED; \
66 if((state) & MFS_DISABLED) (state) ^= MFS_DISABLED; \
68 if((change) & MFS_CHECKED) { \
69 if(!((state) & MFS_CHECKED)) (state) |= MFS_CHECKED; \
71 if((state) & MFS_CHECKED) (state) ^= MFS_CHECKED; \
73 if((change) & MFS_HILITE) { \
74 if(!((state) & MFS_HILITE)) (state) |= MFS_HILITE; \
76 if((state) & MFS_HILITE) (state) ^= MFS_HILITE; \
80 #define FreeMenuText(MenuItem) \
82 if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
83 (MenuItem)->dwTypeData) { \
84 ExFreePool((MenuItem)->dwTypeData); \
85 (MenuItem)->dwTypeData = 0; \
86 (MenuItem)->cch = 0; \
93 return(STATUS_SUCCESS
);
99 return(STATUS_SUCCESS
);
104 DumpMenuItemList(PMENU_ITEM MenuItem
)
109 if(MenuItem
->dwTypeData
)
110 DbgPrint(" %d. %ws\n", ++cnt
, (LPWSTR
)MenuItem
->dwTypeData
);
112 DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt
, MenuItem
->dwTypeData
);
114 if(MFT_BITMAP
& MenuItem
->fType
) DbgPrint("MFT_BITMAP ");
115 if(MFT_MENUBARBREAK
& MenuItem
->fType
) DbgPrint("MFT_MENUBARBREAK ");
116 if(MFT_MENUBREAK
& MenuItem
->fType
) DbgPrint("MFT_MENUBREAK ");
117 if(MFT_OWNERDRAW
& MenuItem
->fType
) DbgPrint("MFT_OWNERDRAW ");
118 if(MFT_RADIOCHECK
& MenuItem
->fType
) DbgPrint("MFT_RADIOCHECK ");
119 if(MFT_RIGHTJUSTIFY
& MenuItem
->fType
) DbgPrint("MFT_RIGHTJUSTIFY ");
120 if(MFT_SEPARATOR
& MenuItem
->fType
) DbgPrint("MFT_SEPARATOR ");
121 if(MFT_STRING
& MenuItem
->fType
) DbgPrint("MFT_STRING ");
122 DbgPrint("\n fState=");
123 if(MFS_DISABLED
& MenuItem
->fState
) DbgPrint("MFS_DISABLED ");
124 else DbgPrint("MFS_ENABLED ");
125 if(MFS_CHECKED
& MenuItem
->fState
) DbgPrint("MFS_CHECKED ");
126 else DbgPrint("MFS_UNCHECKED ");
127 if(MFS_HILITE
& MenuItem
->fState
) DbgPrint("MFS_HILITE ");
128 else DbgPrint("MFS_UNHILITE ");
129 if(MFS_DEFAULT
& MenuItem
->fState
) DbgPrint("MFS_DEFAULT ");
130 if(MFS_GRAYED
& MenuItem
->fState
) DbgPrint("MFS_GRAYED ");
131 DbgPrint("\n wId=%d\n", MenuItem
->wID
);
132 MenuItem
= MenuItem
->Next
;
134 DbgPrint("Entries: %d\n", cnt
);
139 PMENU_OBJECT FASTCALL
140 W32kGetMenuObject(HMENU hMenu
)
142 PMENU_OBJECT MenuObject
;
143 NTSTATUS Status
= ObmReferenceObjectByHandle(PsGetWin32Process()->
144 WindowStation
->HandleTable
, hMenu
, otMenu
,
145 (PVOID
*)&MenuObject
);
146 if (!NT_SUCCESS(Status
))
154 W32kReleaseMenuObject(PMENU_OBJECT MenuObject
)
156 ObmDereferenceObject(MenuObject
);
160 W32kFreeMenuItem(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
,
161 BOOL RemoveFromList
, BOOL bRecurse
)
163 FreeMenuText(MenuItem
);
166 /* FIXME - Remove from List */
167 MenuObject
->MenuItemCount
--;
169 if(bRecurse
&& MenuItem
->hSubMenu
)
171 PMENU_OBJECT SubMenuObject
;
172 SubMenuObject
= (PMENU_OBJECT
)W32kGetWindowObject(
173 MenuItem
->hSubMenu
);
176 W32kDestroyMenuObject(SubMenuObject
, bRecurse
);
181 ExFreePool(MenuItem
);
187 W32kRemoveMenuItem(PMENU_OBJECT MenuObject
, UINT uPosition
, UINT uFlags
,
190 PMENU_ITEM PrevMenuItem
, MenuItem
;
191 if(W32kGetMenuItemByFlag(MenuObject
, uPosition
, uFlags
, &MenuItem
,
197 PrevMenuItem
->Next
= MenuItem
->Next
;
200 MenuObject
->MenuItemList
= MenuItem
->Next
;
202 return W32kFreeMenuItem(MenuObject
, MenuItem
, TRUE
, bRecurse
);
209 W32kDeleteMenuItems(PMENU_OBJECT MenuObject
, BOOL bRecurse
)
213 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
216 NextItem
= CurItem
->Next
;
217 W32kFreeMenuItem(MenuObject
, CurItem
, FALSE
, bRecurse
);
221 MenuObject
->MenuItemCount
= 0;
222 MenuObject
->MenuItemList
= NULL
;
227 W32kDestroyMenuObject(PMENU_OBJECT MenuObject
, BOOL bRecurse
)
229 PW32PROCESS W32Process
;
233 W32Process
= PsGetWin32Process();
234 /* remove all menu items */
235 ExAcquireFastMutexUnsafe (&MenuObject
->MenuItemsLock
);
236 W32kDeleteMenuItems(MenuObject
, bRecurse
); /* do not destroy submenus */
237 ExReleaseFastMutexUnsafe (&MenuObject
->MenuItemsLock
);
239 ExAcquireFastMutexUnsafe(&W32Process
->MenuListLock
);
240 RemoveEntryList(&MenuObject
->ListEntry
);
241 ExReleaseFastMutexUnsafe(&W32Process
->MenuListLock
);
243 W32kReleaseMenuObject(MenuObject
); // needed?
245 ObmCloseHandle(W32Process
->WindowStation
->HandleTable
, MenuObject
->Self
);
252 PMENU_OBJECT FASTCALL
253 W32kCreateMenu(PHANDLE Handle
)
255 PW32PROCESS Win32Process
= PsGetWin32Process();
257 PMENU_OBJECT MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
258 Win32Process
->WindowStation
->HandleTable
, Handle
,
259 otMenu
, sizeof(MENU_OBJECT
));
267 MenuObject
->Self
= *Handle
;
268 MenuObject
->RtoL
= FALSE
; /* default */
269 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
270 MenuObject
->MenuInfo
.fMask
= 0; /* not used */
271 MenuObject
->MenuInfo
.dwStyle
= 0; /* FIXME */
272 MenuObject
->MenuInfo
.cyMax
= 0; /* default */
273 MenuObject
->MenuInfo
.hbrBack
= W32kGetSysColorBrush(COLOR_MENU
); /*default background color */
274 MenuObject
->MenuInfo
.dwContextHelpID
= 0; /* default */
275 MenuObject
->MenuInfo
.dwMenuData
= 0; /* default */
277 MenuObject
->MenuItemCount
= 0;
278 MenuObject
->MenuItemList
= NULL
;
279 ExInitializeFastMutex(&MenuObject
->MenuItemsLock
);
281 /* Insert menu item into process menu handle list */
282 ExAcquireFastMutexUnsafe (&Win32Process
->MenuListLock
);
283 InsertTailList (&Win32Process
->MenuListHead
, &MenuObject
->ListEntry
);
284 ExReleaseFastMutexUnsafe (&Win32Process
->MenuListLock
);
290 W32kSetMenuFlagRtoL(PMENU_OBJECT MenuObject
)
294 MenuObject
->RtoL
= TRUE
;
301 W32kSetMenuContextHelpId(PMENU_OBJECT MenuObject
, DWORD dwContextHelpId
)
305 MenuObject
->MenuInfo
.dwContextHelpID
= dwContextHelpId
;
312 W32kGetMenuInfo(PMENU_OBJECT MenuObject
, LPMENUINFO lpmi
)
316 if(lpmi
->fMask
& MIM_BACKGROUND
)
317 lpmi
->hbrBack
= MenuObject
->MenuInfo
.hbrBack
;
318 if(lpmi
->fMask
& MIM_HELPID
)
319 lpmi
->dwContextHelpID
= MenuObject
->MenuInfo
.dwContextHelpID
;
320 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
321 lpmi
->cyMax
= MenuObject
->MenuInfo
.cyMax
;
322 if(lpmi
->fMask
& MIM_MENUDATA
)
323 lpmi
->dwMenuData
= MenuObject
->MenuInfo
.dwMenuData
;
324 if(lpmi
->fMask
& MIM_STYLE
)
325 lpmi
->dwStyle
= MenuObject
->MenuInfo
.dwStyle
;
332 W32kSetMenuInfo(PMENU_OBJECT MenuObject
, LPMENUINFO lpmi
)
336 if(lpmi
->fMask
& MIM_BACKGROUND
)
337 MenuObject
->MenuInfo
.hbrBack
= lpmi
->hbrBack
;
338 if(lpmi
->fMask
& MIM_HELPID
)
339 MenuObject
->MenuInfo
.dwContextHelpID
= lpmi
->dwContextHelpID
;
340 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
341 MenuObject
->MenuInfo
.cyMax
= lpmi
->cyMax
;
342 if(lpmi
->fMask
& MIM_MENUDATA
)
343 MenuObject
->MenuInfo
.dwMenuData
= lpmi
->dwMenuData
;
344 if(lpmi
->fMask
& MIM_STYLE
)
345 MenuObject
->MenuInfo
.dwStyle
= lpmi
->dwStyle
;
346 if(lpmi
->fMask
& MIM_APPLYTOSUBMENUS
)
357 W32kGetMenuItemByFlag(PMENU_OBJECT MenuObject
, UINT uSearchBy
, UINT fFlag
,
358 PMENU_ITEM
*MenuItem
, PMENU_ITEM
*PrevMenuItem
)
360 PMENU_ITEM PrevItem
= NULL
;
361 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
363 if(MF_BYPOSITION
& fFlag
)
366 while(CurItem
&& (p
> 0))
369 CurItem
= CurItem
->Next
;
374 if(MenuItem
) *MenuItem
= CurItem
;
375 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
379 if(MenuItem
) *MenuItem
= NULL
;
380 if(PrevMenuItem
) *PrevMenuItem
= NULL
; /* ? */
384 return uSearchBy
- p
;
391 if(CurItem
->wID
== uSearchBy
)
393 if(MenuItem
) *MenuItem
= CurItem
;
394 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
398 CurItem
= CurItem
->Next
;
407 W32kInsertMenuItemToList(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, int pos
)
410 PMENU_ITEM LastItem
= NULL
;
413 CurItem
= MenuObject
->MenuItemList
;
419 CurItem
= CurItem
->Next
;
425 while(CurItem
&& (pos
> 0))
428 CurItem
= CurItem
->Next
;
438 /* insert the item before CurItem */
439 MenuItem
->Next
= LastItem
->Next
;
440 LastItem
->Next
= MenuItem
;
444 /* insert at the beginning */
445 MenuObject
->MenuItemList
= MenuItem
;
446 MenuItem
->Next
= CurItem
;
453 /* insert at the end */
454 LastItem
->Next
= MenuItem
;
455 MenuItem
->Next
= NULL
;
459 /* insert first item */
460 MenuObject
->MenuItemList
= MenuItem
;
461 MenuItem
->Next
= NULL
;
464 MenuObject
->MenuItemCount
++;
470 W32kSetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, LPCMENUITEMINFOW lpmii
)
472 if(!MenuItem
|| !MenuObject
|| !lpmii
)
477 /*if((MenuItem->fMask & (MIIM_TYPE | MIIM_STRING)) &&
478 (MENU_ITEM_TYPE(MenuItem->fType) == MF_STRING) &&
479 MenuItem->dwTypeData)
482 ExFreePool(MenuItem->dwTypeData);
483 MenuItem->dwTypeData = 0;
487 MenuItem
->fType
= lpmii
->fType
;
488 MenuItem
->cch
= lpmii
->cch
;
490 if(lpmii
->fMask
& MIIM_BITMAP
)
492 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
494 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
496 MenuItem
->hbmpChecked
= lpmii
->hbmpChecked
;
497 MenuItem
->hbmpUnchecked
= lpmii
->hbmpUnchecked
;
499 if(lpmii
->fMask
& MIIM_DATA
)
501 MenuItem
->dwItemData
= lpmii
->dwItemData
;
503 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
505 MenuItem
->fType
= lpmii
->fType
;
507 if(lpmii
->fMask
& MIIM_ID
)
509 MenuItem
->wID
= lpmii
->wID
;
511 if(lpmii
->fMask
& MIIM_STATE
)
513 UpdateMenuItemState(MenuItem
->fState
, lpmii
->fState
);
514 /* FIXME - only one item can have MFS_DEFAULT */
517 if(lpmii
->fMask
& MIIM_SUBMENU
)
519 MenuItem
->hSubMenu
= lpmii
->hSubMenu
;
521 if((lpmii
->fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
522 (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
) && lpmii
->dwTypeData
)
524 FreeMenuText(MenuItem
);
525 MenuItem
->dwTypeData
= (LPWSTR
)ExAllocatePool(PagedPool
, (lpmii
->cch
+ 1) * sizeof(WCHAR
));
526 if(!MenuItem
->dwTypeData
)
529 /* FIXME Set last error code? */
530 SetLastWin32Error(STATUS_NO_MEMORY
);
533 MenuItem
->cch
= lpmii
->cch
;
534 memcpy(MenuItem
->dwTypeData
, lpmii
->dwTypeData
, (lpmii
->cch
+ 1) * sizeof(WCHAR
));
541 W32kInsertMenuItem(PMENU_OBJECT MenuObject
, UINT uItem
, WINBOOL fByPosition
,
542 LPCMENUITEMINFOW lpmii
)
544 int pos
= (int)uItem
;
547 if(MenuObject
->MenuItemCount
>= MAX_MENU_ITEMS
)
549 /* FIXME Set last error code? */
550 SetLastWin32Error(STATUS_NO_MEMORY
);
556 /* calculate position */
557 if(pos
> MenuObject
->MenuItemCount
)
558 pos
= MenuObject
->MenuItemCount
;
562 pos
= W32kGetMenuItemByFlag(MenuObject
, uItem
, MF_BYCOMMAND
, NULL
, NULL
);
564 if(pos
< -1) pos
= -1;
566 MenuItem
= ExAllocatePool(PagedPool
, sizeof(MENU_ITEM
));
569 /* FIXME Set last error code? */
570 SetLastWin32Error(STATUS_NO_MEMORY
);
574 MenuItem
->fType
= MFT_STRING
;
575 MenuItem
->fState
= MFS_ENABLED
| MFS_UNCHECKED
;
577 MenuItem
->hSubMenu
= (HMENU
)0;
578 MenuItem
->hbmpChecked
= (HBITMAP
)0;
579 MenuItem
->hbmpUnchecked
= (HBITMAP
)0;
580 MenuItem
->dwItemData
= (ULONG_PTR
)NULL
;
582 MenuItem
->hbmpItem
= (HBITMAP
)0;
584 if(!W32kSetMenuItemInfo(MenuObject
, MenuItem
, lpmii
))
586 ExFreePool(MenuItem
);
590 pos
= W32kInsertMenuItemToList(MenuObject
, MenuItem
, pos
);
596 W32kEnableMenuItem(PMENU_OBJECT MenuObject
, UINT uIDEnableItem
, UINT uEnable
)
599 UINT res
= W32kGetMenuItemByFlag(MenuObject
, uIDEnableItem
, uEnable
, &MenuItem
, NULL
);
600 if(!MenuItem
|| (res
== (UINT
)-1))
605 res
= MenuItem
->fState
& (MF_GRAYED
| MF_DISABLED
);
607 if(uEnable
& MF_DISABLED
)
609 if(!(MenuItem
->fState
& MF_DISABLED
))
610 MenuItem
->fState
|= MF_DISABLED
;
611 if(uEnable
& MF_GRAYED
)
613 if(!(MenuItem
->fState
& MF_GRAYED
))
614 MenuItem
->fState
|= MF_GRAYED
;
619 if(uEnable
& MF_GRAYED
)
621 if(!(MenuItem
->fState
& MF_GRAYED
))
622 MenuItem
->fState
|= MF_GRAYED
;
623 if(!(MenuItem
->fState
& MF_DISABLED
))
624 MenuItem
->fState
|= MF_DISABLED
;
628 if(MenuItem
->fState
& MF_DISABLED
)
629 MenuItem
->fState
^= MF_DISABLED
;
630 if(MenuItem
->fState
& MF_GRAYED
)
631 MenuItem
->fState
^= MF_GRAYED
;
640 W32kBuildMenuItemList(PMENU_OBJECT MenuObject, MENUITEMINFOW *lpmiil, ULONG nMax)
643 PMENU_ITEM CurItem = MenuObject->MenuItemList;
644 while(CurItem && (nMax > 0))
646 memcpy(&lpmiil[Index], &CurItem->MenuItem, sizeof(MENUITEMINFOW));
647 CurItem = CurItem->Next;
656 W32kCheckMenuItem(PMENU_OBJECT MenuObject
, UINT uIDCheckItem
, UINT uCheck
)
661 if((W32kGetMenuItemByFlag(MenuObject
, uIDCheckItem
, uCheck
, &MenuItem
, NULL
) < 0) || !MenuItem
)
666 res
= (DWORD
)(MenuItem
->fState
& MF_CHECKED
);
667 if(uCheck
& MF_CHECKED
)
669 if(!(MenuItem
->fState
& MF_CHECKED
))
670 MenuItem
->fState
|= MF_CHECKED
;
674 if(MenuItem
->fState
& MF_CHECKED
)
675 MenuItem
->fState
^= MF_CHECKED
;
682 W32kHiliteMenuItem(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
,
683 UINT uItemHilite
, UINT uHilite
)
686 BOOL res
= W32kGetMenuItemByFlag(MenuObject
, uItemHilite
, uHilite
, &MenuItem
, NULL
);
687 if(!MenuItem
|| !res
)
692 if(uHilite
& MF_HILITE
)
694 if(!(MenuItem
->fState
& MF_HILITE
))
695 MenuItem
->fState
|= MF_HILITE
;
699 if(MenuItem
->fState
& MF_HILITE
)
700 MenuItem
->fState
^= MF_HILITE
;
703 /* FIXME - update the window's menu */
709 W32kSetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT uItem
, UINT fByPos
)
712 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
720 if(!(MenuItem
->fState
& MFS_DEFAULT
))
721 MenuItem
->fState
|= MFS_DEFAULT
;
726 if(MenuItem
->fState
& MFS_DEFAULT
)
727 MenuItem
->fState
^= MFS_DEFAULT
;
730 MenuItem
= MenuItem
->Next
;
737 if(!ret
&& (MenuItem
->wID
== uItem
))
739 if(!(MenuItem
->fState
& MFS_DEFAULT
))
740 MenuItem
->fState
|= MFS_DEFAULT
;
745 if(MenuItem
->fState
& MFS_DEFAULT
)
746 MenuItem
->fState
^= MFS_DEFAULT
;
748 MenuItem
= MenuItem
->Next
;
755 * Internal function. Called when the process is destroyed to free the remaining menu handles.
758 W32kCleanupMenus(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
760 PEPROCESS CurrentProcess
;
761 PLIST_ENTRY LastHead
= NULL
;
762 PMENU_OBJECT MenuObject
;
764 CurrentProcess
= PsGetCurrentProcess();
765 if (CurrentProcess
!= Process
)
767 KeAttachProcess(Process
);
770 ExAcquireFastMutexUnsafe(&Win32Process
->MenuListLock
);
771 while (Win32Process
->MenuListHead
.Flink
!= &(Win32Process
->MenuListHead
) &&
772 Win32Process
->MenuListHead
.Flink
!= LastHead
)
774 LastHead
= Win32Process
->MenuListHead
.Flink
;
775 MenuObject
= CONTAINING_RECORD(Win32Process
->MenuListHead
.Flink
, MENU_OBJECT
, ListEntry
);
777 ExReleaseFastMutexUnsafe(&Win32Process
->MenuListLock
);
778 W32kDestroyMenuObject(MenuObject
, FALSE
);
779 ExAcquireFastMutexUnsafe(&Win32Process
->MenuListLock
);
781 ExReleaseFastMutexUnsafe(&Win32Process
->MenuListLock
);
783 if (CurrentProcess
!= Process
)
790 /* FUNCTIONS *****************************************************************/
798 NtUserBuildMenuItemList(
800 LPCMENUITEMINFOW
* lpmiil
,
805 PMENU_OBJECT MenuObject
= W32kGetMenuObject(hMenu
);
808 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
814 /* FIXME need to pass the menu strings to user32 somehow....
816 ExAcquireFastMutexUnsafe(&MenuObject->MenuItemsLock);
817 res = W32kBuildMenuItemList(MenuObject, lpmiil, nBufSize / sizeof(LPCMENUITEMINFO));
818 ExReleaseFastMutexUnsafe(&MenuObject->MenuItemsLock);
823 res
= MenuObject
->MenuItemCount
;
826 W32kReleaseMenuObject(MenuObject
);
842 PMENU_OBJECT MenuObject
= W32kGetMenuObject(hmenu
);
845 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
848 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
849 res
= W32kCheckMenuItem(MenuObject
, uIDCheckItem
, uCheck
);
850 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
851 W32kReleaseMenuObject(MenuObject
);
860 NtUserCreateMenu(VOID
)
862 PWINSTATION_OBJECT WinStaObject
;
865 NTSTATUS Status
= ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
870 if (!NT_SUCCESS(Status
))
872 DPRINT("Validation of window station handle (0x%X) failed\n",
873 PROCESS_WINDOW_STATION());
874 SetLastWin32Error(Status
);
878 W32kCreateMenu(&Handle
);
879 ObDereferenceObject(WinStaObject
);
880 return (HMENU
)Handle
;
894 PMENU_OBJECT MenuObject
= W32kGetMenuObject(hMenu
);
897 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
901 res
= W32kRemoveMenuItem(MenuObject
, uPosition
, uFlags
, TRUE
);
902 W32kReleaseMenuObject(MenuObject
);
915 /* FIXME, check if menu belongs to the process */
917 PMENU_OBJECT MenuObject
= W32kGetMenuObject(hMenu
);
920 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
924 return W32kDestroyMenuObject(MenuObject
, FALSE
);
932 NtUserEnableMenuItem(
938 PMENU_OBJECT MenuObject
;
939 MenuObject
= W32kGetMenuObject(hMenu
);
942 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
945 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
946 res
= W32kEnableMenuItem(MenuObject
, uIDEnableItem
, uEnable
);
947 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
948 W32kReleaseMenuObject(MenuObject
);
958 NtUserInsertMenuItem(
962 LPCMENUITEMINFOW lpmii
)
965 PMENU_OBJECT MenuObject
;
966 MenuObject
= W32kGetMenuObject(hMenu
);
969 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
972 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
973 res
= W32kInsertMenuItem(MenuObject
, uItem
, fByPosition
, lpmii
);
974 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
975 W32kReleaseMenuObject(MenuObject
);
996 NtUserGetMenuBarInfo(
1026 NtUserGetMenuItemRect(
1042 NtUserHiliteMenuItem(
1049 PMENU_OBJECT MenuObject
;
1050 PWINDOW_OBJECT WindowObject
= W32kGetWindowObject(hwnd
);
1053 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1056 MenuObject
= W32kGetMenuObject(hmenu
);
1059 W32kReleaseWindowObject(WindowObject
);
1060 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1063 if(WindowObject
->Menu
== hmenu
)
1065 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1066 res
= W32kHiliteMenuItem(WindowObject
, MenuObject
, uItemHilite
, uHilite
);
1067 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1069 W32kReleaseMenuObject(MenuObject
);
1070 W32kReleaseWindowObject(WindowObject
);
1086 PMENU_OBJECT MenuObject
;
1088 if(lpmi
->cbSize
!= sizeof(MENUINFO
))
1090 /* FIXME - Set Last Error */
1093 MenuObject
= W32kGetMenuObject(hmenu
);
1096 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1102 res
= W32kSetMenuInfo(MenuObject
, lpmi
);
1107 res
= W32kGetMenuInfo(MenuObject
, lpmi
);
1109 W32kReleaseMenuObject(MenuObject
);
1118 NtUserMenuItemFromPoint(
1139 LPMENUITEMINFOW lpmii
,
1158 PMENU_OBJECT MenuObject
= W32kGetMenuObject(hMenu
);
1161 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1165 res
= W32kRemoveMenuItem(MenuObject
, uPosition
, uFlags
, FALSE
);
1166 W32kReleaseMenuObject(MenuObject
);
1176 NtUserSetMenuContextHelpId(
1178 DWORD dwContextHelpId
)
1181 PMENU_OBJECT MenuObject
= W32kGetMenuObject(hmenu
);
1184 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1188 res
= W32kSetMenuContextHelpId(MenuObject
, dwContextHelpId
);
1189 W32kReleaseMenuObject(MenuObject
);
1198 NtUserSetMenuDefaultItem(
1204 PMENU_OBJECT MenuObject
;
1205 MenuObject
= W32kGetMenuObject(hMenu
);
1208 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1211 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1212 res
= W32kSetMenuDefaultItem(MenuObject
, uItem
, fByPos
);
1213 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1214 W32kReleaseMenuObject(MenuObject
);
1224 NtUserSetMenuFlagRtoL(
1228 PMENU_OBJECT MenuObject
= W32kGetMenuObject(hMenu
);
1231 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1235 res
= W32kSetMenuFlagRtoL(MenuObject
);
1236 W32kReleaseMenuObject(MenuObject
);
1245 NtUserThunkedMenuInfo(
1250 /* This function seems just to call SetMenuInfo() */
1259 NtUserThunkedMenuItemInfo(
1264 LPMENUITEMINFOW lpmii
,
1265 PUNICODE_STRING lpszCaption
)
1268 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
1269 if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
1279 NtUserTrackPopupMenuEx(