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.
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 ******************************************************************/
37 /* STATIC FUNCTION ***********************************************************/
45 PROSMENUITEMINFO UnsafeItemInfo
,
52 PROSMENUINFO UnsafeMenuInfo
,
55 /* INTERNAL ******************************************************************/
57 /* maximum number of menu items a menu can contain */
58 #define MAX_MENU_ITEMS (0x4000)
59 #define MAX_GOINTOSUBMENU (0x10)
61 #define UpdateMenuItemState(state, change) \
63 if((change) & MFS_DISABLED) { \
64 (state) |= MFS_DISABLED; \
66 (state) &= ~MFS_DISABLED; \
68 if((change) & MFS_CHECKED) { \
69 (state) |= MFS_CHECKED; \
71 (state) &= ~MFS_CHECKED; \
73 if((change) & MFS_HILITE) { \
74 (state) |= MFS_HILITE; \
76 (state) &= ~MFS_HILITE; \
78 if((change) & MFS_DEFAULT) { \
79 (state) |= MFS_DEFAULT; \
81 (state) &= ~MFS_DEFAULT; \
83 if((change) & MF_MOUSESELECT) { \
84 (state) |= MF_MOUSESELECT; \
86 (state) &= ~MF_MOUSESELECT; \
90 #define FreeMenuText(MenuItem) \
92 if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
93 (MenuItem)->Text.Length) { \
94 RtlFreeUnicodeString(&(MenuItem)->Text); \
98 #define InRect(r, x, y) \
99 ( ( ((r).right >= x)) && \
100 ( ((r).left <= x)) && \
101 ( ((r).bottom >= y)) && \
107 return(STATUS_SUCCESS
);
111 CleanupMenuImpl(VOID
)
113 return(STATUS_SUCCESS
);
116 PMENU_OBJECT FASTCALL
UserGetMenuObject(HMENU hMenu
)
122 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
126 Menu
= (PMENU_OBJECT
)UserGetObject(&gHandleTable
, hMenu
, otMenu
);
129 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
133 ASSERT(USER_BODY_TO_HEADER(Menu
)->RefCount
>= 0);
140 DumpMenuItemList(PMENU_ITEM MenuItem
)
145 if(MenuItem
->Text
.Length
)
146 DbgPrint(" %d. %wZ\n", ++cnt
, &MenuItem
->Text
);
148 DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt
, (DWORD
)MenuItem
->Text
.Buffer
);
150 if(MFT_BITMAP
& MenuItem
->fType
)
151 DbgPrint("MFT_BITMAP ");
152 if(MFT_MENUBARBREAK
& MenuItem
->fType
)
153 DbgPrint("MFT_MENUBARBREAK ");
154 if(MFT_MENUBREAK
& MenuItem
->fType
)
155 DbgPrint("MFT_MENUBREAK ");
156 if(MFT_OWNERDRAW
& MenuItem
->fType
)
157 DbgPrint("MFT_OWNERDRAW ");
158 if(MFT_RADIOCHECK
& MenuItem
->fType
)
159 DbgPrint("MFT_RADIOCHECK ");
160 if(MFT_RIGHTJUSTIFY
& MenuItem
->fType
)
161 DbgPrint("MFT_RIGHTJUSTIFY ");
162 if(MFT_SEPARATOR
& MenuItem
->fType
)
163 DbgPrint("MFT_SEPARATOR ");
164 if(MFT_STRING
& MenuItem
->fType
)
165 DbgPrint("MFT_STRING ");
166 DbgPrint("\n fState=");
167 if(MFS_DISABLED
& MenuItem
->fState
)
168 DbgPrint("MFS_DISABLED ");
170 DbgPrint("MFS_ENABLED ");
171 if(MFS_CHECKED
& MenuItem
->fState
)
172 DbgPrint("MFS_CHECKED ");
174 DbgPrint("MFS_UNCHECKED ");
175 if(MFS_HILITE
& MenuItem
->fState
)
176 DbgPrint("MFS_HILITE ");
178 DbgPrint("MFS_UNHILITE ");
179 if(MFS_DEFAULT
& MenuItem
->fState
)
180 DbgPrint("MFS_DEFAULT ");
181 if(MFS_GRAYED
& MenuItem
->fState
)
182 DbgPrint("MFS_GRAYED ");
183 DbgPrint("\n wId=%d\n", MenuItem
->wID
);
184 MenuItem
= MenuItem
->Next
;
186 DbgPrint("Entries: %d\n", cnt
);
191 PMENU_OBJECT FASTCALL
192 IntGetMenuObject(HMENU hMenu
)
194 PMENU_OBJECT Menu
= UserGetMenuObject(hMenu
);
197 ASSERT(USER_BODY_TO_HEADER(Menu
)->RefCount
>= 0);
199 USER_BODY_TO_HEADER(Menu
)->RefCount
++;
205 IntFreeMenuItem(PMENU_OBJECT Menu
, PMENU_ITEM MenuItem
,
206 BOOL RemoveFromList
, BOOL bRecurse
)
208 FreeMenuText(MenuItem
);
211 /* FIXME - Remove from List */
212 Menu
->MenuInfo
.MenuItemCount
--;
214 if(bRecurse
&& MenuItem
->hSubMenu
)
216 PMENU_OBJECT SubMenu
;
217 SubMenu
= UserGetMenuObject(MenuItem
->hSubMenu
);
220 IntDestroyMenuObject(SubMenu
, bRecurse
, TRUE
);
225 ExFreePool(MenuItem
);
231 IntRemoveMenuItem(PMENU_OBJECT Menu
, UINT uPosition
, UINT uFlags
,
234 PMENU_ITEM PrevMenuItem
, MenuItem
;
235 if(IntGetMenuItemByFlag(Menu
, uPosition
, uFlags
, &MenuItem
,
241 PrevMenuItem
->Next
= MenuItem
->Next
;
244 Menu
->MenuItemList
= MenuItem
->Next
;
246 return IntFreeMenuItem(Menu
, MenuItem
, TRUE
, bRecurse
);
253 IntDeleteMenuItems(PMENU_OBJECT Menu
, BOOL bRecurse
)
257 PMENU_ITEM CurItem
= Menu
->MenuItemList
;
260 NextItem
= CurItem
->Next
;
261 IntFreeMenuItem(Menu
, CurItem
, FALSE
, bRecurse
);
265 Menu
->MenuInfo
.MenuItemCount
= 0;
266 Menu
->MenuItemList
= NULL
;
271 IntDestroyMenuObject(PMENU_OBJECT Menu
,
272 BOOL bRecurse
, BOOL RemoveFromProcess
)
276 PWINSTATION_OBJECT WindowStation
;
279 /* remove all menu items */
280 IntDeleteMenuItems(Menu
, bRecurse
); /* do not destroy submenus */
282 if(RemoveFromProcess
)
284 RemoveEntryList(&Menu
->ListEntry
);
287 Status
= ObReferenceObjectByHandle(Menu
->Process
->Win32WindowStation
,
289 ExWindowStationObjectType
,
291 (PVOID
*)&WindowStation
,
293 if(NT_SUCCESS(Status
))
295 ObmDeleteObject(Menu
->MenuInfo
.Self
, otMenu
);
296 ObDereferenceObject(WindowStation
);
303 PMENU_OBJECT FASTCALL
304 IntCreateMenu(PHANDLE Handle
, BOOL IsMenuBar
)
308 Menu
= (PMENU_OBJECT
)ObmCreateObject(
309 &gHandleTable
, Handle
,
310 otMenu
, sizeof(MENU_OBJECT
));
318 Menu
->Process
= PsGetCurrentProcess();
319 Menu
->RtoL
= FALSE
; /* default */
320 Menu
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
321 Menu
->MenuInfo
.fMask
= 0; /* not used */
322 Menu
->MenuInfo
.dwStyle
= 0; /* FIXME */
323 Menu
->MenuInfo
.cyMax
= 0; /* default */
324 Menu
->MenuInfo
.hbrBack
=
325 NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */
326 Menu
->MenuInfo
.dwContextHelpID
= 0; /* default */
327 Menu
->MenuInfo
.dwMenuData
= 0; /* default */
328 Menu
->MenuInfo
.Self
= *Handle
;
329 Menu
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
330 Menu
->MenuInfo
.Flags
= (IsMenuBar
? 0 : MF_POPUP
);
331 Menu
->MenuInfo
.Wnd
= NULL
;
332 Menu
->MenuInfo
.WndOwner
= NULL
;
333 Menu
->MenuInfo
.Height
= 0;
334 Menu
->MenuInfo
.Width
= 0;
335 Menu
->MenuInfo
.TimeToHide
= FALSE
;
337 Menu
->MenuInfo
.MenuItemCount
= 0;
338 Menu
->MenuItemList
= NULL
;
340 /* Insert menu item into process menu handle list */
341 InsertTailList(&PsGetWin32Process()->MenuListHead
, &Menu
->ListEntry
);
347 IntCloneMenuItems(PMENU_OBJECT Destination
, PMENU_OBJECT Source
)
349 PMENU_ITEM MenuItem
, NewMenuItem
= NULL
;
350 PMENU_ITEM Old
= NULL
;
352 if(!Source
->MenuInfo
.MenuItemCount
)
355 MenuItem
= Source
->MenuItemList
;
360 NewMenuItem
->Next
= MenuItem
;
361 NewMenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
364 NewMenuItem
->fType
= MenuItem
->fType
;
365 NewMenuItem
->fState
= MenuItem
->fState
;
366 NewMenuItem
->wID
= MenuItem
->wID
;
367 NewMenuItem
->hSubMenu
= MenuItem
->hSubMenu
;
368 NewMenuItem
->hbmpChecked
= MenuItem
->hbmpChecked
;
369 NewMenuItem
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
370 NewMenuItem
->dwItemData
= MenuItem
->dwItemData
;
371 if((MENU_ITEM_TYPE(NewMenuItem
->fType
) == MF_STRING
))
373 if(MenuItem
->Text
.Length
)
375 NewMenuItem
->Text
.Length
= 0;
376 NewMenuItem
->Text
.MaximumLength
= MenuItem
->Text
.MaximumLength
;
377 NewMenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, MenuItem
->Text
.MaximumLength
, TAG_STRING
);
378 if(!NewMenuItem
->Text
.Buffer
)
380 ExFreePool(NewMenuItem
);
383 RtlCopyUnicodeString(&NewMenuItem
->Text
, &MenuItem
->Text
);
387 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
392 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
394 NewMenuItem
->hbmpItem
= MenuItem
->hbmpItem
;
396 NewMenuItem
->Next
= NULL
;
398 Old
->Next
= NewMenuItem
;
400 Destination
->MenuItemList
= NewMenuItem
;
401 Destination
->MenuInfo
.MenuItemCount
++;
402 MenuItem
= MenuItem
->Next
;
408 PMENU_OBJECT FASTCALL
409 IntCloneMenu(PMENU_OBJECT Source
)
417 Menu
= (PMENU_OBJECT
)ObmCreateObject(
418 &gHandleTable
, &hMenu
,
419 otMenu
, sizeof(MENU_OBJECT
));
424 Menu
->Process
= PsGetCurrentProcess();
425 Menu
->RtoL
= Source
->RtoL
;
426 Menu
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
427 Menu
->MenuInfo
.fMask
= Source
->MenuInfo
.fMask
;
428 Menu
->MenuInfo
.dwStyle
= Source
->MenuInfo
.dwStyle
;
429 Menu
->MenuInfo
.cyMax
= Source
->MenuInfo
.cyMax
;
430 Menu
->MenuInfo
.hbrBack
= Source
->MenuInfo
.hbrBack
;
431 Menu
->MenuInfo
.dwContextHelpID
= Source
->MenuInfo
.dwContextHelpID
;
432 Menu
->MenuInfo
.dwMenuData
= Source
->MenuInfo
.dwMenuData
;
433 Menu
->MenuInfo
.Self
= hMenu
;
434 Menu
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
435 Menu
->MenuInfo
.Wnd
= NULL
;
436 Menu
->MenuInfo
.WndOwner
= NULL
;
437 Menu
->MenuInfo
.Height
= 0;
438 Menu
->MenuInfo
.Width
= 0;
439 Menu
->MenuInfo
.TimeToHide
= FALSE
;
441 Menu
->MenuInfo
.MenuItemCount
= 0;
442 Menu
->MenuItemList
= NULL
;
444 /* Insert menu item into process menu handle list */
445 InsertTailList(&PsGetWin32Process()->MenuListHead
, &Menu
->ListEntry
);
447 IntCloneMenuItems(Menu
, Source
);
453 IntSetMenuFlagRtoL(PMENU_OBJECT Menu
)
460 IntSetMenuContextHelpId(PMENU_OBJECT Menu
, DWORD dwContextHelpId
)
462 Menu
->MenuInfo
.dwContextHelpID
= dwContextHelpId
;
467 IntGetMenuInfo(PMENU_OBJECT Menu
, PROSMENUINFO lpmi
)
469 if(lpmi
->fMask
& MIM_BACKGROUND
)
470 lpmi
->hbrBack
= Menu
->MenuInfo
.hbrBack
;
471 if(lpmi
->fMask
& MIM_HELPID
)
472 lpmi
->dwContextHelpID
= Menu
->MenuInfo
.dwContextHelpID
;
473 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
474 lpmi
->cyMax
= Menu
->MenuInfo
.cyMax
;
475 if(lpmi
->fMask
& MIM_MENUDATA
)
476 lpmi
->dwMenuData
= Menu
->MenuInfo
.dwMenuData
;
477 if(lpmi
->fMask
& MIM_STYLE
)
478 lpmi
->dwStyle
= Menu
->MenuInfo
.dwStyle
;
479 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
481 RtlCopyMemory((char *) lpmi
+ sizeof(MENUINFO
),
482 (char *) &Menu
->MenuInfo
+ sizeof(MENUINFO
),
483 lpmi
->cbSize
- sizeof(MENUINFO
));
491 IntIsMenu(HMENU hMenu
)
495 if((Menu
= UserGetMenuObject(hMenu
)))
504 IntSetMenuInfo(PMENU_OBJECT Menu
, PROSMENUINFO lpmi
)
506 if(lpmi
->fMask
& MIM_BACKGROUND
)
507 Menu
->MenuInfo
.hbrBack
= lpmi
->hbrBack
;
508 if(lpmi
->fMask
& MIM_HELPID
)
509 Menu
->MenuInfo
.dwContextHelpID
= lpmi
->dwContextHelpID
;
510 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
511 Menu
->MenuInfo
.cyMax
= lpmi
->cyMax
;
512 if(lpmi
->fMask
& MIM_MENUDATA
)
513 Menu
->MenuInfo
.dwMenuData
= lpmi
->dwMenuData
;
514 if(lpmi
->fMask
& MIM_STYLE
)
515 Menu
->MenuInfo
.dwStyle
= lpmi
->dwStyle
;
516 if(lpmi
->fMask
& MIM_APPLYTOSUBMENUS
)
520 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
522 Menu
->MenuInfo
.FocusedItem
= lpmi
->FocusedItem
;
523 Menu
->MenuInfo
.Height
= lpmi
->Height
;
524 Menu
->MenuInfo
.Width
= lpmi
->Width
;
525 Menu
->MenuInfo
.Wnd
= lpmi
->Wnd
;
526 Menu
->MenuInfo
.WndOwner
= lpmi
->WndOwner
;
527 Menu
->MenuInfo
.TimeToHide
= lpmi
->TimeToHide
;
535 IntGetMenuItemByFlag(PMENU_OBJECT Menu
, UINT uSearchBy
, UINT fFlag
,
536 PMENU_ITEM
*MenuItem
, PMENU_ITEM
*PrevMenuItem
)
538 PMENU_ITEM PrevItem
= NULL
;
539 PMENU_ITEM CurItem
= Menu
->MenuItemList
;
543 if(MF_BYPOSITION
& fFlag
)
546 while(CurItem
&& (p
> 0))
549 CurItem
= CurItem
->Next
;
557 *PrevMenuItem
= PrevItem
;
564 *PrevMenuItem
= NULL
; /* ? */
568 return uSearchBy
- p
;
575 if(CurItem
->wID
== uSearchBy
)
580 *PrevMenuItem
= PrevItem
;
583 else if (0 != (CurItem
->fType
& MF_POPUP
))
585 Menu
= UserGetMenuObject(CurItem
->hSubMenu
);
588 ret
= IntGetMenuItemByFlag(Menu
, uSearchBy
, fFlag
,
589 MenuItem
, PrevMenuItem
);
597 CurItem
= CurItem
->Next
;
606 IntInsertMenuItemToList(PMENU_OBJECT Menu
, PMENU_ITEM MenuItem
, int pos
)
609 PMENU_ITEM LastItem
= NULL
;
612 CurItem
= Menu
->MenuItemList
;
618 CurItem
= CurItem
->Next
;
624 while(CurItem
&& (pos
> 0))
627 CurItem
= CurItem
->Next
;
637 /* insert the item before CurItem */
638 MenuItem
->Next
= LastItem
->Next
;
639 LastItem
->Next
= MenuItem
;
643 /* insert at the beginning */
644 Menu
->MenuItemList
= MenuItem
;
645 MenuItem
->Next
= CurItem
;
653 LastItem
->Next
= MenuItem
;
654 MenuItem
->Next
= NULL
;
658 /* insert first item */
659 Menu
->MenuItemList
= MenuItem
;
660 MenuItem
->Next
= NULL
;
663 Menu
->MenuInfo
.MenuItemCount
++;
669 IntGetMenuItemInfo(PMENU_OBJECT Menu
, /* UNUSED PARAM!! */
670 PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
674 if(lpmii
->fMask
& MIIM_BITMAP
)
676 lpmii
->hbmpItem
= MenuItem
->hbmpItem
;
678 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
680 lpmii
->hbmpChecked
= MenuItem
->hbmpChecked
;
681 lpmii
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
683 if(lpmii
->fMask
& MIIM_DATA
)
685 lpmii
->dwItemData
= MenuItem
->dwItemData
;
687 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
689 lpmii
->fType
= MenuItem
->fType
;
691 if(lpmii
->fMask
& MIIM_ID
)
693 lpmii
->wID
= MenuItem
->wID
;
695 if(lpmii
->fMask
& MIIM_STATE
)
697 lpmii
->fState
= MenuItem
->fState
;
699 if(lpmii
->fMask
& MIIM_SUBMENU
)
701 lpmii
->hSubMenu
= MenuItem
->hSubMenu
;
703 if (lpmii
->fMask
& (MIIM_STRING
| MIIM_TYPE
))
705 if (lpmii
->dwTypeData
== NULL
)
707 lpmii
->cch
= MenuItem
->Text
.Length
/ sizeof(WCHAR
);
711 Status
= MmCopyToCaller(lpmii
->dwTypeData
, MenuItem
->Text
.Buffer
,
712 min(lpmii
->cch
* sizeof(WCHAR
),
713 MenuItem
->Text
.MaximumLength
));
714 if (! NT_SUCCESS(Status
))
716 SetLastNtError(Status
);
722 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
724 lpmii
->Rect
= MenuItem
->Rect
;
725 lpmii
->XTab
= MenuItem
->XTab
;
732 IntSetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
734 PMENU_OBJECT SubMenuObject
;
736 if(!MenuItem
|| !MenuObject
|| !lpmii
)
741 MenuItem
->fType
= lpmii
->fType
;
743 if(lpmii
->fMask
& MIIM_BITMAP
)
745 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
747 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
749 MenuItem
->hbmpChecked
= lpmii
->hbmpChecked
;
750 MenuItem
->hbmpUnchecked
= lpmii
->hbmpUnchecked
;
752 if(lpmii
->fMask
& MIIM_DATA
)
754 MenuItem
->dwItemData
= lpmii
->dwItemData
;
756 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
759 * Delete the menu item type when changing type from
762 if (MenuItem
->fType
!= lpmii
->fType
&&
763 MENU_ITEM_TYPE(MenuItem
->fType
) == MF_STRING
)
765 FreeMenuText(MenuItem
);
766 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
768 MenuItem
->fType
= lpmii
->fType
;
770 if(lpmii
->fMask
& MIIM_ID
)
772 MenuItem
->wID
= lpmii
->wID
;
774 if(lpmii
->fMask
& MIIM_STATE
)
776 /* remove MFS_DEFAULT flag from all other menu items if this item
777 has the MFS_DEFAULT state */
778 if(lpmii
->fState
& MFS_DEFAULT
)
779 UserSetMenuDefaultItem(MenuObject
, -1, 0);
780 /* update the menu item state flags */
781 UpdateMenuItemState(MenuItem
->fState
, lpmii
->fState
);
784 if(lpmii
->fMask
& MIIM_SUBMENU
)
786 MenuItem
->hSubMenu
= lpmii
->hSubMenu
;
787 /* Make sure the submenu is marked as a popup menu */
788 if (MenuItem
->hSubMenu
)
790 SubMenuObject
= UserGetMenuObject(MenuItem
->hSubMenu
);
791 if (SubMenuObject
!= NULL
)
793 SubMenuObject
->MenuInfo
.Flags
|= MF_POPUP
;
794 MenuItem
->fType
|= MF_POPUP
;
798 MenuItem
->fType
&= ~MF_POPUP
;
803 MenuItem
->fType
&= ~MF_POPUP
;
806 if ((lpmii
->fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
807 (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
))
809 FreeMenuText(MenuItem
);
811 if(lpmii
->dwTypeData
&& lpmii
->cch
)
813 UNICODE_STRING Source
;
816 Source
.MaximumLength
= lpmii
->cch
* sizeof(WCHAR
);
817 Source
.Buffer
= lpmii
->dwTypeData
;
819 MenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(
820 PagedPool
, Source
.Length
+ sizeof(WCHAR
), TAG_STRING
);
821 if(MenuItem
->Text
.Buffer
!= NULL
)
823 MenuItem
->Text
.Length
= 0;
824 MenuItem
->Text
.MaximumLength
= Source
.Length
+ sizeof(WCHAR
);
825 RtlCopyUnicodeString(&MenuItem
->Text
, &Source
);
826 MenuItem
->Text
.Buffer
[MenuItem
->Text
.Length
/ sizeof(WCHAR
)] = 0;
830 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
835 if (0 == (MenuObject
->MenuInfo
.Flags
& MF_SYSMENU
))
837 MenuItem
->fType
|= MF_SEPARATOR
;
839 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
843 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
845 MenuItem
->Rect
= lpmii
->Rect
;
846 MenuItem
->XTab
= lpmii
->XTab
;
853 IntInsertMenuItem(PMENU_OBJECT MenuObject
, UINT uItem
, BOOL fByPosition
,
854 PROSMENUITEMINFO ItemInfo
)
856 int pos
= (int)uItem
;
859 if (MAX_MENU_ITEMS
<= MenuObject
->MenuInfo
.MenuItemCount
)
861 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
867 /* calculate position */
868 if(MenuObject
->MenuInfo
.MenuItemCount
< pos
)
870 pos
= MenuObject
->MenuInfo
.MenuItemCount
;
875 pos
= IntGetMenuItemByFlag(MenuObject
, uItem
, MF_BYCOMMAND
, NULL
, NULL
);
882 MenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
883 if (NULL
== MenuItem
)
885 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
889 MenuItem
->fType
= MFT_STRING
;
890 MenuItem
->fState
= MFS_ENABLED
| MFS_UNCHECKED
;
892 MenuItem
->hSubMenu
= (HMENU
)0;
893 MenuItem
->hbmpChecked
= (HBITMAP
)0;
894 MenuItem
->hbmpUnchecked
= (HBITMAP
)0;
895 MenuItem
->dwItemData
= 0;
896 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
897 MenuItem
->hbmpItem
= (HBITMAP
)0;
899 if (! IntSetMenuItemInfo(MenuObject
, MenuItem
, ItemInfo
))
901 ExFreePool(MenuItem
);
905 /* Force size recalculation! */
906 MenuObject
->MenuInfo
.Height
= 0;
908 pos
= IntInsertMenuItemToList(MenuObject
, MenuItem
, pos
);
910 DPRINT("IntInsertMenuItemToList = %i\n", pos
);
916 IntEnableMenuItem(PMENU_OBJECT MenuObject
, UINT uIDEnableItem
, UINT uEnable
)
919 UINT res
= IntGetMenuItemByFlag(MenuObject
, uIDEnableItem
, uEnable
, &MenuItem
, NULL
);
920 if(!MenuItem
|| (res
== (UINT
)-1))
925 res
= MenuItem
->fState
& (MF_GRAYED
| MF_DISABLED
);
927 if(uEnable
& MF_DISABLED
)
929 if(!(MenuItem
->fState
& MF_DISABLED
))
930 MenuItem
->fState
|= MF_DISABLED
;
931 if(uEnable
& MF_GRAYED
)
933 if(!(MenuItem
->fState
& MF_GRAYED
))
934 MenuItem
->fState
|= MF_GRAYED
;
939 if(uEnable
& MF_GRAYED
)
941 if(!(MenuItem
->fState
& MF_GRAYED
))
942 MenuItem
->fState
|= MF_GRAYED
;
943 if(!(MenuItem
->fState
& MF_DISABLED
))
944 MenuItem
->fState
|= MF_DISABLED
;
948 if(MenuItem
->fState
& MF_DISABLED
)
949 MenuItem
->fState
^= MF_DISABLED
;
950 if(MenuItem
->fState
& MF_GRAYED
)
951 MenuItem
->fState
^= MF_GRAYED
;
960 IntBuildMenuItemList(PMENU_OBJECT MenuObject
, PVOID Buffer
, ULONG nMax
)
966 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
973 if (nMax
< MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
))
977 StrOut
= (PWCHAR
)((char *) Buffer
+ MenuObject
->MenuInfo
.MenuItemCount
978 * sizeof(ROSMENUITEMINFO
));
979 nMax
-= MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
);
980 sz
= sizeof(ROSMENUITEMINFO
);
982 mii
.cbSize
= sizeof(ROSMENUITEMINFO
);
986 while (NULL
!= CurItem
)
988 mii
.cch
= CurItem
->Text
.Length
/ sizeof(WCHAR
);
989 mii
.dwItemData
= CurItem
->dwItemData
;
990 if (0 != CurItem
->Text
.Length
)
992 mii
.dwTypeData
= StrOut
;
996 mii
.dwTypeData
= NULL
;
998 mii
.fState
= CurItem
->fState
;
999 mii
.fType
= CurItem
->fType
;
1000 mii
.hbmpChecked
= CurItem
->hbmpChecked
;
1001 mii
.hbmpItem
= CurItem
->hbmpItem
;
1002 mii
.hbmpUnchecked
= CurItem
->hbmpUnchecked
;
1003 mii
.hSubMenu
= CurItem
->hSubMenu
;
1004 mii
.Rect
= CurItem
->Rect
;
1005 mii
.XTab
= CurItem
->XTab
;
1007 Status
= MmCopyToCaller(Buf
, &mii
, sizeof(ROSMENUITEMINFO
));
1008 if (! NT_SUCCESS(Status
))
1010 SetLastNtError(Status
);
1013 Buf
= (PVOID
)((ULONG_PTR
)Buf
+ sizeof(ROSMENUITEMINFO
));
1015 if (0 != CurItem
->Text
.Length
1016 && (nMax
>= CurItem
->Text
.Length
+ sizeof(WCHAR
)))
1019 Status
= MmCopyToCaller(StrOut
, CurItem
->Text
.Buffer
,
1020 CurItem
->Text
.Length
);
1021 if (! NT_SUCCESS(Status
))
1023 SetLastNtError(Status
);
1026 StrOut
+= CurItem
->Text
.Length
/ sizeof(WCHAR
);
1027 Status
= MmCopyToCaller(StrOut
, &NulByte
, sizeof(WCHAR
));
1028 if (! NT_SUCCESS(Status
))
1030 SetLastNtError(Status
);
1034 nMax
-= CurItem
->Text
.Length
+ sizeof(WCHAR
);
1036 else if (0 != CurItem
->Text
.Length
)
1041 CurItem
= CurItem
->Next
;
1047 while (NULL
!= CurItem
)
1049 res
+= sizeof(ROSMENUITEMINFO
) + CurItem
->Text
.Length
+ sizeof(WCHAR
);
1050 CurItem
= CurItem
->Next
;
1059 IntCheckMenuItem(PMENU_OBJECT MenuObject
, UINT uIDCheckItem
, UINT uCheck
)
1061 PMENU_ITEM MenuItem
;
1064 if((IntGetMenuItemByFlag(MenuObject
, uIDCheckItem
, uCheck
, &MenuItem
, NULL
) < 0) || !MenuItem
)
1069 res
= (DWORD
)(MenuItem
->fState
& MF_CHECKED
);
1070 if(uCheck
& MF_CHECKED
)
1072 if(!(MenuItem
->fState
& MF_CHECKED
))
1073 MenuItem
->fState
|= MF_CHECKED
;
1077 if(MenuItem
->fState
& MF_CHECKED
)
1078 MenuItem
->fState
^= MF_CHECKED
;
1085 IntHiliteMenuItem(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
,
1086 UINT uItemHilite
, UINT uHilite
)
1088 PMENU_ITEM MenuItem
;
1089 BOOL res
= IntGetMenuItemByFlag(MenuObject
, uItemHilite
, uHilite
, &MenuItem
, NULL
);
1090 if(!MenuItem
|| !res
)
1095 if(uHilite
& MF_HILITE
)
1097 if(!(MenuItem
->fState
& MF_HILITE
))
1098 MenuItem
->fState
|= MF_HILITE
;
1102 if(MenuItem
->fState
& MF_HILITE
)
1103 MenuItem
->fState
^= MF_HILITE
;
1106 /* FIXME - update the window's menu */
1112 UserSetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT uItem
, UINT fByPos
)
1115 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1117 if(uItem
== (UINT
)-1)
1121 if(MenuItem
->fState
& MFS_DEFAULT
)
1122 MenuItem
->fState
^= MFS_DEFAULT
;
1123 MenuItem
= MenuItem
->Next
;
1135 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1136 MenuItem
->fState
|= MFS_DEFAULT
;
1141 if(MenuItem
->fState
& MFS_DEFAULT
)
1142 MenuItem
->fState
^= MFS_DEFAULT
;
1145 MenuItem
= MenuItem
->Next
;
1152 if(!ret
&& (MenuItem
->wID
== uItem
))
1154 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1155 MenuItem
->fState
|= MFS_DEFAULT
;
1160 if(MenuItem
->fState
& MFS_DEFAULT
)
1161 MenuItem
->fState
^= MFS_DEFAULT
;
1163 MenuItem
= MenuItem
->Next
;
1171 IntGetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT fByPos
, UINT gmdiFlags
,
1177 PMENU_OBJECT SubMenuObject
;
1178 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1182 if(MenuItem
->fState
& MFS_DEFAULT
)
1185 if(!(gmdiFlags
& GMDI_USEDISABLED
) && (MenuItem
->fState
& MFS_DISABLED
))
1188 if(fByPos
& MF_BYPOSITION
)
1191 res
= MenuItem
->wID
;
1193 if((*gismc
< MAX_GOINTOSUBMENU
) && (gmdiFlags
& GMDI_GOINTOPOPUPS
) &&
1197 SubMenuObject
= UserGetMenuObject(MenuItem
->hSubMenu
);
1198 if(!SubMenuObject
|| (SubMenuObject
== MenuObject
))
1202 sres
= IntGetMenuDefaultItem(SubMenuObject
, fByPos
, gmdiFlags
, gismc
);
1212 MenuItem
= MenuItem
->Next
;
1220 co_IntInitTracking(PWINDOW_OBJECT Window
, PMENU_OBJECT Menu
, BOOL Popup
,
1223 /* FIXME - hide caret */
1225 if(!(Flags
& TPM_NONOTIFY
))
1226 co_IntSendMessage(Window
->hSelf
, WM_SETCURSOR
, (WPARAM
)Window
->hSelf
, HTCAPTION
);
1228 /* FIXME - send WM_SETCURSOR message */
1230 if(!(Flags
& TPM_NONOTIFY
))
1231 co_IntSendMessage(Window
->hSelf
, WM_INITMENU
, (WPARAM
)Menu
->MenuInfo
.Self
, 0);
1235 co_IntExitTracking(PWINDOW_OBJECT Window
, PMENU_OBJECT Menu
, BOOL Popup
,
1238 if(!(Flags
& TPM_NONOTIFY
))
1239 co_IntSendMessage(Window
->hSelf
, WM_EXITMENULOOP
, 0 /* FIXME */, 0);
1241 /* FIXME - Show caret again */
1245 IntTrackMenu(PMENU_OBJECT Menu
, PWINDOW_OBJECT Window
, INT x
, INT y
,
1252 co_IntTrackPopupMenu(PMENU_OBJECT Menu
, PWINDOW_OBJECT Window
,
1253 UINT Flags
, POINT
*Pos
, UINT MenuPos
, RECT
*ExcludeRect
)
1255 co_IntInitTracking(Window
, Menu
, TRUE
, Flags
);
1257 co_IntExitTracking(Window
, Menu
, TRUE
, Flags
);
1262 IntSetMenuItemRect(PMENU_OBJECT Menu
, UINT Item
, BOOL fByPos
, RECT
*rcRect
)
1265 if(IntGetMenuItemByFlag(Menu
, Item
, (fByPos
? MF_BYPOSITION
: MF_BYCOMMAND
),
1276 * Internal function. Called when the process is destroyed to free the remaining menu handles.
1279 IntCleanupMenus(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
1281 PEPROCESS CurrentProcess
;
1282 PLIST_ENTRY LastHead
= NULL
;
1283 PMENU_OBJECT MenuObject
;
1285 CurrentProcess
= PsGetCurrentProcess();
1286 if (CurrentProcess
!= Process
)
1288 KeAttachProcess(&Process
->Pcb
);
1291 while (Win32Process
->MenuListHead
.Flink
!= &(Win32Process
->MenuListHead
) &&
1292 Win32Process
->MenuListHead
.Flink
!= LastHead
)
1294 LastHead
= Win32Process
->MenuListHead
.Flink
;
1295 MenuObject
= CONTAINING_RECORD(Win32Process
->MenuListHead
.Flink
, MENU_OBJECT
, ListEntry
);
1297 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1300 if (CurrentProcess
!= Process
)
1307 /* FUNCTIONS *****************************************************************/
1315 NtUserBuildMenuItemList(
1323 DECLARE_RETURN(DWORD
);
1325 DPRINT("Enter NtUserBuildMenuItemList\n");
1326 UserEnterExclusive();
1328 if(!(Menu
= UserGetMenuObject(hMenu
)))
1335 res
= IntBuildMenuItemList(Menu
, Buffer
, nBufSize
);
1339 res
= Menu
->MenuInfo
.MenuItemCount
;
1345 DPRINT("Leave NtUserBuildMenuItemList, ret=%i\n",_ret_
);
1355 NtUserCheckMenuItem(
1361 DECLARE_RETURN(DWORD
);
1363 DPRINT("Enter NtUserCheckMenuItem\n");
1364 UserEnterExclusive();
1366 if(!(Menu
= UserGetMenuObject(hMenu
)))
1371 RETURN( IntCheckMenuItem(Menu
, uIDCheckItem
, uCheck
));
1374 DPRINT("Leave NtUserCheckMenuItem, ret=%i\n",_ret_
);
1380 HMENU FASTCALL
UserCreateMenu(BOOL PopupMenu
)
1382 PWINSTATION_OBJECT WinStaObject
;
1385 NTSTATUS Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1390 if (!NT_SUCCESS(Status
))
1392 DPRINT("Validation of window station handle (0x%X) failed\n",
1393 PsGetCurrentProcess()->Win32WindowStation
);
1394 SetLastNtError(Status
);
1398 IntCreateMenu(&Handle
, !PopupMenu
);
1400 ObDereferenceObject(WinStaObject
);
1401 return (HMENU
)Handle
;
1407 NtUserCreateMenu(BOOL PopupMenu
)
1409 DECLARE_RETURN(HMENU
);
1411 DPRINT("Enter NtUserCreateMenu\n");
1412 UserEnterExclusive();
1414 RETURN(UserCreateMenu(PopupMenu
));
1417 DPRINT("Leave NtUserCreateMenu, ret=%i\n",_ret_
);
1434 DECLARE_RETURN(BOOL
);
1436 DPRINT("Enter NtUserDeleteMenu\n");
1437 UserEnterExclusive();
1439 if(!(Menu
= UserGetMenuObject(hMenu
)))
1444 RETURN( IntRemoveMenuItem(Menu
, uPosition
, uFlags
, TRUE
));
1447 DPRINT("Leave NtUserDeleteMenu, ret=%i\n",_ret_
);
1457 BOOL FASTCALL
UserDestroyMenu(HMENU hMenu
)
1461 if(!(Menu
= UserGetMenuObject(hMenu
)))
1466 if(Menu
->Process
!= PsGetCurrentProcess())
1468 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1472 return IntDestroyMenuObject(Menu
, FALSE
, TRUE
);
1483 DECLARE_RETURN(BOOL
);
1485 DPRINT("Enter NtUserDestroyMenu\n");
1486 UserEnterExclusive();
1488 if(!(Menu
= UserGetMenuObject(hMenu
)))
1493 if(Menu
->Process
!= PsGetCurrentProcess())
1495 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1499 RETURN( IntDestroyMenuObject(Menu
, FALSE
, TRUE
));
1502 DPRINT("Leave NtUserDestroyMenu, ret=%i\n",_ret_
);
1512 NtUserEnableMenuItem(
1518 DECLARE_RETURN(UINT
);
1520 DPRINT("Enter NtUserEnableMenuItem\n");
1521 UserEnterExclusive();
1523 if(!(Menu
= UserGetMenuObject(hMenu
)))
1528 RETURN( IntEnableMenuItem(Menu
, uIDEnableItem
, uEnable
));
1531 DPRINT("Leave NtUserEnableMenuItem, ret=%i\n",_ret_
);
1541 NtUserInsertMenuItem(
1545 LPCMENUITEMINFOW UnsafeItemInfo
)
1549 ROSMENUITEMINFO ItemInfo
;
1550 DECLARE_RETURN(DWORD
);
1552 DPRINT("Enter NtUserInsertMenuItem\n");
1553 UserEnterExclusive();
1555 if(!(Menu
= UserGetMenuObject(hMenu
)))
1560 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, sizeof(MENUITEMINFOW
));
1561 if (! NT_SUCCESS(Status
))
1563 SetLastNtError(Status
);
1566 /* structure can be 44 bytes or 48 bytes in size
1567 if (ItemInfo.cbSize != sizeof(MENUITEMINFOW))
1569 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1574 RETURN( IntInsertMenuItem(Menu
, uItem
, fByPosition
, &ItemInfo
));
1577 DPRINT("Leave NtUserInsertMenuItem, ret=%i\n",_ret_
);
1599 NtUserGetMenuDefaultItem(
1606 DECLARE_RETURN(UINT
);
1608 DPRINT("Enter NtUserGetMenuDefaultItem\n");
1609 UserEnterExclusive();
1611 if(!(Menu
= UserGetMenuObject(hMenu
)))
1616 RETURN( IntGetMenuDefaultItem(Menu
, fByPos
, gmdiFlags
, &gismc
));
1619 DPRINT("Leave NtUserGetMenuDefaultItem, ret=%i\n",_ret_
);
1629 NtUserGetMenuBarInfo(
1641 DPRINT1("OBJID_CLIENT, idItem = %d\n",idItem
);
1646 DPRINT1("OBJID_MENU, idItem = %d\n",idItem
);
1651 DPRINT1("OBJID_SYSMENU, idItem = %d\n",idItem
);
1655 DPRINT1("Unknown idObject = %d, idItem = %d\n",idObject
,idItem
);
1679 NtUserGetMenuItemRect(
1686 ROSMENUITEMINFO mii
;
1689 LPRECT lpRect
= NULL
;
1695 PWINDOW_OBJECT ReferenceWnd
;
1696 DECLARE_RETURN(BOOL
);
1698 DPRINT("Enter NtUserGetMenuItemRect\n");
1701 if (!(Menu
= UserGetMenuObject(hMenu
)))
1706 if(!UserMenuItemInfo(Menu
, uItem
, MF_BYPOSITION
, &mii
, FALSE
))
1709 referenceHwnd
= hWnd
;
1713 if(!UserMenuInfo(Menu
, &mi
, FALSE
))
1717 referenceHwnd
= mi
.Wnd
;
1720 if (lprcItem
== NULL
)
1723 lpPoints
= (LPPOINT
)lpRect
;
1725 ReferenceWnd
= UserGetWindowObject(referenceHwnd
);
1726 if (!ReferenceWnd
|| !UserGetClientOrigin(ReferenceWnd
, &FromOffset
))
1731 XMove
= FromOffset
.x
;
1732 YMove
= FromOffset
.y
;
1734 for (i
= 0; i
< 2; i
++)
1736 lpPoints
[i
].x
+= XMove
;
1737 lpPoints
[i
].y
+= YMove
;
1740 Status
= MmCopyToCaller(lprcItem
, lpPoints
, sizeof(RECT
));
1741 if (! NT_SUCCESS(Status
))
1743 SetLastNtError(Status
);
1749 DPRINT("Leave NtUserGetMenuItemRect, ret=%i\n",_ret_
);
1759 NtUserHiliteMenuItem(
1766 PWINDOW_OBJECT Window
;
1767 DECLARE_RETURN(BOOLEAN
);
1769 DPRINT("Enter NtUserHiliteMenuItem\n");
1770 UserEnterExclusive();
1772 if(!(Window
= UserGetWindowObject(hWnd
)))
1777 if(!(Menu
= UserGetMenuObject(hMenu
)))
1782 if(Window
->IDMenu
== (UINT
)hMenu
)
1784 RETURN( IntHiliteMenuItem(Window
, Menu
, uItemHilite
, uHilite
));
1790 DPRINT("Leave NtUserHiliteMenuItem, ret=%i\n",_ret_
);
1800 PROSMENUINFO UnsafeMenuInfo
,
1806 ROSMENUINFO MenuInfo
;
1808 Status
= MmCopyFromCaller(&Size
, &UnsafeMenuInfo
->cbSize
, sizeof(DWORD
));
1809 if (! NT_SUCCESS(Status
))
1811 SetLastNtError(Status
);
1814 if(Size
< sizeof(MENUINFO
) || sizeof(ROSMENUINFO
) < Size
)
1816 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1819 Status
= MmCopyFromCaller(&MenuInfo
, UnsafeMenuInfo
, Size
);
1820 if (! NT_SUCCESS(Status
))
1822 SetLastNtError(Status
);
1829 Res
= IntSetMenuInfo(Menu
, &MenuInfo
);
1834 Res
= IntGetMenuInfo(Menu
, &MenuInfo
);
1837 Status
= MmCopyToCaller(UnsafeMenuInfo
, &MenuInfo
, Size
);
1838 if (! NT_SUCCESS(Status
))
1840 SetLastNtError(Status
);
1860 PROSMENUINFO UnsafeMenuInfo
,
1864 DECLARE_RETURN(BOOL
);
1866 DPRINT("Enter NtUserMenuInfo\n");
1869 if (!(Menu
= UserGetMenuObject(hMenu
)))
1874 RETURN(UserMenuInfo(Menu
, UnsafeMenuInfo
, SetOrGet
));
1877 DPRINT("Leave NtUserMenuInfo, ret=%i\n",_ret_
);
1888 NtUserMenuItemFromPoint(
1895 PWINDOW_OBJECT Window
= NULL
;
1898 DECLARE_RETURN(int);
1900 DPRINT("Enter NtUserMenuItemFromPoint\n");
1901 UserEnterExclusive();
1903 if (!(Menu
= UserGetMenuObject(hMenu
)))
1908 if (!(Window
= UserGetWindowObject(Menu
->MenuInfo
.Wnd
)))
1913 X
-= Window
->WindowRect
.left
;
1914 Y
-= Window
->WindowRect
.top
;
1916 mi
= Menu
->MenuItemList
;
1917 for (i
= 0; NULL
!= mi
; i
++)
1919 if (InRect(mi
->Rect
, X
, Y
))
1926 RETURN( (mi
? i
: NO_SELECTED_ITEM
));
1929 DPRINT("Leave NtUserMenuItemFromPoint, ret=%i\n",_ret_
);
1942 PROSMENUITEMINFO UnsafeItemInfo
,
1945 PMENU_ITEM MenuItem
;
1946 ROSMENUITEMINFO ItemInfo
;
1951 Status
= MmCopyFromCaller(&Size
, &UnsafeItemInfo
->cbSize
, sizeof(UINT
));
1952 if (! NT_SUCCESS(Status
))
1954 SetLastNtError(Status
);
1957 if (sizeof(MENUITEMINFOW
) != Size
1958 && sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
) != Size
1959 && sizeof(ROSMENUITEMINFO
) != Size
)
1961 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1964 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, Size
);
1965 if (! NT_SUCCESS(Status
))
1967 SetLastNtError(Status
);
1970 /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
1972 if (sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
) == Size
1973 && 0 != (ItemInfo
.fMask
& MIIM_BITMAP
))
1975 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1979 if (IntGetMenuItemByFlag(Menu
, Item
,
1980 (ByPosition
? MF_BYPOSITION
: MF_BYCOMMAND
),
1981 &MenuItem
, NULL
) < 0)
1983 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1989 Ret
= IntSetMenuItemInfo(Menu
, MenuItem
, &ItemInfo
);
1993 Ret
= IntGetMenuItemInfo(Menu
, MenuItem
, &ItemInfo
);
1996 Status
= MmCopyToCaller(UnsafeItemInfo
, &ItemInfo
, Size
);
1997 if (! NT_SUCCESS(Status
))
1999 SetLastNtError(Status
);
2019 PROSMENUITEMINFO UnsafeItemInfo
,
2023 DECLARE_RETURN(BOOL
);
2025 DPRINT("Enter NtUserMenuItemInfo\n");
2026 UserEnterExclusive();
2028 if (!(Menu
= UserGetMenuObject(hMenu
)))
2033 RETURN( UserMenuItemInfo(Menu
, Item
, ByPosition
, UnsafeItemInfo
, SetOrGet
));
2036 DPRINT("Leave NtUserMenuItemInfo, ret=%i\n",_ret_
);
2053 DECLARE_RETURN(BOOL
);
2055 DPRINT("Enter NtUserRemoveMenu\n");
2056 UserEnterExclusive();
2058 if(!(Menu
= UserGetMenuObject(hMenu
)))
2063 RETURN(IntRemoveMenuItem(Menu
, uPosition
, uFlags
, FALSE
));
2066 DPRINT("Leave NtUserRemoveMenu, ret=%i\n",_ret_
);
2077 NtUserSetMenuContextHelpId(
2079 DWORD dwContextHelpId
)
2082 DECLARE_RETURN(BOOL
);
2084 DPRINT("Enter NtUserSetMenuContextHelpId\n");
2085 UserEnterExclusive();
2087 if(!(Menu
= UserGetMenuObject(hMenu
)))
2092 RETURN(IntSetMenuContextHelpId(Menu
, dwContextHelpId
));
2095 DPRINT("Leave NtUserSetMenuContextHelpId, ret=%i\n",_ret_
);
2106 NtUserSetMenuDefaultItem(
2112 DECLARE_RETURN(BOOL
);
2114 DPRINT("Enter NtUserSetMenuDefaultItem\n");
2115 UserEnterExclusive();
2117 if(!(Menu
= UserGetMenuObject(hMenu
)))
2122 RETURN( UserSetMenuDefaultItem(Menu
, uItem
, fByPos
));
2125 DPRINT("Leave NtUserSetMenuDefaultItem, ret=%i\n",_ret_
);
2135 NtUserSetMenuFlagRtoL(
2139 DECLARE_RETURN(BOOL
);
2141 DPRINT("Enter NtUserSetMenuFlagRtoL\n");
2142 UserEnterExclusive();
2144 if(!(Menu
= UserGetMenuObject(hMenu
)))
2149 RETURN(IntSetMenuFlagRtoL(Menu
));
2152 DPRINT("Leave NtUserSetMenuFlagRtoL, ret=%i\n",_ret_
);
2162 NtUserThunkedMenuInfo(
2167 /* This function seems just to call SetMenuInfo() */
2176 NtUserThunkedMenuItemInfo(
2181 LPMENUITEMINFOW lpmii
,
2182 PUNICODE_STRING lpszCaption
)
2185 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
2186 if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
2195 /* NOTE: unused function */
2197 NtUserTrackPopupMenuEx(