2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
5 * FILE: subsys/win32k/ntuser/menu.c
6 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
8 * 07/30/2003 CSH Created
10 /* INCLUDES ******************************************************************/
18 IntGetSystemMenu(PWND Window
, BOOL bRevert
, BOOL RetMenu
);
22 /* STATIC FUNCTION ***********************************************************/
30 PROSMENUITEMINFO UnsafeItemInfo
,
37 PROSMENUINFO UnsafeMenuInfo
,
40 /* INTERNAL ******************************************************************/
42 /* maximum number of menu items a menu can contain */
43 #define MAX_MENU_ITEMS (0x4000)
44 #define MAX_GOINTOSUBMENU (0x10)
46 #define UpdateMenuItemState(state, change) \
48 if((change) & MFS_DISABLED) { \
49 (state) |= MFS_DISABLED; \
51 (state) &= ~MFS_DISABLED; \
53 if((change) & MFS_CHECKED) { \
54 (state) |= MFS_CHECKED; \
56 (state) &= ~MFS_CHECKED; \
58 if((change) & MFS_HILITE) { \
59 (state) |= MFS_HILITE; \
61 (state) &= ~MFS_HILITE; \
63 if((change) & MFS_DEFAULT) { \
64 (state) |= MFS_DEFAULT; \
66 (state) &= ~MFS_DEFAULT; \
68 if((change) & MF_MOUSESELECT) { \
69 (state) |= MF_MOUSESELECT; \
71 (state) &= ~MF_MOUSESELECT; \
75 #define FreeMenuText(MenuItem) \
77 if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
78 (MenuItem)->Text.Length) { \
79 ExFreePoolWithTag((MenuItem)->Text.Buffer, TAG_STRING); \
83 #define InRect(r, x, y) \
84 ( ( ((r).right >= x)) && \
85 ( ((r).left <= x)) && \
86 ( ((r).bottom >= y)) && \
92 return(STATUS_SUCCESS
);
98 return(STATUS_SUCCESS
);
101 PMENU_OBJECT FASTCALL
UserGetMenuObject(HMENU hMenu
)
107 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
111 Menu
= (PMENU_OBJECT
)UserGetObject(gHandleTable
, hMenu
, otMenu
);
114 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
118 ASSERT(Menu
->head
.cLockObj
>= 0);
125 DumpMenuItemList(PMENU_ITEM MenuItem
)
130 if(MenuItem
->Text
.Length
)
131 DbgPrint(" %d. %wZ\n", ++cnt
, &MenuItem
->Text
);
133 DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt
, (DWORD
)MenuItem
->Text
.Buffer
);
135 if(MFT_BITMAP
& MenuItem
->fType
)
136 DbgPrint("MFT_BITMAP ");
137 if(MFT_MENUBARBREAK
& MenuItem
->fType
)
138 DbgPrint("MFT_MENUBARBREAK ");
139 if(MFT_MENUBREAK
& MenuItem
->fType
)
140 DbgPrint("MFT_MENUBREAK ");
141 if(MFT_OWNERDRAW
& MenuItem
->fType
)
142 DbgPrint("MFT_OWNERDRAW ");
143 if(MFT_RADIOCHECK
& MenuItem
->fType
)
144 DbgPrint("MFT_RADIOCHECK ");
145 if(MFT_RIGHTJUSTIFY
& MenuItem
->fType
)
146 DbgPrint("MFT_RIGHTJUSTIFY ");
147 if(MFT_SEPARATOR
& MenuItem
->fType
)
148 DbgPrint("MFT_SEPARATOR ");
149 if(MFT_STRING
& MenuItem
->fType
)
150 DbgPrint("MFT_STRING ");
151 DbgPrint("\n fState=");
152 if(MFS_DISABLED
& MenuItem
->fState
)
153 DbgPrint("MFS_DISABLED ");
155 DbgPrint("MFS_ENABLED ");
156 if(MFS_CHECKED
& MenuItem
->fState
)
157 DbgPrint("MFS_CHECKED ");
159 DbgPrint("MFS_UNCHECKED ");
160 if(MFS_HILITE
& MenuItem
->fState
)
161 DbgPrint("MFS_HILITE ");
163 DbgPrint("MFS_UNHILITE ");
164 if(MFS_DEFAULT
& MenuItem
->fState
)
165 DbgPrint("MFS_DEFAULT ");
166 if(MFS_GRAYED
& MenuItem
->fState
)
167 DbgPrint("MFS_GRAYED ");
168 DbgPrint("\n wId=%d\n", MenuItem
->wID
);
169 MenuItem
= MenuItem
->Next
;
171 DbgPrint("Entries: %d\n", cnt
);
176 PMENU_OBJECT FASTCALL
177 IntGetMenuObject(HMENU hMenu
)
179 PMENU_OBJECT Menu
= UserGetMenuObject(hMenu
);
182 ASSERT(Menu
->head
.cLockObj
>= 0);
184 Menu
->head
.cLockObj
++;
190 IntFreeMenuItem(PMENU_OBJECT Menu
, PMENU_ITEM MenuItem
, BOOL bRecurse
)
192 FreeMenuText(MenuItem
);
193 if(bRecurse
&& MenuItem
->hSubMenu
)
195 PMENU_OBJECT SubMenu
;
196 SubMenu
= UserGetMenuObject(MenuItem
->hSubMenu
);
199 IntDestroyMenuObject(SubMenu
, bRecurse
, TRUE
);
204 ExFreePool(MenuItem
);
210 IntRemoveMenuItem(PMENU_OBJECT Menu
, UINT uPosition
, UINT uFlags
,
213 PMENU_ITEM PrevMenuItem
, MenuItem
;
214 if(IntGetMenuItemByFlag(Menu
, uPosition
, uFlags
, &Menu
, &MenuItem
,
220 PrevMenuItem
->Next
= MenuItem
->Next
;
223 Menu
->MenuItemList
= MenuItem
->Next
;
225 Menu
->MenuInfo
.MenuItemCount
--;
226 return IntFreeMenuItem(Menu
, MenuItem
, bRecurse
);
233 IntDeleteMenuItems(PMENU_OBJECT Menu
, BOOL bRecurse
)
237 PMENU_ITEM CurItem
= Menu
->MenuItemList
;
240 NextItem
= CurItem
->Next
;
241 IntFreeMenuItem(Menu
, CurItem
, bRecurse
);
245 Menu
->MenuInfo
.MenuItemCount
= 0;
246 Menu
->MenuItemList
= NULL
;
251 IntDestroyMenuObject(PMENU_OBJECT Menu
,
252 BOOL bRecurse
, BOOL RemoveFromProcess
)
257 PWINSTATION_OBJECT WindowStation
;
260 /* remove all menu items */
261 IntDeleteMenuItems(Menu
, bRecurse
); /* do not destroy submenus */
263 if(RemoveFromProcess
)
265 RemoveEntryList(&Menu
->ListEntry
);
268 Status
= ObReferenceObjectByHandle(Menu
->Process
->Win32WindowStation
,
270 ExWindowStationObjectType
,
272 (PVOID
*)&WindowStation
,
274 if(NT_SUCCESS(Status
))
277 if (Menu
->MenuInfo
.Wnd
)
279 Window
= UserGetWindowObject(Menu
->MenuInfo
.Wnd
);
285 // UserDereferenceObject(Menu);
286 ret
= UserDeleteObject(Menu
->MenuInfo
.Self
, otMenu
);
287 ObDereferenceObject(WindowStation
);
294 PMENU_OBJECT FASTCALL
295 IntCreateMenu(PHANDLE Handle
, BOOL IsMenuBar
)
298 PPROCESSINFO CurrentWin32Process
;
300 Menu
= (PMENU_OBJECT
)UserCreateObject( gHandleTable
,
304 sizeof(MENU_OBJECT
));
311 Menu
->Process
= PsGetCurrentProcess();
312 Menu
->RtoL
= FALSE
; /* default */
313 Menu
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
314 Menu
->MenuInfo
.fMask
= 0; /* not used */
315 Menu
->MenuInfo
.dwStyle
= 0; /* FIXME */
316 Menu
->MenuInfo
.cyMax
= 0; /* default */
317 Menu
->MenuInfo
.hbrBack
= NULL
; /* no brush */
318 Menu
->MenuInfo
.dwContextHelpID
= 0; /* default */
319 Menu
->MenuInfo
.dwMenuData
= 0; /* default */
320 Menu
->MenuInfo
.Self
= *Handle
;
321 Menu
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
322 Menu
->MenuInfo
.Flags
= (IsMenuBar
? 0 : MF_POPUP
);
323 Menu
->MenuInfo
.Wnd
= NULL
;
324 Menu
->MenuInfo
.WndOwner
= NULL
;
325 Menu
->MenuInfo
.Height
= 0;
326 Menu
->MenuInfo
.Width
= 0;
327 Menu
->MenuInfo
.TimeToHide
= FALSE
;
329 Menu
->MenuInfo
.MenuItemCount
= 0;
330 Menu
->MenuItemList
= NULL
;
332 /* Insert menu item into process menu handle list */
333 CurrentWin32Process
= PsGetCurrentProcessWin32Process();
334 InsertTailList(&CurrentWin32Process
->MenuListHead
, &Menu
->ListEntry
);
340 IntCloneMenuItems(PMENU_OBJECT Destination
, PMENU_OBJECT Source
)
342 PMENU_ITEM MenuItem
, NewMenuItem
= NULL
;
343 PMENU_ITEM Old
= NULL
;
345 if(!Source
->MenuInfo
.MenuItemCount
)
348 MenuItem
= Source
->MenuItemList
;
353 NewMenuItem
->Next
= MenuItem
;
354 NewMenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
357 NewMenuItem
->fType
= MenuItem
->fType
;
358 NewMenuItem
->fState
= MenuItem
->fState
;
359 NewMenuItem
->wID
= MenuItem
->wID
;
360 NewMenuItem
->hSubMenu
= MenuItem
->hSubMenu
;
361 NewMenuItem
->hbmpChecked
= MenuItem
->hbmpChecked
;
362 NewMenuItem
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
363 NewMenuItem
->dwItemData
= MenuItem
->dwItemData
;
364 if((MENU_ITEM_TYPE(NewMenuItem
->fType
) == MF_STRING
))
366 if(MenuItem
->Text
.Length
)
368 NewMenuItem
->Text
.Length
= 0;
369 NewMenuItem
->Text
.MaximumLength
= MenuItem
->Text
.MaximumLength
;
370 NewMenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, MenuItem
->Text
.MaximumLength
, TAG_STRING
);
371 if(!NewMenuItem
->Text
.Buffer
)
373 ExFreePoolWithTag(NewMenuItem
, TAG_MENUITEM
);
376 RtlCopyUnicodeString(&NewMenuItem
->Text
, &MenuItem
->Text
);
380 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
385 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
387 NewMenuItem
->hbmpItem
= MenuItem
->hbmpItem
;
389 NewMenuItem
->Next
= NULL
;
391 Old
->Next
= NewMenuItem
;
393 Destination
->MenuItemList
= NewMenuItem
;
394 Destination
->MenuInfo
.MenuItemCount
++;
395 MenuItem
= MenuItem
->Next
;
401 PMENU_OBJECT FASTCALL
402 IntCloneMenu(PMENU_OBJECT Source
)
404 PPROCESSINFO CurrentWin32Process
;
411 Menu
= (PMENU_OBJECT
)UserCreateObject( gHandleTable
,
415 sizeof(MENU_OBJECT
));
419 Menu
->Process
= PsGetCurrentProcess();
420 Menu
->RtoL
= Source
->RtoL
;
421 Menu
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
422 Menu
->MenuInfo
.fMask
= Source
->MenuInfo
.fMask
;
423 Menu
->MenuInfo
.dwStyle
= Source
->MenuInfo
.dwStyle
;
424 Menu
->MenuInfo
.cyMax
= Source
->MenuInfo
.cyMax
;
425 Menu
->MenuInfo
.hbrBack
= Source
->MenuInfo
.hbrBack
;
426 Menu
->MenuInfo
.dwContextHelpID
= Source
->MenuInfo
.dwContextHelpID
;
427 Menu
->MenuInfo
.dwMenuData
= Source
->MenuInfo
.dwMenuData
;
428 Menu
->MenuInfo
.Self
= hMenu
;
429 Menu
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
430 Menu
->MenuInfo
.Wnd
= NULL
;
431 Menu
->MenuInfo
.WndOwner
= NULL
;
432 Menu
->MenuInfo
.Height
= 0;
433 Menu
->MenuInfo
.Width
= 0;
434 Menu
->MenuInfo
.TimeToHide
= FALSE
;
436 Menu
->MenuInfo
.MenuItemCount
= 0;
437 Menu
->MenuItemList
= NULL
;
439 /* Insert menu item into process menu handle list */
440 CurrentWin32Process
= PsGetCurrentProcessWin32Process();
441 InsertTailList(&CurrentWin32Process
->MenuListHead
, &Menu
->ListEntry
);
443 IntCloneMenuItems(Menu
, Source
);
449 IntSetMenuFlagRtoL(PMENU_OBJECT Menu
)
456 IntSetMenuContextHelpId(PMENU_OBJECT Menu
, DWORD dwContextHelpId
)
458 Menu
->MenuInfo
.dwContextHelpID
= dwContextHelpId
;
463 IntGetMenuInfo(PMENU_OBJECT Menu
, PROSMENUINFO lpmi
)
465 if(lpmi
->fMask
& MIM_BACKGROUND
)
466 lpmi
->hbrBack
= Menu
->MenuInfo
.hbrBack
;
467 if(lpmi
->fMask
& MIM_HELPID
)
468 lpmi
->dwContextHelpID
= Menu
->MenuInfo
.dwContextHelpID
;
469 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
470 lpmi
->cyMax
= Menu
->MenuInfo
.cyMax
;
471 if(lpmi
->fMask
& MIM_MENUDATA
)
472 lpmi
->dwMenuData
= Menu
->MenuInfo
.dwMenuData
;
473 if(lpmi
->fMask
& MIM_STYLE
)
474 lpmi
->dwStyle
= Menu
->MenuInfo
.dwStyle
;
475 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
477 RtlCopyMemory((char *) lpmi
+ sizeof(MENUINFO
),
478 (char *) &Menu
->MenuInfo
+ sizeof(MENUINFO
),
479 lpmi
->cbSize
- sizeof(MENUINFO
));
481 if (sizeof(ROSMENUINFO
) == lpmi
->cbSize
)
483 lpmi
->maxBmpSize
.cx
= Menu
->MenuInfo
.maxBmpSize
.cx
;
484 lpmi
->maxBmpSize
.cy
= Menu
->MenuInfo
.maxBmpSize
.cy
;
490 IntSetMenuInfo(PMENU_OBJECT Menu
, PROSMENUINFO lpmi
)
492 if(lpmi
->fMask
& MIM_BACKGROUND
)
493 Menu
->MenuInfo
.hbrBack
= lpmi
->hbrBack
;
494 if(lpmi
->fMask
& MIM_HELPID
)
495 Menu
->MenuInfo
.dwContextHelpID
= lpmi
->dwContextHelpID
;
496 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
497 Menu
->MenuInfo
.cyMax
= lpmi
->cyMax
;
498 if(lpmi
->fMask
& MIM_MENUDATA
)
499 Menu
->MenuInfo
.dwMenuData
= lpmi
->dwMenuData
;
500 if(lpmi
->fMask
& MIM_STYLE
)
501 Menu
->MenuInfo
.dwStyle
= lpmi
->dwStyle
;
502 if(lpmi
->fMask
& MIM_APPLYTOSUBMENUS
)
506 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
508 Menu
->MenuInfo
.FocusedItem
= lpmi
->FocusedItem
;
509 Menu
->MenuInfo
.Height
= lpmi
->Height
;
510 Menu
->MenuInfo
.Width
= lpmi
->Width
;
511 Menu
->MenuInfo
.Wnd
= lpmi
->Wnd
;
512 Menu
->MenuInfo
.WndOwner
= lpmi
->WndOwner
;
513 Menu
->MenuInfo
.TimeToHide
= lpmi
->TimeToHide
;
515 if (sizeof(ROSMENUINFO
) == lpmi
->cbSize
)
517 Menu
->MenuInfo
.maxBmpSize
.cx
= lpmi
->maxBmpSize
.cx
;
518 Menu
->MenuInfo
.maxBmpSize
.cy
= lpmi
->maxBmpSize
.cy
;
525 IntGetMenuItemByFlag(PMENU_OBJECT Menu
, UINT uSearchBy
, UINT fFlag
,
526 PMENU_OBJECT
*SubMenu
, PMENU_ITEM
*MenuItem
,
527 PMENU_ITEM
*PrevMenuItem
)
529 PMENU_ITEM PrevItem
= NULL
;
530 PMENU_ITEM CurItem
= Menu
->MenuItemList
;
534 if(MF_BYPOSITION
& fFlag
)
537 while(CurItem
&& (p
> 0))
540 CurItem
= CurItem
->Next
;
548 *PrevMenuItem
= PrevItem
;
555 *PrevMenuItem
= NULL
; /* ? */
559 return uSearchBy
- p
;
566 if(CurItem
->wID
== uSearchBy
)
571 *PrevMenuItem
= PrevItem
;
579 if(CurItem
->fType
& MF_POPUP
)
581 PMENU_OBJECT NewMenu
= UserGetMenuObject(CurItem
->hSubMenu
);
584 ret
= IntGetMenuItemByFlag(NewMenu
, uSearchBy
, fFlag
,
585 SubMenu
, MenuItem
, PrevMenuItem
);
594 CurItem
= CurItem
->Next
;
603 IntInsertMenuItemToList(PMENU_OBJECT Menu
, PMENU_ITEM MenuItem
, int pos
)
606 PMENU_ITEM LastItem
= NULL
;
609 CurItem
= Menu
->MenuItemList
;
610 while(CurItem
&& (pos
!= 0))
613 CurItem
= CurItem
->Next
;
620 /* insert the item after LastItem */
621 LastItem
->Next
= MenuItem
;
625 /* insert at the beginning */
626 Menu
->MenuItemList
= MenuItem
;
628 MenuItem
->Next
= CurItem
;
629 Menu
->MenuInfo
.MenuItemCount
++;
635 IntGetMenuItemInfo(PMENU_OBJECT Menu
, /* UNUSED PARAM!! */
636 PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
640 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
642 lpmii
->fType
= MenuItem
->fType
;
644 if(lpmii
->fMask
& MIIM_BITMAP
)
646 lpmii
->hbmpItem
= MenuItem
->hbmpItem
;
648 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
650 lpmii
->hbmpChecked
= MenuItem
->hbmpChecked
;
651 lpmii
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
653 if(lpmii
->fMask
& MIIM_DATA
)
655 lpmii
->dwItemData
= MenuItem
->dwItemData
;
657 if(lpmii
->fMask
& MIIM_ID
)
659 lpmii
->wID
= MenuItem
->wID
;
661 if(lpmii
->fMask
& MIIM_STATE
)
663 lpmii
->fState
= MenuItem
->fState
;
665 if(lpmii
->fMask
& MIIM_SUBMENU
)
667 lpmii
->hSubMenu
= MenuItem
->hSubMenu
;
670 if ((lpmii
->fMask
& MIIM_STRING
) ||
671 ((lpmii
->fMask
& MIIM_TYPE
) && (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
)))
673 if (lpmii
->dwTypeData
== NULL
)
675 lpmii
->cch
= MenuItem
->Text
.Length
/ sizeof(WCHAR
);
679 Status
= MmCopyToCaller(lpmii
->dwTypeData
, MenuItem
->Text
.Buffer
,
680 min(lpmii
->cch
* sizeof(WCHAR
),
681 MenuItem
->Text
.MaximumLength
));
682 if (! NT_SUCCESS(Status
))
684 SetLastNtError(Status
);
690 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
692 lpmii
->Rect
= MenuItem
->Rect
;
693 lpmii
->dxTab
= MenuItem
->dxTab
;
694 lpmii
->lpstr
= MenuItem
->Text
.Buffer
; // Use DesktopHeap!
701 IntSetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
703 PMENU_OBJECT SubMenuObject
;
704 UINT fTypeMask
= (MFT_BITMAP
| MFT_MENUBARBREAK
| MFT_MENUBREAK
| MFT_OWNERDRAW
| MFT_RADIOCHECK
| MFT_RIGHTJUSTIFY
| MFT_SEPARATOR
| MF_POPUP
);
706 if(!MenuItem
|| !MenuObject
|| !lpmii
)
710 if( lpmii
->fType
& ~fTypeMask
)
712 DbgPrint("IntSetMenuItemInfo invalid fType flags %x\n", lpmii
->fType
& ~fTypeMask
);
713 lpmii
->fMask
&= ~(MIIM_TYPE
| MIIM_FTYPE
);
715 if(lpmii
->fMask
& MIIM_TYPE
)
717 if(lpmii
->fMask
& ( MIIM_STRING
| MIIM_FTYPE
| MIIM_BITMAP
))
719 DbgPrint("IntSetMenuItemInfo: Invalid combination of fMask bits used\n");
720 /* this does not happen on Win9x/ME */
721 SetLastNtError( ERROR_INVALID_PARAMETER
);
725 * Delete the menu item type when changing type from
728 if (MenuItem
->fType
!= lpmii
->fType
&&
729 MENU_ITEM_TYPE(MenuItem
->fType
) == MFT_STRING
)
731 FreeMenuText(MenuItem
);
732 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
734 if(lpmii
->fType
& MFT_BITMAP
)
737 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
739 { /* Win 9x/Me stuff */
740 MenuItem
->hbmpItem
= (HBITMAP
)((ULONG_PTR
)(LOWORD(lpmii
->dwTypeData
)));
743 MenuItem
->fType
|= lpmii
->fType
;
745 if (lpmii
->fMask
& MIIM_FTYPE
)
747 if(( lpmii
->fType
& MFT_BITMAP
))
749 DbgPrint("IntSetMenuItemInfo: Can not use FTYPE and MFT_BITMAP.\n");
750 SetLastNtError( ERROR_INVALID_PARAMETER
);
753 MenuItem
->fType
|= lpmii
->fType
; /* Need to save all the flags, this fixed MFT_RIGHTJUSTIFY */
755 if(lpmii
->fMask
& MIIM_BITMAP
)
757 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
759 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
761 MenuItem
->hbmpChecked
= lpmii
->hbmpChecked
;
762 MenuItem
->hbmpUnchecked
= lpmii
->hbmpUnchecked
;
764 if(lpmii
->fMask
& MIIM_DATA
)
766 MenuItem
->dwItemData
= lpmii
->dwItemData
;
768 if(lpmii
->fMask
& MIIM_ID
)
770 MenuItem
->wID
= lpmii
->wID
;
772 if(lpmii
->fMask
& MIIM_STATE
)
774 /* remove MFS_DEFAULT flag from all other menu items if this item
775 has the MFS_DEFAULT state */
776 if(lpmii
->fState
& MFS_DEFAULT
)
777 UserSetMenuDefaultItem(MenuObject
, -1, 0);
778 /* update the menu item state flags */
779 UpdateMenuItemState(MenuItem
->fState
, lpmii
->fState
);
782 if(lpmii
->fMask
& MIIM_SUBMENU
)
784 MenuItem
->hSubMenu
= lpmii
->hSubMenu
;
785 /* Make sure the submenu is marked as a popup menu */
786 if (MenuItem
->hSubMenu
)
788 SubMenuObject
= UserGetMenuObject(MenuItem
->hSubMenu
);
789 if (SubMenuObject
!= NULL
)
791 SubMenuObject
->MenuInfo
.Flags
|= MF_POPUP
;
792 MenuItem
->fType
|= MF_POPUP
;
796 MenuItem
->fType
&= ~MF_POPUP
;
801 MenuItem
->fType
&= ~MF_POPUP
;
805 if ((lpmii
->fMask
& MIIM_STRING
) ||
806 ((lpmii
->fMask
& MIIM_TYPE
) && (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
)))
808 FreeMenuText(MenuItem
);
810 if(lpmii
->dwTypeData
&& lpmii
->cch
)
812 UNICODE_STRING Source
;
815 Source
.MaximumLength
= lpmii
->cch
* sizeof(WCHAR
);
816 Source
.Buffer
= lpmii
->dwTypeData
;
818 MenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(
819 PagedPool
, Source
.Length
+ sizeof(WCHAR
), TAG_STRING
);
820 if(MenuItem
->Text
.Buffer
!= NULL
)
822 MenuItem
->Text
.Length
= 0;
823 MenuItem
->Text
.MaximumLength
= Source
.Length
+ sizeof(WCHAR
);
824 RtlCopyUnicodeString(&MenuItem
->Text
, &Source
);
825 MenuItem
->Text
.Buffer
[MenuItem
->Text
.Length
/ sizeof(WCHAR
)] = 0;
829 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
834 if (0 == (MenuObject
->MenuInfo
.Flags
& MF_SYSMENU
))
836 MenuItem
->fType
|= MF_SEPARATOR
;
838 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
842 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
844 MenuItem
->Rect
= lpmii
->Rect
;
845 MenuItem
->dxTab
= lpmii
->dxTab
;
846 lpmii
->lpstr
= MenuItem
->Text
.Buffer
; /* Use DesktopHeap! Send back new allocated string or zero */
853 IntInsertMenuItem(PMENU_OBJECT MenuObject
, UINT uItem
, BOOL fByPosition
,
854 PROSMENUITEMINFO ItemInfo
)
856 int pos
= (int)uItem
;
858 PMENU_OBJECT SubMenu
= NULL
;
860 if (MAX_MENU_ITEMS
<= MenuObject
->MenuInfo
.MenuItemCount
)
862 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
868 SubMenu
= MenuObject
;
869 /* calculate position */
870 if(MenuObject
->MenuInfo
.MenuItemCount
< pos
)
872 pos
= MenuObject
->MenuInfo
.MenuItemCount
;
877 pos
= IntGetMenuItemByFlag(MenuObject
, uItem
, MF_BYCOMMAND
, &SubMenu
, NULL
, NULL
);
881 /* default to last position of menu */
882 SubMenu
= MenuObject
;
883 pos
= MenuObject
->MenuInfo
.MenuItemCount
;
892 MenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
893 if (NULL
== MenuItem
)
895 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
899 MenuItem
->fType
= MFT_STRING
;
900 MenuItem
->fState
= MFS_ENABLED
| MFS_UNCHECKED
;
902 MenuItem
->hSubMenu
= (HMENU
)0;
903 MenuItem
->hbmpChecked
= (HBITMAP
)0;
904 MenuItem
->hbmpUnchecked
= (HBITMAP
)0;
905 MenuItem
->dwItemData
= 0;
906 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
907 MenuItem
->hbmpItem
= (HBITMAP
)0;
909 if(!IntSetMenuItemInfo(SubMenu
, MenuItem
, ItemInfo
))
911 ExFreePoolWithTag(MenuItem
, TAG_MENUITEM
);
915 /* Force size recalculation! */
916 MenuObject
->MenuInfo
.Height
= 0;
918 pos
= IntInsertMenuItemToList(SubMenu
, MenuItem
, pos
);
920 DPRINT("IntInsertMenuItemToList = %i\n", pos
);
926 IntEnableMenuItem(PMENU_OBJECT MenuObject
, UINT uIDEnableItem
, UINT uEnable
)
929 UINT res
= IntGetMenuItemByFlag(MenuObject
, uIDEnableItem
, uEnable
, NULL
, &MenuItem
, NULL
);
930 if(!MenuItem
|| (res
== (UINT
)-1))
935 res
= MenuItem
->fState
& (MF_GRAYED
| MF_DISABLED
);
937 if(uEnable
& MF_DISABLED
)
939 MenuItem
->fState
|= MF_DISABLED
;
940 MenuItem
->fState
|= uEnable
& MF_GRAYED
;
944 if(uEnable
& MF_GRAYED
)
946 MenuItem
->fState
|= (MF_GRAYED
| MF_DISABLED
);
950 MenuItem
->fState
&= ~(MF_DISABLED
| MF_GRAYED
);
959 IntBuildMenuItemList(PMENU_OBJECT MenuObject
, PVOID Buffer
, ULONG nMax
)
964 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
971 if (nMax
< MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
))
975 StrOut
= (PWCHAR
)((char *) Buffer
+ MenuObject
->MenuInfo
.MenuItemCount
976 * sizeof(ROSMENUITEMINFO
));
977 nMax
-= MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
);
979 mii
.cbSize
= sizeof(ROSMENUITEMINFO
);
983 while (NULL
!= CurItem
)
985 mii
.cch
= CurItem
->Text
.Length
/ sizeof(WCHAR
);
986 mii
.dwItemData
= CurItem
->dwItemData
;
987 if (0 != CurItem
->Text
.Length
)
989 mii
.dwTypeData
= StrOut
;
993 mii
.dwTypeData
= NULL
;
995 mii
.fState
= CurItem
->fState
;
996 mii
.fType
= CurItem
->fType
;
997 mii
.wID
= CurItem
->wID
;
998 mii
.hbmpChecked
= CurItem
->hbmpChecked
;
999 mii
.hbmpItem
= CurItem
->hbmpItem
;
1000 mii
.hbmpUnchecked
= CurItem
->hbmpUnchecked
;
1001 mii
.hSubMenu
= CurItem
->hSubMenu
;
1002 mii
.Rect
= CurItem
->Rect
;
1003 mii
.dxTab
= CurItem
->dxTab
;
1004 mii
.lpstr
= CurItem
->Text
.Buffer
; // Use DesktopHeap!
1006 Status
= MmCopyToCaller(Buf
, &mii
, sizeof(ROSMENUITEMINFO
));
1007 if (! NT_SUCCESS(Status
))
1009 SetLastNtError(Status
);
1012 Buf
= (PVOID
)((ULONG_PTR
)Buf
+ sizeof(ROSMENUITEMINFO
));
1014 if (0 != CurItem
->Text
.Length
1015 && (nMax
>= CurItem
->Text
.Length
+ sizeof(WCHAR
)))
1018 Status
= MmCopyToCaller(StrOut
, CurItem
->Text
.Buffer
,
1019 CurItem
->Text
.Length
);
1020 if (! NT_SUCCESS(Status
))
1022 SetLastNtError(Status
);
1025 StrOut
+= CurItem
->Text
.Length
/ sizeof(WCHAR
);
1026 Status
= MmCopyToCaller(StrOut
, &NulByte
, sizeof(WCHAR
));
1027 if (! NT_SUCCESS(Status
))
1029 SetLastNtError(Status
);
1033 nMax
-= CurItem
->Text
.Length
+ sizeof(WCHAR
);
1035 else if (0 != CurItem
->Text
.Length
)
1040 CurItem
= CurItem
->Next
;
1046 while (NULL
!= CurItem
)
1048 res
+= sizeof(ROSMENUITEMINFO
) + CurItem
->Text
.Length
+ sizeof(WCHAR
);
1049 CurItem
= CurItem
->Next
;
1058 IntCheckMenuItem(PMENU_OBJECT MenuObject
, UINT uIDCheckItem
, UINT uCheck
)
1060 PMENU_ITEM MenuItem
;
1063 if((IntGetMenuItemByFlag(MenuObject
, uIDCheckItem
, uCheck
, NULL
, &MenuItem
, NULL
) < 0) || !MenuItem
)
1068 res
= (DWORD
)(MenuItem
->fState
& MF_CHECKED
);
1069 if(uCheck
& MF_CHECKED
)
1071 MenuItem
->fState
|= MF_CHECKED
;
1075 MenuItem
->fState
&= ~MF_CHECKED
;
1082 IntHiliteMenuItem(PWND WindowObject
, PMENU_OBJECT MenuObject
,
1083 UINT uItemHilite
, UINT uHilite
)
1085 PMENU_ITEM MenuItem
;
1086 BOOL res
= IntGetMenuItemByFlag(MenuObject
, uItemHilite
, uHilite
, NULL
, &MenuItem
, NULL
);
1087 if(!MenuItem
|| !res
)
1092 if(uHilite
& MF_HILITE
)
1094 MenuItem
->fState
|= MF_HILITE
;
1098 MenuItem
->fState
&= ~MF_HILITE
;
1101 /* FIXME - update the window's menu */
1107 UserSetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT uItem
, UINT fByPos
)
1110 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1112 if(uItem
== (UINT
)-1)
1116 MenuItem
->fState
&= ~MFS_DEFAULT
;
1117 MenuItem
= MenuItem
->Next
;
1129 MenuItem
->fState
|= MFS_DEFAULT
;
1134 MenuItem
->fState
&= ~MFS_DEFAULT
;
1137 MenuItem
= MenuItem
->Next
;
1144 if(!ret
&& (MenuItem
->wID
== uItem
))
1146 MenuItem
->fState
|= MFS_DEFAULT
;
1151 MenuItem
->fState
&= ~MFS_DEFAULT
;
1153 MenuItem
= MenuItem
->Next
;
1161 IntGetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT fByPos
, UINT gmdiFlags
,
1167 PMENU_OBJECT SubMenuObject
;
1168 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1172 if(MenuItem
->fState
& MFS_DEFAULT
)
1175 if(!(gmdiFlags
& GMDI_USEDISABLED
) && (MenuItem
->fState
& MFS_DISABLED
))
1181 res
= MenuItem
->wID
;
1183 if((*gismc
< MAX_GOINTOSUBMENU
) && (gmdiFlags
& GMDI_GOINTOPOPUPS
) &&
1187 SubMenuObject
= UserGetMenuObject(MenuItem
->hSubMenu
);
1188 if(!SubMenuObject
|| (SubMenuObject
== MenuObject
))
1192 sres
= IntGetMenuDefaultItem(SubMenuObject
, fByPos
, gmdiFlags
, gismc
);
1202 MenuItem
= MenuItem
->Next
;
1210 co_IntInitTracking(PWND Window
, PMENU_OBJECT Menu
, BOOL Popup
,
1213 /* FIXME - hide caret */
1215 if(!(Flags
& TPM_NONOTIFY
))
1216 co_IntSendMessage(Window
->head
.h
, WM_SETCURSOR
, (WPARAM
)Window
->head
.h
, HTCAPTION
);
1218 /* FIXME - send WM_SETCURSOR message */
1220 if(!(Flags
& TPM_NONOTIFY
))
1221 co_IntSendMessage(Window
->head
.h
, WM_INITMENU
, (WPARAM
)Menu
->MenuInfo
.Self
, 0);
1225 co_IntExitTracking(PWND Window
, PMENU_OBJECT Menu
, BOOL Popup
,
1228 if(!(Flags
& TPM_NONOTIFY
))
1229 co_IntSendMessage(Window
->head
.h
, WM_EXITMENULOOP
, 0 /* FIXME */, 0);
1231 /* FIXME - Show caret again */
1235 IntTrackMenu(PMENU_OBJECT Menu
, PWND Window
, INT x
, INT y
,
1242 co_IntTrackPopupMenu(PMENU_OBJECT Menu
, PWND Window
,
1243 UINT Flags
, POINT
*Pos
, UINT MenuPos
, RECTL
*ExcludeRect
)
1245 co_IntInitTracking(Window
, Menu
, TRUE
, Flags
);
1247 co_IntExitTracking(Window
, Menu
, TRUE
, Flags
);
1252 IntSetMenuItemRect(PMENU_OBJECT Menu
, UINT Item
, BOOL fByPos
, RECTL
*rcRect
)
1255 if(IntGetMenuItemByFlag(Menu
, Item
, (fByPos
? MF_BYPOSITION
: MF_BYCOMMAND
),
1256 NULL
, &mi
, NULL
) > -1)
1266 * Internal function. Called when the process is destroyed to free the remaining menu handles.
1269 IntCleanupMenus(struct _EPROCESS
*Process
, PPROCESSINFO Win32Process
)
1271 PEPROCESS CurrentProcess
;
1272 PLIST_ENTRY LastHead
= NULL
;
1273 PMENU_OBJECT MenuObject
;
1275 CurrentProcess
= PsGetCurrentProcess();
1276 if (CurrentProcess
!= Process
)
1278 KeAttachProcess(&Process
->Pcb
);
1281 while (Win32Process
->MenuListHead
.Flink
!= &(Win32Process
->MenuListHead
) &&
1282 Win32Process
->MenuListHead
.Flink
!= LastHead
)
1284 LastHead
= Win32Process
->MenuListHead
.Flink
;
1285 MenuObject
= CONTAINING_RECORD(Win32Process
->MenuListHead
.Flink
, MENU_OBJECT
, ListEntry
);
1287 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1290 if (CurrentProcess
!= Process
)
1298 intGetTitleBarInfo(PWND pWindowObject
, PTITLEBARINFO bti
)
1302 DWORD dwExStyle
= 0;
1303 BOOLEAN retValue
= TRUE
;
1305 if (bti
->cbSize
== sizeof(TITLEBARINFO
))
1307 RtlZeroMemory(&bti
->rgstate
[0],sizeof(DWORD
)*(CCHILDREN_TITLEBAR
+1));
1309 bti
->rgstate
[0] = STATE_SYSTEM_FOCUSABLE
;
1311 dwStyle
= pWindowObject
->style
;
1312 dwExStyle
= pWindowObject
->ExStyle
;
1314 bti
->rcTitleBar
.top
= 0;
1315 bti
->rcTitleBar
.left
= 0;
1316 bti
->rcTitleBar
.right
= pWindowObject
->rcWindow
.right
- pWindowObject
->rcWindow
.left
;
1317 bti
->rcTitleBar
.bottom
= pWindowObject
->rcWindow
.bottom
- pWindowObject
->rcWindow
.top
;
1319 /* is it iconiced ? */
1320 if ((dwStyle
& WS_ICONIC
)!=WS_ICONIC
)
1322 /* Remove frame from rectangle */
1323 if (HAS_THICKFRAME( dwStyle
, dwExStyle
))
1325 /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXFRAME) and UserGetSystemMetrics(SM_CYFRAME) */
1326 RECTL_vInflateRect( &bti
->rcTitleBar
, -UserGetSystemMetrics(SM_CXFRAME
), -UserGetSystemMetrics(SM_CYFRAME
) );
1328 else if (HAS_DLGFRAME( dwStyle
, dwExStyle
))
1330 /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXDLGFRAME) and UserGetSystemMetrics(SM_CYDLGFRAME) */
1331 RECTL_vInflateRect( &bti
->rcTitleBar
, -UserGetSystemMetrics(SM_CXDLGFRAME
), -UserGetSystemMetrics(SM_CYDLGFRAME
));
1333 else if (HAS_THINFRAME( dwStyle
, dwExStyle
))
1335 /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXBORDER) and UserGetSystemMetrics(SM_CYBORDER) */
1336 RECTL_vInflateRect( &bti
->rcTitleBar
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
) );
1339 /* We have additional border information if the window
1340 * is a child (but not an MDI child) */
1341 if ( (dwStyle
& WS_CHILD
) &&
1342 ((dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
1344 if (dwExStyle
& WS_EX_CLIENTEDGE
)
1346 /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXEDGE) and UserGetSystemMetrics(SM_CYEDGE) */
1347 RECTL_vInflateRect (&bti
->rcTitleBar
, -UserGetSystemMetrics(SM_CXEDGE
), -UserGetSystemMetrics(SM_CYEDGE
));
1350 if (dwExStyle
& WS_EX_STATICEDGE
)
1352 /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CXBORDER) and UserGetSystemMetrics(SM_CYBORDER) */
1353 RECTL_vInflateRect (&bti
->rcTitleBar
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
));
1358 bti
->rcTitleBar
.top
+= pWindowObject
->rcWindow
.top
;
1359 bti
->rcTitleBar
.left
+= pWindowObject
->rcWindow
.left
;
1360 bti
->rcTitleBar
.right
+= pWindowObject
->rcWindow
.left
;
1362 bti
->rcTitleBar
.bottom
= bti
->rcTitleBar
.top
;
1363 if (dwExStyle
& WS_EX_TOOLWINDOW
)
1365 /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CYSMCAPTION) */
1366 bti
->rcTitleBar
.bottom
+= UserGetSystemMetrics(SM_CYSMCAPTION
);
1370 /* FIXME : Note this value should exists in pWindowObject for UserGetSystemMetrics(SM_CYCAPTION) and UserGetSystemMetrics(SM_CXSIZE) */
1371 bti
->rcTitleBar
.bottom
+= UserGetSystemMetrics(SM_CYCAPTION
);
1372 bti
->rcTitleBar
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
1375 if (dwStyle
& WS_CAPTION
)
1377 bti
->rgstate
[1] = STATE_SYSTEM_INVISIBLE
;
1378 if (dwStyle
& WS_SYSMENU
)
1380 if (!(dwStyle
& (WS_MINIMIZEBOX
|WS_MAXIMIZEBOX
)))
1382 bti
->rgstate
[2] = STATE_SYSTEM_INVISIBLE
;
1383 bti
->rgstate
[3] = STATE_SYSTEM_INVISIBLE
;
1387 if (!(dwStyle
& WS_MINIMIZEBOX
))
1389 bti
->rgstate
[2] = STATE_SYSTEM_UNAVAILABLE
;
1391 if (!(dwStyle
& WS_MAXIMIZEBOX
))
1393 bti
->rgstate
[3] = STATE_SYSTEM_UNAVAILABLE
;
1397 if (!(dwExStyle
& WS_EX_CONTEXTHELP
))
1399 bti
->rgstate
[4] = STATE_SYSTEM_INVISIBLE
;
1401 if (pWindowObject
->pcls
->style
& CS_NOCLOSE
)
1403 bti
->rgstate
[5] = STATE_SYSTEM_UNAVAILABLE
;
1408 bti
->rgstate
[2] = STATE_SYSTEM_INVISIBLE
;
1409 bti
->rgstate
[3] = STATE_SYSTEM_INVISIBLE
;
1410 bti
->rgstate
[4] = STATE_SYSTEM_INVISIBLE
;
1411 bti
->rgstate
[5] = STATE_SYSTEM_INVISIBLE
;
1416 bti
->rgstate
[0] |= STATE_SYSTEM_INVISIBLE
;
1421 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1433 LPCMENUITEMINFOW UnsafeItemInfo
)
1436 ROSMENUITEMINFO ItemInfo
;
1438 /* Try to copy the whole MENUITEMINFOW structure */
1439 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, sizeof(MENUITEMINFOW
));
1440 if (NT_SUCCESS(Status
))
1442 if (sizeof(MENUITEMINFOW
) != ItemInfo
.cbSize
1443 && FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
) != ItemInfo
.cbSize
)
1445 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1448 return IntInsertMenuItem(Menu
, uItem
, fByPosition
, &ItemInfo
);
1451 /* Try to copy without last field (not present in older versions) */
1452 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
));
1453 if (NT_SUCCESS(Status
))
1455 if (FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
) != ItemInfo
.cbSize
)
1457 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1460 ItemInfo
.hbmpItem
= (HBITMAP
)0;
1461 return IntInsertMenuItem(Menu
, uItem
, fByPosition
, &ItemInfo
);
1464 SetLastNtError(Status
);
1469 /* FUNCTIONS *****************************************************************/
1475 NtUserCheckMenuItem(
1481 DECLARE_RETURN(DWORD
);
1483 DPRINT("Enter NtUserCheckMenuItem\n");
1484 UserEnterExclusive();
1486 if(!(Menu
= UserGetMenuObject(hMenu
)))
1491 RETURN( IntCheckMenuItem(Menu
, uIDCheckItem
, uCheck
));
1494 DPRINT("Leave NtUserCheckMenuItem, ret=%i\n",_ret_
);
1499 HMENU FASTCALL
UserCreateMenu(BOOL PopupMenu
)
1501 PWINSTATION_OBJECT WinStaObject
;
1505 PEPROCESS CurrentProcess
= PsGetCurrentProcess();
1507 if (CsrProcess
!= CurrentProcess
)
1510 * CsrProcess does not have a Win32WindowStation
1514 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1519 if (!NT_SUCCESS(Status
))
1521 DPRINT1("Validation of window station handle (0x%X) failed\n",
1522 CurrentProcess
->Win32WindowStation
);
1523 SetLastNtError(Status
);
1526 Menu
= IntCreateMenu(&Handle
, !PopupMenu
);
1527 ObDereferenceObject(WinStaObject
);
1531 Menu
= IntCreateMenu(&Handle
, !PopupMenu
);
1534 if (Menu
) UserDereferenceObject(Menu
);
1535 return (HMENU
)Handle
;
1548 DECLARE_RETURN(BOOL
);
1550 DPRINT("Enter NtUserDeleteMenu\n");
1551 UserEnterExclusive();
1553 if(!(Menu
= UserGetMenuObject(hMenu
)))
1558 RETURN( IntRemoveMenuItem(Menu
, uPosition
, uFlags
, TRUE
));
1561 DPRINT("Leave NtUserDeleteMenu, ret=%i\n",_ret_
);
1570 NtUserGetTitleBarInfo(
1575 TITLEBARINFO bartitleinfo
;
1576 DECLARE_RETURN(BOOLEAN
);
1577 BOOLEAN retValue
= TRUE
;
1579 DPRINT("Enter NtUserGetTitleBarInfo\n");
1580 UserEnterExclusive();
1582 /* Vaildate the windows handle */
1583 if (!(WindowObject
= UserGetWindowObject(hwnd
)))
1585 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1591 /* Copy our usermode buffer bti to local buffer bartitleinfo */
1592 ProbeForRead(bti
, sizeof(TITLEBARINFO
), 1);
1593 RtlCopyMemory(&bartitleinfo
, bti
, sizeof(TITLEBARINFO
));
1595 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1597 /* Fail copy the data */
1598 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1603 /* Get the tile bar info */
1606 retValue
= intGetTitleBarInfo(WindowObject
, &bartitleinfo
);
1611 /* Copy our buffer to user mode buffer bti */
1612 ProbeForWrite(bti
, sizeof(TITLEBARINFO
), 1);
1613 RtlCopyMemory(bti
, &bartitleinfo
, sizeof(TITLEBARINFO
));
1615 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1617 /* Fail copy the data */
1618 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1628 DPRINT("Leave NtUserGetTitleBarInfo, ret=%i\n",_ret_
);
1636 BOOL FASTCALL
UserDestroyMenu(HMENU hMenu
)
1640 if(!(Menu
= UserGetMenuObject(hMenu
)))
1645 if(Menu
->Process
!= PsGetCurrentProcess())
1647 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1651 return IntDestroyMenuObject(Menu
, FALSE
, TRUE
);
1662 DECLARE_RETURN(BOOL
);
1664 DPRINT("Enter NtUserDestroyMenu\n");
1665 UserEnterExclusive();
1667 if(!(Menu
= UserGetMenuObject(hMenu
)))
1672 if(Menu
->Process
!= PsGetCurrentProcess())
1674 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1678 RETURN( IntDestroyMenuObject(Menu
, TRUE
, TRUE
));
1681 DPRINT("Leave NtUserDestroyMenu, ret=%i\n",_ret_
);
1690 NtUserEnableMenuItem(
1696 DECLARE_RETURN(UINT
);
1698 DPRINT("Enter NtUserEnableMenuItem\n");
1699 UserEnterExclusive();
1701 if(!(Menu
= UserGetMenuObject(hMenu
)))
1706 RETURN( IntEnableMenuItem(Menu
, uIDEnableItem
, uEnable
));
1709 DPRINT("Leave NtUserEnableMenuItem, ret=%i\n",_ret_
);
1729 NtUserGetMenuBarInfo(
1736 PMENU_OBJECT MenuObject
;
1743 DECLARE_RETURN(BOOL
);
1745 DPRINT("Enter NtUserGetMenuBarInfo\n");
1748 if (!(WindowObject
= UserGetWindowObject(hwnd
)))
1750 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1754 hMenu
= (HMENU
)(DWORD_PTR
)WindowObject
->IDMenu
;
1756 if (!(MenuObject
= UserGetMenuObject(hMenu
)))
1758 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1762 if (pmbi
->cbSize
!= sizeof(MENUBARINFO
))
1764 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1768 kmbi
.cbSize
= sizeof(MENUBARINFO
);
1769 kmbi
.fBarFocused
= FALSE
;
1770 kmbi
.fFocused
= FALSE
;
1771 kmbi
.hwndMenu
= NULL
;
1777 PMENU_OBJECT SubMenuObject
;
1779 if (idItem
) /* Non-Zero-Based. */
1781 if (IntGetMenuItemByFlag(MenuObject
, idItem
-1, MF_BYPOSITION
, NULL
, &mi
, NULL
) > -1)
1782 kmbi
.rcBar
= mi
->Rect
;
1791 /* If items is zero we assume info for the menu itself. */
1792 if (!(IntGetClientOrigin(WindowObject
, &Offset
)))
1797 Rect
.left
= Offset
.x
;
1798 Rect
.right
= Offset
.x
+ MenuObject
->MenuInfo
.Width
;
1799 Rect
.top
= Offset
.y
;
1800 Rect
.bottom
= Offset
.y
+ MenuObject
->MenuInfo
.Height
;
1802 DPRINT("Rect top = %d bottom = %d left = %d right = %d \n",
1803 Rect
.top
, Rect
.bottom
, Rect
.left
, Rect
.right
);
1807 if (idItem
-1 == MenuObject
->MenuInfo
.FocusedItem
)
1808 kmbi
.fFocused
= TRUE
;
1810 if (MenuObject
->MenuInfo
.FocusedItem
!= NO_SELECTED_ITEM
)
1811 kmbi
.fBarFocused
= TRUE
;
1812 SubMenuObject
= UserGetMenuObject(MenuObject
->MenuItemList
->hSubMenu
);
1813 if(SubMenuObject
) kmbi
.hwndMenu
= SubMenuObject
->MenuInfo
.Wnd
;
1814 DPRINT("OBJID_MENU, idItem = %d\n",idItem
);
1819 PMENU_OBJECT SubMenuObject
, XSubMenuObject
;
1820 SubMenuObject
= UserGetMenuObject(MenuObject
->MenuItemList
->hSubMenu
);
1821 if(SubMenuObject
) kmbi
.hMenu
= SubMenuObject
->MenuInfo
.Self
;
1825 DPRINT1("OBJID_CLIENT, No SubMenu!\n");
1830 if (IntGetMenuItemByFlag(SubMenuObject
, idItem
-1, MF_BYPOSITION
, NULL
, &mi
, NULL
) > -1)
1831 kmbi
.rcBar
= mi
->Rect
;
1841 if (!(SubWinObj
= UserGetWindowObject(SubMenuObject
->MenuInfo
.Wnd
)))
1846 if (!(IntGetClientOrigin(SubWinObj
, &Offset
)))
1851 Rect
.left
= Offset
.x
;
1852 Rect
.right
= Offset
.x
+ SubMenuObject
->MenuInfo
.Width
;
1853 Rect
.top
= Offset
.y
;
1854 Rect
.bottom
= Offset
.y
+ SubMenuObject
->MenuInfo
.Height
;
1859 if (idItem
-1 == SubMenuObject
->MenuInfo
.FocusedItem
)
1860 kmbi
.fFocused
= TRUE
;
1862 if (SubMenuObject
->MenuInfo
.FocusedItem
!= NO_SELECTED_ITEM
)
1863 kmbi
.fBarFocused
= TRUE
;
1864 XSubMenuObject
= UserGetMenuObject(SubMenuObject
->MenuItemList
->hSubMenu
);
1865 if (XSubMenuObject
) kmbi
.hwndMenu
= XSubMenuObject
->MenuInfo
.Wnd
;
1866 DPRINT("OBJID_CLIENT, idItem = %d\n",idItem
);
1871 PMENU_OBJECT SysMenuObject
, SubMenuObject
;
1872 if(!(SysMenuObject
= IntGetSystemMenu(WindowObject
, FALSE
, FALSE
)))
1877 kmbi
.hMenu
= SysMenuObject
->MenuInfo
.Self
;
1880 if (IntGetMenuItemByFlag(SysMenuObject
, idItem
-1, MF_BYPOSITION
, NULL
, &mi
, NULL
) > -1)
1881 kmbi
.rcBar
= mi
->Rect
;
1891 if (!(SysWinObj
= UserGetWindowObject(SysMenuObject
->MenuInfo
.Wnd
)))
1896 if (!(IntGetClientOrigin(SysWinObj
, &Offset
)))
1901 Rect
.left
= Offset
.x
;
1902 Rect
.right
= Offset
.x
+ SysMenuObject
->MenuInfo
.Width
;
1903 Rect
.top
= Offset
.y
;
1904 Rect
.bottom
= Offset
.y
+ SysMenuObject
->MenuInfo
.Height
;
1909 if (idItem
-1 == SysMenuObject
->MenuInfo
.FocusedItem
)
1910 kmbi
.fFocused
= TRUE
;
1912 if (SysMenuObject
->MenuInfo
.FocusedItem
!= NO_SELECTED_ITEM
)
1913 kmbi
.fBarFocused
= TRUE
;
1914 SubMenuObject
= UserGetMenuObject(SysMenuObject
->MenuItemList
->hSubMenu
);
1915 if(SubMenuObject
) kmbi
.hwndMenu
= SubMenuObject
->MenuInfo
.Wnd
;
1916 DPRINT("OBJID_SYSMENU, idItem = %d\n",idItem
);
1921 DPRINT1("Unknown idObject = %d, idItem = %d\n",idObject
,idItem
);
1925 NTSTATUS Status
= MmCopyToCaller(pmbi
, &kmbi
, sizeof(MENUBARINFO
));
1926 if (! NT_SUCCESS(Status
))
1928 SetLastNtError(Status
);
1935 DPRINT("Leave NtUserGetMenuBarInfo, ret=%i\n",_ret_
);
1948 PMENU_OBJECT Menu
, SubMenu
;
1949 PMENU_ITEM MenuItem
;
1950 DECLARE_RETURN(UINT
);
1952 DPRINT("Enter NtUserGetMenuIndex\n");
1955 if ( !(Menu
= UserGetMenuObject(hMenu
)) ||
1956 !(SubMenu
= UserGetMenuObject(hSubMenu
)) )
1959 MenuItem
= Menu
->MenuItemList
;
1962 if (MenuItem
->hSubMenu
== hSubMenu
)
1963 RETURN(MenuItem
->wID
);
1964 MenuItem
= MenuItem
->Next
;
1970 DPRINT("Leave NtUserGetMenuIndex, ret=%i\n",_ret_
);
1979 NtUserGetMenuItemRect(
1991 PMENU_ITEM MenuItem
;
1992 DECLARE_RETURN(BOOL
);
1994 DPRINT("Enter NtUserGetMenuItemRect\n");
1997 if (!(Menu
= UserGetMenuObject(hMenu
)))
2002 if (IntGetMenuItemByFlag(Menu
, uItem
, MF_BYPOSITION
, NULL
, &MenuItem
, NULL
) > -1)
2003 Rect
= MenuItem
->Rect
;
2009 if(!UserMenuInfo(Menu
, &mi
, FALSE
))
2015 if (lprcItem
== NULL
) RETURN( FALSE
);
2017 if (!(ReferenceWnd
= UserGetWindowObject(mi
.Wnd
))) RETURN( FALSE
);
2019 if(MenuItem
->fType
& MF_POPUP
)
2021 XMove
= ReferenceWnd
->rcClient
.left
;
2022 YMove
= ReferenceWnd
->rcClient
.top
;
2026 XMove
= ReferenceWnd
->rcWindow
.left
;
2027 YMove
= ReferenceWnd
->rcWindow
.top
;
2032 Rect
.right
+= XMove
;
2033 Rect
.bottom
+= YMove
;
2035 Status
= MmCopyToCaller(lprcItem
, &Rect
, sizeof(RECT
));
2036 if (! NT_SUCCESS(Status
))
2038 SetLastNtError(Status
);
2044 DPRINT("Leave NtUserGetMenuItemRect, ret=%i\n",_ret_
);
2053 NtUserHiliteMenuItem(
2061 DECLARE_RETURN(BOOLEAN
);
2063 DPRINT("Enter NtUserHiliteMenuItem\n");
2064 UserEnterExclusive();
2066 if(!(Window
= UserGetWindowObject(hWnd
)))
2071 if(!(Menu
= UserGetMenuObject(hMenu
)))
2076 if(Window
->IDMenu
== (UINT
)(UINT_PTR
)hMenu
)
2078 RETURN( IntHiliteMenuItem(Window
, Menu
, uItemHilite
, uHilite
));
2084 DPRINT("Leave NtUserHiliteMenuItem, ret=%i\n",_ret_
);
2093 PROSMENUINFO UnsafeMenuInfo
,
2099 ROSMENUINFO MenuInfo
;
2101 Status
= MmCopyFromCaller(&Size
, &UnsafeMenuInfo
->cbSize
, sizeof(DWORD
));
2102 if (! NT_SUCCESS(Status
))
2104 SetLastNtError(Status
);
2107 if(Size
< sizeof(MENUINFO
) || sizeof(ROSMENUINFO
) < Size
)
2109 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2112 Status
= MmCopyFromCaller(&MenuInfo
, UnsafeMenuInfo
, Size
);
2113 if (! NT_SUCCESS(Status
))
2115 SetLastNtError(Status
);
2122 Res
= IntSetMenuInfo(Menu
, &MenuInfo
);
2127 Res
= IntGetMenuInfo(Menu
, &MenuInfo
);
2130 Status
= MmCopyToCaller(UnsafeMenuInfo
, &MenuInfo
, Size
);
2131 if (! NT_SUCCESS(Status
))
2133 SetLastNtError(Status
);
2146 NtUserMenuItemFromPoint(
2156 DECLARE_RETURN(int);
2158 DPRINT("Enter NtUserMenuItemFromPoint\n");
2159 UserEnterExclusive();
2161 if (!(Menu
= UserGetMenuObject(hMenu
)))
2166 if (!(Window
= UserGetWindowObject(Menu
->MenuInfo
.Wnd
)))
2171 X
-= Window
->rcWindow
.left
;
2172 Y
-= Window
->rcWindow
.top
;
2174 mi
= Menu
->MenuItemList
;
2175 for (i
= 0; NULL
!= mi
; i
++)
2177 if (InRect(mi
->Rect
, X
, Y
))
2184 RETURN( (mi
? i
: NO_SELECTED_ITEM
));
2187 DPRINT("Leave NtUserMenuItemFromPoint, ret=%i\n",_ret_
);
2198 PROSMENUITEMINFO UnsafeItemInfo
,
2201 PMENU_ITEM MenuItem
;
2202 ROSMENUITEMINFO ItemInfo
;
2207 Status
= MmCopyFromCaller(&Size
, &UnsafeItemInfo
->cbSize
, sizeof(UINT
));
2208 if (! NT_SUCCESS(Status
))
2210 SetLastNtError(Status
);
2213 if (sizeof(MENUITEMINFOW
) != Size
2214 && FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
) != Size
2215 && sizeof(ROSMENUITEMINFO
) != Size
)
2217 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2220 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, Size
);
2221 if (! NT_SUCCESS(Status
))
2223 SetLastNtError(Status
);
2226 /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
2228 if (FIELD_OFFSET(MENUITEMINFOW
, hbmpItem
) == Size
2229 && 0 != (ItemInfo
.fMask
& MIIM_BITMAP
))
2231 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2235 if (IntGetMenuItemByFlag(Menu
, Item
,
2236 (ByPosition
? MF_BYPOSITION
: MF_BYCOMMAND
),
2237 NULL
, &MenuItem
, NULL
) < 0)
2239 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2245 Ret
= IntSetMenuItemInfo(Menu
, MenuItem
, &ItemInfo
);
2249 Ret
= IntGetMenuItemInfo(Menu
, MenuItem
, &ItemInfo
);
2252 Status
= MmCopyToCaller(UnsafeItemInfo
, &ItemInfo
, Size
);
2253 if (! NT_SUCCESS(Status
))
2255 SetLastNtError(Status
);
2274 DECLARE_RETURN(BOOL
);
2276 DPRINT("Enter NtUserRemoveMenu\n");
2277 UserEnterExclusive();
2279 if(!(Menu
= UserGetMenuObject(hMenu
)))
2284 RETURN(IntRemoveMenuItem(Menu
, uPosition
, uFlags
, FALSE
));
2287 DPRINT("Leave NtUserRemoveMenu, ret=%i\n",_ret_
);
2297 NtUserSetMenuContextHelpId(
2299 DWORD dwContextHelpId
)
2302 DECLARE_RETURN(BOOL
);
2304 DPRINT("Enter NtUserSetMenuContextHelpId\n");
2305 UserEnterExclusive();
2307 if(!(Menu
= UserGetMenuObject(hMenu
)))
2312 RETURN(IntSetMenuContextHelpId(Menu
, dwContextHelpId
));
2315 DPRINT("Leave NtUserSetMenuContextHelpId, ret=%i\n",_ret_
);
2324 NtUserSetMenuDefaultItem(
2330 DECLARE_RETURN(BOOL
);
2332 DPRINT("Enter NtUserSetMenuDefaultItem\n");
2333 UserEnterExclusive();
2335 if(!(Menu
= UserGetMenuObject(hMenu
)))
2340 RETURN( UserSetMenuDefaultItem(Menu
, uItem
, fByPos
));
2343 DPRINT("Leave NtUserSetMenuDefaultItem, ret=%i\n",_ret_
);
2352 NtUserSetMenuFlagRtoL(
2356 DECLARE_RETURN(BOOL
);
2358 DPRINT("Enter NtUserSetMenuFlagRtoL\n");
2359 UserEnterExclusive();
2361 if(!(Menu
= UserGetMenuObject(hMenu
)))
2366 RETURN(IntSetMenuFlagRtoL(Menu
));
2369 DPRINT("Leave NtUserSetMenuFlagRtoL, ret=%i\n",_ret_
);
2378 NtUserThunkedMenuInfo(
2383 DECLARE_RETURN(BOOL
);
2385 DPRINT("Enter NtUserThunkedMenuInfo\n");
2386 UserEnterExclusive();
2388 if (!(Menu
= UserGetMenuObject(hMenu
)))
2393 RETURN(UserMenuInfo(Menu
, (PROSMENUINFO
)lpcmi
, TRUE
));
2396 DPRINT("Leave NtUserThunkedMenuInfo, ret=%i\n",_ret_
);
2405 NtUserThunkedMenuItemInfo(
2410 LPMENUITEMINFOW lpmii
,
2411 PUNICODE_STRING lpszCaption
)
2415 UNICODE_STRING lstrCaption
;
2416 DECLARE_RETURN(BOOL
);
2418 DPRINT("Enter NtUserThunkedMenuItemInfo\n");
2419 UserEnterExclusive();
2421 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
2422 if bInsert == TRUE call UserInsertMenuItem() else UserSetMenuItemInfo() */
2424 if (!(Menu
= UserGetMenuObject(hMenu
)))
2429 lstrCaption
.Buffer
= NULL
;
2431 /* Check if we got a Caption */
2434 /* Copy the string to kernel mode */
2435 Status
= ProbeAndCaptureUnicodeString( &lstrCaption
,
2438 if (!NT_SUCCESS(Status
))
2440 DPRINT1("Failed to capture MenuItem Caption (status 0x%08x)\n",Status
);
2441 SetLastNtError(Status
);
2446 if (bInsert
) RETURN( UserInsertMenuItem(Menu
, uItem
, fByPosition
, lpmii
));
2448 RETURN( UserMenuItemInfo(Menu
, uItem
, fByPosition
, (PROSMENUITEMINFO
)lpmii
, TRUE
));
2451 DPRINT("Leave NtUserThunkedMenuItemInfo, ret=%i\n",_ret_
);
2459 /* NOTE: unused function */
2461 NtUserTrackPopupMenuEx(
2475 ////// ReactOS NtUserBad
2481 NtUserBuildMenuItemList(
2489 DECLARE_RETURN(DWORD
);
2491 DPRINT("Enter NtUserBuildMenuItemList\n");
2492 UserEnterExclusive();
2494 if(!(Menu
= UserGetMenuObject(hMenu
)))
2501 res
= IntBuildMenuItemList(Menu
, Buffer
, nBufSize
);
2505 res
= Menu
->MenuInfo
.MenuItemCount
;
2511 DPRINT("Leave NtUserBuildMenuItemList, ret=%i\n",_ret_
);
2520 NtUserGetMenuDefaultItem(
2527 DECLARE_RETURN(UINT
);
2529 DPRINT("Enter NtUserGetMenuDefaultItem\n");
2530 UserEnterExclusive();
2532 if(!(Menu
= UserGetMenuObject(hMenu
)))
2537 RETURN( IntGetMenuDefaultItem(Menu
, fByPos
, gmdiFlags
, &gismc
));
2540 DPRINT("Leave NtUserGetMenuDefaultItem, ret=%i\n",_ret_
);
2552 PROSMENUINFO UnsafeMenuInfo
,
2556 DECLARE_RETURN(BOOL
);
2558 DPRINT("Enter NtUserMenuInfo\n");
2561 if (!(Menu
= UserGetMenuObject(hMenu
)))
2566 RETURN(UserMenuInfo(Menu
, UnsafeMenuInfo
, SetOrGet
));
2569 DPRINT("Leave NtUserMenuInfo, ret=%i\n",_ret_
);
2583 PROSMENUITEMINFO UnsafeItemInfo
,
2587 DECLARE_RETURN(BOOL
);
2589 DPRINT("Enter NtUserMenuItemInfo\n");
2590 UserEnterExclusive();
2592 if (!(Menu
= UserGetMenuObject(hMenu
)))
2597 RETURN( UserMenuItemInfo(Menu
, Item
, ByPosition
, UnsafeItemInfo
, SetOrGet
));
2600 DPRINT("Leave NtUserMenuItemInfo, ret=%i\n",_ret_
);