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 ******************************************************************/
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(gHandleTable
,
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 IntDeleteMenuItems(MenuObject
, bRecurse
); /* do not destroy submenus */
233 if(RemoveFromProcess
)
235 RemoveEntryList(&MenuObject
->ListEntry
);
238 Status
= ObReferenceObjectByHandle(MenuObject
->Process
->Win32WindowStation
,
240 ExWindowStationObjectType
,
242 (PVOID
*)&WindowStation
,
244 if(NT_SUCCESS(Status
))
246 ObmCloseHandle(gHandleTable
, MenuObject
->MenuInfo
.Self
);
247 ObDereferenceObject(WindowStation
);
254 PMENU_OBJECT FASTCALL
255 IntCreateMenu(PHANDLE Handle
, BOOL IsMenuBar
)
257 PMENU_OBJECT MenuObject
;
259 MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
260 gHandleTable
, Handle
,
261 otMenu
, sizeof(MENU_OBJECT
));
269 MenuObject
->Process
= PsGetCurrentProcess();
270 MenuObject
->RtoL
= FALSE
; /* default */
271 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
272 MenuObject
->MenuInfo
.fMask
= 0; /* not used */
273 MenuObject
->MenuInfo
.dwStyle
= 0; /* FIXME */
274 MenuObject
->MenuInfo
.cyMax
= 0; /* default */
275 MenuObject
->MenuInfo
.hbrBack
=
276 NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */
277 MenuObject
->MenuInfo
.dwContextHelpID
= 0; /* default */
278 MenuObject
->MenuInfo
.dwMenuData
= 0; /* default */
279 MenuObject
->MenuInfo
.Self
= *Handle
;
280 MenuObject
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
281 MenuObject
->MenuInfo
.Flags
= (IsMenuBar
? 0 : MF_POPUP
);
282 MenuObject
->MenuInfo
.Wnd
= NULL
;
283 MenuObject
->MenuInfo
.WndOwner
= NULL
;
284 MenuObject
->MenuInfo
.Height
= 0;
285 MenuObject
->MenuInfo
.Width
= 0;
286 MenuObject
->MenuInfo
.TimeToHide
= FALSE
;
288 MenuObject
->MenuInfo
.MenuItemCount
= 0;
289 MenuObject
->MenuItemList
= NULL
;
291 /* Insert menu item into process menu handle list */
292 InsertTailList(&PsGetWin32Process()->MenuListHead
, &MenuObject
->ListEntry
);
298 IntCloneMenuItems(PMENU_OBJECT Destination
, PMENU_OBJECT Source
)
300 PMENU_ITEM MenuItem
, NewMenuItem
= NULL
;
301 PMENU_ITEM Old
= NULL
;
303 if(!Source
->MenuInfo
.MenuItemCount
)
306 MenuItem
= Source
->MenuItemList
;
311 NewMenuItem
->Next
= MenuItem
;
312 NewMenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
315 NewMenuItem
->fType
= MenuItem
->fType
;
316 NewMenuItem
->fState
= MenuItem
->fState
;
317 NewMenuItem
->wID
= MenuItem
->wID
;
318 NewMenuItem
->hSubMenu
= MenuItem
->hSubMenu
;
319 NewMenuItem
->hbmpChecked
= MenuItem
->hbmpChecked
;
320 NewMenuItem
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
321 NewMenuItem
->dwItemData
= MenuItem
->dwItemData
;
322 if((MENU_ITEM_TYPE(NewMenuItem
->fType
) == MF_STRING
))
324 if(MenuItem
->Text
.Length
)
326 NewMenuItem
->Text
.Length
= 0;
327 NewMenuItem
->Text
.MaximumLength
= MenuItem
->Text
.MaximumLength
;
328 NewMenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, MenuItem
->Text
.MaximumLength
, TAG_STRING
);
329 if(!NewMenuItem
->Text
.Buffer
)
331 ExFreePool(NewMenuItem
);
334 RtlCopyUnicodeString(&NewMenuItem
->Text
, &MenuItem
->Text
);
338 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
343 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
345 NewMenuItem
->hbmpItem
= MenuItem
->hbmpItem
;
347 NewMenuItem
->Next
= NULL
;
349 Old
->Next
= NewMenuItem
;
351 Destination
->MenuItemList
= NewMenuItem
;
352 Destination
->MenuInfo
.MenuItemCount
++;
353 MenuItem
= MenuItem
->Next
;
359 PMENU_OBJECT FASTCALL
360 IntCloneMenu(PMENU_OBJECT Source
)
363 PMENU_OBJECT MenuObject
;
368 MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
369 gHandleTable
, &Handle
,
370 otMenu
, sizeof(MENU_OBJECT
));
374 MenuObject
->Process
= PsGetCurrentProcess();
375 MenuObject
->RtoL
= Source
->RtoL
;
376 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
377 MenuObject
->MenuInfo
.fMask
= Source
->MenuInfo
.fMask
;
378 MenuObject
->MenuInfo
.dwStyle
= Source
->MenuInfo
.dwStyle
;
379 MenuObject
->MenuInfo
.cyMax
= Source
->MenuInfo
.cyMax
;
380 MenuObject
->MenuInfo
.hbrBack
= Source
->MenuInfo
.hbrBack
;
381 MenuObject
->MenuInfo
.dwContextHelpID
= Source
->MenuInfo
.dwContextHelpID
;
382 MenuObject
->MenuInfo
.dwMenuData
= Source
->MenuInfo
.dwMenuData
;
383 MenuObject
->MenuInfo
.Self
= Handle
;
384 MenuObject
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
385 MenuObject
->MenuInfo
.Wnd
= NULL
;
386 MenuObject
->MenuInfo
.WndOwner
= NULL
;
387 MenuObject
->MenuInfo
.Height
= 0;
388 MenuObject
->MenuInfo
.Width
= 0;
389 MenuObject
->MenuInfo
.TimeToHide
= FALSE
;
391 MenuObject
->MenuInfo
.MenuItemCount
= 0;
392 MenuObject
->MenuItemList
= NULL
;
394 /* Insert menu item into process menu handle list */
395 InsertTailList(&PsGetWin32Process()->MenuListHead
, &MenuObject
->ListEntry
);
397 IntCloneMenuItems(MenuObject
, Source
);
403 IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject
)
405 MenuObject
->RtoL
= TRUE
;
410 IntSetMenuContextHelpId(PMENU_OBJECT MenuObject
, DWORD dwContextHelpId
)
412 MenuObject
->MenuInfo
.dwContextHelpID
= dwContextHelpId
;
417 IntGetMenuInfo(PMENU_OBJECT MenuObject
, PROSMENUINFO lpmi
)
419 if(lpmi
->fMask
& MIM_BACKGROUND
)
420 lpmi
->hbrBack
= MenuObject
->MenuInfo
.hbrBack
;
421 if(lpmi
->fMask
& MIM_HELPID
)
422 lpmi
->dwContextHelpID
= MenuObject
->MenuInfo
.dwContextHelpID
;
423 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
424 lpmi
->cyMax
= MenuObject
->MenuInfo
.cyMax
;
425 if(lpmi
->fMask
& MIM_MENUDATA
)
426 lpmi
->dwMenuData
= MenuObject
->MenuInfo
.dwMenuData
;
427 if(lpmi
->fMask
& MIM_STYLE
)
428 lpmi
->dwStyle
= MenuObject
->MenuInfo
.dwStyle
;
429 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
431 RtlCopyMemory((char *) lpmi
+ sizeof(MENUINFO
),
432 (char *) &MenuObject
->MenuInfo
+ sizeof(MENUINFO
),
433 lpmi
->cbSize
- sizeof(MENUINFO
));
441 IntIsMenu(HMENU hMenu
)
445 if((Menu
= IntGetMenuObject(hMenu
)))
447 IntReleaseMenuObject(Menu
);
455 IntSetMenuInfo(PMENU_OBJECT MenuObject
, PROSMENUINFO lpmi
)
457 if(lpmi
->fMask
& MIM_BACKGROUND
)
458 MenuObject
->MenuInfo
.hbrBack
= lpmi
->hbrBack
;
459 if(lpmi
->fMask
& MIM_HELPID
)
460 MenuObject
->MenuInfo
.dwContextHelpID
= lpmi
->dwContextHelpID
;
461 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
462 MenuObject
->MenuInfo
.cyMax
= lpmi
->cyMax
;
463 if(lpmi
->fMask
& MIM_MENUDATA
)
464 MenuObject
->MenuInfo
.dwMenuData
= lpmi
->dwMenuData
;
465 if(lpmi
->fMask
& MIM_STYLE
)
466 MenuObject
->MenuInfo
.dwStyle
= lpmi
->dwStyle
;
467 if(lpmi
->fMask
& MIM_APPLYTOSUBMENUS
)
471 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
473 MenuObject
->MenuInfo
.FocusedItem
= lpmi
->FocusedItem
;
474 MenuObject
->MenuInfo
.Height
= lpmi
->Height
;
475 MenuObject
->MenuInfo
.Width
= lpmi
->Width
;
476 MenuObject
->MenuInfo
.Wnd
= lpmi
->Wnd
;
477 MenuObject
->MenuInfo
.WndOwner
= lpmi
->WndOwner
;
478 MenuObject
->MenuInfo
.TimeToHide
= lpmi
->TimeToHide
;
486 IntGetMenuItemByFlag(PMENU_OBJECT MenuObject
, UINT uSearchBy
, UINT fFlag
,
487 PMENU_ITEM
*MenuItem
, PMENU_ITEM
*PrevMenuItem
)
489 PMENU_ITEM PrevItem
= NULL
;
490 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
494 if(MF_BYPOSITION
& fFlag
)
497 while(CurItem
&& (p
> 0))
500 CurItem
= CurItem
->Next
;
505 if(MenuItem
) *MenuItem
= CurItem
;
506 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
510 if(MenuItem
) *MenuItem
= NULL
;
511 if(PrevMenuItem
) *PrevMenuItem
= NULL
; /* ? */
515 return uSearchBy
- p
;
522 if(CurItem
->wID
== uSearchBy
)
524 if(MenuItem
) *MenuItem
= CurItem
;
525 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
528 else if (0 != (CurItem
->fType
& MF_POPUP
))
530 MenuObject
= IntGetMenuObject(CurItem
->hSubMenu
);
531 if (NULL
!= MenuObject
)
533 ret
= IntGetMenuItemByFlag(MenuObject
, uSearchBy
, fFlag
,
534 MenuItem
, PrevMenuItem
);
537 IntReleaseMenuObject(MenuObject
);
541 IntReleaseMenuObject(MenuObject
);
544 CurItem
= CurItem
->Next
;
553 IntInsertMenuItemToList(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, int pos
)
556 PMENU_ITEM LastItem
= NULL
;
559 CurItem
= MenuObject
->MenuItemList
;
565 CurItem
= CurItem
->Next
;
571 while(CurItem
&& (pos
> 0))
574 CurItem
= CurItem
->Next
;
584 /* insert the item before CurItem */
585 MenuItem
->Next
= LastItem
->Next
;
586 LastItem
->Next
= MenuItem
;
590 /* insert at the beginning */
591 MenuObject
->MenuItemList
= MenuItem
;
592 MenuItem
->Next
= CurItem
;
600 LastItem
->Next
= MenuItem
;
601 MenuItem
->Next
= NULL
;
605 /* insert first item */
606 MenuObject
->MenuItemList
= MenuItem
;
607 MenuItem
->Next
= NULL
;
610 MenuObject
->MenuInfo
.MenuItemCount
++;
616 IntGetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
620 if(lpmii
->fMask
& MIIM_BITMAP
)
622 lpmii
->hbmpItem
= MenuItem
->hbmpItem
;
624 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
626 lpmii
->hbmpChecked
= MenuItem
->hbmpChecked
;
627 lpmii
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
629 if(lpmii
->fMask
& MIIM_DATA
)
631 lpmii
->dwItemData
= MenuItem
->dwItemData
;
633 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
635 lpmii
->fType
= MenuItem
->fType
;
637 if(lpmii
->fMask
& MIIM_ID
)
639 lpmii
->wID
= MenuItem
->wID
;
641 if(lpmii
->fMask
& MIIM_STATE
)
643 lpmii
->fState
= MenuItem
->fState
;
645 if(lpmii
->fMask
& MIIM_SUBMENU
)
647 lpmii
->hSubMenu
= MenuItem
->hSubMenu
;
649 if (lpmii
->fMask
& (MIIM_STRING
| MIIM_TYPE
))
651 if (lpmii
->dwTypeData
== NULL
)
653 lpmii
->cch
= MenuItem
->Text
.Length
/ sizeof(WCHAR
);
657 Status
= MmCopyToCaller(lpmii
->dwTypeData
, MenuItem
->Text
.Buffer
,
658 min(lpmii
->cch
* sizeof(WCHAR
),
659 MenuItem
->Text
.MaximumLength
));
660 if (! NT_SUCCESS(Status
))
662 SetLastNtError(Status
);
668 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
670 lpmii
->Rect
= MenuItem
->Rect
;
671 lpmii
->XTab
= MenuItem
->XTab
;
678 IntSetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
680 PMENU_OBJECT SubMenuObject
;
682 if(!MenuItem
|| !MenuObject
|| !lpmii
)
687 MenuItem
->fType
= lpmii
->fType
;
689 if(lpmii
->fMask
& MIIM_BITMAP
)
691 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
693 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
695 MenuItem
->hbmpChecked
= lpmii
->hbmpChecked
;
696 MenuItem
->hbmpUnchecked
= lpmii
->hbmpUnchecked
;
698 if(lpmii
->fMask
& MIIM_DATA
)
700 MenuItem
->dwItemData
= lpmii
->dwItemData
;
702 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
705 * Delete the menu item type when changing type from
708 if (MenuItem
->fType
!= lpmii
->fType
&&
709 MENU_ITEM_TYPE(MenuItem
->fType
) == MF_STRING
)
711 FreeMenuText(MenuItem
);
712 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
714 MenuItem
->fType
= lpmii
->fType
;
716 if(lpmii
->fMask
& MIIM_ID
)
718 MenuItem
->wID
= lpmii
->wID
;
720 if(lpmii
->fMask
& MIIM_STATE
)
722 /* remove MFS_DEFAULT flag from all other menu items if this item
723 has the MFS_DEFAULT state */
724 if(lpmii
->fState
& MFS_DEFAULT
)
725 IntSetMenuDefaultItem(MenuObject
, -1, 0);
726 /* update the menu item state flags */
727 UpdateMenuItemState(MenuItem
->fState
, lpmii
->fState
);
730 if(lpmii
->fMask
& MIIM_SUBMENU
)
732 MenuItem
->hSubMenu
= lpmii
->hSubMenu
;
733 /* Make sure the submenu is marked as a popup menu */
734 if (MenuItem
->hSubMenu
)
736 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
737 if (SubMenuObject
!= NULL
)
739 SubMenuObject
->MenuInfo
.Flags
|= MF_POPUP
;
740 MenuItem
->fType
|= MF_POPUP
;
741 IntReleaseMenuObject(SubMenuObject
);
745 MenuItem
->fType
&= ~MF_POPUP
;
750 MenuItem
->fType
&= ~MF_POPUP
;
753 if ((lpmii
->fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
754 (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
))
756 FreeMenuText(MenuItem
);
758 if(lpmii
->dwTypeData
&& lpmii
->cch
)
760 UNICODE_STRING Source
;
763 Source
.MaximumLength
= lpmii
->cch
* sizeof(WCHAR
);
764 Source
.Buffer
= lpmii
->dwTypeData
;
766 MenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(
767 PagedPool
, Source
.Length
+ sizeof(WCHAR
), TAG_STRING
);
768 if(MenuItem
->Text
.Buffer
!= NULL
)
770 MenuItem
->Text
.Length
= 0;
771 MenuItem
->Text
.MaximumLength
= Source
.Length
+ sizeof(WCHAR
);
772 RtlCopyUnicodeString(&MenuItem
->Text
, &Source
);
773 MenuItem
->Text
.Buffer
[MenuItem
->Text
.Length
/ sizeof(WCHAR
)] = 0;
777 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
782 MenuItem
->fType
|= MF_SEPARATOR
;
783 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
787 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
789 MenuItem
->Rect
= lpmii
->Rect
;
790 MenuItem
->XTab
= lpmii
->XTab
;
797 IntInsertMenuItem(PMENU_OBJECT MenuObject
, UINT uItem
, BOOL fByPosition
,
798 PROSMENUITEMINFO ItemInfo
)
800 int pos
= (int)uItem
;
803 if (MAX_MENU_ITEMS
<= MenuObject
->MenuInfo
.MenuItemCount
)
805 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
811 /* calculate position */
812 if(MenuObject
->MenuInfo
.MenuItemCount
< pos
)
814 pos
= MenuObject
->MenuInfo
.MenuItemCount
;
819 pos
= IntGetMenuItemByFlag(MenuObject
, uItem
, MF_BYCOMMAND
, NULL
, NULL
);
826 MenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
827 if (NULL
== MenuItem
)
829 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
833 MenuItem
->fType
= MFT_STRING
;
834 MenuItem
->fState
= MFS_ENABLED
| MFS_UNCHECKED
;
836 MenuItem
->hSubMenu
= (HMENU
)0;
837 MenuItem
->hbmpChecked
= (HBITMAP
)0;
838 MenuItem
->hbmpUnchecked
= (HBITMAP
)0;
839 MenuItem
->dwItemData
= 0;
840 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
841 MenuItem
->hbmpItem
= (HBITMAP
)0;
843 if (! IntSetMenuItemInfo(MenuObject
, MenuItem
, ItemInfo
))
845 ExFreePool(MenuItem
);
849 /* Force size recalculation! */
850 MenuObject
->MenuInfo
.Height
= 0;
852 pos
= IntInsertMenuItemToList(MenuObject
, MenuItem
, pos
);
858 IntEnableMenuItem(PMENU_OBJECT MenuObject
, UINT uIDEnableItem
, UINT uEnable
)
861 UINT res
= IntGetMenuItemByFlag(MenuObject
, uIDEnableItem
, uEnable
, &MenuItem
, NULL
);
862 if(!MenuItem
|| (res
== (UINT
)-1))
867 res
= MenuItem
->fState
& (MF_GRAYED
| MF_DISABLED
);
869 if(uEnable
& MF_DISABLED
)
871 if(!(MenuItem
->fState
& MF_DISABLED
))
872 MenuItem
->fState
|= MF_DISABLED
;
873 if(uEnable
& MF_GRAYED
)
875 if(!(MenuItem
->fState
& MF_GRAYED
))
876 MenuItem
->fState
|= MF_GRAYED
;
881 if(uEnable
& MF_GRAYED
)
883 if(!(MenuItem
->fState
& MF_GRAYED
))
884 MenuItem
->fState
|= MF_GRAYED
;
885 if(!(MenuItem
->fState
& MF_DISABLED
))
886 MenuItem
->fState
|= MF_DISABLED
;
890 if(MenuItem
->fState
& MF_DISABLED
)
891 MenuItem
->fState
^= MF_DISABLED
;
892 if(MenuItem
->fState
& MF_GRAYED
)
893 MenuItem
->fState
^= MF_GRAYED
;
902 IntBuildMenuItemList(PMENU_OBJECT MenuObject
, PVOID Buffer
, ULONG nMax
)
908 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
915 if (nMax
< MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
))
919 StrOut
= (PWCHAR
)((char *) Buffer
+ MenuObject
->MenuInfo
.MenuItemCount
920 * sizeof(ROSMENUITEMINFO
));
921 nMax
-= MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
);
922 sz
= sizeof(ROSMENUITEMINFO
);
924 mii
.cbSize
= sizeof(ROSMENUITEMINFO
);
928 while (NULL
!= CurItem
)
930 mii
.cch
= CurItem
->Text
.Length
/ sizeof(WCHAR
);
931 mii
.dwItemData
= CurItem
->dwItemData
;
932 if (0 != CurItem
->Text
.Length
)
934 mii
.dwTypeData
= StrOut
;
938 mii
.dwTypeData
= NULL
;
940 mii
.fState
= CurItem
->fState
;
941 mii
.fType
= CurItem
->fType
;
942 mii
.hbmpChecked
= CurItem
->hbmpChecked
;
943 mii
.hbmpItem
= CurItem
->hbmpItem
;
944 mii
.hbmpUnchecked
= CurItem
->hbmpUnchecked
;
945 mii
.hSubMenu
= CurItem
->hSubMenu
;
946 mii
.Rect
= CurItem
->Rect
;
947 mii
.XTab
= CurItem
->XTab
;
949 Status
= MmCopyToCaller(Buf
, &mii
, sizeof(ROSMENUITEMINFO
));
950 if (! NT_SUCCESS(Status
))
952 SetLastNtError(Status
);
955 Buf
= (PVOID
)((ULONG_PTR
)Buf
+ sizeof(ROSMENUITEMINFO
));
957 if (0 != CurItem
->Text
.Length
958 && (nMax
>= CurItem
->Text
.Length
+ sizeof(WCHAR
)))
961 Status
= MmCopyToCaller(StrOut
, CurItem
->Text
.Buffer
,
962 CurItem
->Text
.Length
);
963 if (! NT_SUCCESS(Status
))
965 SetLastNtError(Status
);
968 StrOut
+= CurItem
->Text
.Length
/ sizeof(WCHAR
);
969 Status
= MmCopyToCaller(StrOut
, &NulByte
, sizeof(WCHAR
));
970 if (! NT_SUCCESS(Status
))
972 SetLastNtError(Status
);
976 nMax
-= CurItem
->Text
.Length
+ sizeof(WCHAR
);
978 else if (0 != CurItem
->Text
.Length
)
983 CurItem
= CurItem
->Next
;
989 while (NULL
!= CurItem
)
991 res
+= sizeof(ROSMENUITEMINFO
) + CurItem
->Text
.Length
+ sizeof(WCHAR
);
992 CurItem
= CurItem
->Next
;
1001 IntCheckMenuItem(PMENU_OBJECT MenuObject
, UINT uIDCheckItem
, UINT uCheck
)
1003 PMENU_ITEM MenuItem
;
1006 if((IntGetMenuItemByFlag(MenuObject
, uIDCheckItem
, uCheck
, &MenuItem
, NULL
) < 0) || !MenuItem
)
1011 res
= (DWORD
)(MenuItem
->fState
& MF_CHECKED
);
1012 if(uCheck
& MF_CHECKED
)
1014 if(!(MenuItem
->fState
& MF_CHECKED
))
1015 MenuItem
->fState
|= MF_CHECKED
;
1019 if(MenuItem
->fState
& MF_CHECKED
)
1020 MenuItem
->fState
^= MF_CHECKED
;
1027 IntHiliteMenuItem(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
,
1028 UINT uItemHilite
, UINT uHilite
)
1030 PMENU_ITEM MenuItem
;
1031 BOOL res
= IntGetMenuItemByFlag(MenuObject
, uItemHilite
, uHilite
, &MenuItem
, NULL
);
1032 if(!MenuItem
|| !res
)
1037 if(uHilite
& MF_HILITE
)
1039 if(!(MenuItem
->fState
& MF_HILITE
))
1040 MenuItem
->fState
|= MF_HILITE
;
1044 if(MenuItem
->fState
& MF_HILITE
)
1045 MenuItem
->fState
^= MF_HILITE
;
1048 /* FIXME - update the window's menu */
1054 IntSetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT uItem
, UINT fByPos
)
1057 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1059 if(uItem
== (UINT
)-1)
1063 if(MenuItem
->fState
& MFS_DEFAULT
)
1064 MenuItem
->fState
^= MFS_DEFAULT
;
1065 MenuItem
= MenuItem
->Next
;
1077 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1078 MenuItem
->fState
|= MFS_DEFAULT
;
1083 if(MenuItem
->fState
& MFS_DEFAULT
)
1084 MenuItem
->fState
^= MFS_DEFAULT
;
1087 MenuItem
= MenuItem
->Next
;
1094 if(!ret
&& (MenuItem
->wID
== uItem
))
1096 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1097 MenuItem
->fState
|= MFS_DEFAULT
;
1102 if(MenuItem
->fState
& MFS_DEFAULT
)
1103 MenuItem
->fState
^= MFS_DEFAULT
;
1105 MenuItem
= MenuItem
->Next
;
1113 IntGetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT fByPos
, UINT gmdiFlags
,
1119 PMENU_OBJECT SubMenuObject
;
1120 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1124 if(MenuItem
->fState
& MFS_DEFAULT
)
1127 if(!(gmdiFlags
& GMDI_USEDISABLED
) && (MenuItem
->fState
& MFS_DISABLED
))
1130 if(fByPos
& MF_BYPOSITION
)
1133 res
= MenuItem
->wID
;
1135 if((*gismc
< MAX_GOINTOSUBMENU
) && (gmdiFlags
& GMDI_GOINTOPOPUPS
) &&
1139 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
1140 if(!SubMenuObject
|| (SubMenuObject
== MenuObject
))
1144 sres
= IntGetMenuDefaultItem(SubMenuObject
, fByPos
, gmdiFlags
, gismc
);
1147 IntReleaseMenuObject(SubMenuObject
);
1156 MenuItem
= MenuItem
->Next
;
1164 co_IntInitTracking(PWINDOW_OBJECT Window
, PMENU_OBJECT Menu
, BOOL Popup
,
1167 /* FIXME - hide caret */
1169 if(!(Flags
& TPM_NONOTIFY
))
1170 co_IntSendMessage(Window
->hSelf
, WM_SETCURSOR
, (WPARAM
)Window
->hSelf
, HTCAPTION
);
1172 /* FIXME - send WM_SETCURSOR message */
1174 if(!(Flags
& TPM_NONOTIFY
))
1175 co_IntSendMessage(Window
->hSelf
, WM_INITMENU
, (WPARAM
)Menu
->MenuInfo
.Self
, 0);
1179 co_IntExitTracking(PWINDOW_OBJECT Window
, PMENU_OBJECT Menu
, BOOL Popup
,
1182 if(!(Flags
& TPM_NONOTIFY
))
1183 co_IntSendMessage(Window
->hSelf
, WM_EXITMENULOOP
, 0 /* FIXME */, 0);
1185 /* FIXME - Show caret again */
1189 IntTrackMenu(PMENU_OBJECT Menu
, PWINDOW_OBJECT Window
, INT x
, INT y
,
1196 co_IntTrackPopupMenu(PMENU_OBJECT Menu
, PWINDOW_OBJECT Window
,
1197 UINT Flags
, POINT
*Pos
, UINT MenuPos
, RECT
*ExcludeRect
)
1199 co_IntInitTracking(Window
, Menu
, TRUE
, Flags
);
1201 co_IntExitTracking(Window
, Menu
, TRUE
, Flags
);
1206 IntSetMenuItemRect(PMENU_OBJECT Menu
, UINT Item
, BOOL fByPos
, RECT
*rcRect
)
1209 if(IntGetMenuItemByFlag(Menu
, Item
, (fByPos
? MF_BYPOSITION
: MF_BYCOMMAND
),
1220 * Internal function. Called when the process is destroyed to free the remaining menu handles.
1223 IntCleanupMenus(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
1225 PEPROCESS CurrentProcess
;
1226 PLIST_ENTRY LastHead
= NULL
;
1227 PMENU_OBJECT MenuObject
;
1229 CurrentProcess
= PsGetCurrentProcess();
1230 if (CurrentProcess
!= Process
)
1232 KeAttachProcess(&Process
->Pcb
);
1235 while (Win32Process
->MenuListHead
.Flink
!= &(Win32Process
->MenuListHead
) &&
1236 Win32Process
->MenuListHead
.Flink
!= LastHead
)
1238 LastHead
= Win32Process
->MenuListHead
.Flink
;
1239 MenuObject
= CONTAINING_RECORD(Win32Process
->MenuListHead
.Flink
, MENU_OBJECT
, ListEntry
);
1241 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1244 if (CurrentProcess
!= Process
)
1251 /* FUNCTIONS *****************************************************************/
1259 NtUserBuildMenuItemList(
1266 PMENU_OBJECT MenuObject
;
1267 DECLARE_RETURN(DWORD
);
1269 DPRINT("Enter NtUserBuildMenuItemList\n");
1270 UserEnterExclusive();
1272 MenuObject
= IntGetMenuObject(hMenu
);
1275 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1281 res
= IntBuildMenuItemList(MenuObject
, Buffer
, nBufSize
);
1285 res
= MenuObject
->MenuInfo
.MenuItemCount
;
1288 IntReleaseMenuObject(MenuObject
);
1293 DPRINT("Leave NtUserBuildMenuItemList, ret=%i\n",_ret_
);
1303 NtUserCheckMenuItem(
1309 PMENU_OBJECT MenuObject
;
1310 DECLARE_RETURN(DWORD
);
1312 DPRINT("Enter NtUserCheckMenuItem\n");
1313 UserEnterExclusive();
1315 MenuObject
= IntGetMenuObject(hmenu
);
1318 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1322 res
= IntCheckMenuItem(MenuObject
, uIDCheckItem
, uCheck
);
1324 IntReleaseMenuObject(MenuObject
);
1328 DPRINT("Leave NtUserCheckMenuItem, ret=%i\n",_ret_
);
1334 HMENU FASTCALL
UserCreateMenu(BOOL PopupMenu
)
1336 PWINSTATION_OBJECT WinStaObject
;
1339 NTSTATUS Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1344 if (!NT_SUCCESS(Status
))
1346 DPRINT("Validation of window station handle (0x%X) failed\n",
1347 PsGetCurrentProcess()->Win32WindowStation
);
1348 SetLastNtError(Status
);
1352 IntCreateMenu(&Handle
, !PopupMenu
);
1354 ObDereferenceObject(WinStaObject
);
1355 return (HMENU
)Handle
;
1361 NtUserCreateMenu(BOOL PopupMenu
)
1363 DECLARE_RETURN(HMENU
);
1365 DPRINT("Enter NtUserCreateMenu\n");
1366 UserEnterExclusive();
1368 RETURN(UserCreateMenu(PopupMenu
));
1371 DPRINT("Leave NtUserCreateMenu, ret=%i\n",_ret_
);
1388 PMENU_OBJECT MenuObject
;
1389 DECLARE_RETURN(BOOL
);
1391 DPRINT("Enter NtUserDeleteMenu\n");
1392 UserEnterExclusive();
1394 MenuObject
= IntGetMenuObject(hMenu
);
1397 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1401 res
= IntRemoveMenuItem(MenuObject
, uPosition
, uFlags
, TRUE
);
1402 IntReleaseMenuObject(MenuObject
);
1407 DPRINT("Leave NtUserDeleteMenu, ret=%i\n",_ret_
);
1417 BOOL FASTCALL
UserDestroyMenu(HMENU hMenu
)
1421 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1424 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1427 if(MenuObject
->Process
!= PsGetCurrentProcess())
1429 IntReleaseMenuObject(MenuObject
);
1430 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1434 Ret
= IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1436 IntReleaseMenuObject(MenuObject
);
1448 DECLARE_RETURN(BOOL
);
1450 DPRINT("Enter NtUserDestroyMenu\n");
1451 UserEnterExclusive();
1453 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1456 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1459 if(MenuObject
->Process
!= PsGetCurrentProcess())
1461 IntReleaseMenuObject(MenuObject
);
1462 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1466 Ret
= IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1468 IntReleaseMenuObject(MenuObject
);
1472 DPRINT("Leave NtUserDestroyMenu, ret=%i\n",_ret_
);
1482 NtUserEnableMenuItem(
1487 UINT res
= (UINT
)-1;
1488 PMENU_OBJECT MenuObject
;
1489 DECLARE_RETURN(UINT
);
1491 DPRINT("Enter NtUserEnableMenuItem\n");
1492 UserEnterExclusive();
1494 MenuObject
= IntGetMenuObject(hMenu
);
1497 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1501 res
= IntEnableMenuItem(MenuObject
, uIDEnableItem
, uEnable
);
1503 IntReleaseMenuObject(MenuObject
);
1508 DPRINT("Leave NtUserEnableMenuItem, ret=%i\n",_ret_
);
1518 NtUserInsertMenuItem(
1522 LPCMENUITEMINFOW UnsafeItemInfo
)
1525 PMENU_OBJECT MenuObject
;
1527 ROSMENUITEMINFO ItemInfo
;
1528 DECLARE_RETURN(DWORD
);
1530 DPRINT("Enter NtUserInsertMenuItem\n");
1531 UserEnterExclusive();
1533 MenuObject
= IntGetMenuObject(hMenu
);
1536 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1540 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, sizeof(MENUITEMINFOW
));
1541 if (! NT_SUCCESS(Status
))
1543 IntReleaseMenuObject(MenuObject
);
1544 SetLastNtError(Status
);
1547 if (ItemInfo
.cbSize
!= sizeof(MENUITEMINFOW
))
1549 IntReleaseMenuObject(MenuObject
);
1550 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1554 Res
= IntInsertMenuItem(MenuObject
, uItem
, fByPosition
, &ItemInfo
);
1556 IntReleaseMenuObject(MenuObject
);
1561 DPRINT("Leave NtUserInsertMenuItem, ret=%i\n",_ret_
);
1583 NtUserGetMenuDefaultItem(
1588 PMENU_OBJECT MenuObject
;
1591 DECLARE_RETURN(UINT
);
1593 DPRINT("Enter NtUserGetMenuDefaultItem\n");
1594 UserEnterExclusive();
1596 MenuObject
= IntGetMenuObject(hMenu
);
1599 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1603 res
= IntGetMenuDefaultItem(MenuObject
, fByPos
, gmdiFlags
, &gismc
);
1605 IntReleaseMenuObject(MenuObject
);
1609 DPRINT("Leave NtUserGetMenuDefaultItem, ret=%i\n",_ret_
);
1619 NtUserGetMenuBarInfo(
1649 NtUserGetMenuItemRect(
1656 ROSMENUITEMINFO mii
;
1659 LPRECT lpRect
= NULL
;
1664 DECLARE_RETURN(BOOL
);
1666 DPRINT("Enter NtUserGetMenuItemRect\n");
1669 if(!UserMenuItemInfo(hMenu
, uItem
, MF_BYPOSITION
, &mii
, FALSE
))
1672 referenceHwnd
= hWnd
;
1676 if(!UserMenuInfo(hMenu
, &mi
, FALSE
)) RETURN( FALSE
);
1677 if(mi
.Wnd
== 0) RETURN( FALSE
);
1678 referenceHwnd
= mi
.Wnd
;
1681 if (lprcItem
== NULL
) RETURN( FALSE
);
1683 lpPoints
= (LPPOINT
)lpRect
;
1685 if(!UserGetClientOrigin(referenceHwnd
, &FromOffset
)) RETURN( FALSE
);
1687 XMove
= FromOffset
.x
;
1688 YMove
= FromOffset
.y
;
1690 for (i
= 0; i
< 2; i
++)
1692 lpPoints
[i
].x
+= XMove
;
1693 lpPoints
[i
].y
+= YMove
;
1696 Status
= MmCopyToCaller(lprcItem
, lpPoints
, sizeof(POINT
));
1697 if (! NT_SUCCESS(Status
))
1699 SetLastNtError(Status
);
1705 DPRINT("Leave NtUserGetMenuItemRect, ret=%i\n",_ret_
);
1715 NtUserHiliteMenuItem(
1722 PMENU_OBJECT MenuObject
;
1723 PWINDOW_OBJECT WindowObject
;
1724 DECLARE_RETURN(BOOLEAN
);
1726 DPRINT("Enter NtUserHiliteMenuItem\n");
1727 UserEnterExclusive();
1729 WindowObject
= IntGetWindowObject(hwnd
);
1732 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1735 MenuObject
= IntGetMenuObject(hmenu
);
1738 IntReleaseWindowObject(WindowObject
);
1739 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1742 if(WindowObject
->IDMenu
== (UINT
)hmenu
)
1744 res
= IntHiliteMenuItem(WindowObject
, MenuObject
, uItemHilite
, uHilite
);
1746 IntReleaseMenuObject(MenuObject
);
1747 IntReleaseWindowObject(WindowObject
);
1751 DPRINT("Leave NtUserHiliteMenuItem, ret=%i\n",_ret_
);
1763 PROSMENUINFO UnsafeMenuInfo
,
1767 PMENU_OBJECT MenuObject
;
1770 ROSMENUINFO MenuInfo
;
1772 Status
= MmCopyFromCaller(&Size
, &UnsafeMenuInfo
->cbSize
, sizeof(DWORD
));
1773 if (! NT_SUCCESS(Status
))
1775 SetLastNtError(Status
);
1778 if(Size
< sizeof(MENUINFO
) || sizeof(ROSMENUINFO
) < Size
)
1780 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1783 Status
= MmCopyFromCaller(&MenuInfo
, UnsafeMenuInfo
, Size
);
1784 if (! NT_SUCCESS(Status
))
1786 SetLastNtError(Status
);
1790 MenuObject
= IntGetMenuObject(Menu
);
1791 if (NULL
== MenuObject
)
1793 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1800 Res
= IntSetMenuInfo(MenuObject
, &MenuInfo
);
1805 Res
= IntGetMenuInfo(MenuObject
, &MenuInfo
);
1808 Status
= MmCopyToCaller(UnsafeMenuInfo
, &MenuInfo
, Size
);
1809 if (! NT_SUCCESS(Status
))
1811 SetLastNtError(Status
);
1817 IntReleaseMenuObject(MenuObject
);
1833 PROSMENUINFO UnsafeMenuInfo
,
1836 DECLARE_RETURN(BOOL
);
1838 DPRINT("Enter NtUserMenuInfo\n");
1841 RETURN(UserMenuInfo(Menu
, UnsafeMenuInfo
, SetOrGet
));
1844 DPRINT("Leave NtUserMenuInfo, ret=%i\n",_ret_
);
1855 NtUserMenuItemFromPoint(
1861 PMENU_OBJECT MenuObject
;
1862 PWINDOW_OBJECT WindowObject
= NULL
;
1865 DECLARE_RETURN(int);
1867 DPRINT("Enter NtUserMenuItemFromPoint\n");
1868 UserEnterExclusive();
1870 MenuObject
= IntGetMenuObject(Menu
);
1871 if (NULL
== MenuObject
)
1873 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1877 WindowObject
= IntGetWindowObject(MenuObject
->MenuInfo
.Wnd
);
1878 if (NULL
== WindowObject
)
1880 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1883 X
-= WindowObject
->WindowRect
.left
;
1884 Y
-= WindowObject
->WindowRect
.top
;
1885 IntReleaseWindowObject(WindowObject
);
1887 mi
= MenuObject
->MenuItemList
;
1888 for (i
= 0; NULL
!= mi
; i
++)
1890 if (InRect(mi
->Rect
, X
, Y
))
1897 IntReleaseMenuObject(MenuObject
);
1899 RETURN( (mi
? i
: NO_SELECTED_ITEM
));
1902 DPRINT("Leave NtUserMenuItemFromPoint, ret=%i\n",_ret_
);
1916 PROSMENUITEMINFO UnsafeItemInfo
,
1919 PMENU_OBJECT MenuObject
;
1920 PMENU_ITEM MenuItem
;
1921 ROSMENUITEMINFO ItemInfo
;
1926 MenuObject
= IntGetMenuObject(Menu
);
1927 if (NULL
== MenuObject
)
1929 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1932 Status
= MmCopyFromCaller(&Size
, &UnsafeItemInfo
->cbSize
, sizeof(UINT
));
1933 if (! NT_SUCCESS(Status
))
1935 IntReleaseMenuObject(MenuObject
);
1936 SetLastNtError(Status
);
1939 if (sizeof(MENUITEMINFOW
) != Size
1940 && sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
) != Size
1941 && sizeof(ROSMENUITEMINFO
) != Size
)
1943 IntReleaseMenuObject(MenuObject
);
1944 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1947 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, Size
);
1948 if (! NT_SUCCESS(Status
))
1950 IntReleaseMenuObject(MenuObject
);
1951 SetLastNtError(Status
);
1954 /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
1956 if (sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
) == Size
1957 && 0 != (ItemInfo
.fMask
& MIIM_BITMAP
))
1959 IntReleaseMenuObject(MenuObject
);
1960 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1964 if (IntGetMenuItemByFlag(MenuObject
, Item
,
1965 (ByPosition
? MF_BYPOSITION
: MF_BYCOMMAND
),
1966 &MenuItem
, NULL
) < 0)
1968 IntReleaseMenuObject(MenuObject
);
1969 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1975 Ret
= IntSetMenuItemInfo(MenuObject
, MenuItem
, &ItemInfo
);
1979 Ret
= IntGetMenuItemInfo(MenuObject
, MenuItem
, &ItemInfo
);
1982 Status
= MmCopyToCaller(UnsafeItemInfo
, &ItemInfo
, Size
);
1983 if (! NT_SUCCESS(Status
))
1985 IntReleaseMenuObject(MenuObject
);
1986 SetLastNtError(Status
);
1992 IntReleaseMenuObject(MenuObject
);
2009 PROSMENUITEMINFO UnsafeItemInfo
,
2012 DECLARE_RETURN(BOOL
);
2014 DPRINT("Enter NtUserMenuItemInfo\n");
2015 UserEnterExclusive();
2017 RETURN( UserMenuItemInfo(Menu
, Item
, ByPosition
, UnsafeItemInfo
, SetOrGet
));
2020 DPRINT("Leave NtUserMenuItemInfo, ret=%i\n",_ret_
);
2037 PMENU_OBJECT MenuObject
;
2038 DECLARE_RETURN(BOOL
);
2040 DPRINT("Enter NtUserRemoveMenu\n");
2041 UserEnterExclusive();
2043 MenuObject
= IntGetMenuObject(hMenu
);
2046 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2050 res
= IntRemoveMenuItem(MenuObject
, uPosition
, uFlags
, FALSE
);
2051 IntReleaseMenuObject(MenuObject
);
2056 DPRINT("Leave NtUserRemoveMenu, ret=%i\n",_ret_
);
2067 NtUserSetMenuContextHelpId(
2069 DWORD dwContextHelpId
)
2072 PMENU_OBJECT MenuObject
;
2073 DECLARE_RETURN(BOOL
);
2075 DPRINT("Enter NtUserSetMenuContextHelpId\n");
2076 UserEnterExclusive();
2078 MenuObject
= IntGetMenuObject(hmenu
);
2081 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2085 res
= IntSetMenuContextHelpId(MenuObject
, dwContextHelpId
);
2086 IntReleaseMenuObject(MenuObject
);
2090 DPRINT("Leave NtUserSetMenuContextHelpId, ret=%i\n",_ret_
);
2102 UserSetMenuDefaultItem(
2108 PMENU_OBJECT MenuObject
;
2110 MenuObject
= IntGetMenuObject(hMenu
);
2113 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2117 res
= IntSetMenuDefaultItem(MenuObject
, uItem
, fByPos
);
2119 IntReleaseMenuObject(MenuObject
);
2129 NtUserSetMenuDefaultItem(
2135 PMENU_OBJECT MenuObject
;
2136 DECLARE_RETURN(BOOL
);
2138 DPRINT("Enter NtUserSetMenuDefaultItem\n");
2139 UserEnterExclusive();
2141 MenuObject
= IntGetMenuObject(hMenu
);
2144 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2148 res
= IntSetMenuDefaultItem(MenuObject
, uItem
, fByPos
);
2150 IntReleaseMenuObject(MenuObject
);
2155 DPRINT("Leave NtUserSetMenuDefaultItem, ret=%i\n",_ret_
);
2165 NtUserSetMenuFlagRtoL(
2169 PMENU_OBJECT MenuObject
;
2170 DECLARE_RETURN(BOOL
);
2172 DPRINT("Enter NtUserSetMenuFlagRtoL\n");
2173 UserEnterExclusive();
2175 MenuObject
= IntGetMenuObject(hMenu
);
2178 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2182 res
= IntSetMenuFlagRtoL(MenuObject
);
2183 IntReleaseMenuObject(MenuObject
);
2187 DPRINT("Leave NtUserSetMenuFlagRtoL, ret=%i\n",_ret_
);
2197 NtUserThunkedMenuInfo(
2202 /* This function seems just to call SetMenuInfo() */
2211 NtUserThunkedMenuItemInfo(
2216 LPMENUITEMINFOW lpmii
,
2217 PUNICODE_STRING lpszCaption
)
2220 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
2221 if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
2230 /* NOTE: unused function */
2232 NtUserTrackPopupMenuEx(
2240 PMENU_OBJECT MenuObject
;
2241 PWINDOW_OBJECT WindowObject
;
2247 MenuObject
= IntGetMenuObject(hmenu
);
2250 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2254 WindowObject
= IntGetWindowObject(hwnd
);
2257 IntReleaseMenuObject(MenuObject
);
2258 SetLastWin32Error(ERROR_INVALID_HANDLE
);
2264 Status
= MmCopyFromCaller(&Safetpm
, lptpm
, sizeof(TPMPARAMS
));
2265 if(!NT_SUCCESS(Status
))
2267 IntReleaseWindowObject(WindowObject
);
2268 IntReleaseMenuObject(MenuObject
);
2269 SetLastNtError(Status
);
2272 if(Safetpm
.cbSize
!= sizeof(TPMPARAMS
))
2274 IntReleaseWindowObject(WindowObject
);
2275 IntReleaseMenuObject(MenuObject
);
2276 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2284 Ret
= co_IntTrackPopupMenu(MenuObject
, WindowObject
, fuFlags
, &Pos
, 0,
2285 (lptpm
? &Safetpm
.rcExclude
: NULL
));
2287 IntReleaseWindowObject(WindowObject
);
2288 IntReleaseMenuObject(MenuObject
);