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.48 2004/02/22 23:40:58 gvg Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
24 * FILE: subsys/win32k/ntuser/menu.c
25 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
27 * 07/30/2003 CSH Created
29 /* INCLUDES ******************************************************************/
31 #include <ddk/ntddk.h>
32 #include <win32k/win32k.h>
33 #include <napi/win32.h>
34 #include <include/menu.h>
35 #include <include/error.h>
36 #include <include/winsta.h>
37 #include <include/object.h>
38 #include <include/guicheck.h>
39 #include <include/window.h>
40 #include <include/color.h>
41 #include <include/tags.h>
42 #include <internal/safe.h>
47 /* INTERNAL ******************************************************************/
49 /* maximum number of menu items a menu can contain */
50 #define MAX_MENU_ITEMS (0x4000)
51 #define MAX_GOINTOSUBMENU (0x10)
53 #define UpdateMenuItemState(state, change) \
55 if((change) & MFS_DISABLED) { \
56 (state) |= MFS_DISABLED; \
58 (state) &= ~MFS_DISABLED; \
60 if((change) & MFS_CHECKED) { \
61 (state) |= MFS_CHECKED; \
63 (state) &= ~MFS_CHECKED; \
65 if((change) & MFS_HILITE) { \
66 (state) |= MFS_HILITE; \
68 (state) &= ~MFS_HILITE; \
70 if((change) & MFS_DEFAULT) { \
71 (state) |= MFS_DEFAULT; \
73 (state) &= ~MFS_DEFAULT; \
75 if((change) & MF_MOUSESELECT) { \
76 (state) |= MF_MOUSESELECT; \
78 (state) &= ~MF_MOUSESELECT; \
82 #define FreeMenuText(MenuItem) \
84 if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
85 (MenuItem)->Text.Length) { \
86 RtlFreeUnicodeString(&(MenuItem)->Text); \
90 #define InRect(r, x, y) \
91 ( ( ((r).right >= x)) && \
92 ( ((r).left <= x)) && \
93 ( ((r).bottom >= y)) && \
99 return(STATUS_SUCCESS
);
103 CleanupMenuImpl(VOID
)
105 return(STATUS_SUCCESS
);
110 DumpMenuItemList(PMENU_ITEM MenuItem
)
115 if(MenuItem
->Text
.Length
)
116 DbgPrint(" %d. %wZ\n", ++cnt
, &MenuItem
->Text
);
118 DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt
, (DWORD
)MenuItem
->Text
.Buffer
);
120 if(MFT_BITMAP
& MenuItem
->fType
) DbgPrint("MFT_BITMAP ");
121 if(MFT_MENUBARBREAK
& MenuItem
->fType
) DbgPrint("MFT_MENUBARBREAK ");
122 if(MFT_MENUBREAK
& MenuItem
->fType
) DbgPrint("MFT_MENUBREAK ");
123 if(MFT_OWNERDRAW
& MenuItem
->fType
) DbgPrint("MFT_OWNERDRAW ");
124 if(MFT_RADIOCHECK
& MenuItem
->fType
) DbgPrint("MFT_RADIOCHECK ");
125 if(MFT_RIGHTJUSTIFY
& MenuItem
->fType
) DbgPrint("MFT_RIGHTJUSTIFY ");
126 if(MFT_SEPARATOR
& MenuItem
->fType
) DbgPrint("MFT_SEPARATOR ");
127 if(MFT_STRING
& MenuItem
->fType
) DbgPrint("MFT_STRING ");
128 DbgPrint("\n fState=");
129 if(MFS_DISABLED
& MenuItem
->fState
) DbgPrint("MFS_DISABLED ");
130 else DbgPrint("MFS_ENABLED ");
131 if(MFS_CHECKED
& MenuItem
->fState
) DbgPrint("MFS_CHECKED ");
132 else DbgPrint("MFS_UNCHECKED ");
133 if(MFS_HILITE
& MenuItem
->fState
) DbgPrint("MFS_HILITE ");
134 else DbgPrint("MFS_UNHILITE ");
135 if(MFS_DEFAULT
& MenuItem
->fState
) DbgPrint("MFS_DEFAULT ");
136 if(MFS_GRAYED
& MenuItem
->fState
) DbgPrint("MFS_GRAYED ");
137 DbgPrint("\n wId=%d\n", MenuItem
->wID
);
138 MenuItem
= MenuItem
->Next
;
140 DbgPrint("Entries: %d\n", cnt
);
145 PMENU_OBJECT FASTCALL
146 IntGetMenuObject(HMENU hMenu
)
148 PMENU_OBJECT MenuObject
;
149 PW32PROCESS W32Process
= PsGetWin32Process();
156 NTSTATUS Status
= ObmReferenceObjectByHandle(W32Process
->
157 WindowStation
->HandleTable
, hMenu
, otMenu
,
158 (PVOID
*)&MenuObject
);
159 if (!NT_SUCCESS(Status
))
167 IntReleaseMenuObject(PMENU_OBJECT MenuObject
)
169 ObmDereferenceObject(MenuObject
);
173 IntFreeMenuItem(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
,
174 BOOL RemoveFromList
, BOOL bRecurse
)
176 FreeMenuText(MenuItem
);
179 /* FIXME - Remove from List */
180 MenuObject
->MenuInfo
.MenuItemCount
--;
182 if(bRecurse
&& MenuItem
->hSubMenu
)
184 PMENU_OBJECT SubMenuObject
;
185 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
188 IntDestroyMenuObject(SubMenuObject
, bRecurse
, TRUE
);
189 IntReleaseMenuObject(SubMenuObject
);
194 ExFreePool(MenuItem
);
200 IntRemoveMenuItem(PMENU_OBJECT MenuObject
, UINT uPosition
, UINT uFlags
,
203 PMENU_ITEM PrevMenuItem
, MenuItem
;
204 if(IntGetMenuItemByFlag(MenuObject
, uPosition
, uFlags
, &MenuItem
,
210 PrevMenuItem
->Next
= MenuItem
->Next
;
213 MenuObject
->MenuItemList
= MenuItem
->Next
;
215 return IntFreeMenuItem(MenuObject
, MenuItem
, TRUE
, bRecurse
);
222 IntDeleteMenuItems(PMENU_OBJECT MenuObject
, BOOL bRecurse
)
226 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
229 NextItem
= CurItem
->Next
;
230 IntFreeMenuItem(MenuObject
, CurItem
, FALSE
, bRecurse
);
234 MenuObject
->MenuInfo
.MenuItemCount
= 0;
235 MenuObject
->MenuItemList
= NULL
;
240 IntDestroyMenuObject(PMENU_OBJECT MenuObject
,
241 BOOL bRecurse
, BOOL RemoveFromProcess
)
245 /* remove all menu items */
246 ExAcquireFastMutexUnsafe (&MenuObject
->MenuItemsLock
);
247 IntDeleteMenuItems(MenuObject
, bRecurse
); /* do not destroy submenus */
248 ExReleaseFastMutexUnsafe (&MenuObject
->MenuItemsLock
);
250 if(RemoveFromProcess
)
252 ExAcquireFastMutexUnsafe(&MenuObject
->W32Process
->MenuListLock
);
253 RemoveEntryList(&MenuObject
->ListEntry
);
254 ExReleaseFastMutexUnsafe(&MenuObject
->W32Process
->MenuListLock
);
257 ObmCloseHandle(MenuObject
->W32Process
->WindowStation
->HandleTable
, MenuObject
->MenuInfo
.Self
);
264 PMENU_OBJECT FASTCALL
265 IntCreateMenu(PHANDLE Handle
, BOOL IsMenuBar
)
267 PMENU_OBJECT MenuObject
;
268 PW32PROCESS Win32Process
= PsGetWin32Process();
270 MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
271 Win32Process
->WindowStation
->HandleTable
, Handle
,
272 otMenu
, sizeof(MENU_OBJECT
));
280 MenuObject
->W32Process
= Win32Process
;
281 MenuObject
->RtoL
= FALSE
; /* default */
282 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
283 MenuObject
->MenuInfo
.fMask
= 0; /* not used */
284 MenuObject
->MenuInfo
.dwStyle
= 0; /* FIXME */
285 MenuObject
->MenuInfo
.cyMax
= 0; /* default */
286 MenuObject
->MenuInfo
.hbrBack
=
287 NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */
288 MenuObject
->MenuInfo
.dwContextHelpID
= 0; /* default */
289 MenuObject
->MenuInfo
.dwMenuData
= 0; /* default */
290 MenuObject
->MenuInfo
.Self
= *Handle
;
291 MenuObject
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
292 MenuObject
->MenuInfo
.Flags
= (IsMenuBar
? 0 : MF_POPUP
);
293 MenuObject
->MenuInfo
.Wnd
= NULL
;
294 MenuObject
->MenuInfo
.WndOwner
= NULL
;
295 MenuObject
->MenuInfo
.Height
= 0;
296 MenuObject
->MenuInfo
.Width
= 0;
297 MenuObject
->MenuInfo
.TimeToHide
= FALSE
;
299 MenuObject
->MenuInfo
.MenuItemCount
= 0;
300 MenuObject
->MenuItemList
= NULL
;
301 ExInitializeFastMutex(&MenuObject
->MenuItemsLock
);
303 /* Insert menu item into process menu handle list */
304 ExAcquireFastMutexUnsafe(&Win32Process
->MenuListLock
);
305 InsertTailList(&Win32Process
->MenuListHead
, &MenuObject
->ListEntry
);
306 ExReleaseFastMutexUnsafe(&Win32Process
->MenuListLock
);
312 IntCloneMenuItems(PMENU_OBJECT Destination
, PMENU_OBJECT Source
)
314 PMENU_ITEM MenuItem
, NewMenuItem
= NULL
;
315 PMENU_ITEM Old
= NULL
;
317 if(!Source
->MenuInfo
.MenuItemCount
)
320 ExAcquireFastMutexUnsafe(&Destination
->MenuItemsLock
);
321 ExAcquireFastMutexUnsafe(&Source
->MenuItemsLock
);
323 MenuItem
= Source
->MenuItemList
;
328 NewMenuItem
->Next
= MenuItem
;
329 NewMenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
332 NewMenuItem
->fType
= MenuItem
->fType
;
333 NewMenuItem
->fState
= MenuItem
->fState
;
334 NewMenuItem
->wID
= MenuItem
->wID
;
335 NewMenuItem
->hSubMenu
= MenuItem
->hSubMenu
;
336 NewMenuItem
->hbmpChecked
= MenuItem
->hbmpChecked
;
337 NewMenuItem
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
338 NewMenuItem
->dwItemData
= MenuItem
->dwItemData
;
339 if((MENU_ITEM_TYPE(NewMenuItem
->fType
) == MF_STRING
))
341 if(MenuItem
->Text
.Length
)
343 NewMenuItem
->Text
.Length
= 0;
344 NewMenuItem
->Text
.MaximumLength
= MenuItem
->Text
.MaximumLength
;
345 NewMenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, MenuItem
->Text
.MaximumLength
, TAG_STRING
);
346 if(!NewMenuItem
->Text
.Buffer
)
348 ExFreePool(NewMenuItem
);
351 RtlCopyUnicodeString(&NewMenuItem
->Text
, &MenuItem
->Text
);
355 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
360 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
362 NewMenuItem
->hbmpItem
= MenuItem
->hbmpItem
;
364 NewMenuItem
->Next
= NULL
;
366 Old
->Next
= NewMenuItem
;
368 Destination
->MenuItemList
= NewMenuItem
;
369 Destination
->MenuInfo
.MenuItemCount
++;
370 MenuItem
= MenuItem
->Next
;
373 ExReleaseFastMutexUnsafe(&Source
->MenuItemsLock
);
374 ExReleaseFastMutexUnsafe(&Destination
->MenuItemsLock
);
378 PMENU_OBJECT FASTCALL
379 IntCloneMenu(PMENU_OBJECT Source
)
382 PMENU_OBJECT MenuObject
;
383 PW32PROCESS Process
= PsGetWin32Process();
388 MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
389 Process
->WindowStation
->HandleTable
, &Handle
,
390 otMenu
, sizeof(MENU_OBJECT
));
394 MenuObject
->W32Process
= Process
;
395 MenuObject
->RtoL
= Source
->RtoL
;
396 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
397 MenuObject
->MenuInfo
.fMask
= Source
->MenuInfo
.fMask
;
398 MenuObject
->MenuInfo
.dwStyle
= Source
->MenuInfo
.dwStyle
;
399 MenuObject
->MenuInfo
.cyMax
= Source
->MenuInfo
.cyMax
;
400 MenuObject
->MenuInfo
.hbrBack
= Source
->MenuInfo
.hbrBack
;
401 MenuObject
->MenuInfo
.dwContextHelpID
= Source
->MenuInfo
.dwContextHelpID
;
402 MenuObject
->MenuInfo
.dwMenuData
= Source
->MenuInfo
.dwMenuData
;
403 MenuObject
->MenuInfo
.Self
= Handle
;
404 MenuObject
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
405 MenuObject
->MenuInfo
.Wnd
= NULL
;
406 MenuObject
->MenuInfo
.WndOwner
= NULL
;
407 MenuObject
->MenuInfo
.Height
= 0;
408 MenuObject
->MenuInfo
.Width
= 0;
409 MenuObject
->MenuInfo
.TimeToHide
= FALSE
;
411 MenuObject
->MenuInfo
.MenuItemCount
= 0;
412 MenuObject
->MenuItemList
= NULL
;
413 ExInitializeFastMutex(&MenuObject
->MenuItemsLock
);
415 /* Insert menu item into process menu handle list */
416 ExAcquireFastMutexUnsafe(&Process
->MenuListLock
);
417 InsertTailList(&Process
->MenuListHead
, &MenuObject
->ListEntry
);
418 ExReleaseFastMutexUnsafe(&Process
->MenuListLock
);
420 IntCloneMenuItems(MenuObject
, Source
);
426 IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject
)
428 MenuObject
->RtoL
= TRUE
;
433 IntSetMenuContextHelpId(PMENU_OBJECT MenuObject
, DWORD dwContextHelpId
)
435 MenuObject
->MenuInfo
.dwContextHelpID
= dwContextHelpId
;
440 IntGetMenuInfo(PMENU_OBJECT MenuObject
, PROSMENUINFO lpmi
)
442 if(lpmi
->fMask
& MIM_BACKGROUND
)
443 lpmi
->hbrBack
= MenuObject
->MenuInfo
.hbrBack
;
444 if(lpmi
->fMask
& MIM_HELPID
)
445 lpmi
->dwContextHelpID
= MenuObject
->MenuInfo
.dwContextHelpID
;
446 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
447 lpmi
->cyMax
= MenuObject
->MenuInfo
.cyMax
;
448 if(lpmi
->fMask
& MIM_MENUDATA
)
449 lpmi
->dwMenuData
= MenuObject
->MenuInfo
.dwMenuData
;
450 if(lpmi
->fMask
& MIM_STYLE
)
451 lpmi
->dwStyle
= MenuObject
->MenuInfo
.dwStyle
;
452 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
454 RtlCopyMemory((char *) lpmi
+ sizeof(MENUINFO
),
455 (char *) &MenuObject
->MenuInfo
+ sizeof(MENUINFO
),
456 lpmi
->cbSize
- sizeof(MENUINFO
));
464 IntIsMenu(HMENU hMenu
)
468 if((Menu
= IntGetMenuObject(hMenu
)))
470 IntReleaseMenuObject(Menu
);
478 IntSetMenuInfo(PMENU_OBJECT MenuObject
, PROSMENUINFO lpmi
)
480 if(lpmi
->fMask
& MIM_BACKGROUND
)
481 MenuObject
->MenuInfo
.hbrBack
= lpmi
->hbrBack
;
482 if(lpmi
->fMask
& MIM_HELPID
)
483 MenuObject
->MenuInfo
.dwContextHelpID
= lpmi
->dwContextHelpID
;
484 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
485 MenuObject
->MenuInfo
.cyMax
= lpmi
->cyMax
;
486 if(lpmi
->fMask
& MIM_MENUDATA
)
487 MenuObject
->MenuInfo
.dwMenuData
= lpmi
->dwMenuData
;
488 if(lpmi
->fMask
& MIM_STYLE
)
489 MenuObject
->MenuInfo
.dwStyle
= lpmi
->dwStyle
;
490 if(lpmi
->fMask
& MIM_APPLYTOSUBMENUS
)
494 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
496 MenuObject
->MenuInfo
.FocusedItem
= lpmi
->FocusedItem
;
497 MenuObject
->MenuInfo
.Height
= lpmi
->Height
;
498 MenuObject
->MenuInfo
.Width
= lpmi
->Width
;
499 MenuObject
->MenuInfo
.Wnd
= lpmi
->Wnd
;
500 MenuObject
->MenuInfo
.WndOwner
= lpmi
->WndOwner
;
501 MenuObject
->MenuInfo
.TimeToHide
= lpmi
->TimeToHide
;
509 IntGetMenuItemByFlag(PMENU_OBJECT MenuObject
, UINT uSearchBy
, UINT fFlag
,
510 PMENU_ITEM
*MenuItem
, PMENU_ITEM
*PrevMenuItem
)
512 PMENU_ITEM PrevItem
= NULL
;
513 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
515 if(MF_BYPOSITION
& fFlag
)
518 while(CurItem
&& (p
> 0))
521 CurItem
= CurItem
->Next
;
526 if(MenuItem
) *MenuItem
= CurItem
;
527 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
531 if(MenuItem
) *MenuItem
= NULL
;
532 if(PrevMenuItem
) *PrevMenuItem
= NULL
; /* ? */
536 return uSearchBy
- p
;
543 if(CurItem
->wID
== uSearchBy
)
545 if(MenuItem
) *MenuItem
= CurItem
;
546 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
550 CurItem
= CurItem
->Next
;
559 IntInsertMenuItemToList(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, int pos
)
562 PMENU_ITEM LastItem
= NULL
;
565 CurItem
= MenuObject
->MenuItemList
;
571 CurItem
= CurItem
->Next
;
577 while(CurItem
&& (pos
> 0))
580 CurItem
= CurItem
->Next
;
590 /* insert the item before CurItem */
591 MenuItem
->Next
= LastItem
->Next
;
592 LastItem
->Next
= MenuItem
;
596 /* insert at the beginning */
597 MenuObject
->MenuItemList
= MenuItem
;
598 MenuItem
->Next
= CurItem
;
606 LastItem
->Next
= MenuItem
;
607 MenuItem
->Next
= NULL
;
611 /* insert first item */
612 MenuObject
->MenuItemList
= MenuItem
;
613 MenuItem
->Next
= NULL
;
616 MenuObject
->MenuInfo
.MenuItemCount
++;
622 IntGetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
627 lpmii
->cch
= MenuItem
->Text
.Length
/ sizeof(WCHAR
);
629 if(lpmii
->fMask
& MIIM_BITMAP
)
631 lpmii
->hbmpItem
= MenuItem
->hbmpItem
;
633 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
635 lpmii
->hbmpChecked
= MenuItem
->hbmpChecked
;
636 lpmii
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
638 if(lpmii
->fMask
& MIIM_DATA
)
640 lpmii
->dwItemData
= MenuItem
->dwItemData
;
642 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
644 lpmii
->fType
= MenuItem
->fType
;
646 if(lpmii
->fMask
& MIIM_ID
)
648 lpmii
->wID
= MenuItem
->wID
;
650 if(lpmii
->fMask
& MIIM_STATE
)
652 lpmii
->fState
= MenuItem
->fState
;
654 if(lpmii
->fMask
& MIIM_SUBMENU
)
656 lpmii
->hSubMenu
= MenuItem
->hSubMenu
;
658 if (0 != (lpmii
->fMask
& MIIM_STRING
) ||
659 0 != (lpmii
->fMask
& MIIM_TYPE
))
661 Status
= MmCopyFromCaller(&Text
, lpmii
->dwTypeData
, sizeof(UNICODE_STRING
));
662 if (! NT_SUCCESS(Status
))
664 SetLastNtError(Status
);
667 Text
.Length
= min(Text
.MaximumLength
, MenuItem
->Text
.Length
);
668 if (0 != Text
.Length
)
670 Status
= MmCopyToCaller(Text
.Buffer
, MenuItem
->Text
.Buffer
, Text
.Length
);
671 if (! NT_SUCCESS(Status
))
673 SetLastNtError(Status
);
677 Status
= MmCopyToCaller(lpmii
->dwTypeData
, &Text
, sizeof(UNICODE_STRING
));
678 if (! NT_SUCCESS(Status
))
680 SetLastNtError(Status
);
685 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
687 lpmii
->Rect
= MenuItem
->Rect
;
688 lpmii
->XTab
= MenuItem
->XTab
;
695 IntSetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
697 PUNICODE_STRING Source
;
700 if(!MenuItem
|| !MenuObject
|| !lpmii
)
705 MenuItem
->fType
= lpmii
->fType
;
707 if(lpmii
->fMask
& MIIM_BITMAP
)
709 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
711 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
713 MenuItem
->hbmpChecked
= lpmii
->hbmpChecked
;
714 MenuItem
->hbmpUnchecked
= lpmii
->hbmpUnchecked
;
716 if(lpmii
->fMask
& MIIM_DATA
)
718 MenuItem
->dwItemData
= lpmii
->dwItemData
;
720 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
722 MenuItem
->fType
= lpmii
->fType
;
724 if(lpmii
->fMask
& MIIM_ID
)
726 MenuItem
->wID
= lpmii
->wID
;
728 if(lpmii
->fMask
& MIIM_STATE
)
730 /* remove MFS_DEFAULT flag from all other menu items if this item
731 has the MFS_DEFAULT state */
732 if(lpmii
->fState
& MFS_DEFAULT
)
733 IntSetMenuDefaultItem(MenuObject
, -1, 0);
734 /* update the menu item state flags */
735 UpdateMenuItemState(MenuItem
->fState
, lpmii
->fState
);
738 if(lpmii
->fMask
& MIIM_SUBMENU
)
740 MenuItem
->hSubMenu
= lpmii
->hSubMenu
;
742 if((lpmii
->fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
743 (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
))
745 if(lpmii
->dwTypeData
&& lpmii
->cch
)
747 Source
= (PUNICODE_STRING
)lpmii
->dwTypeData
;
748 FreeMenuText(MenuItem
);
749 copylen
= min((UINT
)Source
->MaximumLength
, (lpmii
->cch
+ 1) * sizeof(WCHAR
));
750 MenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, copylen
, TAG_STRING
);
751 if(MenuItem
->Text
.Buffer
)
753 MenuItem
->Text
.Length
= 0;
754 MenuItem
->Text
.MaximumLength
= copylen
;
755 RtlCopyUnicodeString(&MenuItem
->Text
, Source
);
759 MenuItem
->Text
.Length
= 0;
760 MenuItem
->Text
.MaximumLength
= 0;
761 MenuItem
->Text
.Buffer
= NULL
;
766 MenuItem
->fType
|= MF_SEPARATOR
;
767 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
772 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
775 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
777 MenuItem
->Rect
= lpmii
->Rect
;
778 MenuItem
->XTab
= lpmii
->XTab
;
785 IntInsertMenuItem(PMENU_OBJECT MenuObject
, UINT uItem
, BOOL fByPosition
,
786 PROSMENUITEMINFO ItemInfo
)
788 int pos
= (int)uItem
;
791 if (MAX_MENU_ITEMS
<= MenuObject
->MenuInfo
.MenuItemCount
)
793 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
799 /* calculate position */
800 if(MenuObject
->MenuInfo
.MenuItemCount
< pos
)
802 pos
= MenuObject
->MenuInfo
.MenuItemCount
;
807 pos
= IntGetMenuItemByFlag(MenuObject
, uItem
, MF_BYCOMMAND
, NULL
, NULL
);
814 MenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
815 if (NULL
== MenuItem
)
817 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
821 MenuItem
->fType
= MFT_STRING
;
822 MenuItem
->fState
= MFS_ENABLED
| MFS_UNCHECKED
;
824 MenuItem
->hSubMenu
= (HMENU
)0;
825 MenuItem
->hbmpChecked
= (HBITMAP
)0;
826 MenuItem
->hbmpUnchecked
= (HBITMAP
)0;
827 MenuItem
->dwItemData
= 0;
828 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
829 MenuItem
->hbmpItem
= (HBITMAP
)0;
831 if (! IntSetMenuItemInfo(MenuObject
, MenuItem
, ItemInfo
))
833 ExFreePool(MenuItem
);
837 pos
= IntInsertMenuItemToList(MenuObject
, MenuItem
, pos
);
843 IntEnableMenuItem(PMENU_OBJECT MenuObject
, UINT uIDEnableItem
, UINT uEnable
)
846 UINT res
= IntGetMenuItemByFlag(MenuObject
, uIDEnableItem
, uEnable
, &MenuItem
, NULL
);
847 if(!MenuItem
|| (res
== (UINT
)-1))
852 res
= MenuItem
->fState
& (MF_GRAYED
| MF_DISABLED
);
854 if(uEnable
& MF_DISABLED
)
856 if(!(MenuItem
->fState
& MF_DISABLED
))
857 MenuItem
->fState
|= MF_DISABLED
;
858 if(uEnable
& MF_GRAYED
)
860 if(!(MenuItem
->fState
& MF_GRAYED
))
861 MenuItem
->fState
|= MF_GRAYED
;
866 if(uEnable
& MF_GRAYED
)
868 if(!(MenuItem
->fState
& MF_GRAYED
))
869 MenuItem
->fState
|= MF_GRAYED
;
870 if(!(MenuItem
->fState
& MF_DISABLED
))
871 MenuItem
->fState
|= MF_DISABLED
;
875 if(MenuItem
->fState
& MF_DISABLED
)
876 MenuItem
->fState
^= MF_DISABLED
;
877 if(MenuItem
->fState
& MF_GRAYED
)
878 MenuItem
->fState
^= MF_GRAYED
;
887 IntBuildMenuItemList(PMENU_OBJECT MenuObject
, PVOID Buffer
, ULONG nMax
)
893 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
900 if (nMax
< MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
))
904 StrOut
= (PWCHAR
)((char *) Buffer
+ MenuObject
->MenuInfo
.MenuItemCount
905 * sizeof(ROSMENUITEMINFO
));
906 nMax
-= MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
);
907 sz
= sizeof(ROSMENUITEMINFO
);
909 mii
.cbSize
= sizeof(ROSMENUITEMINFO
);
913 while (NULL
!= CurItem
)
915 mii
.cch
= CurItem
->Text
.Length
/ sizeof(WCHAR
);
916 mii
.dwItemData
= CurItem
->dwItemData
;
917 if (0 != CurItem
->Text
.Length
)
919 mii
.dwTypeData
= StrOut
;
923 mii
.dwTypeData
= NULL
;
925 mii
.fState
= CurItem
->fState
;
926 mii
.fType
= CurItem
->fType
;
927 mii
.hbmpChecked
= CurItem
->hbmpChecked
;
928 mii
.hbmpItem
= CurItem
->hbmpItem
;
929 mii
.hbmpUnchecked
= CurItem
->hbmpUnchecked
;
930 mii
.hSubMenu
= CurItem
->hSubMenu
;
931 mii
.Rect
= CurItem
->Rect
;
932 mii
.XTab
= CurItem
->XTab
;
934 Status
= MmCopyToCaller(Buf
, &mii
, sizeof(ROSMENUITEMINFO
));
935 if (! NT_SUCCESS(Status
))
937 SetLastNtError(Status
);
940 Buf
+= sizeof(ROSMENUITEMINFO
);
942 if (0 != CurItem
->Text
.Length
943 && (nMax
>= CurItem
->Text
.Length
+ sizeof(WCHAR
)))
946 Status
= MmCopyToCaller(StrOut
, CurItem
->Text
.Buffer
,
947 CurItem
->Text
.Length
);
948 if (! NT_SUCCESS(Status
))
950 SetLastNtError(Status
);
953 StrOut
+= CurItem
->Text
.Length
/ sizeof(WCHAR
);
954 Status
= MmCopyToCaller(StrOut
, &NulByte
, sizeof(WCHAR
));
955 if (! NT_SUCCESS(Status
))
957 SetLastNtError(Status
);
961 nMax
-= CurItem
->Text
.Length
+ sizeof(WCHAR
);
963 else if (0 != CurItem
->Text
.Length
)
968 CurItem
= CurItem
->Next
;
974 while (NULL
!= CurItem
)
976 res
+= sizeof(ROSMENUITEMINFO
) + CurItem
->Text
.Length
+ sizeof(WCHAR
);
977 CurItem
= CurItem
->Next
;
986 IntCheckMenuItem(PMENU_OBJECT MenuObject
, UINT uIDCheckItem
, UINT uCheck
)
991 if((IntGetMenuItemByFlag(MenuObject
, uIDCheckItem
, uCheck
, &MenuItem
, NULL
) < 0) || !MenuItem
)
996 res
= (DWORD
)(MenuItem
->fState
& MF_CHECKED
);
997 if(uCheck
& MF_CHECKED
)
999 if(!(MenuItem
->fState
& MF_CHECKED
))
1000 MenuItem
->fState
|= MF_CHECKED
;
1004 if(MenuItem
->fState
& MF_CHECKED
)
1005 MenuItem
->fState
^= MF_CHECKED
;
1012 IntHiliteMenuItem(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
,
1013 UINT uItemHilite
, UINT uHilite
)
1015 PMENU_ITEM MenuItem
;
1016 BOOL res
= IntGetMenuItemByFlag(MenuObject
, uItemHilite
, uHilite
, &MenuItem
, NULL
);
1017 if(!MenuItem
|| !res
)
1022 if(uHilite
& MF_HILITE
)
1024 if(!(MenuItem
->fState
& MF_HILITE
))
1025 MenuItem
->fState
|= MF_HILITE
;
1029 if(MenuItem
->fState
& MF_HILITE
)
1030 MenuItem
->fState
^= MF_HILITE
;
1033 /* FIXME - update the window's menu */
1039 IntSetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT uItem
, UINT fByPos
)
1042 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1044 if(uItem
== (UINT
)-1)
1048 if(MenuItem
->fState
& MFS_DEFAULT
)
1049 MenuItem
->fState
^= MFS_DEFAULT
;
1050 MenuItem
= MenuItem
->Next
;
1062 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1063 MenuItem
->fState
|= MFS_DEFAULT
;
1068 if(MenuItem
->fState
& MFS_DEFAULT
)
1069 MenuItem
->fState
^= MFS_DEFAULT
;
1072 MenuItem
= MenuItem
->Next
;
1079 if(!ret
&& (MenuItem
->wID
== uItem
))
1081 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1082 MenuItem
->fState
|= MFS_DEFAULT
;
1087 if(MenuItem
->fState
& MFS_DEFAULT
)
1088 MenuItem
->fState
^= MFS_DEFAULT
;
1090 MenuItem
= MenuItem
->Next
;
1098 IntGetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT fByPos
, UINT gmdiFlags
,
1104 PMENU_OBJECT SubMenuObject
;
1105 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1109 if(MenuItem
->fState
& MFS_DEFAULT
)
1112 if(!(gmdiFlags
& GMDI_USEDISABLED
) && (MenuItem
->fState
& MFS_DISABLED
))
1115 if(fByPos
& MF_BYPOSITION
)
1118 res
= MenuItem
->wID
;
1120 if((*gismc
< MAX_GOINTOSUBMENU
) && (gmdiFlags
& GMDI_GOINTOPOPUPS
) &&
1124 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
1125 if(!SubMenuObject
|| (SubMenuObject
== MenuObject
))
1128 ExAcquireFastMutexUnsafe(&SubMenuObject
->MenuItemsLock
);
1129 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1132 sres
= IntGetMenuDefaultItem(SubMenuObject
, fByPos
, gmdiFlags
, gismc
);
1135 ExReleaseFastMutexUnsafe(&SubMenuObject
->MenuItemsLock
);
1136 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1137 IntReleaseMenuObject(SubMenuObject
);
1146 MenuItem
= MenuItem
->Next
;
1154 IntInitTracking(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
, BOOL Popup
,
1157 /* FIXME - hide caret */
1159 if(!(Flags
& TPM_NONOTIFY
))
1160 IntSendMessage(WindowObject
->Self
, WM_SETCURSOR
, (WPARAM
)WindowObject
->Self
, HTCAPTION
);
1162 /* FIXME - send WM_SETCURSOR message */
1164 if(!(Flags
& TPM_NONOTIFY
))
1165 IntSendMessage(WindowObject
->Self
, WM_INITMENU
, (WPARAM
)MenuObject
->MenuInfo
.Self
, 0);
1169 IntExitTracking(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
, BOOL Popup
,
1172 if(!(Flags
& TPM_NONOTIFY
))
1173 IntSendMessage(WindowObject
->Self
, WM_EXITMENULOOP
, 0 /* FIXME */, 0);
1175 /* FIXME - Show caret again */
1179 IntTrackMenu(PMENU_OBJECT MenuObject
, PWINDOW_OBJECT WindowObject
, INT x
, INT y
,
1186 IntTrackPopupMenu(PMENU_OBJECT MenuObject
, PWINDOW_OBJECT WindowObject
,
1187 UINT Flags
, POINT
*Pos
, UINT MenuPos
, RECT
*ExcludeRect
)
1189 IntInitTracking(WindowObject
, MenuObject
, TRUE
, Flags
);
1191 IntExitTracking(WindowObject
, MenuObject
, TRUE
, Flags
);
1196 IntSetMenuItemRect(PMENU_OBJECT MenuObject
, UINT Item
, BOOL fByPos
, RECT
*rcRect
)
1199 if(IntGetMenuItemByFlag(MenuObject
, Item
, (fByPos
? MF_BYPOSITION
: MF_BYCOMMAND
),
1210 * Internal function. Called when the process is destroyed to free the remaining menu handles.
1213 IntCleanupMenus(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
1215 PEPROCESS CurrentProcess
;
1216 PLIST_ENTRY LastHead
= NULL
;
1217 PMENU_OBJECT MenuObject
;
1219 CurrentProcess
= PsGetCurrentProcess();
1220 if (CurrentProcess
!= Process
)
1222 KeAttachProcess(Process
);
1225 ExAcquireFastMutexUnsafe(&Win32Process
->MenuListLock
);
1226 while (Win32Process
->MenuListHead
.Flink
!= &(Win32Process
->MenuListHead
) &&
1227 Win32Process
->MenuListHead
.Flink
!= LastHead
)
1229 LastHead
= Win32Process
->MenuListHead
.Flink
;
1230 MenuObject
= CONTAINING_RECORD(Win32Process
->MenuListHead
.Flink
, MENU_OBJECT
, ListEntry
);
1232 ExReleaseFastMutexUnsafe(&Win32Process
->MenuListLock
);
1233 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1234 ExAcquireFastMutexUnsafe(&Win32Process
->MenuListLock
);
1236 ExReleaseFastMutexUnsafe(&Win32Process
->MenuListLock
);
1238 if (CurrentProcess
!= Process
)
1245 /* FUNCTIONS *****************************************************************/
1253 NtUserBuildMenuItemList(
1260 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1263 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1269 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1270 res
= IntBuildMenuItemList(MenuObject
, Buffer
, nBufSize
);
1271 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1275 res
= MenuObject
->MenuInfo
.MenuItemCount
;
1278 IntReleaseMenuObject(MenuObject
);
1288 NtUserCheckMenuItem(
1294 PMENU_OBJECT MenuObject
= IntGetMenuObject(hmenu
);
1297 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1300 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1301 res
= IntCheckMenuItem(MenuObject
, uIDCheckItem
, uCheck
);
1302 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1303 IntReleaseMenuObject(MenuObject
);
1312 NtUserCreateMenu(BOOL PopupMenu
)
1314 PWINSTATION_OBJECT WinStaObject
;
1317 NTSTATUS Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
1322 if (!NT_SUCCESS(Status
))
1324 DPRINT("Validation of window station handle (0x%X) failed\n",
1325 PROCESS_WINDOW_STATION());
1326 SetLastNtError(Status
);
1330 IntCreateMenu(&Handle
, !PopupMenu
);
1332 ObDereferenceObject(WinStaObject
);
1333 return (HMENU
)Handle
;
1347 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1350 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1354 res
= IntRemoveMenuItem(MenuObject
, uPosition
, uFlags
, TRUE
);
1355 IntReleaseMenuObject(MenuObject
);
1370 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1373 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1376 if(MenuObject
->W32Process
!= PsGetWin32Process())
1378 IntReleaseMenuObject(MenuObject
);
1379 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1383 Ret
= IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1385 IntReleaseMenuObject(MenuObject
);
1394 NtUserEnableMenuItem(
1399 UINT res
= (UINT
)-1;
1400 PMENU_OBJECT MenuObject
;
1401 MenuObject
= IntGetMenuObject(hMenu
);
1404 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1407 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1408 res
= IntEnableMenuItem(MenuObject
, uIDEnableItem
, uEnable
);
1409 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1410 IntReleaseMenuObject(MenuObject
);
1420 NtUserInsertMenuItem(
1424 LPCMENUITEMINFOW UnsafeItemInfo
)
1427 PMENU_OBJECT MenuObject
;
1429 ROSMENUITEMINFO ItemInfo
;
1431 MenuObject
= IntGetMenuObject(hMenu
);
1434 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1438 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, sizeof(MENUITEMINFOW
));
1439 if (! NT_SUCCESS(Status
))
1441 IntReleaseMenuObject(MenuObject
);
1442 SetLastNtError(Status
);
1445 if (ItemInfo
.cbSize
!= sizeof(MENUITEMINFOW
))
1447 IntReleaseMenuObject(MenuObject
);
1448 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1452 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1453 Res
= IntInsertMenuItem(MenuObject
, uItem
, fByPosition
, &ItemInfo
);
1454 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1455 IntReleaseMenuObject(MenuObject
);
1477 NtUserGetMenuDefaultItem(
1482 PMENU_OBJECT MenuObject
;
1485 MenuObject
= IntGetMenuObject(hMenu
);
1488 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1491 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1492 res
= IntGetMenuDefaultItem(MenuObject
, fByPos
, gmdiFlags
, &gismc
);
1493 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1494 IntReleaseMenuObject(MenuObject
);
1503 NtUserGetMenuBarInfo(
1533 NtUserGetMenuItemRect(
1549 NtUserHiliteMenuItem(
1556 PMENU_OBJECT MenuObject
;
1557 PWINDOW_OBJECT WindowObject
= IntGetWindowObject(hwnd
);
1560 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1563 MenuObject
= IntGetMenuObject(hmenu
);
1566 IntReleaseWindowObject(WindowObject
);
1567 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1570 if(WindowObject
->IDMenu
== (UINT
)hmenu
)
1572 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1573 res
= IntHiliteMenuItem(WindowObject
, MenuObject
, uItemHilite
, uHilite
);
1574 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1576 IntReleaseMenuObject(MenuObject
);
1577 IntReleaseWindowObject(WindowObject
);
1589 PROSMENUINFO UnsafeMenuInfo
,
1593 PMENU_OBJECT MenuObject
;
1596 ROSMENUINFO MenuInfo
;
1598 Status
= MmCopyFromCaller(&Size
, &UnsafeMenuInfo
->cbSize
, sizeof(DWORD
));
1599 if (! NT_SUCCESS(Status
))
1601 SetLastNtError(Status
);
1604 if(Size
< sizeof(MENUINFO
) || sizeof(ROSMENUINFO
) < Size
)
1606 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1609 Status
= MmCopyFromCaller(&MenuInfo
, UnsafeMenuInfo
, Size
);
1610 if (! NT_SUCCESS(Status
))
1612 SetLastNtError(Status
);
1616 MenuObject
= IntGetMenuObject(Menu
);
1617 if (NULL
== MenuObject
)
1619 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1626 Res
= IntSetMenuInfo(MenuObject
, &MenuInfo
);
1631 Res
= IntGetMenuInfo(MenuObject
, &MenuInfo
);
1634 Status
= MmCopyToCaller(UnsafeMenuInfo
, &MenuInfo
, Size
);
1635 if (! NT_SUCCESS(Status
))
1637 SetLastNtError(Status
);
1643 IntReleaseMenuObject(MenuObject
);
1653 NtUserMenuItemFromPoint(
1659 PMENU_OBJECT MenuObject
;
1660 PWINDOW_OBJECT WindowObject
= NULL
;
1664 MenuObject
= IntGetMenuObject(Menu
);
1665 if (NULL
== MenuObject
)
1667 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1670 if (0 != (MenuObject
->MenuInfo
.Flags
& MF_POPUP
))
1672 WindowObject
= IntGetWindowObject(MenuObject
->MenuInfo
.Wnd
);
1673 if (NULL
== WindowObject
)
1675 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1678 X
-= WindowObject
->WindowRect
.left
;
1679 Y
-= WindowObject
->WindowRect
.top
;
1680 IntReleaseWindowObject(WindowObject
);
1683 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1684 mi
= MenuObject
->MenuItemList
;
1685 for (i
= 0; NULL
!= mi
; i
++)
1687 if (InRect(mi
->Rect
, X
, Y
))
1693 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1695 IntReleaseMenuObject(MenuObject
);
1697 return (mi
? i
: NO_SELECTED_ITEM
);
1710 PROSMENUITEMINFO UnsafeItemInfo
,
1713 PMENU_OBJECT MenuObject
;
1714 PMENU_ITEM MenuItem
;
1715 ROSMENUITEMINFO ItemInfo
;
1720 MenuObject
= IntGetMenuObject(Menu
);
1721 if (NULL
== MenuObject
)
1723 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1726 Status
= MmCopyFromCaller(&Size
, &UnsafeItemInfo
->cbSize
, sizeof(UINT
));
1727 if (! NT_SUCCESS(Status
))
1729 IntReleaseMenuObject(MenuObject
);
1730 SetLastNtError(Status
);
1733 if(sizeof(MENUITEMINFOW
) != Size
&& sizeof(ROSMENUITEMINFO
) != Size
)
1735 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1738 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, Size
);
1739 if (! NT_SUCCESS(Status
))
1741 IntReleaseMenuObject(MenuObject
);
1742 SetLastNtError(Status
);
1746 if (IntGetMenuItemByFlag(MenuObject
, Item
,
1747 (ByPosition
? MF_BYPOSITION
: MF_BYCOMMAND
),
1748 &MenuItem
, NULL
) < 0)
1750 IntReleaseMenuObject(MenuObject
);
1751 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1757 Ret
= IntSetMenuItemInfo(MenuObject
, MenuItem
, &ItemInfo
);
1761 Ret
= IntGetMenuItemInfo(MenuObject
, MenuItem
, &ItemInfo
);
1764 Status
= MmCopyToCaller(UnsafeItemInfo
, &ItemInfo
, Size
);
1765 if (! NT_SUCCESS(Status
))
1767 IntReleaseMenuObject(MenuObject
);
1768 SetLastNtError(Status
);
1774 IntReleaseMenuObject(MenuObject
);
1790 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1793 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1797 res
= IntRemoveMenuItem(MenuObject
, uPosition
, uFlags
, FALSE
);
1798 IntReleaseMenuObject(MenuObject
);
1808 NtUserSetMenuContextHelpId(
1810 DWORD dwContextHelpId
)
1813 PMENU_OBJECT MenuObject
= IntGetMenuObject(hmenu
);
1816 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1820 res
= IntSetMenuContextHelpId(MenuObject
, dwContextHelpId
);
1821 IntReleaseMenuObject(MenuObject
);
1830 NtUserSetMenuDefaultItem(
1836 PMENU_OBJECT MenuObject
;
1837 MenuObject
= IntGetMenuObject(hMenu
);
1840 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1843 ExAcquireFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1844 res
= IntSetMenuDefaultItem(MenuObject
, uItem
, fByPos
);
1845 ExReleaseFastMutexUnsafe(&MenuObject
->MenuItemsLock
);
1846 IntReleaseMenuObject(MenuObject
);
1856 NtUserSetMenuFlagRtoL(
1860 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1863 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1867 res
= IntSetMenuFlagRtoL(MenuObject
);
1868 IntReleaseMenuObject(MenuObject
);
1877 NtUserThunkedMenuInfo(
1882 /* This function seems just to call SetMenuInfo() */
1891 NtUserThunkedMenuItemInfo(
1896 LPMENUITEMINFOW lpmii
,
1897 PUNICODE_STRING lpszCaption
)
1900 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
1901 if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
1911 NtUserTrackPopupMenuEx(
1919 PMENU_OBJECT MenuObject
;
1920 PWINDOW_OBJECT WindowObject
;
1926 MenuObject
= IntGetMenuObject(hmenu
);
1929 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1933 WindowObject
= IntGetWindowObject(hwnd
);
1936 IntReleaseMenuObject(MenuObject
);
1937 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1943 Status
= MmCopyFromCaller(&Safetpm
, lptpm
, sizeof(TPMPARAMS
));
1944 if(!NT_SUCCESS(Status
))
1946 IntReleaseWindowObject(WindowObject
);
1947 IntReleaseMenuObject(MenuObject
);
1948 SetLastNtError(Status
);
1951 if(Safetpm
.cbSize
!= sizeof(TPMPARAMS
))
1953 IntReleaseWindowObject(WindowObject
);
1954 IntReleaseMenuObject(MenuObject
);
1955 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1963 Ret
= IntTrackPopupMenu(MenuObject
, WindowObject
, fuFlags
, &Pos
, 0,
1964 (lptpm
? &Safetpm
.rcExclude
: NULL
));
1966 IntReleaseWindowObject(WindowObject
);
1967 IntReleaseMenuObject(MenuObject
);