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.56 2004/11/20 16:46:06 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 ******************************************************************/
36 /* INTERNAL ******************************************************************/
38 /* maximum number of menu items a menu can contain */
39 #define MAX_MENU_ITEMS (0x4000)
40 #define MAX_GOINTOSUBMENU (0x10)
42 #define UpdateMenuItemState(state, change) \
44 if((change) & MFS_DISABLED) { \
45 (state) |= MFS_DISABLED; \
47 (state) &= ~MFS_DISABLED; \
49 if((change) & MFS_CHECKED) { \
50 (state) |= MFS_CHECKED; \
52 (state) &= ~MFS_CHECKED; \
54 if((change) & MFS_HILITE) { \
55 (state) |= MFS_HILITE; \
57 (state) &= ~MFS_HILITE; \
59 if((change) & MFS_DEFAULT) { \
60 (state) |= MFS_DEFAULT; \
62 (state) &= ~MFS_DEFAULT; \
64 if((change) & MF_MOUSESELECT) { \
65 (state) |= MF_MOUSESELECT; \
67 (state) &= ~MF_MOUSESELECT; \
71 #define FreeMenuText(MenuItem) \
73 if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
74 (MenuItem)->Text.Length) { \
75 RtlFreeUnicodeString(&(MenuItem)->Text); \
79 #define InRect(r, x, y) \
80 ( ( ((r).right >= x)) && \
81 ( ((r).left <= x)) && \
82 ( ((r).bottom >= y)) && \
88 return(STATUS_SUCCESS
);
94 return(STATUS_SUCCESS
);
99 DumpMenuItemList(PMENU_ITEM MenuItem
)
104 if(MenuItem
->Text
.Length
)
105 DbgPrint(" %d. %wZ\n", ++cnt
, &MenuItem
->Text
);
107 DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt
, (DWORD
)MenuItem
->Text
.Buffer
);
109 if(MFT_BITMAP
& MenuItem
->fType
) DbgPrint("MFT_BITMAP ");
110 if(MFT_MENUBARBREAK
& MenuItem
->fType
) DbgPrint("MFT_MENUBARBREAK ");
111 if(MFT_MENUBREAK
& MenuItem
->fType
) DbgPrint("MFT_MENUBREAK ");
112 if(MFT_OWNERDRAW
& MenuItem
->fType
) DbgPrint("MFT_OWNERDRAW ");
113 if(MFT_RADIOCHECK
& MenuItem
->fType
) DbgPrint("MFT_RADIOCHECK ");
114 if(MFT_RIGHTJUSTIFY
& MenuItem
->fType
) DbgPrint("MFT_RIGHTJUSTIFY ");
115 if(MFT_SEPARATOR
& MenuItem
->fType
) DbgPrint("MFT_SEPARATOR ");
116 if(MFT_STRING
& MenuItem
->fType
) DbgPrint("MFT_STRING ");
117 DbgPrint("\n fState=");
118 if(MFS_DISABLED
& MenuItem
->fState
) DbgPrint("MFS_DISABLED ");
119 else DbgPrint("MFS_ENABLED ");
120 if(MFS_CHECKED
& MenuItem
->fState
) DbgPrint("MFS_CHECKED ");
121 else DbgPrint("MFS_UNCHECKED ");
122 if(MFS_HILITE
& MenuItem
->fState
) DbgPrint("MFS_HILITE ");
123 else DbgPrint("MFS_UNHILITE ");
124 if(MFS_DEFAULT
& MenuItem
->fState
) DbgPrint("MFS_DEFAULT ");
125 if(MFS_GRAYED
& MenuItem
->fState
) DbgPrint("MFS_GRAYED ");
126 DbgPrint("\n wId=%d\n", MenuItem
->wID
);
127 MenuItem
= MenuItem
->Next
;
129 DbgPrint("Entries: %d\n", cnt
);
134 PMENU_OBJECT FASTCALL
135 IntGetMenuObject(HMENU hMenu
)
137 PMENU_OBJECT MenuObject
;
138 PW32THREAD W32Thread
= PsGetWin32Thread();
145 NTSTATUS Status
= ObmReferenceObjectByHandle(W32Thread
->Desktop
->WindowStation
->HandleTable
,
146 hMenu
, otMenu
, (PVOID
*)&MenuObject
);
147 if (!NT_SUCCESS(Status
))
155 IntFreeMenuItem(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
,
156 BOOL RemoveFromList
, BOOL bRecurse
)
158 FreeMenuText(MenuItem
);
161 /* FIXME - Remove from List */
162 MenuObject
->MenuInfo
.MenuItemCount
--;
164 if(bRecurse
&& MenuItem
->hSubMenu
)
166 PMENU_OBJECT SubMenuObject
;
167 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
170 IntDestroyMenuObject(SubMenuObject
, bRecurse
, TRUE
);
171 IntReleaseMenuObject(SubMenuObject
);
176 ExFreePool(MenuItem
);
182 IntRemoveMenuItem(PMENU_OBJECT MenuObject
, UINT uPosition
, UINT uFlags
,
185 PMENU_ITEM PrevMenuItem
, MenuItem
;
186 if(IntGetMenuItemByFlag(MenuObject
, uPosition
, uFlags
, &MenuItem
,
192 PrevMenuItem
->Next
= MenuItem
->Next
;
195 MenuObject
->MenuItemList
= MenuItem
->Next
;
197 return IntFreeMenuItem(MenuObject
, MenuItem
, TRUE
, bRecurse
);
204 IntDeleteMenuItems(PMENU_OBJECT MenuObject
, BOOL bRecurse
)
208 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
211 NextItem
= CurItem
->Next
;
212 IntFreeMenuItem(MenuObject
, CurItem
, FALSE
, bRecurse
);
216 MenuObject
->MenuInfo
.MenuItemCount
= 0;
217 MenuObject
->MenuItemList
= NULL
;
222 IntDestroyMenuObject(PMENU_OBJECT MenuObject
,
223 BOOL bRecurse
, BOOL RemoveFromProcess
)
227 PWINSTATION_OBJECT WindowStation
;
230 /* remove all menu items */
231 IntLockMenuItems(MenuObject
);
232 IntDeleteMenuItems(MenuObject
, bRecurse
); /* do not destroy submenus */
233 IntUnLockMenuItems(MenuObject
);
235 if(RemoveFromProcess
)
237 IntLockProcessMenus(MenuObject
->Process
->Win32Process
);
238 RemoveEntryList(&MenuObject
->ListEntry
);
239 IntUnLockProcessMenus(MenuObject
->Process
->Win32Process
);
242 Status
= ObReferenceObjectByHandle(MenuObject
->Process
->Win32WindowStation
,
244 ExWindowStationObjectType
,
246 (PVOID
*)&WindowStation
,
248 if(NT_SUCCESS(Status
))
250 ObmCloseHandle(WindowStation
->HandleTable
, MenuObject
->MenuInfo
.Self
);
251 ObDereferenceObject(WindowStation
);
258 PMENU_OBJECT FASTCALL
259 IntCreateMenu(PHANDLE Handle
, BOOL IsMenuBar
)
261 PMENU_OBJECT MenuObject
;
262 PW32THREAD Win32Thread
= PsGetWin32Thread();
264 MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
265 Win32Thread
->Desktop
->WindowStation
->HandleTable
, Handle
,
266 otMenu
, sizeof(MENU_OBJECT
));
274 MenuObject
->Process
= PsGetCurrentProcess();
275 MenuObject
->RtoL
= FALSE
; /* default */
276 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
277 MenuObject
->MenuInfo
.fMask
= 0; /* not used */
278 MenuObject
->MenuInfo
.dwStyle
= 0; /* FIXME */
279 MenuObject
->MenuInfo
.cyMax
= 0; /* default */
280 MenuObject
->MenuInfo
.hbrBack
=
281 NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */
282 MenuObject
->MenuInfo
.dwContextHelpID
= 0; /* default */
283 MenuObject
->MenuInfo
.dwMenuData
= 0; /* default */
284 MenuObject
->MenuInfo
.Self
= *Handle
;
285 MenuObject
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
286 MenuObject
->MenuInfo
.Flags
= (IsMenuBar
? 0 : MF_POPUP
);
287 MenuObject
->MenuInfo
.Wnd
= NULL
;
288 MenuObject
->MenuInfo
.WndOwner
= NULL
;
289 MenuObject
->MenuInfo
.Height
= 0;
290 MenuObject
->MenuInfo
.Width
= 0;
291 MenuObject
->MenuInfo
.TimeToHide
= FALSE
;
293 MenuObject
->MenuInfo
.MenuItemCount
= 0;
294 MenuObject
->MenuItemList
= NULL
;
295 ExInitializeFastMutex(&MenuObject
->MenuItemsLock
);
297 /* Insert menu item into process menu handle list */
298 IntLockProcessMenus(PsGetWin32Process());
299 InsertTailList(&PsGetWin32Process()->MenuListHead
, &MenuObject
->ListEntry
);
300 IntUnLockProcessMenus(PsGetWin32Process());
306 IntCloneMenuItems(PMENU_OBJECT Destination
, PMENU_OBJECT Source
)
308 PMENU_ITEM MenuItem
, NewMenuItem
= NULL
;
309 PMENU_ITEM Old
= NULL
;
311 if(!Source
->MenuInfo
.MenuItemCount
)
314 IntLockMenuItems(Destination
);
315 IntLockMenuItems(Source
);
317 MenuItem
= Source
->MenuItemList
;
322 NewMenuItem
->Next
= MenuItem
;
323 NewMenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
326 NewMenuItem
->fType
= MenuItem
->fType
;
327 NewMenuItem
->fState
= MenuItem
->fState
;
328 NewMenuItem
->wID
= MenuItem
->wID
;
329 NewMenuItem
->hSubMenu
= MenuItem
->hSubMenu
;
330 NewMenuItem
->hbmpChecked
= MenuItem
->hbmpChecked
;
331 NewMenuItem
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
332 NewMenuItem
->dwItemData
= MenuItem
->dwItemData
;
333 if((MENU_ITEM_TYPE(NewMenuItem
->fType
) == MF_STRING
))
335 if(MenuItem
->Text
.Length
)
337 NewMenuItem
->Text
.Length
= 0;
338 NewMenuItem
->Text
.MaximumLength
= MenuItem
->Text
.MaximumLength
;
339 NewMenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, MenuItem
->Text
.MaximumLength
, TAG_STRING
);
340 if(!NewMenuItem
->Text
.Buffer
)
342 ExFreePool(NewMenuItem
);
345 RtlCopyUnicodeString(&NewMenuItem
->Text
, &MenuItem
->Text
);
349 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
354 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
356 NewMenuItem
->hbmpItem
= MenuItem
->hbmpItem
;
358 NewMenuItem
->Next
= NULL
;
360 Old
->Next
= NewMenuItem
;
362 Destination
->MenuItemList
= NewMenuItem
;
363 Destination
->MenuInfo
.MenuItemCount
++;
364 MenuItem
= MenuItem
->Next
;
367 IntUnLockMenuItems(Source
);
368 IntUnLockMenuItems(Destination
);
372 PMENU_OBJECT FASTCALL
373 IntCloneMenu(PMENU_OBJECT Source
)
376 PMENU_OBJECT MenuObject
;
381 MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
382 PsGetWin32Thread()->Desktop
->WindowStation
->HandleTable
, &Handle
,
383 otMenu
, sizeof(MENU_OBJECT
));
387 MenuObject
->Process
= PsGetCurrentProcess();
388 MenuObject
->RtoL
= Source
->RtoL
;
389 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
390 MenuObject
->MenuInfo
.fMask
= Source
->MenuInfo
.fMask
;
391 MenuObject
->MenuInfo
.dwStyle
= Source
->MenuInfo
.dwStyle
;
392 MenuObject
->MenuInfo
.cyMax
= Source
->MenuInfo
.cyMax
;
393 MenuObject
->MenuInfo
.hbrBack
= Source
->MenuInfo
.hbrBack
;
394 MenuObject
->MenuInfo
.dwContextHelpID
= Source
->MenuInfo
.dwContextHelpID
;
395 MenuObject
->MenuInfo
.dwMenuData
= Source
->MenuInfo
.dwMenuData
;
396 MenuObject
->MenuInfo
.Self
= Handle
;
397 MenuObject
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
398 MenuObject
->MenuInfo
.Wnd
= NULL
;
399 MenuObject
->MenuInfo
.WndOwner
= NULL
;
400 MenuObject
->MenuInfo
.Height
= 0;
401 MenuObject
->MenuInfo
.Width
= 0;
402 MenuObject
->MenuInfo
.TimeToHide
= FALSE
;
404 MenuObject
->MenuInfo
.MenuItemCount
= 0;
405 MenuObject
->MenuItemList
= NULL
;
406 ExInitializeFastMutex(&MenuObject
->MenuItemsLock
);
408 /* Insert menu item into process menu handle list */
409 IntLockProcessMenus(PsGetWin32Process());
410 InsertTailList(&PsGetWin32Process()->MenuListHead
, &MenuObject
->ListEntry
);
411 IntUnLockProcessMenus(PsGetWin32Process());
413 IntCloneMenuItems(MenuObject
, Source
);
419 IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject
)
421 MenuObject
->RtoL
= TRUE
;
426 IntSetMenuContextHelpId(PMENU_OBJECT MenuObject
, DWORD dwContextHelpId
)
428 MenuObject
->MenuInfo
.dwContextHelpID
= dwContextHelpId
;
433 IntGetMenuInfo(PMENU_OBJECT MenuObject
, PROSMENUINFO lpmi
)
435 if(lpmi
->fMask
& MIM_BACKGROUND
)
436 lpmi
->hbrBack
= MenuObject
->MenuInfo
.hbrBack
;
437 if(lpmi
->fMask
& MIM_HELPID
)
438 lpmi
->dwContextHelpID
= MenuObject
->MenuInfo
.dwContextHelpID
;
439 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
440 lpmi
->cyMax
= MenuObject
->MenuInfo
.cyMax
;
441 if(lpmi
->fMask
& MIM_MENUDATA
)
442 lpmi
->dwMenuData
= MenuObject
->MenuInfo
.dwMenuData
;
443 if(lpmi
->fMask
& MIM_STYLE
)
444 lpmi
->dwStyle
= MenuObject
->MenuInfo
.dwStyle
;
445 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
447 RtlCopyMemory((char *) lpmi
+ sizeof(MENUINFO
),
448 (char *) &MenuObject
->MenuInfo
+ sizeof(MENUINFO
),
449 lpmi
->cbSize
- sizeof(MENUINFO
));
457 IntIsMenu(HMENU hMenu
)
461 if((Menu
= IntGetMenuObject(hMenu
)))
463 IntReleaseMenuObject(Menu
);
471 IntSetMenuInfo(PMENU_OBJECT MenuObject
, PROSMENUINFO lpmi
)
473 if(lpmi
->fMask
& MIM_BACKGROUND
)
474 MenuObject
->MenuInfo
.hbrBack
= lpmi
->hbrBack
;
475 if(lpmi
->fMask
& MIM_HELPID
)
476 MenuObject
->MenuInfo
.dwContextHelpID
= lpmi
->dwContextHelpID
;
477 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
478 MenuObject
->MenuInfo
.cyMax
= lpmi
->cyMax
;
479 if(lpmi
->fMask
& MIM_MENUDATA
)
480 MenuObject
->MenuInfo
.dwMenuData
= lpmi
->dwMenuData
;
481 if(lpmi
->fMask
& MIM_STYLE
)
482 MenuObject
->MenuInfo
.dwStyle
= lpmi
->dwStyle
;
483 if(lpmi
->fMask
& MIM_APPLYTOSUBMENUS
)
487 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
489 MenuObject
->MenuInfo
.FocusedItem
= lpmi
->FocusedItem
;
490 MenuObject
->MenuInfo
.Height
= lpmi
->Height
;
491 MenuObject
->MenuInfo
.Width
= lpmi
->Width
;
492 MenuObject
->MenuInfo
.Wnd
= lpmi
->Wnd
;
493 MenuObject
->MenuInfo
.WndOwner
= lpmi
->WndOwner
;
494 MenuObject
->MenuInfo
.TimeToHide
= lpmi
->TimeToHide
;
502 IntGetMenuItemByFlag(PMENU_OBJECT MenuObject
, UINT uSearchBy
, UINT fFlag
,
503 PMENU_ITEM
*MenuItem
, PMENU_ITEM
*PrevMenuItem
)
505 PMENU_ITEM PrevItem
= NULL
;
506 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
510 if(MF_BYPOSITION
& fFlag
)
513 while(CurItem
&& (p
> 0))
516 CurItem
= CurItem
->Next
;
521 if(MenuItem
) *MenuItem
= CurItem
;
522 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
526 if(MenuItem
) *MenuItem
= NULL
;
527 if(PrevMenuItem
) *PrevMenuItem
= NULL
; /* ? */
531 return uSearchBy
- p
;
538 if(CurItem
->wID
== uSearchBy
)
540 if(MenuItem
) *MenuItem
= CurItem
;
541 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
544 else if (0 != (CurItem
->fType
& MF_POPUP
))
546 MenuObject
= IntGetMenuObject(CurItem
->hSubMenu
);
547 if (NULL
!= MenuObject
)
549 ret
= IntGetMenuItemByFlag(MenuObject
, uSearchBy
, fFlag
,
550 MenuItem
, PrevMenuItem
);
553 IntReleaseMenuObject(MenuObject
);
557 IntReleaseMenuObject(MenuObject
);
560 CurItem
= CurItem
->Next
;
569 IntInsertMenuItemToList(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, int pos
)
572 PMENU_ITEM LastItem
= NULL
;
575 CurItem
= MenuObject
->MenuItemList
;
581 CurItem
= CurItem
->Next
;
587 while(CurItem
&& (pos
> 0))
590 CurItem
= CurItem
->Next
;
600 /* insert the item before CurItem */
601 MenuItem
->Next
= LastItem
->Next
;
602 LastItem
->Next
= MenuItem
;
606 /* insert at the beginning */
607 MenuObject
->MenuItemList
= MenuItem
;
608 MenuItem
->Next
= CurItem
;
616 LastItem
->Next
= MenuItem
;
617 MenuItem
->Next
= NULL
;
621 /* insert first item */
622 MenuObject
->MenuItemList
= MenuItem
;
623 MenuItem
->Next
= NULL
;
626 MenuObject
->MenuInfo
.MenuItemCount
++;
632 IntGetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
637 lpmii
->cch
= MenuItem
->Text
.Length
/ sizeof(WCHAR
);
639 if(lpmii
->fMask
& MIIM_BITMAP
)
641 lpmii
->hbmpItem
= MenuItem
->hbmpItem
;
643 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
645 lpmii
->hbmpChecked
= MenuItem
->hbmpChecked
;
646 lpmii
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
648 if(lpmii
->fMask
& MIIM_DATA
)
650 lpmii
->dwItemData
= MenuItem
->dwItemData
;
652 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
654 lpmii
->fType
= MenuItem
->fType
;
656 if(lpmii
->fMask
& MIIM_ID
)
658 lpmii
->wID
= MenuItem
->wID
;
660 if(lpmii
->fMask
& MIIM_STATE
)
662 lpmii
->fState
= MenuItem
->fState
;
664 if(lpmii
->fMask
& MIIM_SUBMENU
)
666 lpmii
->hSubMenu
= MenuItem
->hSubMenu
;
668 if (0 != (lpmii
->fMask
& MIIM_STRING
) ||
669 0 != (lpmii
->fMask
& MIIM_TYPE
))
671 Status
= MmCopyFromCaller(&Text
, lpmii
->dwTypeData
, sizeof(UNICODE_STRING
));
672 if (! NT_SUCCESS(Status
))
674 SetLastNtError(Status
);
677 Text
.Length
= min(Text
.MaximumLength
, MenuItem
->Text
.Length
);
678 if (0 != Text
.Length
)
680 Status
= MmCopyToCaller(Text
.Buffer
, MenuItem
->Text
.Buffer
, Text
.Length
);
681 if (! NT_SUCCESS(Status
))
683 SetLastNtError(Status
);
687 Status
= MmCopyToCaller(lpmii
->dwTypeData
, &Text
, sizeof(UNICODE_STRING
));
688 if (! NT_SUCCESS(Status
))
690 SetLastNtError(Status
);
695 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
697 lpmii
->Rect
= MenuItem
->Rect
;
698 lpmii
->XTab
= MenuItem
->XTab
;
705 IntSetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
707 PUNICODE_STRING Source
;
709 PMENU_OBJECT SubMenuObject
;
711 if(!MenuItem
|| !MenuObject
|| !lpmii
)
716 MenuItem
->fType
= lpmii
->fType
;
718 if(lpmii
->fMask
& MIIM_BITMAP
)
720 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
722 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
724 MenuItem
->hbmpChecked
= lpmii
->hbmpChecked
;
725 MenuItem
->hbmpUnchecked
= lpmii
->hbmpUnchecked
;
727 if(lpmii
->fMask
& MIIM_DATA
)
729 MenuItem
->dwItemData
= lpmii
->dwItemData
;
731 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
733 MenuItem
->fType
= lpmii
->fType
;
735 if(lpmii
->fMask
& MIIM_ID
)
737 MenuItem
->wID
= lpmii
->wID
;
739 if(lpmii
->fMask
& MIIM_STATE
)
741 /* remove MFS_DEFAULT flag from all other menu items if this item
742 has the MFS_DEFAULT state */
743 if(lpmii
->fState
& MFS_DEFAULT
)
744 IntSetMenuDefaultItem(MenuObject
, -1, 0);
745 /* update the menu item state flags */
746 UpdateMenuItemState(MenuItem
->fState
, lpmii
->fState
);
749 if(lpmii
->fMask
& MIIM_SUBMENU
)
751 MenuItem
->hSubMenu
= lpmii
->hSubMenu
;
752 /* Make sure the submenu is marked as a popup menu */
753 if (0 != (MenuItem
->fType
& MF_POPUP
))
755 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
756 if (NULL
!= SubMenuObject
)
758 SubMenuObject
->MenuInfo
.Flags
|= MF_POPUP
;
759 IntReleaseMenuObject(SubMenuObject
);
763 if((lpmii
->fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
764 (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
))
766 if(lpmii
->dwTypeData
&& lpmii
->cch
)
768 Source
= (PUNICODE_STRING
)lpmii
->dwTypeData
;
769 FreeMenuText(MenuItem
);
770 copylen
= min((UINT
)Source
->MaximumLength
, (lpmii
->cch
+ 1) * sizeof(WCHAR
));
771 MenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, copylen
, TAG_STRING
);
772 if(MenuItem
->Text
.Buffer
)
774 MenuItem
->Text
.Length
= 0;
775 MenuItem
->Text
.MaximumLength
= copylen
;
776 RtlCopyUnicodeString(&MenuItem
->Text
, Source
);
780 MenuItem
->Text
.Length
= 0;
781 MenuItem
->Text
.MaximumLength
= 0;
782 MenuItem
->Text
.Buffer
= NULL
;
787 MenuItem
->fType
|= MF_SEPARATOR
;
788 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
793 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
796 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
798 MenuItem
->Rect
= lpmii
->Rect
;
799 MenuItem
->XTab
= lpmii
->XTab
;
806 IntInsertMenuItem(PMENU_OBJECT MenuObject
, UINT uItem
, BOOL fByPosition
,
807 PROSMENUITEMINFO ItemInfo
)
809 int pos
= (int)uItem
;
812 if (MAX_MENU_ITEMS
<= MenuObject
->MenuInfo
.MenuItemCount
)
814 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
820 /* calculate position */
821 if(MenuObject
->MenuInfo
.MenuItemCount
< pos
)
823 pos
= MenuObject
->MenuInfo
.MenuItemCount
;
828 pos
= IntGetMenuItemByFlag(MenuObject
, uItem
, MF_BYCOMMAND
, NULL
, NULL
);
835 MenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
836 if (NULL
== MenuItem
)
838 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
842 MenuItem
->fType
= MFT_STRING
;
843 MenuItem
->fState
= MFS_ENABLED
| MFS_UNCHECKED
;
845 MenuItem
->hSubMenu
= (HMENU
)0;
846 MenuItem
->hbmpChecked
= (HBITMAP
)0;
847 MenuItem
->hbmpUnchecked
= (HBITMAP
)0;
848 MenuItem
->dwItemData
= 0;
849 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
850 MenuItem
->hbmpItem
= (HBITMAP
)0;
852 if (! IntSetMenuItemInfo(MenuObject
, MenuItem
, ItemInfo
))
854 ExFreePool(MenuItem
);
858 /* Force size recalculation! */
859 MenuObject
->MenuInfo
.Height
= 0;
861 pos
= IntInsertMenuItemToList(MenuObject
, MenuItem
, pos
);
867 IntEnableMenuItem(PMENU_OBJECT MenuObject
, UINT uIDEnableItem
, UINT uEnable
)
870 UINT res
= IntGetMenuItemByFlag(MenuObject
, uIDEnableItem
, uEnable
, &MenuItem
, NULL
);
871 if(!MenuItem
|| (res
== (UINT
)-1))
876 res
= MenuItem
->fState
& (MF_GRAYED
| MF_DISABLED
);
878 if(uEnable
& MF_DISABLED
)
880 if(!(MenuItem
->fState
& MF_DISABLED
))
881 MenuItem
->fState
|= MF_DISABLED
;
882 if(uEnable
& MF_GRAYED
)
884 if(!(MenuItem
->fState
& MF_GRAYED
))
885 MenuItem
->fState
|= MF_GRAYED
;
890 if(uEnable
& MF_GRAYED
)
892 if(!(MenuItem
->fState
& MF_GRAYED
))
893 MenuItem
->fState
|= MF_GRAYED
;
894 if(!(MenuItem
->fState
& MF_DISABLED
))
895 MenuItem
->fState
|= MF_DISABLED
;
899 if(MenuItem
->fState
& MF_DISABLED
)
900 MenuItem
->fState
^= MF_DISABLED
;
901 if(MenuItem
->fState
& MF_GRAYED
)
902 MenuItem
->fState
^= MF_GRAYED
;
911 IntBuildMenuItemList(PMENU_OBJECT MenuObject
, PVOID Buffer
, ULONG nMax
)
917 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
924 if (nMax
< MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
))
928 StrOut
= (PWCHAR
)((char *) Buffer
+ MenuObject
->MenuInfo
.MenuItemCount
929 * sizeof(ROSMENUITEMINFO
));
930 nMax
-= MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
);
931 sz
= sizeof(ROSMENUITEMINFO
);
933 mii
.cbSize
= sizeof(ROSMENUITEMINFO
);
937 while (NULL
!= CurItem
)
939 mii
.cch
= CurItem
->Text
.Length
/ sizeof(WCHAR
);
940 mii
.dwItemData
= CurItem
->dwItemData
;
941 if (0 != CurItem
->Text
.Length
)
943 mii
.dwTypeData
= StrOut
;
947 mii
.dwTypeData
= NULL
;
949 mii
.fState
= CurItem
->fState
;
950 mii
.fType
= CurItem
->fType
;
951 mii
.hbmpChecked
= CurItem
->hbmpChecked
;
952 mii
.hbmpItem
= CurItem
->hbmpItem
;
953 mii
.hbmpUnchecked
= CurItem
->hbmpUnchecked
;
954 mii
.hSubMenu
= CurItem
->hSubMenu
;
955 mii
.Rect
= CurItem
->Rect
;
956 mii
.XTab
= CurItem
->XTab
;
958 Status
= MmCopyToCaller(Buf
, &mii
, sizeof(ROSMENUITEMINFO
));
959 if (! NT_SUCCESS(Status
))
961 SetLastNtError(Status
);
964 Buf
+= sizeof(ROSMENUITEMINFO
);
966 if (0 != CurItem
->Text
.Length
967 && (nMax
>= CurItem
->Text
.Length
+ sizeof(WCHAR
)))
970 Status
= MmCopyToCaller(StrOut
, CurItem
->Text
.Buffer
,
971 CurItem
->Text
.Length
);
972 if (! NT_SUCCESS(Status
))
974 SetLastNtError(Status
);
977 StrOut
+= CurItem
->Text
.Length
/ sizeof(WCHAR
);
978 Status
= MmCopyToCaller(StrOut
, &NulByte
, sizeof(WCHAR
));
979 if (! NT_SUCCESS(Status
))
981 SetLastNtError(Status
);
985 nMax
-= CurItem
->Text
.Length
+ sizeof(WCHAR
);
987 else if (0 != CurItem
->Text
.Length
)
992 CurItem
= CurItem
->Next
;
998 while (NULL
!= CurItem
)
1000 res
+= sizeof(ROSMENUITEMINFO
) + CurItem
->Text
.Length
+ sizeof(WCHAR
);
1001 CurItem
= CurItem
->Next
;
1010 IntCheckMenuItem(PMENU_OBJECT MenuObject
, UINT uIDCheckItem
, UINT uCheck
)
1012 PMENU_ITEM MenuItem
;
1015 if((IntGetMenuItemByFlag(MenuObject
, uIDCheckItem
, uCheck
, &MenuItem
, NULL
) < 0) || !MenuItem
)
1020 res
= (DWORD
)(MenuItem
->fState
& MF_CHECKED
);
1021 if(uCheck
& MF_CHECKED
)
1023 if(!(MenuItem
->fState
& MF_CHECKED
))
1024 MenuItem
->fState
|= MF_CHECKED
;
1028 if(MenuItem
->fState
& MF_CHECKED
)
1029 MenuItem
->fState
^= MF_CHECKED
;
1036 IntHiliteMenuItem(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
,
1037 UINT uItemHilite
, UINT uHilite
)
1039 PMENU_ITEM MenuItem
;
1040 BOOL res
= IntGetMenuItemByFlag(MenuObject
, uItemHilite
, uHilite
, &MenuItem
, NULL
);
1041 if(!MenuItem
|| !res
)
1046 if(uHilite
& MF_HILITE
)
1048 if(!(MenuItem
->fState
& MF_HILITE
))
1049 MenuItem
->fState
|= MF_HILITE
;
1053 if(MenuItem
->fState
& MF_HILITE
)
1054 MenuItem
->fState
^= MF_HILITE
;
1057 /* FIXME - update the window's menu */
1063 IntSetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT uItem
, UINT fByPos
)
1066 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1068 if(uItem
== (UINT
)-1)
1072 if(MenuItem
->fState
& MFS_DEFAULT
)
1073 MenuItem
->fState
^= MFS_DEFAULT
;
1074 MenuItem
= MenuItem
->Next
;
1086 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1087 MenuItem
->fState
|= MFS_DEFAULT
;
1092 if(MenuItem
->fState
& MFS_DEFAULT
)
1093 MenuItem
->fState
^= MFS_DEFAULT
;
1096 MenuItem
= MenuItem
->Next
;
1103 if(!ret
&& (MenuItem
->wID
== uItem
))
1105 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1106 MenuItem
->fState
|= MFS_DEFAULT
;
1111 if(MenuItem
->fState
& MFS_DEFAULT
)
1112 MenuItem
->fState
^= MFS_DEFAULT
;
1114 MenuItem
= MenuItem
->Next
;
1122 IntGetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT fByPos
, UINT gmdiFlags
,
1128 PMENU_OBJECT SubMenuObject
;
1129 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1133 if(MenuItem
->fState
& MFS_DEFAULT
)
1136 if(!(gmdiFlags
& GMDI_USEDISABLED
) && (MenuItem
->fState
& MFS_DISABLED
))
1139 if(fByPos
& MF_BYPOSITION
)
1142 res
= MenuItem
->wID
;
1144 if((*gismc
< MAX_GOINTOSUBMENU
) && (gmdiFlags
& GMDI_GOINTOPOPUPS
) &&
1148 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
1149 if(!SubMenuObject
|| (SubMenuObject
== MenuObject
))
1152 IntLockMenuItems(SubMenuObject
);
1153 IntUnLockMenuItems(MenuObject
);
1156 sres
= IntGetMenuDefaultItem(SubMenuObject
, fByPos
, gmdiFlags
, gismc
);
1159 IntUnLockMenuItems(SubMenuObject
);
1160 IntLockMenuItems(MenuObject
);
1161 IntReleaseMenuObject(SubMenuObject
);
1170 MenuItem
= MenuItem
->Next
;
1178 IntInitTracking(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
, BOOL Popup
,
1181 /* FIXME - hide caret */
1183 if(!(Flags
& TPM_NONOTIFY
))
1184 IntSendMessage(WindowObject
->Self
, WM_SETCURSOR
, (WPARAM
)WindowObject
->Self
, HTCAPTION
);
1186 /* FIXME - send WM_SETCURSOR message */
1188 if(!(Flags
& TPM_NONOTIFY
))
1189 IntSendMessage(WindowObject
->Self
, WM_INITMENU
, (WPARAM
)MenuObject
->MenuInfo
.Self
, 0);
1193 IntExitTracking(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
, BOOL Popup
,
1196 if(!(Flags
& TPM_NONOTIFY
))
1197 IntSendMessage(WindowObject
->Self
, WM_EXITMENULOOP
, 0 /* FIXME */, 0);
1199 /* FIXME - Show caret again */
1203 IntTrackMenu(PMENU_OBJECT MenuObject
, PWINDOW_OBJECT WindowObject
, INT x
, INT y
,
1210 IntTrackPopupMenu(PMENU_OBJECT MenuObject
, PWINDOW_OBJECT WindowObject
,
1211 UINT Flags
, POINT
*Pos
, UINT MenuPos
, RECT
*ExcludeRect
)
1213 IntInitTracking(WindowObject
, MenuObject
, TRUE
, Flags
);
1215 IntExitTracking(WindowObject
, MenuObject
, TRUE
, Flags
);
1220 IntSetMenuItemRect(PMENU_OBJECT MenuObject
, UINT Item
, BOOL fByPos
, RECT
*rcRect
)
1223 if(IntGetMenuItemByFlag(MenuObject
, Item
, (fByPos
? MF_BYPOSITION
: MF_BYCOMMAND
),
1234 * Internal function. Called when the process is destroyed to free the remaining menu handles.
1237 IntCleanupMenus(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
1239 PEPROCESS CurrentProcess
;
1240 PLIST_ENTRY LastHead
= NULL
;
1241 PMENU_OBJECT MenuObject
;
1243 CurrentProcess
= PsGetCurrentProcess();
1244 if (CurrentProcess
!= Process
)
1246 KeAttachProcess(Process
);
1249 IntLockProcessMenus(Win32Process
);
1250 while (Win32Process
->MenuListHead
.Flink
!= &(Win32Process
->MenuListHead
) &&
1251 Win32Process
->MenuListHead
.Flink
!= LastHead
)
1253 LastHead
= Win32Process
->MenuListHead
.Flink
;
1254 MenuObject
= CONTAINING_RECORD(Win32Process
->MenuListHead
.Flink
, MENU_OBJECT
, ListEntry
);
1256 IntUnLockProcessMenus(Win32Process
);
1257 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1258 IntLockProcessMenus(Win32Process
);
1260 IntUnLockProcessMenus(Win32Process
);
1262 if (CurrentProcess
!= Process
)
1269 /* FUNCTIONS *****************************************************************/
1277 NtUserBuildMenuItemList(
1284 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1287 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1293 IntLockMenuItems(MenuObject
);
1294 res
= IntBuildMenuItemList(MenuObject
, Buffer
, nBufSize
);
1295 IntUnLockMenuItems(MenuObject
);
1299 res
= MenuObject
->MenuInfo
.MenuItemCount
;
1302 IntReleaseMenuObject(MenuObject
);
1312 NtUserCheckMenuItem(
1318 PMENU_OBJECT MenuObject
= IntGetMenuObject(hmenu
);
1321 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1324 IntLockMenuItems(MenuObject
);
1325 res
= IntCheckMenuItem(MenuObject
, uIDCheckItem
, uCheck
);
1326 IntUnLockMenuItems(MenuObject
);
1327 IntReleaseMenuObject(MenuObject
);
1336 NtUserCreateMenu(BOOL PopupMenu
)
1338 PWINSTATION_OBJECT WinStaObject
;
1341 NTSTATUS Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1346 if (!NT_SUCCESS(Status
))
1348 DPRINT("Validation of window station handle (0x%X) failed\n",
1349 PROCESS_WINDOW_STATION());
1350 SetLastNtError(Status
);
1354 IntCreateMenu(&Handle
, !PopupMenu
);
1356 ObDereferenceObject(WinStaObject
);
1357 return (HMENU
)Handle
;
1371 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1374 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1378 res
= IntRemoveMenuItem(MenuObject
, uPosition
, uFlags
, TRUE
);
1379 IntReleaseMenuObject(MenuObject
);
1394 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1397 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1400 if(MenuObject
->Process
!= PsGetCurrentProcess())
1402 IntReleaseMenuObject(MenuObject
);
1403 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1407 Ret
= IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1409 IntReleaseMenuObject(MenuObject
);
1418 NtUserEnableMenuItem(
1423 UINT res
= (UINT
)-1;
1424 PMENU_OBJECT MenuObject
;
1425 MenuObject
= IntGetMenuObject(hMenu
);
1428 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1431 IntLockMenuItems(MenuObject
);
1432 res
= IntEnableMenuItem(MenuObject
, uIDEnableItem
, uEnable
);
1433 IntUnLockMenuItems(MenuObject
);
1434 IntReleaseMenuObject(MenuObject
);
1444 NtUserInsertMenuItem(
1448 LPCMENUITEMINFOW UnsafeItemInfo
)
1451 PMENU_OBJECT MenuObject
;
1453 ROSMENUITEMINFO ItemInfo
;
1455 MenuObject
= IntGetMenuObject(hMenu
);
1458 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1462 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, sizeof(MENUITEMINFOW
));
1463 if (! NT_SUCCESS(Status
))
1465 IntReleaseMenuObject(MenuObject
);
1466 SetLastNtError(Status
);
1469 if (ItemInfo
.cbSize
!= sizeof(MENUITEMINFOW
))
1471 IntReleaseMenuObject(MenuObject
);
1472 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1476 IntLockMenuItems(MenuObject
);
1477 Res
= IntInsertMenuItem(MenuObject
, uItem
, fByPosition
, &ItemInfo
);
1478 IntUnLockMenuItems(MenuObject
);
1479 IntReleaseMenuObject(MenuObject
);
1501 NtUserGetMenuDefaultItem(
1506 PMENU_OBJECT MenuObject
;
1509 MenuObject
= IntGetMenuObject(hMenu
);
1512 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1515 IntLockMenuItems(MenuObject
);
1516 res
= IntGetMenuDefaultItem(MenuObject
, fByPos
, gmdiFlags
, &gismc
);
1517 IntUnLockMenuItems(MenuObject
);
1518 IntReleaseMenuObject(MenuObject
);
1527 NtUserGetMenuBarInfo(
1557 NtUserGetMenuItemRect(
1573 NtUserHiliteMenuItem(
1580 PMENU_OBJECT MenuObject
;
1581 PWINDOW_OBJECT WindowObject
= IntGetWindowObject(hwnd
);
1584 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1587 MenuObject
= IntGetMenuObject(hmenu
);
1590 IntReleaseWindowObject(WindowObject
);
1591 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1594 if(WindowObject
->IDMenu
== (UINT
)hmenu
)
1596 IntLockMenuItems(MenuObject
);
1597 res
= IntHiliteMenuItem(WindowObject
, MenuObject
, uItemHilite
, uHilite
);
1598 IntUnLockMenuItems(MenuObject
);
1600 IntReleaseMenuObject(MenuObject
);
1601 IntReleaseWindowObject(WindowObject
);
1613 PROSMENUINFO UnsafeMenuInfo
,
1617 PMENU_OBJECT MenuObject
;
1620 ROSMENUINFO MenuInfo
;
1622 Status
= MmCopyFromCaller(&Size
, &UnsafeMenuInfo
->cbSize
, sizeof(DWORD
));
1623 if (! NT_SUCCESS(Status
))
1625 SetLastNtError(Status
);
1628 if(Size
< sizeof(MENUINFO
) || sizeof(ROSMENUINFO
) < Size
)
1630 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1633 Status
= MmCopyFromCaller(&MenuInfo
, UnsafeMenuInfo
, Size
);
1634 if (! NT_SUCCESS(Status
))
1636 SetLastNtError(Status
);
1640 MenuObject
= IntGetMenuObject(Menu
);
1641 if (NULL
== MenuObject
)
1643 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1650 Res
= IntSetMenuInfo(MenuObject
, &MenuInfo
);
1655 Res
= IntGetMenuInfo(MenuObject
, &MenuInfo
);
1658 Status
= MmCopyToCaller(UnsafeMenuInfo
, &MenuInfo
, Size
);
1659 if (! NT_SUCCESS(Status
))
1661 SetLastNtError(Status
);
1667 IntReleaseMenuObject(MenuObject
);
1677 NtUserMenuItemFromPoint(
1683 PMENU_OBJECT MenuObject
;
1684 PWINDOW_OBJECT WindowObject
= NULL
;
1688 MenuObject
= IntGetMenuObject(Menu
);
1689 if (NULL
== MenuObject
)
1691 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1695 WindowObject
= IntGetWindowObject(MenuObject
->MenuInfo
.Wnd
);
1696 if (NULL
== WindowObject
)
1698 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1701 X
-= WindowObject
->WindowRect
.left
;
1702 Y
-= WindowObject
->WindowRect
.top
;
1703 IntReleaseWindowObject(WindowObject
);
1705 IntLockMenuItems(MenuObject
);
1706 mi
= MenuObject
->MenuItemList
;
1707 for (i
= 0; NULL
!= mi
; i
++)
1709 if (InRect(mi
->Rect
, X
, Y
))
1715 IntUnLockMenuItems(MenuObject
);
1717 IntReleaseMenuObject(MenuObject
);
1719 return (mi
? i
: NO_SELECTED_ITEM
);
1732 PROSMENUITEMINFO UnsafeItemInfo
,
1735 PMENU_OBJECT MenuObject
;
1736 PMENU_ITEM MenuItem
;
1737 ROSMENUITEMINFO ItemInfo
;
1742 MenuObject
= IntGetMenuObject(Menu
);
1743 if (NULL
== MenuObject
)
1745 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1748 Status
= MmCopyFromCaller(&Size
, &UnsafeItemInfo
->cbSize
, sizeof(UINT
));
1749 if (! NT_SUCCESS(Status
))
1751 IntReleaseMenuObject(MenuObject
);
1752 SetLastNtError(Status
);
1755 if (sizeof(MENUITEMINFOW
) != Size
1756 && sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
) != Size
1757 && sizeof(ROSMENUITEMINFO
) != Size
)
1759 IntReleaseMenuObject(MenuObject
);
1760 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1763 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, Size
);
1764 if (! NT_SUCCESS(Status
))
1766 IntReleaseMenuObject(MenuObject
);
1767 SetLastNtError(Status
);
1770 /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
1772 if (sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
) == Size
1773 && 0 != (ItemInfo
.fMask
& MIIM_BITMAP
))
1775 IntReleaseMenuObject(MenuObject
);
1776 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1780 if (IntGetMenuItemByFlag(MenuObject
, Item
,
1781 (ByPosition
? MF_BYPOSITION
: MF_BYCOMMAND
),
1782 &MenuItem
, NULL
) < 0)
1784 IntReleaseMenuObject(MenuObject
);
1785 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1791 Ret
= IntSetMenuItemInfo(MenuObject
, MenuItem
, &ItemInfo
);
1795 Ret
= IntGetMenuItemInfo(MenuObject
, MenuItem
, &ItemInfo
);
1798 Status
= MmCopyToCaller(UnsafeItemInfo
, &ItemInfo
, Size
);
1799 if (! NT_SUCCESS(Status
))
1801 IntReleaseMenuObject(MenuObject
);
1802 SetLastNtError(Status
);
1808 IntReleaseMenuObject(MenuObject
);
1824 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1827 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1831 res
= IntRemoveMenuItem(MenuObject
, uPosition
, uFlags
, FALSE
);
1832 IntReleaseMenuObject(MenuObject
);
1842 NtUserSetMenuContextHelpId(
1844 DWORD dwContextHelpId
)
1847 PMENU_OBJECT MenuObject
= IntGetMenuObject(hmenu
);
1850 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1854 res
= IntSetMenuContextHelpId(MenuObject
, dwContextHelpId
);
1855 IntReleaseMenuObject(MenuObject
);
1864 NtUserSetMenuDefaultItem(
1870 PMENU_OBJECT MenuObject
;
1871 MenuObject
= IntGetMenuObject(hMenu
);
1874 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1877 IntLockMenuItems(MenuObject
);
1878 res
= IntSetMenuDefaultItem(MenuObject
, uItem
, fByPos
);
1879 IntUnLockMenuItems(MenuObject
);
1880 IntReleaseMenuObject(MenuObject
);
1890 NtUserSetMenuFlagRtoL(
1894 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1897 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1901 res
= IntSetMenuFlagRtoL(MenuObject
);
1902 IntReleaseMenuObject(MenuObject
);
1911 NtUserThunkedMenuInfo(
1916 /* This function seems just to call SetMenuInfo() */
1925 NtUserThunkedMenuItemInfo(
1930 LPMENUITEMINFOW lpmii
,
1931 PUNICODE_STRING lpszCaption
)
1934 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
1935 if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
1945 NtUserTrackPopupMenuEx(
1953 PMENU_OBJECT MenuObject
;
1954 PWINDOW_OBJECT WindowObject
;
1960 MenuObject
= IntGetMenuObject(hmenu
);
1963 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1967 WindowObject
= IntGetWindowObject(hwnd
);
1970 IntReleaseMenuObject(MenuObject
);
1971 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1977 Status
= MmCopyFromCaller(&Safetpm
, lptpm
, sizeof(TPMPARAMS
));
1978 if(!NT_SUCCESS(Status
))
1980 IntReleaseWindowObject(WindowObject
);
1981 IntReleaseMenuObject(MenuObject
);
1982 SetLastNtError(Status
);
1985 if(Safetpm
.cbSize
!= sizeof(TPMPARAMS
))
1987 IntReleaseWindowObject(WindowObject
);
1988 IntReleaseMenuObject(MenuObject
);
1989 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1997 Ret
= IntTrackPopupMenu(MenuObject
, WindowObject
, fuFlags
, &Pos
, 0,
1998 (lptpm
? &Safetpm
.rcExclude
: NULL
));
2000 IntReleaseWindowObject(WindowObject
);
2001 IntReleaseMenuObject(MenuObject
);