2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
24 * FILE: subsys/win32k/ntuser/menu.c
25 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
27 * 07/30/2003 CSH Created
29 /* INCLUDES ******************************************************************/
37 IntGetSystemMenu(PWINDOW_OBJECT Window
, BOOL bRevert
, BOOL RetMenu
);
41 /* STATIC FUNCTION ***********************************************************/
49 PROSMENUITEMINFO UnsafeItemInfo
,
56 PROSMENUINFO UnsafeMenuInfo
,
59 /* INTERNAL ******************************************************************/
61 /* maximum number of menu items a menu can contain */
62 #define MAX_MENU_ITEMS (0x4000)
63 #define MAX_GOINTOSUBMENU (0x10)
65 #define UpdateMenuItemState(state, change) \
67 if((change) & MFS_DISABLED) { \
68 (state) |= MFS_DISABLED; \
70 (state) &= ~MFS_DISABLED; \
72 if((change) & MFS_CHECKED) { \
73 (state) |= MFS_CHECKED; \
75 (state) &= ~MFS_CHECKED; \
77 if((change) & MFS_HILITE) { \
78 (state) |= MFS_HILITE; \
80 (state) &= ~MFS_HILITE; \
82 if((change) & MFS_DEFAULT) { \
83 (state) |= MFS_DEFAULT; \
85 (state) &= ~MFS_DEFAULT; \
87 if((change) & MF_MOUSESELECT) { \
88 (state) |= MF_MOUSESELECT; \
90 (state) &= ~MF_MOUSESELECT; \
94 #define FreeMenuText(MenuItem) \
96 if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
97 (MenuItem)->Text.Length) { \
98 RtlFreeUnicodeString(&(MenuItem)->Text); \
102 #define InRect(r, x, y) \
103 ( ( ((r).right >= x)) && \
104 ( ((r).left <= x)) && \
105 ( ((r).bottom >= y)) && \
111 return(STATUS_SUCCESS
);
115 CleanupMenuImpl(VOID
)
117 return(STATUS_SUCCESS
);
120 PMENU_OBJECT FASTCALL
UserGetMenuObject(HMENU hMenu
)
126 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
130 Menu
= (PMENU_OBJECT
)UserGetObject(gHandleTable
, hMenu
, otMenu
);
133 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
137 ASSERT(USER_BODY_TO_HEADER(Menu
)->RefCount
>= 0);
144 DumpMenuItemList(PMENU_ITEM MenuItem
)
149 if(MenuItem
->Text
.Length
)
150 DbgPrint(" %d. %wZ\n", ++cnt
, &MenuItem
->Text
);
152 DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt
, (DWORD
)MenuItem
->Text
.Buffer
);
154 if(MFT_BITMAP
& MenuItem
->fType
)
155 DbgPrint("MFT_BITMAP ");
156 if(MFT_MENUBARBREAK
& MenuItem
->fType
)
157 DbgPrint("MFT_MENUBARBREAK ");
158 if(MFT_MENUBREAK
& MenuItem
->fType
)
159 DbgPrint("MFT_MENUBREAK ");
160 if(MFT_OWNERDRAW
& MenuItem
->fType
)
161 DbgPrint("MFT_OWNERDRAW ");
162 if(MFT_RADIOCHECK
& MenuItem
->fType
)
163 DbgPrint("MFT_RADIOCHECK ");
164 if(MFT_RIGHTJUSTIFY
& MenuItem
->fType
)
165 DbgPrint("MFT_RIGHTJUSTIFY ");
166 if(MFT_SEPARATOR
& MenuItem
->fType
)
167 DbgPrint("MFT_SEPARATOR ");
168 if(MFT_STRING
& MenuItem
->fType
)
169 DbgPrint("MFT_STRING ");
170 DbgPrint("\n fState=");
171 if(MFS_DISABLED
& MenuItem
->fState
)
172 DbgPrint("MFS_DISABLED ");
174 DbgPrint("MFS_ENABLED ");
175 if(MFS_CHECKED
& MenuItem
->fState
)
176 DbgPrint("MFS_CHECKED ");
178 DbgPrint("MFS_UNCHECKED ");
179 if(MFS_HILITE
& MenuItem
->fState
)
180 DbgPrint("MFS_HILITE ");
182 DbgPrint("MFS_UNHILITE ");
183 if(MFS_DEFAULT
& MenuItem
->fState
)
184 DbgPrint("MFS_DEFAULT ");
185 if(MFS_GRAYED
& MenuItem
->fState
)
186 DbgPrint("MFS_GRAYED ");
187 DbgPrint("\n wId=%d\n", MenuItem
->wID
);
188 MenuItem
= MenuItem
->Next
;
190 DbgPrint("Entries: %d\n", cnt
);
195 PMENU_OBJECT FASTCALL
196 IntGetMenuObject(HMENU hMenu
)
198 PMENU_OBJECT Menu
= UserGetMenuObject(hMenu
);
201 ASSERT(USER_BODY_TO_HEADER(Menu
)->RefCount
>= 0);
203 USER_BODY_TO_HEADER(Menu
)->RefCount
++;
209 IntFreeMenuItem(PMENU_OBJECT Menu
, PMENU_ITEM MenuItem
,
210 BOOL RemoveFromList
, BOOL bRecurse
)
212 FreeMenuText(MenuItem
);
215 PMENU_ITEM CurItem
= Menu
->MenuItemList
;
218 if (CurItem
->Next
== MenuItem
)
220 CurItem
->Next
= MenuItem
->Next
;
225 CurItem
= CurItem
->Next
;
228 Menu
->MenuInfo
.MenuItemCount
--;
230 if(bRecurse
&& MenuItem
->hSubMenu
)
232 PMENU_OBJECT SubMenu
;
233 SubMenu
= UserGetMenuObject(MenuItem
->hSubMenu
);
236 IntDestroyMenuObject(SubMenu
, bRecurse
, TRUE
);
241 if (MenuItem
->Text
.Buffer
) ExFreePool(MenuItem
->Text
.Buffer
);
242 ExFreePool(MenuItem
);
248 IntRemoveMenuItem(PMENU_OBJECT Menu
, UINT uPosition
, UINT uFlags
,
251 PMENU_ITEM PrevMenuItem
, MenuItem
;
252 if(IntGetMenuItemByFlag(Menu
, uPosition
, uFlags
, NULL
, &MenuItem
,
258 PrevMenuItem
->Next
= MenuItem
->Next
;
261 Menu
->MenuItemList
= MenuItem
->Next
;
263 return IntFreeMenuItem(Menu
, MenuItem
, TRUE
, bRecurse
);
270 IntDeleteMenuItems(PMENU_OBJECT Menu
, BOOL bRecurse
)
274 PMENU_ITEM CurItem
= Menu
->MenuItemList
;
277 NextItem
= CurItem
->Next
;
278 IntFreeMenuItem(Menu
, CurItem
, FALSE
, bRecurse
);
282 Menu
->MenuInfo
.MenuItemCount
= 0;
283 Menu
->MenuItemList
= NULL
;
288 IntDestroyMenuObject(PMENU_OBJECT Menu
,
289 BOOL bRecurse
, BOOL RemoveFromProcess
)
293 PWINDOW_OBJECT Window
;
294 PWINSTATION_OBJECT WindowStation
;
297 /* remove all menu items */
298 IntDeleteMenuItems(Menu
, bRecurse
); /* do not destroy submenus */
300 if(RemoveFromProcess
)
302 RemoveEntryList(&Menu
->ListEntry
);
305 Status
= ObReferenceObjectByHandle(Menu
->Process
->Win32WindowStation
,
307 ExWindowStationObjectType
,
309 (PVOID
*)&WindowStation
,
311 if(NT_SUCCESS(Status
))
313 if (Menu
->MenuInfo
.Wnd
)
315 Window
= UserGetWindowObject(Menu
->MenuInfo
.Wnd
);
318 Window
->Wnd
->IDMenu
= 0;
321 // UserDereferenceObject(Menu);
322 BOOL ret
= UserDeleteObject(Menu
->MenuInfo
.Self
, otMenu
);
323 ObDereferenceObject(WindowStation
);
330 PMENU_OBJECT FASTCALL
331 IntCreateMenu(PHANDLE Handle
, BOOL IsMenuBar
)
335 Menu
= (PMENU_OBJECT
)UserCreateObject(
336 gHandleTable
, Handle
,
337 otMenu
, sizeof(MENU_OBJECT
));
345 Menu
->Process
= PsGetCurrentProcess();
346 Menu
->RtoL
= FALSE
; /* default */
347 Menu
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
348 Menu
->MenuInfo
.fMask
= 0; /* not used */
349 Menu
->MenuInfo
.dwStyle
= 0; /* FIXME */
350 Menu
->MenuInfo
.cyMax
= 0; /* default */
351 Menu
->MenuInfo
.hbrBack
= NULL
; /* no brush */
352 Menu
->MenuInfo
.dwContextHelpID
= 0; /* default */
353 Menu
->MenuInfo
.dwMenuData
= 0; /* default */
354 Menu
->MenuInfo
.Self
= *Handle
;
355 Menu
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
356 Menu
->MenuInfo
.Flags
= (IsMenuBar
? 0 : MF_POPUP
);
357 Menu
->MenuInfo
.Wnd
= NULL
;
358 Menu
->MenuInfo
.WndOwner
= NULL
;
359 Menu
->MenuInfo
.Height
= 0;
360 Menu
->MenuInfo
.Width
= 0;
361 Menu
->MenuInfo
.TimeToHide
= FALSE
;
363 Menu
->MenuInfo
.MenuItemCount
= 0;
364 Menu
->MenuItemList
= NULL
;
366 /* Insert menu item into process menu handle list */
367 InsertTailList(&PsGetCurrentProcessWin32Process()->MenuListHead
, &Menu
->ListEntry
);
373 IntCloneMenuItems(PMENU_OBJECT Destination
, PMENU_OBJECT Source
)
375 PMENU_ITEM MenuItem
, NewMenuItem
= NULL
;
376 PMENU_ITEM Old
= NULL
;
378 if(!Source
->MenuInfo
.MenuItemCount
)
381 MenuItem
= Source
->MenuItemList
;
386 NewMenuItem
->Next
= MenuItem
;
387 NewMenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
390 NewMenuItem
->fType
= MenuItem
->fType
;
391 NewMenuItem
->fState
= MenuItem
->fState
;
392 NewMenuItem
->wID
= MenuItem
->wID
;
393 NewMenuItem
->hSubMenu
= MenuItem
->hSubMenu
;
394 NewMenuItem
->hbmpChecked
= MenuItem
->hbmpChecked
;
395 NewMenuItem
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
396 NewMenuItem
->dwItemData
= MenuItem
->dwItemData
;
397 if((MENU_ITEM_TYPE(NewMenuItem
->fType
) == MF_STRING
))
399 if(MenuItem
->Text
.Length
)
401 NewMenuItem
->Text
.Length
= 0;
402 NewMenuItem
->Text
.MaximumLength
= MenuItem
->Text
.MaximumLength
;
403 NewMenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, MenuItem
->Text
.MaximumLength
, TAG_STRING
);
404 if(!NewMenuItem
->Text
.Buffer
)
406 ExFreePool(NewMenuItem
);
409 RtlCopyUnicodeString(&NewMenuItem
->Text
, &MenuItem
->Text
);
413 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
418 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
420 NewMenuItem
->hbmpItem
= MenuItem
->hbmpItem
;
422 NewMenuItem
->Next
= NULL
;
424 Old
->Next
= NewMenuItem
;
426 Destination
->MenuItemList
= NewMenuItem
;
427 Destination
->MenuInfo
.MenuItemCount
++;
428 MenuItem
= MenuItem
->Next
;
434 PMENU_OBJECT FASTCALL
435 IntCloneMenu(PMENU_OBJECT Source
)
443 Menu
= (PMENU_OBJECT
)UserCreateObject(
444 gHandleTable
, &hMenu
,
445 otMenu
, sizeof(MENU_OBJECT
));
450 Menu
->Process
= PsGetCurrentProcess();
451 Menu
->RtoL
= Source
->RtoL
;
452 Menu
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
453 Menu
->MenuInfo
.fMask
= Source
->MenuInfo
.fMask
;
454 Menu
->MenuInfo
.dwStyle
= Source
->MenuInfo
.dwStyle
;
455 Menu
->MenuInfo
.cyMax
= Source
->MenuInfo
.cyMax
;
456 Menu
->MenuInfo
.hbrBack
= Source
->MenuInfo
.hbrBack
;
457 Menu
->MenuInfo
.dwContextHelpID
= Source
->MenuInfo
.dwContextHelpID
;
458 Menu
->MenuInfo
.dwMenuData
= Source
->MenuInfo
.dwMenuData
;
459 Menu
->MenuInfo
.Self
= hMenu
;
460 Menu
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
461 Menu
->MenuInfo
.Wnd
= NULL
;
462 Menu
->MenuInfo
.WndOwner
= NULL
;
463 Menu
->MenuInfo
.Height
= 0;
464 Menu
->MenuInfo
.Width
= 0;
465 Menu
->MenuInfo
.TimeToHide
= FALSE
;
467 Menu
->MenuInfo
.MenuItemCount
= 0;
468 Menu
->MenuItemList
= NULL
;
470 /* Insert menu item into process menu handle list */
471 InsertTailList(&PsGetCurrentProcessWin32Process()->MenuListHead
, &Menu
->ListEntry
);
473 IntCloneMenuItems(Menu
, Source
);
479 IntSetMenuFlagRtoL(PMENU_OBJECT Menu
)
486 IntSetMenuContextHelpId(PMENU_OBJECT Menu
, DWORD dwContextHelpId
)
488 Menu
->MenuInfo
.dwContextHelpID
= dwContextHelpId
;
493 IntGetMenuInfo(PMENU_OBJECT Menu
, PROSMENUINFO lpmi
)
495 if(lpmi
->fMask
& MIM_BACKGROUND
)
496 lpmi
->hbrBack
= Menu
->MenuInfo
.hbrBack
;
497 if(lpmi
->fMask
& MIM_HELPID
)
498 lpmi
->dwContextHelpID
= Menu
->MenuInfo
.dwContextHelpID
;
499 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
500 lpmi
->cyMax
= Menu
->MenuInfo
.cyMax
;
501 if(lpmi
->fMask
& MIM_MENUDATA
)
502 lpmi
->dwMenuData
= Menu
->MenuInfo
.dwMenuData
;
503 if(lpmi
->fMask
& MIM_STYLE
)
504 lpmi
->dwStyle
= Menu
->MenuInfo
.dwStyle
;
505 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
507 RtlCopyMemory((char *) lpmi
+ sizeof(MENUINFO
),
508 (char *) &Menu
->MenuInfo
+ sizeof(MENUINFO
),
509 lpmi
->cbSize
- sizeof(MENUINFO
));
511 if (sizeof(ROSMENUINFO
) == lpmi
->cbSize
)
513 lpmi
->maxBmpSize
.cx
= Menu
->MenuInfo
.maxBmpSize
.cx
;
514 lpmi
->maxBmpSize
.cy
= Menu
->MenuInfo
.maxBmpSize
.cy
;
521 IntIsMenu(HMENU hMenu
)
525 if((Menu
= UserGetMenuObject(hMenu
)))
534 IntSetMenuInfo(PMENU_OBJECT Menu
, PROSMENUINFO lpmi
)
536 if(lpmi
->fMask
& MIM_BACKGROUND
)
537 Menu
->MenuInfo
.hbrBack
= lpmi
->hbrBack
;
538 if(lpmi
->fMask
& MIM_HELPID
)
539 Menu
->MenuInfo
.dwContextHelpID
= lpmi
->dwContextHelpID
;
540 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
541 Menu
->MenuInfo
.cyMax
= lpmi
->cyMax
;
542 if(lpmi
->fMask
& MIM_MENUDATA
)
543 Menu
->MenuInfo
.dwMenuData
= lpmi
->dwMenuData
;
544 if(lpmi
->fMask
& MIM_STYLE
)
545 Menu
->MenuInfo
.dwStyle
= lpmi
->dwStyle
;
546 if(lpmi
->fMask
& MIM_APPLYTOSUBMENUS
)
550 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
552 Menu
->MenuInfo
.FocusedItem
= lpmi
->FocusedItem
;
553 Menu
->MenuInfo
.Height
= lpmi
->Height
;
554 Menu
->MenuInfo
.Width
= lpmi
->Width
;
555 Menu
->MenuInfo
.Wnd
= lpmi
->Wnd
;
556 Menu
->MenuInfo
.WndOwner
= lpmi
->WndOwner
;
557 Menu
->MenuInfo
.TimeToHide
= lpmi
->TimeToHide
;
559 if (sizeof(ROSMENUINFO
) == lpmi
->cbSize
)
561 Menu
->MenuInfo
.maxBmpSize
.cx
= lpmi
->maxBmpSize
.cx
;
562 Menu
->MenuInfo
.maxBmpSize
.cy
= lpmi
->maxBmpSize
.cy
;
569 IntGetMenuItemByFlag(PMENU_OBJECT Menu
, UINT uSearchBy
, UINT fFlag
,
570 PMENU_OBJECT
*SubMenu
, PMENU_ITEM
*MenuItem
,
571 PMENU_ITEM
*PrevMenuItem
)
573 PMENU_ITEM PrevItem
= NULL
;
574 PMENU_ITEM CurItem
= Menu
->MenuItemList
;
578 if(MF_BYPOSITION
& fFlag
)
581 while(CurItem
&& (p
> 0))
584 CurItem
= CurItem
->Next
;
592 *PrevMenuItem
= PrevItem
;
599 *PrevMenuItem
= NULL
; /* ? */
603 return uSearchBy
- p
;
610 if(CurItem
->wID
== uSearchBy
)
615 *PrevMenuItem
= PrevItem
;
623 if(CurItem
->fType
& MF_POPUP
)
625 PMENU_OBJECT NewMenu
= UserGetMenuObject(CurItem
->hSubMenu
);
628 ret
= IntGetMenuItemByFlag(NewMenu
, uSearchBy
, fFlag
,
629 SubMenu
, MenuItem
, PrevMenuItem
);
638 CurItem
= CurItem
->Next
;
647 IntInsertMenuItemToList(PMENU_OBJECT Menu
, PMENU_ITEM MenuItem
, int pos
)
650 PMENU_ITEM LastItem
= NULL
;
653 CurItem
= Menu
->MenuItemList
;
659 CurItem
= CurItem
->Next
;
665 while(CurItem
&& (pos
> 0))
668 CurItem
= CurItem
->Next
;
678 /* insert the item before CurItem */
679 MenuItem
->Next
= LastItem
->Next
;
680 LastItem
->Next
= MenuItem
;
684 /* insert at the beginning */
685 Menu
->MenuItemList
= MenuItem
;
686 MenuItem
->Next
= CurItem
;
694 LastItem
->Next
= MenuItem
;
695 MenuItem
->Next
= NULL
;
699 /* insert first item */
700 Menu
->MenuItemList
= MenuItem
;
701 MenuItem
->Next
= NULL
;
704 Menu
->MenuInfo
.MenuItemCount
++;
710 IntGetMenuItemInfo(PMENU_OBJECT Menu
, /* UNUSED PARAM!! */
711 PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
715 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
717 lpmii
->fType
= MenuItem
->fType
;
719 if(lpmii
->fMask
& MIIM_BITMAP
)
721 lpmii
->hbmpItem
= MenuItem
->hbmpItem
;
723 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
725 lpmii
->hbmpChecked
= MenuItem
->hbmpChecked
;
726 lpmii
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
728 if(lpmii
->fMask
& MIIM_DATA
)
730 lpmii
->dwItemData
= MenuItem
->dwItemData
;
732 if(lpmii
->fMask
& MIIM_ID
)
734 lpmii
->wID
= MenuItem
->wID
;
736 if(lpmii
->fMask
& MIIM_STATE
)
738 lpmii
->fState
= MenuItem
->fState
;
740 if(lpmii
->fMask
& MIIM_SUBMENU
)
742 lpmii
->hSubMenu
= MenuItem
->hSubMenu
;
745 if ((lpmii
->fMask
& MIIM_STRING
) ||
746 ((lpmii
->fMask
& MIIM_TYPE
) && (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
)))
748 if (lpmii
->dwTypeData
== NULL
)
750 lpmii
->cch
= MenuItem
->Text
.Length
/ sizeof(WCHAR
);
754 Status
= MmCopyToCaller(lpmii
->dwTypeData
, MenuItem
->Text
.Buffer
,
755 min(lpmii
->cch
* sizeof(WCHAR
),
756 MenuItem
->Text
.MaximumLength
));
757 if (! NT_SUCCESS(Status
))
759 SetLastNtError(Status
);
765 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
767 lpmii
->Rect
= MenuItem
->Rect
;
768 lpmii
->XTab
= MenuItem
->XTab
;
769 lpmii
->Text
= MenuItem
->Text
.Buffer
;
776 IntSetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
778 PMENU_OBJECT SubMenuObject
;
779 UINT fTypeMask
= (MFT_BITMAP
| MFT_MENUBARBREAK
| MFT_MENUBREAK
| MFT_OWNERDRAW
| MFT_RADIOCHECK
| MFT_RIGHTJUSTIFY
| MFT_SEPARATOR
| MF_POPUP
);
781 if(!MenuItem
|| !MenuObject
|| !lpmii
)
785 if( lpmii
->fType
& ~fTypeMask
)
787 DbgPrint("IntSetMenuItemInfo invalid fType flags %x\n", lpmii
->fType
& ~fTypeMask
);
788 lpmii
->fMask
&= ~(MIIM_TYPE
| MIIM_FTYPE
);
790 if(lpmii
->fMask
& MIIM_TYPE
)
792 if(lpmii
->fMask
& ( MIIM_STRING
| MIIM_FTYPE
| MIIM_BITMAP
))
794 DbgPrint("IntSetMenuItemInfo: Invalid combination of fMask bits used\n");
795 /* this does not happen on Win9x/ME */
796 SetLastNtError( ERROR_INVALID_PARAMETER
);
800 * Delete the menu item type when changing type from
803 if (MenuItem
->fType
!= lpmii
->fType
&&
804 MENU_ITEM_TYPE(MenuItem
->fType
) == MFT_STRING
)
806 FreeMenuText(MenuItem
);
807 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
809 if(lpmii
->fType
& MFT_BITMAP
)
812 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
814 { /* Win 9x/Me stuff */
815 MenuItem
->hbmpItem
= (HBITMAP
)((ULONG_PTR
)(LOWORD(lpmii
->dwTypeData
)));
818 MenuItem
->fType
|= lpmii
->fType
;
820 if (lpmii
->fMask
& MIIM_FTYPE
)
822 if(( lpmii
->fType
& MFT_BITMAP
))
824 DbgPrint("IntSetMenuItemInfo: Can not use FTYPE and MFT_BITMAP.\n");
825 SetLastNtError( ERROR_INVALID_PARAMETER
);
828 MenuItem
->fType
|= lpmii
->fType
; /* Need to save all the flags, this fixed MFT_RIGHTJUSTIFY */
830 if(lpmii
->fMask
& MIIM_BITMAP
)
832 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
834 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
836 MenuItem
->hbmpChecked
= lpmii
->hbmpChecked
;
837 MenuItem
->hbmpUnchecked
= lpmii
->hbmpUnchecked
;
839 if(lpmii
->fMask
& MIIM_DATA
)
841 MenuItem
->dwItemData
= lpmii
->dwItemData
;
843 if(lpmii
->fMask
& MIIM_ID
)
845 MenuItem
->wID
= lpmii
->wID
;
847 if(lpmii
->fMask
& MIIM_STATE
)
849 /* remove MFS_DEFAULT flag from all other menu items if this item
850 has the MFS_DEFAULT state */
851 if(lpmii
->fState
& MFS_DEFAULT
)
852 UserSetMenuDefaultItem(MenuObject
, -1, 0);
853 /* update the menu item state flags */
854 UpdateMenuItemState(MenuItem
->fState
, lpmii
->fState
);
857 if(lpmii
->fMask
& MIIM_SUBMENU
)
859 MenuItem
->hSubMenu
= lpmii
->hSubMenu
;
860 /* Make sure the submenu is marked as a popup menu */
861 if (MenuItem
->hSubMenu
)
863 SubMenuObject
= UserGetMenuObject(MenuItem
->hSubMenu
);
864 if (SubMenuObject
!= NULL
)
866 SubMenuObject
->MenuInfo
.Flags
|= MF_POPUP
;
867 MenuItem
->fType
|= MF_POPUP
;
871 MenuItem
->fType
&= ~MF_POPUP
;
876 MenuItem
->fType
&= ~MF_POPUP
;
880 if ((lpmii
->fMask
& MIIM_STRING
) ||
881 ((lpmii
->fMask
& MIIM_TYPE
) && (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
)))
883 FreeMenuText(MenuItem
);
885 if(lpmii
->dwTypeData
&& lpmii
->cch
)
887 UNICODE_STRING Source
;
890 Source
.MaximumLength
= lpmii
->cch
* sizeof(WCHAR
);
891 Source
.Buffer
= lpmii
->dwTypeData
;
893 MenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(
894 PagedPool
, Source
.Length
+ sizeof(WCHAR
), TAG_STRING
);
895 if(MenuItem
->Text
.Buffer
!= NULL
)
897 MenuItem
->Text
.Length
= 0;
898 MenuItem
->Text
.MaximumLength
= Source
.Length
+ sizeof(WCHAR
);
899 RtlCopyUnicodeString(&MenuItem
->Text
, &Source
);
900 MenuItem
->Text
.Buffer
[MenuItem
->Text
.Length
/ sizeof(WCHAR
)] = 0;
904 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
909 if (0 == (MenuObject
->MenuInfo
.Flags
& MF_SYSMENU
))
911 MenuItem
->fType
|= MF_SEPARATOR
;
913 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
917 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
919 MenuItem
->Rect
= lpmii
->Rect
;
920 MenuItem
->XTab
= lpmii
->XTab
;
921 lpmii
->Text
= MenuItem
->Text
.Buffer
; /* Send back new allocated string or zero */
928 IntInsertMenuItem(PMENU_OBJECT MenuObject
, UINT uItem
, BOOL fByPosition
,
929 PROSMENUITEMINFO ItemInfo
)
931 int pos
= (int)uItem
;
933 PMENU_OBJECT SubMenu
;
935 if (MAX_MENU_ITEMS
<= MenuObject
->MenuInfo
.MenuItemCount
)
937 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
943 SubMenu
= MenuObject
;
944 /* calculate position */
945 if(MenuObject
->MenuInfo
.MenuItemCount
< pos
)
947 pos
= MenuObject
->MenuInfo
.MenuItemCount
;
952 pos
= IntGetMenuItemByFlag(MenuObject
, uItem
, MF_BYCOMMAND
, &SubMenu
, NULL
, NULL
);
959 MenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
960 if (NULL
== MenuItem
)
962 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
966 MenuItem
->fType
= MFT_STRING
;
967 MenuItem
->fState
= MFS_ENABLED
| MFS_UNCHECKED
;
969 MenuItem
->hSubMenu
= (HMENU
)0;
970 MenuItem
->hbmpChecked
= (HBITMAP
)0;
971 MenuItem
->hbmpUnchecked
= (HBITMAP
)0;
972 MenuItem
->dwItemData
= 0;
973 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
974 MenuItem
->hbmpItem
= (HBITMAP
)0;
976 if(!IntSetMenuItemInfo(SubMenu
, MenuItem
, ItemInfo
))
978 ExFreePool(MenuItem
);
982 /* Force size recalculation! */
983 MenuObject
->MenuInfo
.Height
= 0;
985 pos
= IntInsertMenuItemToList(SubMenu
, MenuItem
, pos
);
987 DPRINT("IntInsertMenuItemToList = %i\n", pos
);
993 IntEnableMenuItem(PMENU_OBJECT MenuObject
, UINT uIDEnableItem
, UINT uEnable
)
996 UINT res
= IntGetMenuItemByFlag(MenuObject
, uIDEnableItem
, uEnable
, NULL
, &MenuItem
, NULL
);
997 if(!MenuItem
|| (res
== (UINT
)-1))
1002 res
= MenuItem
->fState
& (MF_GRAYED
| MF_DISABLED
);
1004 if(uEnable
& MF_DISABLED
)
1006 if(!(MenuItem
->fState
& MF_DISABLED
))
1007 MenuItem
->fState
|= MF_DISABLED
;
1008 if(uEnable
& MF_GRAYED
)
1010 if(!(MenuItem
->fState
& MF_GRAYED
))
1011 MenuItem
->fState
|= MF_GRAYED
;
1016 if(uEnable
& MF_GRAYED
)
1018 if(!(MenuItem
->fState
& MF_GRAYED
))
1019 MenuItem
->fState
|= MF_GRAYED
;
1020 if(!(MenuItem
->fState
& MF_DISABLED
))
1021 MenuItem
->fState
|= MF_DISABLED
;
1025 if(MenuItem
->fState
& MF_DISABLED
)
1026 MenuItem
->fState
^= MF_DISABLED
;
1027 if(MenuItem
->fState
& MF_GRAYED
)
1028 MenuItem
->fState
^= MF_GRAYED
;
1037 IntBuildMenuItemList(PMENU_OBJECT MenuObject
, PVOID Buffer
, ULONG nMax
)
1041 ROSMENUITEMINFO mii
;
1043 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
1050 if (nMax
< MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
))
1054 StrOut
= (PWCHAR
)((char *) Buffer
+ MenuObject
->MenuInfo
.MenuItemCount
1055 * sizeof(ROSMENUITEMINFO
));
1056 nMax
-= MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
);
1057 sz
= sizeof(ROSMENUITEMINFO
);
1059 mii
.cbSize
= sizeof(ROSMENUITEMINFO
);
1063 while (NULL
!= CurItem
)
1065 mii
.cch
= CurItem
->Text
.Length
/ sizeof(WCHAR
);
1066 mii
.dwItemData
= CurItem
->dwItemData
;
1067 if (0 != CurItem
->Text
.Length
)
1069 mii
.dwTypeData
= StrOut
;
1073 mii
.dwTypeData
= NULL
;
1075 mii
.fState
= CurItem
->fState
;
1076 mii
.fType
= CurItem
->fType
;
1077 mii
.hbmpChecked
= CurItem
->hbmpChecked
;
1078 mii
.hbmpItem
= CurItem
->hbmpItem
;
1079 mii
.hbmpUnchecked
= CurItem
->hbmpUnchecked
;
1080 mii
.hSubMenu
= CurItem
->hSubMenu
;
1081 mii
.Rect
= CurItem
->Rect
;
1082 mii
.XTab
= CurItem
->XTab
;
1083 mii
.Text
= CurItem
->Text
.Buffer
;
1085 Status
= MmCopyToCaller(Buf
, &mii
, sizeof(ROSMENUITEMINFO
));
1086 if (! NT_SUCCESS(Status
))
1088 SetLastNtError(Status
);
1091 Buf
= (PVOID
)((ULONG_PTR
)Buf
+ sizeof(ROSMENUITEMINFO
));
1093 if (0 != CurItem
->Text
.Length
1094 && (nMax
>= CurItem
->Text
.Length
+ sizeof(WCHAR
)))
1097 Status
= MmCopyToCaller(StrOut
, CurItem
->Text
.Buffer
,
1098 CurItem
->Text
.Length
);
1099 if (! NT_SUCCESS(Status
))
1101 SetLastNtError(Status
);
1104 StrOut
+= CurItem
->Text
.Length
/ sizeof(WCHAR
);
1105 Status
= MmCopyToCaller(StrOut
, &NulByte
, sizeof(WCHAR
));
1106 if (! NT_SUCCESS(Status
))
1108 SetLastNtError(Status
);
1112 nMax
-= CurItem
->Text
.Length
+ sizeof(WCHAR
);
1114 else if (0 != CurItem
->Text
.Length
)
1119 CurItem
= CurItem
->Next
;
1125 while (NULL
!= CurItem
)
1127 res
+= sizeof(ROSMENUITEMINFO
) + CurItem
->Text
.Length
+ sizeof(WCHAR
);
1128 CurItem
= CurItem
->Next
;
1137 IntCheckMenuItem(PMENU_OBJECT MenuObject
, UINT uIDCheckItem
, UINT uCheck
)
1139 PMENU_ITEM MenuItem
;
1142 if((IntGetMenuItemByFlag(MenuObject
, uIDCheckItem
, uCheck
, NULL
, &MenuItem
, NULL
) < 0) || !MenuItem
)
1147 res
= (DWORD
)(MenuItem
->fState
& MF_CHECKED
);
1148 if(uCheck
& MF_CHECKED
)
1150 if(!(MenuItem
->fState
& MF_CHECKED
))
1151 MenuItem
->fState
|= MF_CHECKED
;
1155 if(MenuItem
->fState
& MF_CHECKED
)
1156 MenuItem
->fState
^= MF_CHECKED
;
1163 IntHiliteMenuItem(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
,
1164 UINT uItemHilite
, UINT uHilite
)
1166 PMENU_ITEM MenuItem
;
1167 BOOL res
= IntGetMenuItemByFlag(MenuObject
, uItemHilite
, uHilite
, NULL
, &MenuItem
, NULL
);
1168 if(!MenuItem
|| !res
)
1173 if(uHilite
& MF_HILITE
)
1175 if(!(MenuItem
->fState
& MF_HILITE
))
1176 MenuItem
->fState
|= MF_HILITE
;
1180 if(MenuItem
->fState
& MF_HILITE
)
1181 MenuItem
->fState
^= MF_HILITE
;
1184 /* FIXME - update the window's menu */
1190 UserSetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT uItem
, UINT fByPos
)
1193 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1195 if(uItem
== (UINT
)-1)
1199 if(MenuItem
->fState
& MFS_DEFAULT
)
1200 MenuItem
->fState
^= MFS_DEFAULT
;
1201 MenuItem
= MenuItem
->Next
;
1213 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1214 MenuItem
->fState
|= MFS_DEFAULT
;
1219 if(MenuItem
->fState
& MFS_DEFAULT
)
1220 MenuItem
->fState
^= MFS_DEFAULT
;
1223 MenuItem
= MenuItem
->Next
;
1230 if(!ret
&& (MenuItem
->wID
== uItem
))
1232 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1233 MenuItem
->fState
|= MFS_DEFAULT
;
1238 if(MenuItem
->fState
& MFS_DEFAULT
)
1239 MenuItem
->fState
^= MFS_DEFAULT
;
1241 MenuItem
= MenuItem
->Next
;
1249 IntGetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT fByPos
, UINT gmdiFlags
,
1255 PMENU_OBJECT SubMenuObject
;
1256 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1260 if(MenuItem
->fState
& MFS_DEFAULT
)
1263 if(!(gmdiFlags
& GMDI_USEDISABLED
) && (MenuItem
->fState
& MFS_DISABLED
))
1269 res
= MenuItem
->wID
;
1271 if((*gismc
< MAX_GOINTOSUBMENU
) && (gmdiFlags
& GMDI_GOINTOPOPUPS
) &&
1275 SubMenuObject
= UserGetMenuObject(MenuItem
->hSubMenu
);
1276 if(!SubMenuObject
|| (SubMenuObject
== MenuObject
))
1280 sres
= IntGetMenuDefaultItem(SubMenuObject
, fByPos
, gmdiFlags
, gismc
);
1290 MenuItem
= MenuItem
->Next
;
1298 co_IntInitTracking(PWINDOW_OBJECT Window
, PMENU_OBJECT Menu
, BOOL Popup
,
1301 /* FIXME - hide caret */
1303 if(!(Flags
& TPM_NONOTIFY
))
1304 co_IntSendMessage(Window
->hSelf
, WM_SETCURSOR
, (WPARAM
)Window
->hSelf
, HTCAPTION
);
1306 /* FIXME - send WM_SETCURSOR message */
1308 if(!(Flags
& TPM_NONOTIFY
))
1309 co_IntSendMessage(Window
->hSelf
, WM_INITMENU
, (WPARAM
)Menu
->MenuInfo
.Self
, 0);
1313 co_IntExitTracking(PWINDOW_OBJECT Window
, PMENU_OBJECT Menu
, BOOL Popup
,
1316 if(!(Flags
& TPM_NONOTIFY
))
1317 co_IntSendMessage(Window
->hSelf
, WM_EXITMENULOOP
, 0 /* FIXME */, 0);
1319 /* FIXME - Show caret again */
1323 IntTrackMenu(PMENU_OBJECT Menu
, PWINDOW_OBJECT Window
, INT x
, INT y
,
1330 co_IntTrackPopupMenu(PMENU_OBJECT Menu
, PWINDOW_OBJECT Window
,
1331 UINT Flags
, POINT
*Pos
, UINT MenuPos
, RECT
*ExcludeRect
)
1333 co_IntInitTracking(Window
, Menu
, TRUE
, Flags
);
1335 co_IntExitTracking(Window
, Menu
, TRUE
, Flags
);
1340 IntSetMenuItemRect(PMENU_OBJECT Menu
, UINT Item
, BOOL fByPos
, RECT
*rcRect
)
1343 if(IntGetMenuItemByFlag(Menu
, Item
, (fByPos
? MF_BYPOSITION
: MF_BYCOMMAND
),
1344 NULL
, &mi
, NULL
) > -1)
1354 * Internal function. Called when the process is destroyed to free the remaining menu handles.
1357 IntCleanupMenus(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
1359 PEPROCESS CurrentProcess
;
1360 PLIST_ENTRY LastHead
= NULL
;
1361 PMENU_OBJECT MenuObject
;
1363 CurrentProcess
= PsGetCurrentProcess();
1364 if (CurrentProcess
!= Process
)
1366 KeAttachProcess(&Process
->Pcb
);
1369 while (Win32Process
->MenuListHead
.Flink
!= &(Win32Process
->MenuListHead
) &&
1370 Win32Process
->MenuListHead
.Flink
!= LastHead
)
1372 LastHead
= Win32Process
->MenuListHead
.Flink
;
1373 MenuObject
= CONTAINING_RECORD(Win32Process
->MenuListHead
.Flink
, MENU_OBJECT
, ListEntry
);
1375 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1378 if (CurrentProcess
!= Process
)
1385 /* FUNCTIONS *****************************************************************/
1393 NtUserBuildMenuItemList(
1401 DECLARE_RETURN(DWORD
);
1403 DPRINT("Enter NtUserBuildMenuItemList\n");
1404 UserEnterExclusive();
1406 if(!(Menu
= UserGetMenuObject(hMenu
)))
1413 res
= IntBuildMenuItemList(Menu
, Buffer
, nBufSize
);
1417 res
= Menu
->MenuInfo
.MenuItemCount
;
1423 DPRINT("Leave NtUserBuildMenuItemList, ret=%i\n",_ret_
);
1433 NtUserCheckMenuItem(
1439 DECLARE_RETURN(DWORD
);
1441 DPRINT("Enter NtUserCheckMenuItem\n");
1442 UserEnterExclusive();
1444 if(!(Menu
= UserGetMenuObject(hMenu
)))
1449 RETURN( IntCheckMenuItem(Menu
, uIDCheckItem
, uCheck
));
1452 DPRINT("Leave NtUserCheckMenuItem, ret=%i\n",_ret_
);
1458 HMENU FASTCALL
UserCreateMenu(BOOL PopupMenu
)
1460 PWINSTATION_OBJECT WinStaObject
;
1464 PEPROCESS CurrentProcess
= PsGetCurrentProcess();
1466 if (CsrProcess
!= CurrentProcess
)
1469 * CsrProcess does not have a Win32WindowStation
1473 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1478 if (!NT_SUCCESS(Status
))
1480 DPRINT1("Validation of window station handle (0x%X) failed\n",
1481 CurrentProcess
->Win32WindowStation
);
1482 SetLastNtError(Status
);
1485 Menu
= IntCreateMenu(&Handle
, !PopupMenu
);
1486 UserDereferenceObject(Menu
);
1487 ObDereferenceObject(WinStaObject
);
1491 Menu
= IntCreateMenu(&Handle
, !PopupMenu
);
1492 UserDereferenceObject(Menu
);
1495 return (HMENU
)Handle
;
1509 DECLARE_RETURN(BOOL
);
1511 DPRINT("Enter NtUserDeleteMenu\n");
1512 UserEnterExclusive();
1514 if(!(Menu
= UserGetMenuObject(hMenu
)))
1519 RETURN( IntRemoveMenuItem(Menu
, uPosition
, uFlags
, TRUE
));
1522 DPRINT("Leave NtUserDeleteMenu, ret=%i\n",_ret_
);
1532 BOOL FASTCALL
UserDestroyMenu(HMENU hMenu
)
1536 if(!(Menu
= UserGetMenuObject(hMenu
)))
1541 if(Menu
->Process
!= PsGetCurrentProcess())
1543 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1547 return IntDestroyMenuObject(Menu
, FALSE
, TRUE
);
1558 DECLARE_RETURN(BOOL
);
1560 DPRINT("Enter NtUserDestroyMenu\n");
1561 UserEnterExclusive();
1563 if(!(Menu
= UserGetMenuObject(hMenu
)))
1568 if(Menu
->Process
!= PsGetCurrentProcess())
1570 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1574 RETURN( IntDestroyMenuObject(Menu
, TRUE
, TRUE
));
1577 DPRINT("Leave NtUserDestroyMenu, ret=%i\n",_ret_
);
1587 NtUserEnableMenuItem(
1593 DECLARE_RETURN(UINT
);
1595 DPRINT("Enter NtUserEnableMenuItem\n");
1596 UserEnterExclusive();
1598 if(!(Menu
= UserGetMenuObject(hMenu
)))
1603 RETURN( IntEnableMenuItem(Menu
, uIDEnableItem
, uEnable
));
1606 DPRINT("Leave NtUserEnableMenuItem, ret=%i\n",_ret_
);
1616 NtUserInsertMenuItem(
1620 LPCMENUITEMINFOW UnsafeItemInfo
)
1624 ROSMENUITEMINFO ItemInfo
;
1625 DECLARE_RETURN(DWORD
);
1627 DPRINT("Enter NtUserInsertMenuItem\n");
1628 UserEnterExclusive();
1630 if(!(Menu
= UserGetMenuObject(hMenu
)))
1635 /* Try to copy the whole MENUITEMINFOW structure */
1636 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, sizeof(MENUITEMINFOW
));
1637 if (NT_SUCCESS(Status
))
1639 if (sizeof(MENUITEMINFOW
) != ItemInfo
.cbSize
1640 && FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
) != ItemInfo
.cbSize
)
1642 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1645 RETURN( IntInsertMenuItem(Menu
, uItem
, fByPosition
, &ItemInfo
));
1648 /* Try to copy without last field (not present in older versions) */
1649 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
));
1650 if (NT_SUCCESS(Status
))
1652 if (FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
) != ItemInfo
.cbSize
)
1654 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1657 ItemInfo
.hbmpItem
= (HBITMAP
)0;
1658 RETURN( IntInsertMenuItem(Menu
, uItem
, fByPosition
, &ItemInfo
));
1661 SetLastNtError(Status
);
1665 DPRINT("Leave NtUserInsertMenuItem, ret=%i\n",_ret_
);
1687 NtUserGetMenuDefaultItem(
1694 DECLARE_RETURN(UINT
);
1696 DPRINT("Enter NtUserGetMenuDefaultItem\n");
1697 UserEnterExclusive();
1699 if(!(Menu
= UserGetMenuObject(hMenu
)))
1704 RETURN( IntGetMenuDefaultItem(Menu
, fByPos
, gmdiFlags
, &gismc
));
1707 DPRINT("Leave NtUserGetMenuDefaultItem, ret=%i\n",_ret_
);
1717 NtUserGetMenuBarInfo(
1724 PMENU_OBJECT MenuObject
;
1726 PWINDOW_OBJECT WindowObject
;
1731 DECLARE_RETURN(BOOL
);
1733 DPRINT("Enter NtUserGetMenuBarInfo\n");
1736 if (!(WindowObject
= UserGetWindowObject(hwnd
)))
1738 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1742 hMenu
= (HMENU
)WindowObject
->Wnd
->IDMenu
;
1744 if (!(MenuObject
= UserGetMenuObject(hMenu
)))
1746 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1750 if (pmbi
->cbSize
!= sizeof(MENUBARINFO
))
1752 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1756 kmbi
.cbSize
= sizeof(MENUBARINFO
);
1757 kmbi
.fBarFocused
= FALSE
;
1758 kmbi
.fFocused
= FALSE
;
1759 kmbi
.hwndMenu
= NULL
;
1765 PMENU_OBJECT SubMenuObject
;
1767 if (idItem
) /* Non-Zero-Based. */
1769 if (IntGetMenuItemByFlag(MenuObject
, idItem
-1, MF_BYPOSITION
, NULL
, &mi
, NULL
) > -1)
1770 kmbi
.rcBar
= mi
->Rect
;
1779 /* If items is zero we assume info for the menu itself. */
1780 if (!(IntGetClientOrigin(WindowObject
, &Offset
)))
1785 Rect
.left
= Offset
.x
;
1786 Rect
.right
= Offset
.x
+ MenuObject
->MenuInfo
.Width
;
1787 Rect
.top
= Offset
.y
;
1788 Rect
.bottom
= Offset
.y
+ MenuObject
->MenuInfo
.Height
;
1790 DPRINT("Rect top = %d bottom = %d left = %d right = %d \n",
1791 Rect
.top
, Rect
.bottom
, Rect
.left
, Rect
.right
);
1795 if (idItem
-1 == MenuObject
->MenuInfo
.FocusedItem
)
1796 kmbi
.fFocused
= TRUE
;
1798 if (MenuObject
->MenuInfo
.FocusedItem
!= NO_SELECTED_ITEM
)
1799 kmbi
.fBarFocused
= TRUE
;
1800 SubMenuObject
= UserGetMenuObject(MenuObject
->MenuItemList
->hSubMenu
);
1801 if(SubMenuObject
) kmbi
.hwndMenu
= SubMenuObject
->MenuInfo
.Wnd
;
1802 DPRINT("OBJID_MENU, idItem = %d\n",idItem
);
1807 PMENU_OBJECT SubMenuObject
, XSubMenuObject
;
1808 SubMenuObject
= UserGetMenuObject(MenuObject
->MenuItemList
->hSubMenu
);
1809 if(SubMenuObject
) kmbi
.hMenu
= SubMenuObject
->MenuInfo
.Self
;
1813 DPRINT1("OBJID_CLIENT, No SubMenu!\n");
1818 if (IntGetMenuItemByFlag(SubMenuObject
, idItem
-1, MF_BYPOSITION
, NULL
, &mi
, NULL
) > -1)
1819 kmbi
.rcBar
= mi
->Rect
;
1828 PWINDOW_OBJECT SubWinObj
;
1829 if (!(SubWinObj
= UserGetWindowObject(SubMenuObject
->MenuInfo
.Wnd
)))
1834 if (!(IntGetClientOrigin(SubWinObj
, &Offset
)))
1839 Rect
.left
= Offset
.x
;
1840 Rect
.right
= Offset
.x
+ SubMenuObject
->MenuInfo
.Width
;
1841 Rect
.top
= Offset
.y
;
1842 Rect
.bottom
= Offset
.y
+ SubMenuObject
->MenuInfo
.Height
;
1847 if (idItem
-1 == SubMenuObject
->MenuInfo
.FocusedItem
)
1848 kmbi
.fFocused
= TRUE
;
1850 if (SubMenuObject
->MenuInfo
.FocusedItem
!= NO_SELECTED_ITEM
)
1851 kmbi
.fBarFocused
= TRUE
;
1852 XSubMenuObject
= UserGetMenuObject(SubMenuObject
->MenuItemList
->hSubMenu
);
1853 if (XSubMenuObject
) kmbi
.hwndMenu
= XSubMenuObject
->MenuInfo
.Wnd
;
1854 DPRINT("OBJID_CLIENT, idItem = %d\n",idItem
);
1859 PMENU_OBJECT SysMenuObject
, SubMenuObject
;
1860 if(!(SysMenuObject
= IntGetSystemMenu(WindowObject
, FALSE
, FALSE
)))
1865 kmbi
.hMenu
= SysMenuObject
->MenuInfo
.Self
;
1868 if (IntGetMenuItemByFlag(SysMenuObject
, idItem
-1, MF_BYPOSITION
, NULL
, &mi
, NULL
) > -1)
1869 kmbi
.rcBar
= mi
->Rect
;
1878 PWINDOW_OBJECT SysWinObj
;
1879 if (!(SysWinObj
= UserGetWindowObject(SysMenuObject
->MenuInfo
.Wnd
)))
1884 if (!(IntGetClientOrigin(SysWinObj
, &Offset
)))
1889 Rect
.left
= Offset
.x
;
1890 Rect
.right
= Offset
.x
+ SysMenuObject
->MenuInfo
.Width
;
1891 Rect
.top
= Offset
.y
;
1892 Rect
.bottom
= Offset
.y
+ SysMenuObject
->MenuInfo
.Height
;
1897 if (idItem
-1 == SysMenuObject
->MenuInfo
.FocusedItem
)
1898 kmbi
.fFocused
= TRUE
;
1900 if (SysMenuObject
->MenuInfo
.FocusedItem
!= NO_SELECTED_ITEM
)
1901 kmbi
.fBarFocused
= TRUE
;
1902 SubMenuObject
= UserGetMenuObject(SysMenuObject
->MenuItemList
->hSubMenu
);
1903 if(SubMenuObject
) kmbi
.hwndMenu
= SubMenuObject
->MenuInfo
.Wnd
;
1904 DPRINT("OBJID_SYSMENU, idItem = %d\n",idItem
);
1909 DPRINT1("Unknown idObject = %d, idItem = %d\n",idObject
,idItem
);
1913 NTSTATUS Status
= MmCopyToCaller(pmbi
, &kmbi
, sizeof(MENUBARINFO
));
1914 if (! NT_SUCCESS(Status
))
1916 SetLastNtError(Status
);
1923 DPRINT("Leave NtUserGetMenuBarInfo, ret=%i\n",_ret_
);
1947 NtUserGetMenuItemRect(
1954 PWINDOW_OBJECT ReferenceWnd
;
1959 PMENU_ITEM MenuItem
;
1960 DECLARE_RETURN(BOOL
);
1962 DPRINT("Enter NtUserGetMenuItemRect\n");
1965 if (!(Menu
= UserGetMenuObject(hMenu
)))
1970 if (IntGetMenuItemByFlag(Menu
, uItem
, MF_BYPOSITION
, NULL
, &MenuItem
, NULL
) > -1)
1971 Rect
= MenuItem
->Rect
;
1977 if(!UserMenuInfo(Menu
, &mi
, FALSE
))
1983 if (lprcItem
== NULL
) RETURN( FALSE
);
1985 if (!(ReferenceWnd
= UserGetWindowObject(mi
.Wnd
))) RETURN( FALSE
);
1987 if(MenuItem
->fType
& MF_POPUP
)
1989 XMove
= ReferenceWnd
->Wnd
->ClientRect
.left
;
1990 YMove
= ReferenceWnd
->Wnd
->ClientRect
.top
;
1994 XMove
= ReferenceWnd
->Wnd
->WindowRect
.left
;
1995 YMove
= ReferenceWnd
->Wnd
->WindowRect
.top
;
2000 Rect
.right
+= XMove
;
2001 Rect
.bottom
+= YMove
;
2003 Status
= MmCopyToCaller(lprcItem
, &Rect
, sizeof(RECT
));
2004 if (! NT_SUCCESS(Status
))
2006 SetLastNtError(Status
);
2012 DPRINT("Leave NtUserGetMenuItemRect, ret=%i\n",_ret_
);
2022 NtUserHiliteMenuItem(
2029 PWINDOW_OBJECT Window
;
2030 DECLARE_RETURN(BOOLEAN
);
2032 DPRINT("Enter NtUserHiliteMenuItem\n");
2033 UserEnterExclusive();
2035 if(!(Window
= UserGetWindowObject(hWnd
)))
2040 if(!(Menu
= UserGetMenuObject(hMenu
)))
2045 if(Window
->Wnd
->IDMenu
== (UINT
)hMenu
)
2047 RETURN( IntHiliteMenuItem(Window
, Menu
, uItemHilite
, uHilite
));
2053 DPRINT("Leave NtUserHiliteMenuItem, ret=%i\n",_ret_
);
2063 PROSMENUINFO UnsafeMenuInfo
,
2069 ROSMENUINFO MenuInfo
;
2071 Status
= MmCopyFromCaller(&Size
, &UnsafeMenuInfo
->cbSize
, sizeof(DWORD
));
2072 if (! NT_SUCCESS(Status
))
2074 SetLastNtError(Status
);
2077 if(Size
< sizeof(MENUINFO
) || sizeof(ROSMENUINFO
) < Size
)
2079 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2082 Status
= MmCopyFromCaller(&MenuInfo
, UnsafeMenuInfo
, Size
);
2083 if (! NT_SUCCESS(Status
))
2085 SetLastNtError(Status
);
2092 Res
= IntSetMenuInfo(Menu
, &MenuInfo
);
2097 Res
= IntGetMenuInfo(Menu
, &MenuInfo
);
2100 Status
= MmCopyToCaller(UnsafeMenuInfo
, &MenuInfo
, Size
);
2101 if (! NT_SUCCESS(Status
))
2103 SetLastNtError(Status
);
2123 PROSMENUINFO UnsafeMenuInfo
,
2127 DECLARE_RETURN(BOOL
);
2129 DPRINT("Enter NtUserMenuInfo\n");
2132 if (!(Menu
= UserGetMenuObject(hMenu
)))
2137 RETURN(UserMenuInfo(Menu
, UnsafeMenuInfo
, SetOrGet
));
2140 DPRINT("Leave NtUserMenuInfo, ret=%i\n",_ret_
);
2151 NtUserMenuItemFromPoint(
2158 PWINDOW_OBJECT Window
= NULL
;
2161 DECLARE_RETURN(int);
2163 DPRINT("Enter NtUserMenuItemFromPoint\n");
2164 UserEnterExclusive();
2166 if (!(Menu
= UserGetMenuObject(hMenu
)))
2171 if (!(Window
= UserGetWindowObject(Menu
->MenuInfo
.Wnd
)))
2176 X
-= Window
->Wnd
->WindowRect
.left
;
2177 Y
-= Window
->Wnd
->WindowRect
.top
;
2179 mi
= Menu
->MenuItemList
;
2180 for (i
= 0; NULL
!= mi
; i
++)
2182 if (InRect(mi
->Rect
, X
, Y
))
2189 RETURN( (mi
? i
: NO_SELECTED_ITEM
));
2192 DPRINT("Leave NtUserMenuItemFromPoint, ret=%i\n",_ret_
);
2205 PROSMENUITEMINFO UnsafeItemInfo
,
2208 PMENU_ITEM MenuItem
;
2209 ROSMENUITEMINFO ItemInfo
;
2214 Status
= MmCopyFromCaller(&Size
, &UnsafeItemInfo
->cbSize
, sizeof(UINT
));
2215 if (! NT_SUCCESS(Status
))
2217 SetLastNtError(Status
);
2220 if (sizeof(MENUITEMINFOW
) != Size
2221 && FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
) != Size
2222 && sizeof(ROSMENUITEMINFO
) != Size
)
2224 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2227 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, Size
);
2228 if (! NT_SUCCESS(Status
))
2230 SetLastNtError(Status
);
2233 /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
2235 if (FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
) == Size
2236 && 0 != (ItemInfo
.fMask
& MIIM_BITMAP
))
2238 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2242 if (IntGetMenuItemByFlag(Menu
, Item
,
2243 (ByPosition
? MF_BYPOSITION
: MF_BYCOMMAND
),
2244 NULL
, &MenuItem
, NULL
) < 0)
2246 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2252 Ret
= IntSetMenuItemInfo(Menu
, MenuItem
, &ItemInfo
);
2256 Ret
= IntGetMenuItemInfo(Menu
, MenuItem
, &ItemInfo
);
2259 Status
= MmCopyToCaller(UnsafeItemInfo
, &ItemInfo
, Size
);
2260 if (! NT_SUCCESS(Status
))
2262 SetLastNtError(Status
);
2282 PROSMENUITEMINFO UnsafeItemInfo
,
2286 DECLARE_RETURN(BOOL
);
2288 DPRINT("Enter NtUserMenuItemInfo\n");
2289 UserEnterExclusive();
2291 if (!(Menu
= UserGetMenuObject(hMenu
)))
2296 RETURN( UserMenuItemInfo(Menu
, Item
, ByPosition
, UnsafeItemInfo
, SetOrGet
));
2299 DPRINT("Leave NtUserMenuItemInfo, ret=%i\n",_ret_
);
2316 DECLARE_RETURN(BOOL
);
2318 DPRINT("Enter NtUserRemoveMenu\n");
2319 UserEnterExclusive();
2321 if(!(Menu
= UserGetMenuObject(hMenu
)))
2326 RETURN(IntRemoveMenuItem(Menu
, uPosition
, uFlags
, FALSE
));
2329 DPRINT("Leave NtUserRemoveMenu, ret=%i\n",_ret_
);
2340 NtUserSetMenuContextHelpId(
2342 DWORD dwContextHelpId
)
2345 DECLARE_RETURN(BOOL
);
2347 DPRINT("Enter NtUserSetMenuContextHelpId\n");
2348 UserEnterExclusive();
2350 if(!(Menu
= UserGetMenuObject(hMenu
)))
2355 RETURN(IntSetMenuContextHelpId(Menu
, dwContextHelpId
));
2358 DPRINT("Leave NtUserSetMenuContextHelpId, ret=%i\n",_ret_
);
2369 NtUserSetMenuDefaultItem(
2375 DECLARE_RETURN(BOOL
);
2377 DPRINT("Enter NtUserSetMenuDefaultItem\n");
2378 UserEnterExclusive();
2380 if(!(Menu
= UserGetMenuObject(hMenu
)))
2385 RETURN( UserSetMenuDefaultItem(Menu
, uItem
, fByPos
));
2388 DPRINT("Leave NtUserSetMenuDefaultItem, ret=%i\n",_ret_
);
2398 NtUserSetMenuFlagRtoL(
2402 DECLARE_RETURN(BOOL
);
2404 DPRINT("Enter NtUserSetMenuFlagRtoL\n");
2405 UserEnterExclusive();
2407 if(!(Menu
= UserGetMenuObject(hMenu
)))
2412 RETURN(IntSetMenuFlagRtoL(Menu
));
2415 DPRINT("Leave NtUserSetMenuFlagRtoL, ret=%i\n",_ret_
);
2425 NtUserThunkedMenuInfo(
2430 /* This function seems just to call SetMenuInfo() */
2439 NtUserThunkedMenuItemInfo(
2444 LPMENUITEMINFOW lpmii
,
2445 PUNICODE_STRING lpszCaption
)
2448 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
2449 if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
2458 /* NOTE: unused function */
2460 NtUserTrackPopupMenuEx(