3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: menu.c,v 1.37 2003/12/15 19:39:37 sedwards Exp $
21 * PROJECT: ReactOS user32.dll
22 * FILE: lib/user32/windows/menu.c
24 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * 09-05-2001 CSH Created
29 /* INCLUDES ******************************************************************/
39 #include <user32/callback.h>
40 #include "user32/regcontrol.h"
41 #include "../controls/controls.h"
42 #include "wine/unicode.h"
44 /* TYPES *********************************************************************/
46 #define MENU_TYPE_MASK ((MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
48 #define MENU_ITEM_TYPE(flags) \
49 ((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
51 #define MENU_BAR_ITEMS_SPACE (12)
52 #define SEPARATOR_HEIGHT (5)
53 #define MENU_TAB_SPACE (8)
56 #define MF_END (0x0080)
60 #define MIIM_STRING (0x00000040)
63 #define MAKEINTATOMA(atom) ((LPCSTR)((ULONG_PTR)((WORD)(atom))))
64 #define MAKEINTATOMW(atom) ((LPCWSTR)((ULONG_PTR)((WORD)(atom))))
65 #define POPUPMENU_CLASS_ATOMA MAKEINTATOMA(32768) /* PopupMenu */
66 #define POPUPMENU_CLASS_ATOMW MAKEINTATOMW(32768) /* PopupMenu */
68 /*********************************************************************
69 * PopupMenu class descriptor
71 const struct builtin_class_descr POPUPMENU_builtin_class
=
73 POPUPMENU_CLASS_ATOMW
, /* name */
74 CS_GLOBALCLASS
| CS_SAVEBITS
| CS_DBLCLKS
, /* style */
75 (WNDPROC
) NULL
, /* FIXME - procW */
76 (WNDPROC
) NULL
, /* FIXME - procA */
77 sizeof(MENUINFO
*), /* extra */
78 (LPCWSTR
) IDC_ARROW
, /* cursor */
79 (HBRUSH
)COLOR_MENU
/* brush */
83 /* INTERNAL FUNCTIONS ********************************************************/
85 /* Rip the fun and easy to use and fun WINE unicode string manipulation routines.
86 * Of course I didnt copy the ASM code because we want this to be portable
87 * and it needs to go away.
91 #define GET_WORD(ptr) (*(WORD *)(ptr))
94 #define GET_DWORD(ptr) (*(DWORD *)(ptr))
97 HFONT hMenuFont
= NULL
;
98 HFONT hMenuFontBold
= NULL
;
100 /**********************************************************************
101 * MENUEX_ParseResource
103 * Parse an extended menu resource and add items to the menu.
104 * Return a pointer to the end of the resource.
106 * FIXME - should we be passing an LPCSTR to a predominantly UNICODE function?
108 static LPCSTR
MENUEX_ParseResource( LPCSTR res
, HMENU hMenu
)
116 mii
.cbSize
= sizeof(mii
);
117 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_TYPE
;
118 mii
.fType
= GET_DWORD(res
);
119 res
+= sizeof(DWORD
);
120 mii
.fState
= GET_DWORD(res
);
121 res
+= sizeof(DWORD
);
122 mii
.wID
= GET_DWORD(res
);
123 res
+= sizeof(DWORD
);
124 resinfo
= GET_WORD(res
);
126 /* Align the text on a word boundary. */
127 res
+= (~((int)res
- 1)) & 1;
128 mii
.dwTypeData
= (LPWSTR
) res
;
129 res
+= (1 + strlenW(mii
.dwTypeData
)) * sizeof(WCHAR
);
130 /* Align the following fields on a dword boundary. */
131 res
+= (~((int)res
- 1)) & 3;
133 if (resinfo
& 1) /* Pop-up? */
135 /* DWORD helpid = GET_DWORD(res); FIXME: use this. */
136 res
+= sizeof(DWORD
);
137 mii
.hSubMenu
= CreatePopupMenu();
140 if (!(res
= MENUEX_ParseResource(res
, mii
.hSubMenu
)))
142 DestroyMenu(mii
.hSubMenu
);
145 mii
.fMask
|= MIIM_SUBMENU
;
146 mii
.fType
|= MF_POPUP
;
148 else if(!*mii
.dwTypeData
&& !(mii
.fType
& MF_SEPARATOR
))
150 DbgPrint("WARN: Converting NULL menu item %04x, type %04x to SEPARATOR\n",
152 mii
.fType
|= MF_SEPARATOR
;
154 InsertMenuItemW(hMenu
, -1, MF_BYPOSITION
, &mii
);
156 while (!(resinfo
& MF_END
));
161 /**********************************************************************
164 * Parse a standard menu resource and add items to the menu.
165 * Return a pointer to the end of the resource.
167 * NOTE: flags is equivalent to the mtOption field
169 static LPCSTR
MENU_ParseResource( LPCSTR res
, HMENU hMenu
, BOOL unicode
)
178 flags
= GET_WORD(res
);
180 /* remove MF_END flag before passing it to AppendMenu()! */
181 end
= (flags
& MF_END
);
182 if(end
) flags
^= MF_END
;
185 if(!(flags
& MF_POPUP
))
192 res
+= strlen(str
) + 1;
194 res
+= (strlenW((LPCWSTR
)str
) + 1) * sizeof(WCHAR
);
195 if (flags
& MF_POPUP
)
197 hSubMenu
= CreatePopupMenu();
198 if(!hSubMenu
) return NULL
;
199 if(!(res
= MENU_ParseResource(res
, hSubMenu
, unicode
)))
202 AppendMenuA(hMenu
, flags
, (UINT
)hSubMenu
, str
);
204 AppendMenuW(hMenu
, flags
, (UINT
)hSubMenu
, (LPCWSTR
)str
);
206 else /* Not a popup */
209 AppendMenuA(hMenu
, flags
, id
, *str
? str
: NULL
);
211 AppendMenuW(hMenu
, flags
, id
,
212 *(LPCWSTR
)str
? (LPCWSTR
)str
: NULL
);
221 User32LoadSysMenuTemplateForKernel(PVOID Arguments
, ULONG ArgumentLength
)
225 hUser32
= GetModuleHandleW(L
"USER32");
226 Result
= (LRESULT
)LoadMenuW(hUser32
, L
"SYSMENU");
227 return(ZwCallbackReturn(&Result
, sizeof(LRESULT
), STATUS_SUCCESS
));
234 NONCLIENTMETRICSW ncm
;
236 /* get the menu font */
237 if(!hMenuFont
|| !hMenuFontBold
)
239 ncm
.cbSize
= sizeof(ncm
);
240 if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, sizeof(ncm
), &ncm
, 0))
242 DbgPrint("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n");
246 hMenuFont
= CreateFontIndirectW(&ncm
.lfMenuFont
);
247 if(hMenuFont
== NULL
)
249 DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n");
253 ncm
.lfMenuFont
.lfWeight
= max(ncm
.lfMenuFont
.lfWeight
+ 300, 1000);
254 hMenuFontBold
= CreateFontIndirectW(&ncm
.lfMenuFont
);
255 if(hMenuFontBold
== NULL
)
257 DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
267 MenuGetMenuBarHeight(HWND hWnd
, ULONG MenuBarWidth
, LONG OrgX
, LONG OrgY
)
274 MenuId = GetWindowLong(hWnd, GWL_ID);
275 Menu = MenuGetMenu((HMENU)MenuId);
280 hDC = GetDCEx(hWnd, 0, DCX_CACHE | DCX_WINDOW);
281 SelectObject(hDC, hMenuFont);
282 SetRect(&Rect, OrgX, OrgY, OrgX + MenuBarWidth,
283 OrgY + GetSystemMetrics(SM_CYMENU));
284 MenuMenuBarCalcSize(hDC, &Rect, Menu, hWnd);
285 ReleaseDC(hWnd, hDC);*/
286 return(GetSystemMetrics(SM_CYMENU
));
290 MeasureMenuItem(HWND hWnd
, HMENU mnu
, HDC hDC
, MENUITEMINFOW
*mii
, RECT
*mir
, LPWSTR str
)
293 MEASUREITEMSTRUCT mis
;
296 if(mii
->fType
& MFT_OWNERDRAW
)
298 /* send WM_MEASUREITEM message to window */
299 mis
.CtlType
= ODT_MENU
;
301 mis
.itemID
= mii
->wID
;
304 mis
.itemData
= mii
->dwItemData
;
305 res
= (BOOL
)SendMessageW(hWnd
, WM_MEASUREITEM
, 0, (LPARAM
)&mis
);
308 mir
->right
= mir
->left
+ mis
.itemWidth
;
309 mir
->bottom
= mir
->top
+ mis
.itemHeight
;
313 /* FIXME calculate size internally assuming the menu item is empty */
314 mir
->right
= mir
->left
+ 1;
315 mir
->bottom
= mir
->top
+ 1;
321 GetTextExtentPoint32W(hDC
, str
, mii
->cch
, &sz
);
322 /* FIXME calculate the size of the menu item */
323 mir
->right
= mir
->left
+ sz
.cx
+ 6;
324 mir
->bottom
= mir
->top
+ max(sz
.cy
, GetSystemMetrics(SM_CYMENU
));
330 DrawMenuItem(HWND hWnd
, HMENU mnu
, HDC hDC
, MENUITEMINFOW
*mii
, RECT
*mir
, LPWSTR str
)
335 if(mii
->fType
& MFT_OWNERDRAW
)
337 /* send WM_DRAWITEM message to window */
338 dis
.CtlType
= ODT_MENU
;
340 dis
.itemID
= mii
->wID
;
341 dis
.itemAction
= ODA_DRAWENTIRE
; /* FIXME */
342 dis
.itemState
= 0; /* FIXME */
343 dis
.hwndItem
= (HWND
)mnu
;
345 RtlCopyMemory(&dis
.rcItem
, mir
, sizeof(RECT
));
346 dis
.itemData
= mii
->dwItemData
;
347 res
= (BOOL
)SendMessageW(hWnd
, WM_DRAWITEM
, 0, (LPARAM
)&dis
);
352 /* FIXME draw the menu item */
353 SetTextColor(hDC
, COLOR_MENUTEXT
);
354 DrawTextW(hDC
, str
, mii
->cch
, mir
, DT_SINGLELINE
| DT_VCENTER
| DT_CENTER
);
361 MenuDrawMenuBar(HDC hDC
, LPRECT Rect
, HWND hWnd
, BOOL Draw
)
367 DWORD BufSize
, Items
, Items2
;
369 RECT
*omir
, *mir
= NULL
;
372 FillRect(hDC
, Rect
, GetSysColorBrush(COLOR_MENU
));
374 height
= Rect
->bottom
- Rect
->top
;
375 mnu
= GetMenu(hWnd
); /* Fixme - pass menu handle as parameter */
376 /* get menu item list size */
377 BufSize
= NtUserBuildMenuItemList(mnu
, (VOID
*)1, 0, 0);
380 /* FIXME cache menu bar items using NtUserDrawMenuBarTemp()
381 instead of allocating and deallocating memory everytime */
383 hHeap
= GetProcessHeap();
384 hBuf
= HeapAlloc(hHeap
, 0, BufSize
);
386 return(Rect
->bottom
- Rect
->top
);
388 /* copy menu items into buffer */
389 Items
= Items2
= NtUserBuildMenuItemList(mnu
, Buf
, BufSize
, 0);
391 /* calculate menu item rectangles */
395 mii
= (LPMENUITEMINFOW
)Buf
;
396 Buf
+= sizeof(MENUITEMINFOW
);
402 Buf
+= (mii
->cch
+ 1) * sizeof(WCHAR
);
408 mir
->left
= omir
->right
+ 1;
409 mir
->top
= omir
->top
;
410 mir
->right
+= mir
->left
;
411 mir
->bottom
+= mir
->top
;
415 mir
->left
= Rect
->left
;
416 mir
->top
= Rect
->top
;
418 MeasureMenuItem(hWnd
, mnu
, hDC
, mii
, mir
, str
);
420 height
= max(height
, mir
->top
+ mir
->bottom
);
421 /* DbgPrint("Measure menu item %ws: (%d, %d, %d, %d)\n", str, mir->left, mir->top, mir->right, mir->bottom); */
424 height
= max(height
, GetSystemMetrics(SM_CYMENU
));
427 /* draw menu items */
430 mii
= (LPMENUITEMINFOW
)Buf
;
431 Buf
+= sizeof(MENUITEMINFOW
);
437 Buf
+= (mii
->cch
+ 1) * sizeof(WCHAR
);
441 /* DbgPrint("Draw menu item %ws at (%d, %d, %d, %d)\n", str, mir->left, mir->top, mir->right, mir->bottom); */
442 DrawMenuItem(hWnd
, mnu
, hDC
, mii
, mir
, str
);
446 HeapFree(hHeap
, 0, hBuf
);
454 MenuTrackMouseMenuBar(HWND hWnd
, ULONG Ht
, POINT Pt
)
460 MenuTrackKbdMenuBar(HWND hWnd
, ULONG wParam
, ULONG Key
)
464 /* FUNCTIONS *****************************************************************/
467 MenuIsStringItem(ULONG TypeData)
469 return((TypeData & MENU_TYPE_MASK) == MF_STRING);
477 AppendMenuA(HMENU hMenu
,
482 return(InsertMenuA(hMenu
, -1, uFlags
| MF_BYPOSITION
, uIDNewItem
,
491 AppendMenuW(HMENU hMenu
,
496 return(InsertMenuW(hMenu
, -1, uFlags
| MF_BYPOSITION
, uIDNewItem
,
505 CheckMenuItem(HMENU hmenu
,
509 return NtUserCheckMenuItem(hmenu
, uIDCheckItem
, uCheck
);
517 CheckMenuRadioItem(HMENU hmenu
,
534 return NtUserCreateMenu();
542 CreatePopupMenu(VOID
)
544 /* FIXME - add MF_POPUP style? */
545 return NtUserCreateMenu();
553 DeleteMenu(HMENU hMenu
,
557 return NtUserDeleteMenu(hMenu
, uPosition
, uFlags
);
565 DestroyMenu(HMENU hMenu
)
567 return NtUserDestroyMenu(hMenu
);
575 DrawMenuBar(HWND hWnd
)
578 /* FIXME - return NtUserCallHwndLock(hWnd, 0x55); */
587 EnableMenuItem(HMENU hMenu
,
591 return NtUserEnableMenuItem(hMenu
, uIDEnableItem
, uEnable
);
601 /* FIXME - return NtUserEndMenu(); */
612 return (HMENU
)NtUserCallOneParam((DWORD
)hWnd
, ONEPARAM_ROUTINE_GETMENU
);
620 GetMenuBarInfo(HWND hwnd
,
634 GetMenuCheckMarkDimensions(VOID
)
636 return(MAKELONG(GetSystemMetrics(SM_CXMENUCHECK
),
637 GetSystemMetrics(SM_CYMENUCHECK
)));
645 GetMenuDefaultItem(HMENU hMenu
,
649 return NtUserGetMenuDefaultItem(hMenu
, fByPos
, gmdiFlags
);
657 GetMenuInfo(HMENU hmenu
,
663 if(!lpcmi
|| (lpcmi
->cbSize
!= sizeof(MENUINFO
)))
666 RtlZeroMemory(&mi
, sizeof(MENUINFO
));
667 mi
.cbSize
= sizeof(MENUINFO
);
668 mi
.fMask
= lpcmi
->fMask
;
670 res
= NtUserMenuInfo(hmenu
, &mi
, FALSE
);
672 memcpy(lpcmi
, &mi
, sizeof(MENUINFO
));
681 GetMenuItemCount(HMENU hMenu
)
683 return NtUserBuildMenuItemList(hMenu
, NULL
, 0, 0);
691 GetMenuItemID(HMENU hMenu
,
696 mii
.cbSize
= sizeof(MENUITEMINFOW
);
697 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
699 if(!NtUserMenuItemInfo(hMenu
, nPos
, MF_BYPOSITION
, &mii
, FALSE
))
704 if(mii
.hSubMenu
) return -1;
705 if(mii
.wID
== 0) return -1;
719 LPMENUITEMINFOA lpmii
)
735 LPMENUITEMINFOW lpmii
)
746 GetMenuItemRect(HWND hWnd
,
767 mii
.cbSize
= sizeof(MENUITEMINFOW
);
768 mii
.fMask
= MIIM_STATE
| MIIM_TYPE
| MIIM_SUBMENU
;
771 if(NtUserMenuItemInfo(hMenu
, uId
, uFlags
, &mii
, FALSE
))
776 nSubItems
= (UINT
)NtUserBuildMenuItemList(mii
.hSubMenu
, NULL
, 0, 0);
778 /* FIXME - ported from wine, does that work (0xff)? */
779 if(GetLastError() != ERROR_INVALID_MENU_HANDLE
)
780 return (nSubItems
<< 8) | ((mii
.fState
| mii
.fType
) & 0xff);
782 return (UINT
)-1; /* Invalid submenu */
785 /* FIXME - ported from wine, does that work? */
786 return (mii
.fType
| mii
.fState
);
837 mi
.cbSize
= sizeof(mi
);
838 mi
.fMask
= MIIM_SUBMENU
;
839 if(NtUserMenuItemInfo(hMenu
, (UINT
)nPos
, MF_BYPOSITION
, &mi
, FALSE
))
858 return NtUserHiliteMenuItem(hwnd
, hmenu
, uItemHilite
, uHilite
);
875 mii
.cbSize
= sizeof(MENUITEMINFOA
);
876 mii
.fMask
= MIIM_FTYPE
| MIIM_STRING
;
879 if(uFlags
& MF_BITMAP
)
881 mii
.fType
|= MFT_BITMAP
;
883 else if(uFlags
& MF_OWNERDRAW
)
885 mii
.fType
|= MFT_OWNERDRAW
;
887 mii
.dwTypeData
= (LPSTR
)lpNewItem
;
888 if(uFlags
& MF_POPUP
)
890 mii
.fMask
|= MIIM_SUBMENU
;
891 mii
.hSubMenu
= (HMENU
)uIDNewItem
;
895 mii
.fMask
|= MIIM_ID
;
896 mii
.wID
= (UINT
)uIDNewItem
;
898 return InsertMenuItemA(hMenu
, uPosition
, (WINBOOL
)!(MF_BYPOSITION
& uFlags
), &mii
);
911 LPCMENUITEMINFOA lpmii
)
914 UNICODE_STRING MenuText
;
916 BOOL CleanHeap
= FALSE
;
919 if((lpmii
->cbSize
== sizeof(MENUITEMINFOA
)) ||
920 (lpmii
->cbSize
== sizeof(MENUITEMINFOA
) - sizeof(HBITMAP
)))
922 RtlMoveMemory ( &mi
, lpmii
, lpmii
->cbSize
);
924 /* copy the text string */
925 if((mi
.fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
926 (MENU_ITEM_TYPE(mi
.fType
) == MF_STRING
) && mi
.dwTypeData
)
928 Status
= HEAP_strdupAtoW ( &mi
.dwTypeData
, (LPCSTR
)mi
.dwTypeData
, &mi
.cch
);
929 if (!NT_SUCCESS (Status
))
931 SetLastError (RtlNtStatusToDosError(Status
));
934 RtlInitUnicodeString(&MenuText
, (PWSTR
)mi
.dwTypeData
);
935 mi
.dwTypeData
= (LPWSTR
)&MenuText
;
939 res
= NtUserInsertMenuItem(hMenu
, uItem
, fByPosition
, &mi
);
941 if ( CleanHeap
) HEAP_free ( mi
.dwTypeData
);
956 LPCMENUITEMINFOW lpmii
)
959 UNICODE_STRING MenuText
;
961 BOOL CleanHeap
= FALSE
;
962 HANDLE hHeap
= RtlGetProcessHeap();
963 mi
.hbmpItem
= (HBITMAP
)0;
965 // while we could just pass 'lpmii' to win32k, we make a copy so that
966 // if a bad user passes bad data, we crash his process instead of the
969 if((lpmii
->cbSize
== sizeof(MENUITEMINFOW
)) ||
970 (lpmii
->cbSize
== sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
)))
972 memcpy(&mi
, lpmii
, lpmii
->cbSize
);
974 /* copy the text string */
975 if((mi
.fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
976 (MENU_ITEM_TYPE(mi
.fType
) == MF_STRING
) && mi
.dwTypeData
)
980 if(!RtlCreateUnicodeString(&MenuText
, (PWSTR
)lpmii
->dwTypeData
))
982 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
985 mi
.dwTypeData
= (LPWSTR
)&MenuText
;
986 mi
.cch
= MenuText
.Length
/ sizeof(WCHAR
);
991 res
= NtUserInsertMenuItem(hMenu
, uItem
, fByPosition
, &mi
);
993 if(CleanHeap
) RtlFreeHeap (hHeap
, 0, mi
.dwTypeData
);
1008 UINT_PTR uIDNewItem
,
1012 mii
.cbSize
= sizeof(MENUITEMINFOW
);
1013 mii
.fMask
= MIIM_FTYPE
| MIIM_STRING
;
1016 if(uFlags
& MF_BITMAP
)
1018 mii
.fType
|= MFT_BITMAP
;
1020 else if(uFlags
& MF_OWNERDRAW
)
1022 mii
.fType
|= MFT_OWNERDRAW
;
1024 mii
.dwTypeData
= (LPWSTR
)lpNewItem
;
1025 if(uFlags
& MF_POPUP
)
1027 mii
.fMask
|= MIIM_SUBMENU
;
1028 mii
.hSubMenu
= (HMENU
)uIDNewItem
;
1032 mii
.fMask
|= MIIM_ID
;
1033 mii
.wID
= (UINT
)uIDNewItem
;
1035 return InsertMenuItemW(hMenu
, uPosition
, (WINBOOL
)!(MF_BYPOSITION
& uFlags
), &mii
);
1048 SetLastError(ERROR_SUCCESS
);
1049 ret
= NtUserBuildMenuItemList(hMenu
, NULL
, 0, 0);
1050 return ((ret
== (DWORD
)-1) || (GetLastError() == ERROR_INVALID_MENU_HANDLE
));
1058 LoadMenuA(HINSTANCE hInstance
,
1061 HANDLE Resource
= FindResourceA(hInstance
, lpMenuName
, MAKEINTRESOURCEA(4));
1062 if (Resource
== NULL
)
1066 return(LoadMenuIndirectA((PVOID
)LoadResource(hInstance
, Resource
)));
1074 LoadMenuIndirectA(CONST MENUTEMPLATE
*lpMenuTemplate
)
1076 return(LoadMenuIndirectW(lpMenuTemplate
));
1084 LoadMenuIndirectW(CONST MENUTEMPLATE
*lpMenuTemplate
)
1087 WORD version
, offset
;
1088 LPCSTR p
= (LPCSTR
)lpMenuTemplate
;
1090 version
= GET_WORD(p
);
1095 case 0: /* standard format is version of 0 */
1096 offset
= GET_WORD(p
);
1097 p
+= sizeof(WORD
) + offset
;
1098 if (!(hMenu
= CreateMenu())) return 0;
1099 if (!MENU_ParseResource(p
, hMenu
, TRUE
))
1105 case 1: /* extended format is version of 1 */
1106 offset
= GET_WORD(p
);
1107 p
+= sizeof(WORD
) + offset
;
1108 if (!(hMenu
= CreateMenu())) return 0;
1109 if (!MENUEX_ParseResource(p
, hMenu
))
1111 DestroyMenu( hMenu
);
1116 DbgPrint("LoadMenuIndirectW(): version %d not supported.\n", version
);
1126 LoadMenuW(HINSTANCE hInstance
,
1129 HANDLE Resource
= FindResourceW(hInstance
, lpMenuName
, RT_MENU
);
1130 if (Resource
== NULL
)
1134 return(LoadMenuIndirectW((PVOID
)LoadResource(hInstance
, Resource
)));
1162 UINT_PTR uIDNewItem
,
1179 UINT_PTR uIDNewItem
,
1197 return NtUserRemoveMenu(hMenu
, uPosition
, uFlags
);
1208 return NtUserSetMenu(hWnd
, hMenu
, TRUE
);
1222 return NtUserSetMenuDefaultItem(hMenu
, uItem
, fByPos
);
1237 if(lpcmi
->cbSize
!= sizeof(MENUINFO
))
1240 memcpy(&mi
, lpcmi
, sizeof(MENUINFO
));
1241 return NtUserMenuInfo(hmenu
, &mi
, TRUE
);
1254 HBITMAP hBitmapUnchecked
,
1255 HBITMAP hBitmapChecked
)
1270 WINBOOL fByPosition
,
1271 LPMENUITEMINFOA lpmii
)
1286 WINBOOL fByPosition
,
1287 LPMENUITEMINFOW lpmii
)
1306 CONST RECT
*prcRect
)
1336 SetMenuContextHelpId(HMENU hmenu
,
1337 DWORD dwContextHelpId
)
1339 return NtUserSetMenuContextHelpId(hmenu
, dwContextHelpId
);
1348 GetMenuContextHelpId(HMENU hmenu
)
1351 mi
.cbSize
= sizeof(MENUINFO
);
1352 mi
.fMask
= MIM_HELPID
;
1354 if(NtUserMenuInfo(hmenu
, &mi
, FALSE
))
1356 return mi
.dwContextHelpID
;
1418 LPCWSTR lpszNewItem
,