2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
24 * FILE: subsys/win32k/ntuser/menu.c
25 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
27 * 07/30/2003 CSH Created
29 /* INCLUDES ******************************************************************/
36 /* INTERNAL ******************************************************************/
38 /* maximum number of menu items a menu can contain */
39 #define MAX_MENU_ITEMS (0x4000)
40 #define MAX_GOINTOSUBMENU (0x10)
42 #define UpdateMenuItemState(state, change) \
44 if((change) & MFS_DISABLED) { \
45 (state) |= MFS_DISABLED; \
47 (state) &= ~MFS_DISABLED; \
49 if((change) & MFS_CHECKED) { \
50 (state) |= MFS_CHECKED; \
52 (state) &= ~MFS_CHECKED; \
54 if((change) & MFS_HILITE) { \
55 (state) |= MFS_HILITE; \
57 (state) &= ~MFS_HILITE; \
59 if((change) & MFS_DEFAULT) { \
60 (state) |= MFS_DEFAULT; \
62 (state) &= ~MFS_DEFAULT; \
64 if((change) & MF_MOUSESELECT) { \
65 (state) |= MF_MOUSESELECT; \
67 (state) &= ~MF_MOUSESELECT; \
71 #define FreeMenuText(MenuItem) \
73 if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \
74 (MenuItem)->Text.Length) { \
75 RtlFreeUnicodeString(&(MenuItem)->Text); \
79 #define InRect(r, x, y) \
80 ( ( ((r).right >= x)) && \
81 ( ((r).left <= x)) && \
82 ( ((r).bottom >= y)) && \
88 return(STATUS_SUCCESS
);
94 return(STATUS_SUCCESS
);
99 DumpMenuItemList(PMENU_ITEM MenuItem
)
104 if(MenuItem
->Text
.Length
)
105 DbgPrint(" %d. %wZ\n", ++cnt
, &MenuItem
->Text
);
107 DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt
, (DWORD
)MenuItem
->Text
.Buffer
);
109 if(MFT_BITMAP
& MenuItem
->fType
) DbgPrint("MFT_BITMAP ");
110 if(MFT_MENUBARBREAK
& MenuItem
->fType
) DbgPrint("MFT_MENUBARBREAK ");
111 if(MFT_MENUBREAK
& MenuItem
->fType
) DbgPrint("MFT_MENUBREAK ");
112 if(MFT_OWNERDRAW
& MenuItem
->fType
) DbgPrint("MFT_OWNERDRAW ");
113 if(MFT_RADIOCHECK
& MenuItem
->fType
) DbgPrint("MFT_RADIOCHECK ");
114 if(MFT_RIGHTJUSTIFY
& MenuItem
->fType
) DbgPrint("MFT_RIGHTJUSTIFY ");
115 if(MFT_SEPARATOR
& MenuItem
->fType
) DbgPrint("MFT_SEPARATOR ");
116 if(MFT_STRING
& MenuItem
->fType
) DbgPrint("MFT_STRING ");
117 DbgPrint("\n fState=");
118 if(MFS_DISABLED
& MenuItem
->fState
) DbgPrint("MFS_DISABLED ");
119 else DbgPrint("MFS_ENABLED ");
120 if(MFS_CHECKED
& MenuItem
->fState
) DbgPrint("MFS_CHECKED ");
121 else DbgPrint("MFS_UNCHECKED ");
122 if(MFS_HILITE
& MenuItem
->fState
) DbgPrint("MFS_HILITE ");
123 else DbgPrint("MFS_UNHILITE ");
124 if(MFS_DEFAULT
& MenuItem
->fState
) DbgPrint("MFS_DEFAULT ");
125 if(MFS_GRAYED
& MenuItem
->fState
) DbgPrint("MFS_GRAYED ");
126 DbgPrint("\n wId=%d\n", MenuItem
->wID
);
127 MenuItem
= MenuItem
->Next
;
129 DbgPrint("Entries: %d\n", cnt
);
134 PMENU_OBJECT FASTCALL
135 IntGetMenuObject(HMENU hMenu
)
137 PMENU_OBJECT MenuObject
;
138 PW32THREAD W32Thread
= PsGetWin32Thread();
145 NTSTATUS Status
= ObmReferenceObjectByHandle(W32Thread
->Desktop
->WindowStation
->HandleTable
,
146 hMenu
, otMenu
, (PVOID
*)&MenuObject
);
147 if (!NT_SUCCESS(Status
))
155 IntFreeMenuItem(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
,
156 BOOL RemoveFromList
, BOOL bRecurse
)
158 FreeMenuText(MenuItem
);
161 /* FIXME - Remove from List */
162 MenuObject
->MenuInfo
.MenuItemCount
--;
164 if(bRecurse
&& MenuItem
->hSubMenu
)
166 PMENU_OBJECT SubMenuObject
;
167 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
170 IntDestroyMenuObject(SubMenuObject
, bRecurse
, TRUE
);
171 IntReleaseMenuObject(SubMenuObject
);
176 ExFreePool(MenuItem
);
182 IntRemoveMenuItem(PMENU_OBJECT MenuObject
, UINT uPosition
, UINT uFlags
,
185 PMENU_ITEM PrevMenuItem
, MenuItem
;
186 if(IntGetMenuItemByFlag(MenuObject
, uPosition
, uFlags
, &MenuItem
,
192 PrevMenuItem
->Next
= MenuItem
->Next
;
195 MenuObject
->MenuItemList
= MenuItem
->Next
;
197 return IntFreeMenuItem(MenuObject
, MenuItem
, TRUE
, bRecurse
);
204 IntDeleteMenuItems(PMENU_OBJECT MenuObject
, BOOL bRecurse
)
208 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
211 NextItem
= CurItem
->Next
;
212 IntFreeMenuItem(MenuObject
, CurItem
, FALSE
, bRecurse
);
216 MenuObject
->MenuInfo
.MenuItemCount
= 0;
217 MenuObject
->MenuItemList
= NULL
;
222 IntDestroyMenuObject(PMENU_OBJECT MenuObject
,
223 BOOL bRecurse
, BOOL RemoveFromProcess
)
227 PWINSTATION_OBJECT WindowStation
;
230 /* remove all menu items */
231 IntLockMenuItems(MenuObject
);
232 IntDeleteMenuItems(MenuObject
, bRecurse
); /* do not destroy submenus */
233 IntUnLockMenuItems(MenuObject
);
235 if(RemoveFromProcess
)
237 IntLockProcessMenus((PW32PROCESS
)MenuObject
->Process
->Win32Process
);
238 RemoveEntryList(&MenuObject
->ListEntry
);
239 IntUnLockProcessMenus((PW32PROCESS
)MenuObject
->Process
->Win32Process
);
242 Status
= ObReferenceObjectByHandle(MenuObject
->Process
->Win32WindowStation
,
244 ExWindowStationObjectType
,
246 (PVOID
*)&WindowStation
,
248 if(NT_SUCCESS(Status
))
250 ObmCloseHandle(WindowStation
->HandleTable
, MenuObject
->MenuInfo
.Self
);
251 ObDereferenceObject(WindowStation
);
258 PMENU_OBJECT FASTCALL
259 IntCreateMenu(PHANDLE Handle
, BOOL IsMenuBar
)
261 PMENU_OBJECT MenuObject
;
262 PW32THREAD Win32Thread
= PsGetWin32Thread();
264 MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
265 Win32Thread
->Desktop
->WindowStation
->HandleTable
, Handle
,
266 otMenu
, sizeof(MENU_OBJECT
));
274 MenuObject
->Process
= PsGetCurrentProcess();
275 MenuObject
->RtoL
= FALSE
; /* default */
276 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
277 MenuObject
->MenuInfo
.fMask
= 0; /* not used */
278 MenuObject
->MenuInfo
.dwStyle
= 0; /* FIXME */
279 MenuObject
->MenuInfo
.cyMax
= 0; /* default */
280 MenuObject
->MenuInfo
.hbrBack
=
281 NtGdiCreateSolidBrush(RGB(192, 192, 192)); /* FIXME: default background color */
282 MenuObject
->MenuInfo
.dwContextHelpID
= 0; /* default */
283 MenuObject
->MenuInfo
.dwMenuData
= 0; /* default */
284 MenuObject
->MenuInfo
.Self
= *Handle
;
285 MenuObject
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
286 MenuObject
->MenuInfo
.Flags
= (IsMenuBar
? 0 : MF_POPUP
);
287 MenuObject
->MenuInfo
.Wnd
= NULL
;
288 MenuObject
->MenuInfo
.WndOwner
= NULL
;
289 MenuObject
->MenuInfo
.Height
= 0;
290 MenuObject
->MenuInfo
.Width
= 0;
291 MenuObject
->MenuInfo
.TimeToHide
= FALSE
;
293 MenuObject
->MenuInfo
.MenuItemCount
= 0;
294 MenuObject
->MenuItemList
= NULL
;
295 ExInitializeFastMutex(&MenuObject
->MenuItemsLock
);
297 /* Insert menu item into process menu handle list */
298 IntLockProcessMenus(PsGetWin32Process());
299 InsertTailList(&PsGetWin32Process()->MenuListHead
, &MenuObject
->ListEntry
);
300 IntUnLockProcessMenus(PsGetWin32Process());
306 IntCloneMenuItems(PMENU_OBJECT Destination
, PMENU_OBJECT Source
)
308 PMENU_ITEM MenuItem
, NewMenuItem
= NULL
;
309 PMENU_ITEM Old
= NULL
;
311 if(!Source
->MenuInfo
.MenuItemCount
)
314 IntLockMenuItems(Destination
);
315 IntLockMenuItems(Source
);
317 MenuItem
= Source
->MenuItemList
;
322 NewMenuItem
->Next
= MenuItem
;
323 NewMenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
326 NewMenuItem
->fType
= MenuItem
->fType
;
327 NewMenuItem
->fState
= MenuItem
->fState
;
328 NewMenuItem
->wID
= MenuItem
->wID
;
329 NewMenuItem
->hSubMenu
= MenuItem
->hSubMenu
;
330 NewMenuItem
->hbmpChecked
= MenuItem
->hbmpChecked
;
331 NewMenuItem
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
332 NewMenuItem
->dwItemData
= MenuItem
->dwItemData
;
333 if((MENU_ITEM_TYPE(NewMenuItem
->fType
) == MF_STRING
))
335 if(MenuItem
->Text
.Length
)
337 NewMenuItem
->Text
.Length
= 0;
338 NewMenuItem
->Text
.MaximumLength
= MenuItem
->Text
.MaximumLength
;
339 NewMenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, MenuItem
->Text
.MaximumLength
, TAG_STRING
);
340 if(!NewMenuItem
->Text
.Buffer
)
342 ExFreePool(NewMenuItem
);
345 RtlCopyUnicodeString(&NewMenuItem
->Text
, &MenuItem
->Text
);
349 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
354 NewMenuItem
->Text
.Buffer
= MenuItem
->Text
.Buffer
;
356 NewMenuItem
->hbmpItem
= MenuItem
->hbmpItem
;
358 NewMenuItem
->Next
= NULL
;
360 Old
->Next
= NewMenuItem
;
362 Destination
->MenuItemList
= NewMenuItem
;
363 Destination
->MenuInfo
.MenuItemCount
++;
364 MenuItem
= MenuItem
->Next
;
367 IntUnLockMenuItems(Source
);
368 IntUnLockMenuItems(Destination
);
372 PMENU_OBJECT FASTCALL
373 IntCloneMenu(PMENU_OBJECT Source
)
376 PMENU_OBJECT MenuObject
;
381 MenuObject
= (PMENU_OBJECT
)ObmCreateObject(
382 PsGetWin32Thread()->Desktop
->WindowStation
->HandleTable
, &Handle
,
383 otMenu
, sizeof(MENU_OBJECT
));
387 MenuObject
->Process
= PsGetCurrentProcess();
388 MenuObject
->RtoL
= Source
->RtoL
;
389 MenuObject
->MenuInfo
.cbSize
= sizeof(MENUINFO
); /* not used */
390 MenuObject
->MenuInfo
.fMask
= Source
->MenuInfo
.fMask
;
391 MenuObject
->MenuInfo
.dwStyle
= Source
->MenuInfo
.dwStyle
;
392 MenuObject
->MenuInfo
.cyMax
= Source
->MenuInfo
.cyMax
;
393 MenuObject
->MenuInfo
.hbrBack
= Source
->MenuInfo
.hbrBack
;
394 MenuObject
->MenuInfo
.dwContextHelpID
= Source
->MenuInfo
.dwContextHelpID
;
395 MenuObject
->MenuInfo
.dwMenuData
= Source
->MenuInfo
.dwMenuData
;
396 MenuObject
->MenuInfo
.Self
= Handle
;
397 MenuObject
->MenuInfo
.FocusedItem
= NO_SELECTED_ITEM
;
398 MenuObject
->MenuInfo
.Wnd
= NULL
;
399 MenuObject
->MenuInfo
.WndOwner
= NULL
;
400 MenuObject
->MenuInfo
.Height
= 0;
401 MenuObject
->MenuInfo
.Width
= 0;
402 MenuObject
->MenuInfo
.TimeToHide
= FALSE
;
404 MenuObject
->MenuInfo
.MenuItemCount
= 0;
405 MenuObject
->MenuItemList
= NULL
;
406 ExInitializeFastMutex(&MenuObject
->MenuItemsLock
);
408 /* Insert menu item into process menu handle list */
409 IntLockProcessMenus(PsGetWin32Process());
410 InsertTailList(&PsGetWin32Process()->MenuListHead
, &MenuObject
->ListEntry
);
411 IntUnLockProcessMenus(PsGetWin32Process());
413 IntCloneMenuItems(MenuObject
, Source
);
419 IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject
)
421 MenuObject
->RtoL
= TRUE
;
426 IntSetMenuContextHelpId(PMENU_OBJECT MenuObject
, DWORD dwContextHelpId
)
428 MenuObject
->MenuInfo
.dwContextHelpID
= dwContextHelpId
;
433 IntGetMenuInfo(PMENU_OBJECT MenuObject
, PROSMENUINFO lpmi
)
435 if(lpmi
->fMask
& MIM_BACKGROUND
)
436 lpmi
->hbrBack
= MenuObject
->MenuInfo
.hbrBack
;
437 if(lpmi
->fMask
& MIM_HELPID
)
438 lpmi
->dwContextHelpID
= MenuObject
->MenuInfo
.dwContextHelpID
;
439 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
440 lpmi
->cyMax
= MenuObject
->MenuInfo
.cyMax
;
441 if(lpmi
->fMask
& MIM_MENUDATA
)
442 lpmi
->dwMenuData
= MenuObject
->MenuInfo
.dwMenuData
;
443 if(lpmi
->fMask
& MIM_STYLE
)
444 lpmi
->dwStyle
= MenuObject
->MenuInfo
.dwStyle
;
445 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
447 RtlCopyMemory((char *) lpmi
+ sizeof(MENUINFO
),
448 (char *) &MenuObject
->MenuInfo
+ sizeof(MENUINFO
),
449 lpmi
->cbSize
- sizeof(MENUINFO
));
457 IntIsMenu(HMENU hMenu
)
461 if((Menu
= IntGetMenuObject(hMenu
)))
463 IntReleaseMenuObject(Menu
);
471 IntSetMenuInfo(PMENU_OBJECT MenuObject
, PROSMENUINFO lpmi
)
473 if(lpmi
->fMask
& MIM_BACKGROUND
)
474 MenuObject
->MenuInfo
.hbrBack
= lpmi
->hbrBack
;
475 if(lpmi
->fMask
& MIM_HELPID
)
476 MenuObject
->MenuInfo
.dwContextHelpID
= lpmi
->dwContextHelpID
;
477 if(lpmi
->fMask
& MIM_MAXHEIGHT
)
478 MenuObject
->MenuInfo
.cyMax
= lpmi
->cyMax
;
479 if(lpmi
->fMask
& MIM_MENUDATA
)
480 MenuObject
->MenuInfo
.dwMenuData
= lpmi
->dwMenuData
;
481 if(lpmi
->fMask
& MIM_STYLE
)
482 MenuObject
->MenuInfo
.dwStyle
= lpmi
->dwStyle
;
483 if(lpmi
->fMask
& MIM_APPLYTOSUBMENUS
)
487 if (sizeof(MENUINFO
) < lpmi
->cbSize
)
489 MenuObject
->MenuInfo
.FocusedItem
= lpmi
->FocusedItem
;
490 MenuObject
->MenuInfo
.Height
= lpmi
->Height
;
491 MenuObject
->MenuInfo
.Width
= lpmi
->Width
;
492 MenuObject
->MenuInfo
.Wnd
= lpmi
->Wnd
;
493 MenuObject
->MenuInfo
.WndOwner
= lpmi
->WndOwner
;
494 MenuObject
->MenuInfo
.TimeToHide
= lpmi
->TimeToHide
;
502 IntGetMenuItemByFlag(PMENU_OBJECT MenuObject
, UINT uSearchBy
, UINT fFlag
,
503 PMENU_ITEM
*MenuItem
, PMENU_ITEM
*PrevMenuItem
)
505 PMENU_ITEM PrevItem
= NULL
;
506 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
510 if(MF_BYPOSITION
& fFlag
)
513 while(CurItem
&& (p
> 0))
516 CurItem
= CurItem
->Next
;
521 if(MenuItem
) *MenuItem
= CurItem
;
522 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
526 if(MenuItem
) *MenuItem
= NULL
;
527 if(PrevMenuItem
) *PrevMenuItem
= NULL
; /* ? */
531 return uSearchBy
- p
;
538 if(CurItem
->wID
== uSearchBy
)
540 if(MenuItem
) *MenuItem
= CurItem
;
541 if(PrevMenuItem
) *PrevMenuItem
= PrevItem
;
544 else if (0 != (CurItem
->fType
& MF_POPUP
))
546 MenuObject
= IntGetMenuObject(CurItem
->hSubMenu
);
547 if (NULL
!= MenuObject
)
549 ret
= IntGetMenuItemByFlag(MenuObject
, uSearchBy
, fFlag
,
550 MenuItem
, PrevMenuItem
);
553 IntReleaseMenuObject(MenuObject
);
557 IntReleaseMenuObject(MenuObject
);
560 CurItem
= CurItem
->Next
;
569 IntInsertMenuItemToList(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, int pos
)
572 PMENU_ITEM LastItem
= NULL
;
575 CurItem
= MenuObject
->MenuItemList
;
581 CurItem
= CurItem
->Next
;
587 while(CurItem
&& (pos
> 0))
590 CurItem
= CurItem
->Next
;
600 /* insert the item before CurItem */
601 MenuItem
->Next
= LastItem
->Next
;
602 LastItem
->Next
= MenuItem
;
606 /* insert at the beginning */
607 MenuObject
->MenuItemList
= MenuItem
;
608 MenuItem
->Next
= CurItem
;
616 LastItem
->Next
= MenuItem
;
617 MenuItem
->Next
= NULL
;
621 /* insert first item */
622 MenuObject
->MenuItemList
= MenuItem
;
623 MenuItem
->Next
= NULL
;
626 MenuObject
->MenuInfo
.MenuItemCount
++;
632 IntGetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
636 if(lpmii
->fMask
& MIIM_BITMAP
)
638 lpmii
->hbmpItem
= MenuItem
->hbmpItem
;
640 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
642 lpmii
->hbmpChecked
= MenuItem
->hbmpChecked
;
643 lpmii
->hbmpUnchecked
= MenuItem
->hbmpUnchecked
;
645 if(lpmii
->fMask
& MIIM_DATA
)
647 lpmii
->dwItemData
= MenuItem
->dwItemData
;
649 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
651 lpmii
->fType
= MenuItem
->fType
;
653 if(lpmii
->fMask
& MIIM_ID
)
655 lpmii
->wID
= MenuItem
->wID
;
657 if(lpmii
->fMask
& MIIM_STATE
)
659 lpmii
->fState
= MenuItem
->fState
;
661 if(lpmii
->fMask
& MIIM_SUBMENU
)
663 lpmii
->hSubMenu
= MenuItem
->hSubMenu
;
665 if (lpmii
->fMask
& (MIIM_STRING
| MIIM_TYPE
))
667 if (lpmii
->dwTypeData
== NULL
)
669 lpmii
->cch
= MenuItem
->Text
.Length
/ sizeof(WCHAR
);
673 Status
= MmCopyToCaller(lpmii
->dwTypeData
, MenuItem
->Text
.Buffer
,
674 min(lpmii
->cch
* sizeof(WCHAR
),
675 MenuItem
->Text
.MaximumLength
));
676 if (! NT_SUCCESS(Status
))
678 SetLastNtError(Status
);
684 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
686 lpmii
->Rect
= MenuItem
->Rect
;
687 lpmii
->XTab
= MenuItem
->XTab
;
694 IntSetMenuItemInfo(PMENU_OBJECT MenuObject
, PMENU_ITEM MenuItem
, PROSMENUITEMINFO lpmii
)
696 PMENU_OBJECT SubMenuObject
;
698 if(!MenuItem
|| !MenuObject
|| !lpmii
)
703 MenuItem
->fType
= lpmii
->fType
;
705 if(lpmii
->fMask
& MIIM_BITMAP
)
707 MenuItem
->hbmpItem
= lpmii
->hbmpItem
;
709 if(lpmii
->fMask
& MIIM_CHECKMARKS
)
711 MenuItem
->hbmpChecked
= lpmii
->hbmpChecked
;
712 MenuItem
->hbmpUnchecked
= lpmii
->hbmpUnchecked
;
714 if(lpmii
->fMask
& MIIM_DATA
)
716 MenuItem
->dwItemData
= lpmii
->dwItemData
;
718 if(lpmii
->fMask
& (MIIM_FTYPE
| MIIM_TYPE
))
721 * Delete the menu item type when changing type from
724 if (MenuItem
->fType
!= lpmii
->fType
&&
725 MENU_ITEM_TYPE(MenuItem
->fType
) == MF_STRING
)
727 FreeMenuText(MenuItem
);
728 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
730 MenuItem
->fType
= lpmii
->fType
;
732 if(lpmii
->fMask
& MIIM_ID
)
734 MenuItem
->wID
= lpmii
->wID
;
736 if(lpmii
->fMask
& MIIM_STATE
)
738 /* remove MFS_DEFAULT flag from all other menu items if this item
739 has the MFS_DEFAULT state */
740 if(lpmii
->fState
& MFS_DEFAULT
)
741 IntSetMenuDefaultItem(MenuObject
, -1, 0);
742 /* update the menu item state flags */
743 UpdateMenuItemState(MenuItem
->fState
, lpmii
->fState
);
746 if(lpmii
->fMask
& MIIM_SUBMENU
)
748 MenuItem
->hSubMenu
= lpmii
->hSubMenu
;
749 /* Make sure the submenu is marked as a popup menu */
750 if (MenuItem
->hSubMenu
)
752 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
753 if (SubMenuObject
!= NULL
)
755 SubMenuObject
->MenuInfo
.Flags
|= MF_POPUP
;
756 MenuItem
->fType
|= MF_POPUP
;
757 IntReleaseMenuObject(SubMenuObject
);
761 MenuItem
->fType
&= ~MF_POPUP
;
766 MenuItem
->fType
&= ~MF_POPUP
;
769 if ((lpmii
->fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
770 (MENU_ITEM_TYPE(lpmii
->fType
) == MF_STRING
))
772 FreeMenuText(MenuItem
);
774 if(lpmii
->dwTypeData
&& lpmii
->cch
)
776 UNICODE_STRING Source
;
779 Source
.MaximumLength
= lpmii
->cch
* sizeof(WCHAR
);
780 Source
.Buffer
= lpmii
->dwTypeData
;
782 MenuItem
->Text
.Buffer
= (PWSTR
)ExAllocatePoolWithTag(
783 PagedPool
, Source
.Length
+ sizeof(WCHAR
), TAG_STRING
);
784 if(MenuItem
->Text
.Buffer
!= NULL
)
786 MenuItem
->Text
.Length
= 0;
787 MenuItem
->Text
.MaximumLength
= Source
.Length
+ sizeof(WCHAR
);
788 RtlCopyUnicodeString(&MenuItem
->Text
, &Source
);
789 MenuItem
->Text
.Buffer
[MenuItem
->Text
.Length
/ sizeof(WCHAR
)] = 0;
793 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
798 MenuItem
->fType
|= MF_SEPARATOR
;
799 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
803 if (sizeof(ROSMENUITEMINFO
) == lpmii
->cbSize
)
805 MenuItem
->Rect
= lpmii
->Rect
;
806 MenuItem
->XTab
= lpmii
->XTab
;
813 IntInsertMenuItem(PMENU_OBJECT MenuObject
, UINT uItem
, BOOL fByPosition
,
814 PROSMENUITEMINFO ItemInfo
)
816 int pos
= (int)uItem
;
819 if (MAX_MENU_ITEMS
<= MenuObject
->MenuInfo
.MenuItemCount
)
821 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
827 /* calculate position */
828 if(MenuObject
->MenuInfo
.MenuItemCount
< pos
)
830 pos
= MenuObject
->MenuInfo
.MenuItemCount
;
835 pos
= IntGetMenuItemByFlag(MenuObject
, uItem
, MF_BYCOMMAND
, NULL
, NULL
);
842 MenuItem
= ExAllocatePoolWithTag(PagedPool
, sizeof(MENU_ITEM
), TAG_MENUITEM
);
843 if (NULL
== MenuItem
)
845 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
849 MenuItem
->fType
= MFT_STRING
;
850 MenuItem
->fState
= MFS_ENABLED
| MFS_UNCHECKED
;
852 MenuItem
->hSubMenu
= (HMENU
)0;
853 MenuItem
->hbmpChecked
= (HBITMAP
)0;
854 MenuItem
->hbmpUnchecked
= (HBITMAP
)0;
855 MenuItem
->dwItemData
= 0;
856 RtlInitUnicodeString(&MenuItem
->Text
, NULL
);
857 MenuItem
->hbmpItem
= (HBITMAP
)0;
859 if (! IntSetMenuItemInfo(MenuObject
, MenuItem
, ItemInfo
))
861 ExFreePool(MenuItem
);
865 /* Force size recalculation! */
866 MenuObject
->MenuInfo
.Height
= 0;
868 pos
= IntInsertMenuItemToList(MenuObject
, MenuItem
, pos
);
874 IntEnableMenuItem(PMENU_OBJECT MenuObject
, UINT uIDEnableItem
, UINT uEnable
)
877 UINT res
= IntGetMenuItemByFlag(MenuObject
, uIDEnableItem
, uEnable
, &MenuItem
, NULL
);
878 if(!MenuItem
|| (res
== (UINT
)-1))
883 res
= MenuItem
->fState
& (MF_GRAYED
| MF_DISABLED
);
885 if(uEnable
& MF_DISABLED
)
887 if(!(MenuItem
->fState
& MF_DISABLED
))
888 MenuItem
->fState
|= MF_DISABLED
;
889 if(uEnable
& MF_GRAYED
)
891 if(!(MenuItem
->fState
& MF_GRAYED
))
892 MenuItem
->fState
|= MF_GRAYED
;
897 if(uEnable
& MF_GRAYED
)
899 if(!(MenuItem
->fState
& MF_GRAYED
))
900 MenuItem
->fState
|= MF_GRAYED
;
901 if(!(MenuItem
->fState
& MF_DISABLED
))
902 MenuItem
->fState
|= MF_DISABLED
;
906 if(MenuItem
->fState
& MF_DISABLED
)
907 MenuItem
->fState
^= MF_DISABLED
;
908 if(MenuItem
->fState
& MF_GRAYED
)
909 MenuItem
->fState
^= MF_GRAYED
;
918 IntBuildMenuItemList(PMENU_OBJECT MenuObject
, PVOID Buffer
, ULONG nMax
)
924 PMENU_ITEM CurItem
= MenuObject
->MenuItemList
;
931 if (nMax
< MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
))
935 StrOut
= (PWCHAR
)((char *) Buffer
+ MenuObject
->MenuInfo
.MenuItemCount
936 * sizeof(ROSMENUITEMINFO
));
937 nMax
-= MenuObject
->MenuInfo
.MenuItemCount
* sizeof(ROSMENUITEMINFO
);
938 sz
= sizeof(ROSMENUITEMINFO
);
940 mii
.cbSize
= sizeof(ROSMENUITEMINFO
);
944 while (NULL
!= CurItem
)
946 mii
.cch
= CurItem
->Text
.Length
/ sizeof(WCHAR
);
947 mii
.dwItemData
= CurItem
->dwItemData
;
948 if (0 != CurItem
->Text
.Length
)
950 mii
.dwTypeData
= StrOut
;
954 mii
.dwTypeData
= NULL
;
956 mii
.fState
= CurItem
->fState
;
957 mii
.fType
= CurItem
->fType
;
958 mii
.hbmpChecked
= CurItem
->hbmpChecked
;
959 mii
.hbmpItem
= CurItem
->hbmpItem
;
960 mii
.hbmpUnchecked
= CurItem
->hbmpUnchecked
;
961 mii
.hSubMenu
= CurItem
->hSubMenu
;
962 mii
.Rect
= CurItem
->Rect
;
963 mii
.XTab
= CurItem
->XTab
;
965 Status
= MmCopyToCaller(Buf
, &mii
, sizeof(ROSMENUITEMINFO
));
966 if (! NT_SUCCESS(Status
))
968 SetLastNtError(Status
);
971 Buf
= (PVOID
)((ULONG_PTR
)Buf
+ sizeof(ROSMENUITEMINFO
));
973 if (0 != CurItem
->Text
.Length
974 && (nMax
>= CurItem
->Text
.Length
+ sizeof(WCHAR
)))
977 Status
= MmCopyToCaller(StrOut
, CurItem
->Text
.Buffer
,
978 CurItem
->Text
.Length
);
979 if (! NT_SUCCESS(Status
))
981 SetLastNtError(Status
);
984 StrOut
+= CurItem
->Text
.Length
/ sizeof(WCHAR
);
985 Status
= MmCopyToCaller(StrOut
, &NulByte
, sizeof(WCHAR
));
986 if (! NT_SUCCESS(Status
))
988 SetLastNtError(Status
);
992 nMax
-= CurItem
->Text
.Length
+ sizeof(WCHAR
);
994 else if (0 != CurItem
->Text
.Length
)
999 CurItem
= CurItem
->Next
;
1005 while (NULL
!= CurItem
)
1007 res
+= sizeof(ROSMENUITEMINFO
) + CurItem
->Text
.Length
+ sizeof(WCHAR
);
1008 CurItem
= CurItem
->Next
;
1017 IntCheckMenuItem(PMENU_OBJECT MenuObject
, UINT uIDCheckItem
, UINT uCheck
)
1019 PMENU_ITEM MenuItem
;
1022 if((IntGetMenuItemByFlag(MenuObject
, uIDCheckItem
, uCheck
, &MenuItem
, NULL
) < 0) || !MenuItem
)
1027 res
= (DWORD
)(MenuItem
->fState
& MF_CHECKED
);
1028 if(uCheck
& MF_CHECKED
)
1030 if(!(MenuItem
->fState
& MF_CHECKED
))
1031 MenuItem
->fState
|= MF_CHECKED
;
1035 if(MenuItem
->fState
& MF_CHECKED
)
1036 MenuItem
->fState
^= MF_CHECKED
;
1043 IntHiliteMenuItem(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
,
1044 UINT uItemHilite
, UINT uHilite
)
1046 PMENU_ITEM MenuItem
;
1047 BOOL res
= IntGetMenuItemByFlag(MenuObject
, uItemHilite
, uHilite
, &MenuItem
, NULL
);
1048 if(!MenuItem
|| !res
)
1053 if(uHilite
& MF_HILITE
)
1055 if(!(MenuItem
->fState
& MF_HILITE
))
1056 MenuItem
->fState
|= MF_HILITE
;
1060 if(MenuItem
->fState
& MF_HILITE
)
1061 MenuItem
->fState
^= MF_HILITE
;
1064 /* FIXME - update the window's menu */
1070 IntSetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT uItem
, UINT fByPos
)
1073 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1075 if(uItem
== (UINT
)-1)
1079 if(MenuItem
->fState
& MFS_DEFAULT
)
1080 MenuItem
->fState
^= MFS_DEFAULT
;
1081 MenuItem
= MenuItem
->Next
;
1093 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1094 MenuItem
->fState
|= MFS_DEFAULT
;
1099 if(MenuItem
->fState
& MFS_DEFAULT
)
1100 MenuItem
->fState
^= MFS_DEFAULT
;
1103 MenuItem
= MenuItem
->Next
;
1110 if(!ret
&& (MenuItem
->wID
== uItem
))
1112 if(!(MenuItem
->fState
& MFS_DEFAULT
))
1113 MenuItem
->fState
|= MFS_DEFAULT
;
1118 if(MenuItem
->fState
& MFS_DEFAULT
)
1119 MenuItem
->fState
^= MFS_DEFAULT
;
1121 MenuItem
= MenuItem
->Next
;
1129 IntGetMenuDefaultItem(PMENU_OBJECT MenuObject
, UINT fByPos
, UINT gmdiFlags
,
1135 PMENU_OBJECT SubMenuObject
;
1136 PMENU_ITEM MenuItem
= MenuObject
->MenuItemList
;
1140 if(MenuItem
->fState
& MFS_DEFAULT
)
1143 if(!(gmdiFlags
& GMDI_USEDISABLED
) && (MenuItem
->fState
& MFS_DISABLED
))
1146 if(fByPos
& MF_BYPOSITION
)
1149 res
= MenuItem
->wID
;
1151 if((*gismc
< MAX_GOINTOSUBMENU
) && (gmdiFlags
& GMDI_GOINTOPOPUPS
) &&
1155 SubMenuObject
= IntGetMenuObject(MenuItem
->hSubMenu
);
1156 if(!SubMenuObject
|| (SubMenuObject
== MenuObject
))
1159 IntLockMenuItems(SubMenuObject
);
1160 IntUnLockMenuItems(MenuObject
);
1163 sres
= IntGetMenuDefaultItem(SubMenuObject
, fByPos
, gmdiFlags
, gismc
);
1166 IntUnLockMenuItems(SubMenuObject
);
1167 IntLockMenuItems(MenuObject
);
1168 IntReleaseMenuObject(SubMenuObject
);
1177 MenuItem
= MenuItem
->Next
;
1185 co_IntInitTracking(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
, BOOL Popup
,
1188 /* FIXME - hide caret */
1190 if(!(Flags
& TPM_NONOTIFY
))
1191 co_IntSendMessage(WindowObject
->Self
, WM_SETCURSOR
, (WPARAM
)WindowObject
->Self
, HTCAPTION
);
1193 /* FIXME - send WM_SETCURSOR message */
1195 if(!(Flags
& TPM_NONOTIFY
))
1196 co_IntSendMessage(WindowObject
->Self
, WM_INITMENU
, (WPARAM
)MenuObject
->MenuInfo
.Self
, 0);
1200 co_IntExitTracking(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
, BOOL Popup
,
1203 if(!(Flags
& TPM_NONOTIFY
))
1204 co_IntSendMessage(WindowObject
->Self
, WM_EXITMENULOOP
, 0 /* FIXME */, 0);
1206 /* FIXME - Show caret again */
1210 IntTrackMenu(PMENU_OBJECT MenuObject
, PWINDOW_OBJECT WindowObject
, INT x
, INT y
,
1217 co_IntTrackPopupMenu(PMENU_OBJECT MenuObject
, PWINDOW_OBJECT WindowObject
,
1218 UINT Flags
, POINT
*Pos
, UINT MenuPos
, RECT
*ExcludeRect
)
1220 co_IntInitTracking(WindowObject
, MenuObject
, TRUE
, Flags
);
1222 co_IntExitTracking(WindowObject
, MenuObject
, TRUE
, Flags
);
1227 IntSetMenuItemRect(PMENU_OBJECT MenuObject
, UINT Item
, BOOL fByPos
, RECT
*rcRect
)
1230 if(IntGetMenuItemByFlag(MenuObject
, Item
, (fByPos
? MF_BYPOSITION
: MF_BYCOMMAND
),
1241 * Internal function. Called when the process is destroyed to free the remaining menu handles.
1244 IntCleanupMenus(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
1246 PEPROCESS CurrentProcess
;
1247 PLIST_ENTRY LastHead
= NULL
;
1248 PMENU_OBJECT MenuObject
;
1250 CurrentProcess
= PsGetCurrentProcess();
1251 if (CurrentProcess
!= Process
)
1253 KeAttachProcess(&Process
->Pcb
);
1256 IntLockProcessMenus(Win32Process
);
1257 while (Win32Process
->MenuListHead
.Flink
!= &(Win32Process
->MenuListHead
) &&
1258 Win32Process
->MenuListHead
.Flink
!= LastHead
)
1260 LastHead
= Win32Process
->MenuListHead
.Flink
;
1261 MenuObject
= CONTAINING_RECORD(Win32Process
->MenuListHead
.Flink
, MENU_OBJECT
, ListEntry
);
1263 IntUnLockProcessMenus(Win32Process
);
1264 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1265 IntLockProcessMenus(Win32Process
);
1267 IntUnLockProcessMenus(Win32Process
);
1269 if (CurrentProcess
!= Process
)
1276 /* FUNCTIONS *****************************************************************/
1284 NtUserBuildMenuItemList(
1291 PMENU_OBJECT MenuObject
;
1292 DECLARE_RETURN(DWORD
);
1294 DPRINT("Enter NtUserBuildMenuItemList\n");
1295 UserEnterExclusive();
1297 MenuObject
= IntGetMenuObject(hMenu
);
1300 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1306 IntLockMenuItems(MenuObject
);
1307 res
= IntBuildMenuItemList(MenuObject
, Buffer
, nBufSize
);
1308 IntUnLockMenuItems(MenuObject
);
1312 res
= MenuObject
->MenuInfo
.MenuItemCount
;
1315 IntReleaseMenuObject(MenuObject
);
1320 DPRINT("Leave NtUserBuildMenuItemList, ret=%i\n",_ret_
);
1330 NtUserCheckMenuItem(
1336 PMENU_OBJECT MenuObject
;
1337 DECLARE_RETURN(DWORD
);
1339 DPRINT("Enter NtUserCheckMenuItem\n");
1340 UserEnterExclusive();
1342 MenuObject
= IntGetMenuObject(hmenu
);
1345 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1348 IntLockMenuItems(MenuObject
);
1349 res
= IntCheckMenuItem(MenuObject
, uIDCheckItem
, uCheck
);
1350 IntUnLockMenuItems(MenuObject
);
1351 IntReleaseMenuObject(MenuObject
);
1355 DPRINT("Leave NtUserCheckMenuItem, ret=%i\n",_ret_
);
1361 HMENU FASTCALL
UserCreateMenu(BOOL PopupMenu
)
1363 PWINSTATION_OBJECT WinStaObject
;
1366 NTSTATUS Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1371 if (!NT_SUCCESS(Status
))
1373 DPRINT("Validation of window station handle (0x%X) failed\n",
1374 PsGetCurrentProcess()->Win32WindowStation
);
1375 SetLastNtError(Status
);
1379 IntCreateMenu(&Handle
, !PopupMenu
);
1381 ObDereferenceObject(WinStaObject
);
1382 return (HMENU
)Handle
;
1388 NtUserCreateMenu(BOOL PopupMenu
)
1390 DECLARE_RETURN(HMENU
);
1392 DPRINT("Enter NtUserCreateMenu\n");
1393 UserEnterExclusive();
1395 RETURN(UserCreateMenu(PopupMenu
));
1398 DPRINT("Leave NtUserCreateMenu, ret=%i\n",_ret_
);
1415 PMENU_OBJECT MenuObject
;
1416 DECLARE_RETURN(BOOL
);
1418 DPRINT("Enter NtUserDeleteMenu\n");
1419 UserEnterExclusive();
1421 MenuObject
= IntGetMenuObject(hMenu
);
1424 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1428 res
= IntRemoveMenuItem(MenuObject
, uPosition
, uFlags
, TRUE
);
1429 IntReleaseMenuObject(MenuObject
);
1434 DPRINT("Leave NtUserDeleteMenu, ret=%i\n",_ret_
);
1444 BOOL FASTCALL
UserDestroyMenu(HMENU hMenu
)
1448 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1451 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1454 if(MenuObject
->Process
!= PsGetCurrentProcess())
1456 IntReleaseMenuObject(MenuObject
);
1457 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1461 Ret
= IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1463 IntReleaseMenuObject(MenuObject
);
1475 DECLARE_RETURN(BOOL
);
1477 DPRINT("Enter NtUserDestroyMenu\n");
1478 UserEnterExclusive();
1480 PMENU_OBJECT MenuObject
= IntGetMenuObject(hMenu
);
1483 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1486 if(MenuObject
->Process
!= PsGetCurrentProcess())
1488 IntReleaseMenuObject(MenuObject
);
1489 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1493 Ret
= IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
1495 IntReleaseMenuObject(MenuObject
);
1499 DPRINT("Leave NtUserDestroyMenu, ret=%i\n",_ret_
);
1509 NtUserEnableMenuItem(
1514 UINT res
= (UINT
)-1;
1515 PMENU_OBJECT MenuObject
;
1516 DECLARE_RETURN(UINT
);
1518 DPRINT("Enter NtUserEnableMenuItem\n");
1519 UserEnterExclusive();
1521 MenuObject
= IntGetMenuObject(hMenu
);
1524 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1527 IntLockMenuItems(MenuObject
);
1528 res
= IntEnableMenuItem(MenuObject
, uIDEnableItem
, uEnable
);
1529 IntUnLockMenuItems(MenuObject
);
1530 IntReleaseMenuObject(MenuObject
);
1535 DPRINT("Leave NtUserEnableMenuItem, ret=%i\n",_ret_
);
1545 NtUserInsertMenuItem(
1549 LPCMENUITEMINFOW UnsafeItemInfo
)
1552 PMENU_OBJECT MenuObject
;
1554 ROSMENUITEMINFO ItemInfo
;
1555 DECLARE_RETURN(DWORD
);
1557 DPRINT("Enter NtUserInsertMenuItem\n");
1558 UserEnterExclusive();
1560 MenuObject
= IntGetMenuObject(hMenu
);
1563 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1567 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, sizeof(MENUITEMINFOW
));
1568 if (! NT_SUCCESS(Status
))
1570 IntReleaseMenuObject(MenuObject
);
1571 SetLastNtError(Status
);
1574 if (ItemInfo
.cbSize
!= sizeof(MENUITEMINFOW
))
1576 IntReleaseMenuObject(MenuObject
);
1577 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1581 IntLockMenuItems(MenuObject
);
1582 Res
= IntInsertMenuItem(MenuObject
, uItem
, fByPosition
, &ItemInfo
);
1583 IntUnLockMenuItems(MenuObject
);
1584 IntReleaseMenuObject(MenuObject
);
1589 DPRINT("Leave NtUserInsertMenuItem, ret=%i\n",_ret_
);
1611 NtUserGetMenuDefaultItem(
1616 PMENU_OBJECT MenuObject
;
1619 DECLARE_RETURN(UINT
);
1621 DPRINT("Enter NtUserGetMenuDefaultItem\n");
1622 UserEnterExclusive();
1624 MenuObject
= IntGetMenuObject(hMenu
);
1627 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1630 IntLockMenuItems(MenuObject
);
1631 res
= IntGetMenuDefaultItem(MenuObject
, fByPos
, gmdiFlags
, &gismc
);
1632 IntUnLockMenuItems(MenuObject
);
1633 IntReleaseMenuObject(MenuObject
);
1637 DPRINT("Leave NtUserGetMenuDefaultItem, ret=%i\n",_ret_
);
1647 NtUserGetMenuBarInfo(
1677 NtUserGetMenuItemRect(
1684 ROSMENUITEMINFO mii
;
1692 DECLARE_RETURN(BOOL
);
1694 DPRINT("Enter NtUserGetMenuItemRect\n");
1697 if(!UserMenuItemInfo(hMenu
, uItem
, MF_BYPOSITION
, &mii
, FALSE
))
1700 referenceHwnd
= hWnd
;
1704 if(!UserMenuInfo(hMenu
, &mi
, FALSE
)) RETURN( FALSE
);
1705 if(mi
.Wnd
== 0) RETURN( FALSE
);
1706 referenceHwnd
= mi
.Wnd
;
1709 if (lprcItem
== NULL
) RETURN( FALSE
);
1711 lpPoints
= (LPPOINT
)lpRect
;
1713 if(!UserGetClientOrigin(referenceHwnd
, &FromOffset
)) RETURN( FALSE
);
1715 XMove
= FromOffset
.x
;
1716 YMove
= FromOffset
.y
;
1718 for (i
= 0; i
< 2; i
++)
1720 lpPoints
[i
].x
+= XMove
;
1721 lpPoints
[i
].y
+= YMove
;
1724 Status
= MmCopyToCaller(lprcItem
, lpPoints
, sizeof(POINT
));
1725 if (! NT_SUCCESS(Status
))
1727 SetLastNtError(Status
);
1733 DPRINT("Leave NtUserGetMenuItemRect, ret=%i\n",_ret_
);
1743 NtUserHiliteMenuItem(
1750 PMENU_OBJECT MenuObject
;
1751 PWINDOW_OBJECT WindowObject
;
1752 DECLARE_RETURN(BOOLEAN
);
1754 DPRINT("Enter NtUserHiliteMenuItem\n");
1755 UserEnterExclusive();
1757 WindowObject
= IntGetWindowObject(hwnd
);
1760 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1763 MenuObject
= IntGetMenuObject(hmenu
);
1766 IntReleaseWindowObject(WindowObject
);
1767 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1770 if(WindowObject
->IDMenu
== (UINT
)hmenu
)
1772 IntLockMenuItems(MenuObject
);
1773 res
= IntHiliteMenuItem(WindowObject
, MenuObject
, uItemHilite
, uHilite
);
1774 IntUnLockMenuItems(MenuObject
);
1776 IntReleaseMenuObject(MenuObject
);
1777 IntReleaseWindowObject(WindowObject
);
1781 DPRINT("Leave NtUserHiliteMenuItem, ret=%i\n",_ret_
);
1793 PROSMENUINFO UnsafeMenuInfo
,
1797 PMENU_OBJECT MenuObject
;
1800 ROSMENUINFO MenuInfo
;
1802 Status
= MmCopyFromCaller(&Size
, &UnsafeMenuInfo
->cbSize
, sizeof(DWORD
));
1803 if (! NT_SUCCESS(Status
))
1805 SetLastNtError(Status
);
1808 if(Size
< sizeof(MENUINFO
) || sizeof(ROSMENUINFO
) < Size
)
1810 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1813 Status
= MmCopyFromCaller(&MenuInfo
, UnsafeMenuInfo
, Size
);
1814 if (! NT_SUCCESS(Status
))
1816 SetLastNtError(Status
);
1820 MenuObject
= IntGetMenuObject(Menu
);
1821 if (NULL
== MenuObject
)
1823 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1830 Res
= IntSetMenuInfo(MenuObject
, &MenuInfo
);
1835 Res
= IntGetMenuInfo(MenuObject
, &MenuInfo
);
1838 Status
= MmCopyToCaller(UnsafeMenuInfo
, &MenuInfo
, Size
);
1839 if (! NT_SUCCESS(Status
))
1841 SetLastNtError(Status
);
1847 IntReleaseMenuObject(MenuObject
);
1863 PROSMENUINFO UnsafeMenuInfo
,
1866 DECLARE_RETURN(BOOL
);
1868 DPRINT("Enter NtUserMenuInfo\n");
1871 RETURN(UserMenuInfo(Menu
, UnsafeMenuInfo
, SetOrGet
));
1874 DPRINT("Leave NtUserMenuInfo, ret=%i\n",_ret_
);
1885 NtUserMenuItemFromPoint(
1891 PMENU_OBJECT MenuObject
;
1892 PWINDOW_OBJECT WindowObject
= NULL
;
1895 DECLARE_RETURN(int);
1897 DPRINT("Enter NtUserMenuItemFromPoint\n");
1898 UserEnterExclusive();
1900 MenuObject
= IntGetMenuObject(Menu
);
1901 if (NULL
== MenuObject
)
1903 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1907 WindowObject
= IntGetWindowObject(MenuObject
->MenuInfo
.Wnd
);
1908 if (NULL
== WindowObject
)
1910 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1913 X
-= WindowObject
->WindowRect
.left
;
1914 Y
-= WindowObject
->WindowRect
.top
;
1915 IntReleaseWindowObject(WindowObject
);
1917 IntLockMenuItems(MenuObject
);
1918 mi
= MenuObject
->MenuItemList
;
1919 for (i
= 0; NULL
!= mi
; i
++)
1921 if (InRect(mi
->Rect
, X
, Y
))
1927 IntUnLockMenuItems(MenuObject
);
1929 IntReleaseMenuObject(MenuObject
);
1931 RETURN( (mi
? i
: NO_SELECTED_ITEM
));
1934 DPRINT("Leave NtUserMenuItemFromPoint, ret=%i\n",_ret_
);
1948 PROSMENUITEMINFO UnsafeItemInfo
,
1951 PMENU_OBJECT MenuObject
;
1952 PMENU_ITEM MenuItem
;
1953 ROSMENUITEMINFO ItemInfo
;
1958 MenuObject
= IntGetMenuObject(Menu
);
1959 if (NULL
== MenuObject
)
1961 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
1964 Status
= MmCopyFromCaller(&Size
, &UnsafeItemInfo
->cbSize
, sizeof(UINT
));
1965 if (! NT_SUCCESS(Status
))
1967 IntReleaseMenuObject(MenuObject
);
1968 SetLastNtError(Status
);
1971 if (sizeof(MENUITEMINFOW
) != Size
1972 && sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
) != Size
1973 && sizeof(ROSMENUITEMINFO
) != Size
)
1975 IntReleaseMenuObject(MenuObject
);
1976 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1979 Status
= MmCopyFromCaller(&ItemInfo
, UnsafeItemInfo
, Size
);
1980 if (! NT_SUCCESS(Status
))
1982 IntReleaseMenuObject(MenuObject
);
1983 SetLastNtError(Status
);
1986 /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't
1988 if (sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
) == Size
1989 && 0 != (ItemInfo
.fMask
& MIIM_BITMAP
))
1991 IntReleaseMenuObject(MenuObject
);
1992 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1996 if (IntGetMenuItemByFlag(MenuObject
, Item
,
1997 (ByPosition
? MF_BYPOSITION
: MF_BYCOMMAND
),
1998 &MenuItem
, NULL
) < 0)
2000 IntReleaseMenuObject(MenuObject
);
2001 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2007 Ret
= IntSetMenuItemInfo(MenuObject
, MenuItem
, &ItemInfo
);
2011 Ret
= IntGetMenuItemInfo(MenuObject
, MenuItem
, &ItemInfo
);
2014 Status
= MmCopyToCaller(UnsafeItemInfo
, &ItemInfo
, Size
);
2015 if (! NT_SUCCESS(Status
))
2017 IntReleaseMenuObject(MenuObject
);
2018 SetLastNtError(Status
);
2024 IntReleaseMenuObject(MenuObject
);
2041 PROSMENUITEMINFO UnsafeItemInfo
,
2044 DECLARE_RETURN(BOOL
);
2046 DPRINT("Enter NtUserMenuItemInfo\n");
2047 UserEnterExclusive();
2049 RETURN( UserMenuItemInfo(Menu
, Item
, ByPosition
, UnsafeItemInfo
, SetOrGet
));
2052 DPRINT("Leave NtUserMenuItemInfo, ret=%i\n",_ret_
);
2069 PMENU_OBJECT MenuObject
;
2070 DECLARE_RETURN(BOOL
);
2072 DPRINT("Enter NtUserRemoveMenu\n");
2073 UserEnterExclusive();
2075 MenuObject
= IntGetMenuObject(hMenu
);
2078 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2082 res
= IntRemoveMenuItem(MenuObject
, uPosition
, uFlags
, FALSE
);
2083 IntReleaseMenuObject(MenuObject
);
2088 DPRINT("Leave NtUserRemoveMenu, ret=%i\n",_ret_
);
2099 NtUserSetMenuContextHelpId(
2101 DWORD dwContextHelpId
)
2104 PMENU_OBJECT MenuObject
;
2105 DECLARE_RETURN(BOOL
);
2107 DPRINT("Enter NtUserSetMenuContextHelpId\n");
2108 UserEnterExclusive();
2110 MenuObject
= IntGetMenuObject(hmenu
);
2113 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2117 res
= IntSetMenuContextHelpId(MenuObject
, dwContextHelpId
);
2118 IntReleaseMenuObject(MenuObject
);
2122 DPRINT("Leave NtUserSetMenuContextHelpId, ret=%i\n",_ret_
);
2134 UserSetMenuDefaultItem(
2140 PMENU_OBJECT MenuObject
;
2142 MenuObject
= IntGetMenuObject(hMenu
);
2145 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2148 IntLockMenuItems(MenuObject
);
2149 res
= IntSetMenuDefaultItem(MenuObject
, uItem
, fByPos
);
2150 IntUnLockMenuItems(MenuObject
);
2151 IntReleaseMenuObject(MenuObject
);
2161 NtUserSetMenuDefaultItem(
2167 PMENU_OBJECT MenuObject
;
2168 DECLARE_RETURN(BOOL
);
2170 DPRINT("Enter NtUserSetMenuDefaultItem\n");
2171 UserEnterExclusive();
2173 MenuObject
= IntGetMenuObject(hMenu
);
2176 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2179 IntLockMenuItems(MenuObject
);
2180 res
= IntSetMenuDefaultItem(MenuObject
, uItem
, fByPos
);
2181 IntUnLockMenuItems(MenuObject
);
2182 IntReleaseMenuObject(MenuObject
);
2187 DPRINT("Leave NtUserSetMenuDefaultItem, ret=%i\n",_ret_
);
2197 NtUserSetMenuFlagRtoL(
2201 PMENU_OBJECT MenuObject
;
2202 DECLARE_RETURN(BOOL
);
2204 DPRINT("Enter NtUserSetMenuFlagRtoL\n");
2205 UserEnterExclusive();
2207 MenuObject
= IntGetMenuObject(hMenu
);
2210 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2214 res
= IntSetMenuFlagRtoL(MenuObject
);
2215 IntReleaseMenuObject(MenuObject
);
2219 DPRINT("Leave NtUserSetMenuFlagRtoL, ret=%i\n",_ret_
);
2229 NtUserThunkedMenuInfo(
2234 /* This function seems just to call SetMenuInfo() */
2243 NtUserThunkedMenuItemInfo(
2248 LPMENUITEMINFOW lpmii
,
2249 PUNICODE_STRING lpszCaption
)
2252 /* lpszCaption may be NULL, check for it and call RtlInitUnicodeString()
2253 if bInsert == TRUE call NtUserInsertMenuItem() else NtUserSetMenuItemInfo()
2262 /* NOTE: unused function */
2264 NtUserTrackPopupMenuEx(
2272 PMENU_OBJECT MenuObject
;
2273 PWINDOW_OBJECT WindowObject
;
2279 MenuObject
= IntGetMenuObject(hmenu
);
2282 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2286 WindowObject
= IntGetWindowObject(hwnd
);
2289 IntReleaseMenuObject(MenuObject
);
2290 SetLastWin32Error(ERROR_INVALID_HANDLE
);
2296 Status
= MmCopyFromCaller(&Safetpm
, lptpm
, sizeof(TPMPARAMS
));
2297 if(!NT_SUCCESS(Status
))
2299 IntReleaseWindowObject(WindowObject
);
2300 IntReleaseMenuObject(MenuObject
);
2301 SetLastNtError(Status
);
2304 if(Safetpm
.cbSize
!= sizeof(TPMPARAMS
))
2306 IntReleaseWindowObject(WindowObject
);
2307 IntReleaseMenuObject(MenuObject
);
2308 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2316 Ret
= co_IntTrackPopupMenu(MenuObject
, WindowObject
, fuFlags
, &Pos
, 0,
2317 (lptpm
? &Safetpm
.rcExclude
: NULL
));
2319 IntReleaseWindowObject(WindowObject
);
2320 IntReleaseMenuObject(MenuObject
);