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.32 2003/08/29 09:29:11 gvg 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"
43 /* TYPES *********************************************************************/
45 #define MENU_TYPE_MASK ((MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
47 #define MENU_ITEM_TYPE(flags) \
48 ((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
50 #define MENU_BAR_ITEMS_SPACE (12)
51 #define SEPARATOR_HEIGHT (5)
52 #define MENU_TAB_SPACE (8)
55 #define MF_END (0x0080)
59 #define MIIM_STRING (0x00000040)
62 #define MAKEINTATOMA(atom) ((LPCSTR)((ULONG_PTR)((WORD)(atom))))
63 #define MAKEINTATOMW(atom) ((LPCWSTR)((ULONG_PTR)((WORD)(atom))))
64 #define POPUPMENU_CLASS_ATOMA MAKEINTATOMA(32768) /* PopupMenu */
65 #define POPUPMENU_CLASS_ATOMW MAKEINTATOMW(32768) /* PopupMenu */
67 /*********************************************************************
68 * PopupMenu class descriptor
70 const struct builtin_class_descr POPUPMENU_builtin_class
=
72 POPUPMENU_CLASS_ATOMW
, /* name */
73 CS_GLOBALCLASS
| CS_SAVEBITS
| CS_DBLCLKS
, /* style */
74 (WNDPROC
) NULL
, /* FIXME - procW */
75 sizeof(MENUINFO
*), /* extra */
76 (LPCWSTR
) IDC_ARROW
, /* cursor */
77 (HBRUSH
)COLOR_MENU
/* brush */
81 /* INTERNAL FUNCTIONS ********************************************************/
83 /* Rip the fun and easy to use and fun WINE unicode string manipulation routines.
84 * Of course I didnt copy the ASM code because we want this to be portable
85 * and it needs to go away.
88 static inline unsigned int strlenW( const WCHAR
*str
)
95 static inline WCHAR
*strncpyW( WCHAR
*str1
, const WCHAR
*str2
, int n
)
98 while (n
-- > 0) if (!(*str1
++ = *str2
++)) break;
99 while (n
-- > 0) *str1
++ = 0;
103 static inline WCHAR
*strcpyW( WCHAR
*dst
, const WCHAR
*src
)
106 while ((*p
++ = *src
++));
110 static inline WCHAR
*strcatW( WCHAR
*dst
, const WCHAR
*src
)
112 strcpyW( dst
+ strlenW(dst
), src
);
117 #define GET_WORD(ptr) (*(WORD *)(ptr))
120 #define GET_DWORD(ptr) (*(DWORD *)(ptr))
123 HFONT hMenuFont
= NULL
;
124 HFONT hMenuFontBold
= NULL
;
126 /**********************************************************************
127 * MENUEX_ParseResource
129 * Parse an extended menu resource and add items to the menu.
130 * Return a pointer to the end of the resource.
132 * FIXME - should we be passing an LPCSTR to a predominantly UNICODE function?
134 static LPCSTR
MENUEX_ParseResource( LPCSTR res
, HMENU hMenu
)
142 mii
.cbSize
= sizeof(mii
);
143 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_TYPE
;
144 mii
.fType
= GET_DWORD(res
);
145 res
+= sizeof(DWORD
);
146 mii
.fState
= GET_DWORD(res
);
147 res
+= sizeof(DWORD
);
148 mii
.wID
= GET_DWORD(res
);
149 res
+= sizeof(DWORD
);
150 resinfo
= GET_WORD(res
);
152 /* Align the text on a word boundary. */
153 res
+= (~((int)res
- 1)) & 1;
154 mii
.dwTypeData
= (LPWSTR
) res
;
155 res
+= (1 + strlenW(mii
.dwTypeData
)) * sizeof(WCHAR
);
156 /* Align the following fields on a dword boundary. */
157 res
+= (~((int)res
- 1)) & 3;
159 if (resinfo
& 1) /* Pop-up? */
161 /* DWORD helpid = GET_DWORD(res); FIXME: use this. */
162 res
+= sizeof(DWORD
);
163 mii
.hSubMenu
= CreatePopupMenu();
166 if (!(res
= MENUEX_ParseResource(res
, mii
.hSubMenu
)))
168 DestroyMenu(mii
.hSubMenu
);
171 mii
.fMask
|= MIIM_SUBMENU
;
172 mii
.fType
|= MF_POPUP
;
174 else if(!*mii
.dwTypeData
&& !(mii
.fType
& MF_SEPARATOR
))
176 DbgPrint("WARN: Converting NULL menu item %04x, type %04x to SEPARATOR\n",
178 mii
.fType
|= MF_SEPARATOR
;
180 InsertMenuItemW(hMenu
, -1, MF_BYPOSITION
, &mii
);
182 while (!(resinfo
& MF_END
));
187 /**********************************************************************
190 * Parse a standard menu resource and add items to the menu.
191 * Return a pointer to the end of the resource.
193 * NOTE: flags is equivalent to the mtOption field
195 static LPCSTR
MENU_ParseResource( LPCSTR res
, HMENU hMenu
, BOOL unicode
)
204 flags
= GET_WORD(res
);
206 /* remove MF_END flag before passing it to AppendMenu()! */
207 end
= (flags
& MF_END
);
208 if(end
) flags
^= MF_END
;
211 if(!(flags
& MF_POPUP
))
218 res
+= strlen(str
) + 1;
220 res
+= (strlenW((LPCWSTR
)str
) + 1) * sizeof(WCHAR
);
221 if (flags
& MF_POPUP
)
223 hSubMenu
= CreatePopupMenu();
224 if(!hSubMenu
) return NULL
;
225 if(!(res
= MENU_ParseResource(res
, hSubMenu
, unicode
)))
228 AppendMenuA(hMenu
, flags
, (UINT
)hSubMenu
, str
);
230 AppendMenuW(hMenu
, flags
, (UINT
)hSubMenu
, (LPCWSTR
)str
);
232 else /* Not a popup */
235 AppendMenuA(hMenu
, flags
, id
, *str
? str
: NULL
);
237 AppendMenuW(hMenu
, flags
, id
,
238 *(LPCWSTR
)str
? (LPCWSTR
)str
: NULL
);
247 User32LoadSysMenuTemplateForKernel(PVOID Arguments
, ULONG ArgumentLength
)
251 hUser32
= GetModuleHandleW(L
"USER32");
252 Result
= (LRESULT
)LoadMenuW(hUser32
, L
"SYSMENU");
253 return(ZwCallbackReturn(&Result
, sizeof(LRESULT
), STATUS_SUCCESS
));
260 NONCLIENTMETRICSW ncm
;
262 /* get the menu font */
263 if(!hMenuFont
|| !hMenuFontBold
)
265 ncm
.cbSize
= sizeof(ncm
);
266 if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, sizeof(ncm
), &ncm
, 0))
268 DbgPrint("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n");
272 hMenuFont
= CreateFontIndirectW(&ncm
.lfMenuFont
);
273 if(hMenuFont
== NULL
)
275 DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n");
279 ncm
.lfMenuFont
.lfWeight
= max(ncm
.lfMenuFont
.lfWeight
+ 300, 1000);
280 hMenuFontBold
= CreateFontIndirectW(&ncm
.lfMenuFont
);
281 if(hMenuFontBold
== NULL
)
283 DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
293 MenuGetMenuBarHeight(HWND hWnd
, ULONG MenuBarWidth
, LONG OrgX
, LONG OrgY
)
300 MenuId = GetWindowLong(hWnd, GWL_ID);
301 Menu = MenuGetMenu((HMENU)MenuId);
306 hDC = GetDCEx(hWnd, 0, DCX_CACHE | DCX_WINDOW);
307 SelectObject(hDC, hMenuFont);
308 SetRect(&Rect, OrgX, OrgY, OrgX + MenuBarWidth,
309 OrgY + GetSystemMetrics(SM_CYMENU));
310 MenuMenuBarCalcSize(hDC, &Rect, Menu, hWnd);
311 ReleaseDC(hWnd, hDC);*/
312 return(GetSystemMetrics(SM_CYMENU
));
316 MeasureMenuItem(HWND hWnd
, HMENU mnu
, HDC hDC
, MENUITEMINFOW
*mii
, RECT
*mir
, LPWSTR str
)
319 MEASUREITEMSTRUCT mis
;
322 if(mii
->fType
& MFT_OWNERDRAW
)
324 /* send WM_MEASUREITEM message to window */
325 mis
.CtlType
= ODT_MENU
;
327 mis
.itemID
= mii
->wID
;
330 mis
.itemData
= mii
->dwItemData
;
331 res
= (BOOL
)SendMessageW(hWnd
, WM_MEASUREITEM
, 0, (LPARAM
)&mis
);
334 mir
->right
= mir
->left
+ mis
.itemWidth
;
335 mir
->bottom
= mir
->top
+ mis
.itemHeight
;
339 /* FIXME calculate size internally assuming the menu item is empty */
340 mir
->right
= mir
->left
+ 1;
341 mir
->bottom
= mir
->top
+ 1;
347 GetTextExtentPoint32W(hDC
, str
, mii
->cch
, &sz
);
348 /* FIXME calculate the size of the menu item */
349 mir
->right
= mir
->left
+ sz
.cx
+ 6;
350 mir
->bottom
= mir
->top
+ max(sz
.cy
, GetSystemMetrics(SM_CYMENU
));
356 DrawMenuItem(HWND hWnd
, HMENU mnu
, HDC hDC
, MENUITEMINFOW
*mii
, RECT
*mir
, LPWSTR str
)
361 if(mii
->fType
& MFT_OWNERDRAW
)
363 /* send WM_DRAWITEM message to window */
364 dis
.CtlType
= ODT_MENU
;
366 dis
.itemID
= mii
->wID
;
367 dis
.itemAction
= ODA_DRAWENTIRE
; /* FIXME */
368 dis
.itemState
= 0; /* FIXME */
369 dis
.hwndItem
= (HWND
)mnu
;
371 RtlCopyMemory(&dis
.rcItem
, mir
, sizeof(RECT
));
372 dis
.itemData
= mii
->dwItemData
;
373 res
= (BOOL
)SendMessageW(hWnd
, WM_DRAWITEM
, 0, (LPARAM
)&dis
);
378 /* FIXME draw the menu item */
379 SetTextColor(hDC
, COLOR_MENUTEXT
);
380 DrawTextW(hDC
, str
, -1, mir
, DT_SINGLELINE
| DT_VCENTER
| DT_CENTER
);
387 MenuDrawMenuBar(HDC hDC
, LPRECT Rect
, HWND hWnd
, BOOL Draw
)
393 DWORD BufSize
, Items
, Items2
;
395 RECT
*omir
, *mir
= NULL
;
398 height
= Rect
->bottom
- Rect
->top
;
399 mnu
= GetMenu(hWnd
); /* Fixme - pass menu handle as parameter */
400 /* get menu item list size */
401 BufSize
= NtUserBuildMenuItemList(mnu
, (VOID
*)1, 0, 0);
404 /* FIXME cache menu bar items using NtUserDrawMenuBarTemp()
405 instead of allocating and deallocating memory everytime */
407 hHeap
= GetProcessHeap();
408 hBuf
= HeapAlloc(hHeap
, 0, BufSize
);
410 return(Rect
->bottom
- Rect
->top
);
412 /* copy menu items into buffer */
413 Items
= Items2
= NtUserBuildMenuItemList(mnu
, Buf
, BufSize
, 0);
415 /* calculate menu item rectangles */
419 mii
= (LPMENUITEMINFOW
)Buf
;
420 Buf
+= sizeof(MENUITEMINFOW
);
426 Buf
+= (mii
->cch
+ 1) * sizeof(WCHAR
);
432 mir
->left
= omir
->right
+ 1;
433 mir
->top
= omir
->top
;
434 mir
->right
+= mir
->left
;
435 mir
->bottom
+= mir
->top
;
439 mir
->left
= Rect
->left
;
440 mir
->top
= Rect
->top
;
442 MeasureMenuItem(hWnd
, mnu
, hDC
, mii
, mir
, str
);
444 height
= max(height
, mir
->top
+ mir
->bottom
);
445 /* DbgPrint("Measure menu item %ws: (%d, %d, %d, %d)\n", str, mir->left, mir->top, mir->right, mir->bottom); */
448 height
= max(height
, GetSystemMetrics(SM_CYMENU
));
451 /* draw menu items */
454 mii
= (LPMENUITEMINFOW
)Buf
;
455 Buf
+= sizeof(MENUITEMINFOW
);
461 Buf
+= (mii
->cch
+ 1) * sizeof(WCHAR
);
465 /* DbgPrint("Draw menu item %ws at (%d, %d, %d, %d)\n", str, mir->left, mir->top, mir->right, mir->bottom); */
466 DrawMenuItem(hWnd
, mnu
, hDC
, mii
, mir
, str
);
470 HeapFree(hHeap
, 0, hBuf
);
478 MenuTrackMouseMenuBar(HWND hWnd
, ULONG Ht
, POINT Pt
)
484 MenuTrackKbdMenuBar(HWND hWnd
, ULONG wParam
, ULONG Key
)
488 /* FUNCTIONS *****************************************************************/
491 MenuIsStringItem(ULONG TypeData)
493 return((TypeData & MENU_TYPE_MASK) == MF_STRING);
501 AppendMenuA(HMENU hMenu
,
506 return(InsertMenuA(hMenu
, -1, uFlags
| MF_BYPOSITION
, uIDNewItem
,
515 AppendMenuW(HMENU hMenu
,
520 return(InsertMenuW(hMenu
, -1, uFlags
| MF_BYPOSITION
, uIDNewItem
,
529 CheckMenuItem(HMENU hmenu
,
533 return NtUserCheckMenuItem(hmenu
, uIDCheckItem
, uCheck
);
541 CheckMenuRadioItem(HMENU hmenu
,
558 return NtUserCreateMenu();
566 CreatePopupMenu(VOID
)
568 /* FIXME - add MF_POPUP style? */
569 return NtUserCreateMenu();
577 DeleteMenu(HMENU hMenu
,
581 return NtUserDeleteMenu(hMenu
, uPosition
, uFlags
);
589 DestroyMenu(HMENU hMenu
)
591 return NtUserDestroyMenu(hMenu
);
599 DrawMenuBar(HWND hWnd
)
602 /* FIXME - return NtUserCallHwndLock(hWnd, 0x55); */
611 EnableMenuItem(HMENU hMenu
,
615 return NtUserEnableMenuItem(hMenu
, uIDEnableItem
, uEnable
);
625 /* FIXME - return NtUserEndMenu(); */
636 return (HMENU
)NtUserCallOneParam((DWORD
)hWnd
, ONEPARAM_ROUTINE_GETMENU
);
644 GetMenuBarInfo(HWND hwnd
,
658 GetMenuCheckMarkDimensions(VOID
)
660 return(MAKELONG(GetSystemMetrics(SM_CXMENUCHECK
),
661 GetSystemMetrics(SM_CYMENUCHECK
)));
669 GetMenuDefaultItem(HMENU hMenu
,
673 return NtUserGetMenuDefaultItem(hMenu
, fByPos
, gmdiFlags
);
681 GetMenuInfo(HMENU hmenu
,
687 if(!lpcmi
|| (lpcmi
->cbSize
!= sizeof(MENUINFO
)))
690 RtlZeroMemory(&mi
, sizeof(MENUINFO
));
691 mi
.cbSize
= sizeof(MENUINFO
);
692 mi
.fMask
= lpcmi
->fMask
;
694 res
= NtUserMenuInfo(hmenu
, &mi
, FALSE
);
696 memcpy(lpcmi
, &mi
, sizeof(MENUINFO
));
705 GetMenuItemCount(HMENU hMenu
)
707 return NtUserBuildMenuItemList(hMenu
, NULL
, 0, 0);
715 GetMenuItemID(HMENU hMenu
,
720 mii
.cbSize
= sizeof(MENUITEMINFOW
);
721 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
723 if(!NtUserMenuItemInfo(hMenu
, nPos
, MF_BYPOSITION
, &mii
, FALSE
))
728 if(mii
.hSubMenu
) return -1;
729 if(mii
.wID
== 0) return -1;
743 LPMENUITEMINFOA lpmii
)
759 LPMENUITEMINFOW lpmii
)
770 GetMenuItemRect(HWND hWnd
,
791 mii
.cbSize
= sizeof(MENUITEMINFOW
);
792 mii
.fMask
= MIIM_STATE
| MIIM_TYPE
| MIIM_SUBMENU
;
795 if(NtUserMenuItemInfo(hMenu
, uId
, uFlags
, &mii
, FALSE
))
800 nSubItems
= (UINT
)NtUserBuildMenuItemList(mii
.hSubMenu
, NULL
, 0, 0);
802 /* FIXME - ported from wine, does that work (0xff)? */
803 if(GetLastError() != ERROR_INVALID_MENU_HANDLE
)
804 return (nSubItems
<< 8) | ((mii
.fState
| mii
.fType
) & 0xff);
806 return (UINT
)-1; /* Invalid submenu */
809 /* FIXME - ported from wine, does that work? */
810 return (mii
.fType
| mii
.fState
);
861 mi
.cbSize
= sizeof(mi
);
862 mi
.fMask
= MIIM_SUBMENU
;
863 if(NtUserMenuItemInfo(hMenu
, (UINT
)nPos
, MF_BYPOSITION
, &mi
, FALSE
))
882 return NtUserHiliteMenuItem(hwnd
, hmenu
, uItemHilite
, uHilite
);
899 mii
.cbSize
= sizeof(MENUITEMINFOA
);
900 mii
.fMask
= MIIM_FTYPE
| MIIM_STRING
;
903 if(uFlags
& MF_BITMAP
)
905 mii
.fType
|= MFT_BITMAP
;
907 else if(uFlags
& MF_OWNERDRAW
)
909 mii
.fType
|= MFT_OWNERDRAW
;
911 mii
.dwTypeData
= (LPSTR
)lpNewItem
;
912 if(uFlags
& MF_POPUP
)
914 mii
.fMask
|= MIIM_SUBMENU
;
915 mii
.hSubMenu
= (HMENU
)uIDNewItem
;
919 mii
.fMask
|= MIIM_ID
;
920 mii
.wID
= (UINT
)uIDNewItem
;
922 return InsertMenuItemA(hMenu
, uPosition
, (WINBOOL
)!(MF_BYPOSITION
& uFlags
), &mii
);
935 LPCMENUITEMINFOA lpmii
)
938 UNICODE_STRING MenuText
;
940 BOOL CleanHeap
= FALSE
;
943 if((lpmii
->cbSize
== sizeof(MENUITEMINFOA
)) ||
944 (lpmii
->cbSize
== sizeof(MENUITEMINFOA
) - sizeof(HBITMAP
)))
946 RtlMoveMemory ( &mi
, lpmii
, lpmii
->cbSize
);
948 /* copy the text string */
949 if((mi
.fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
950 (MENU_ITEM_TYPE(mi
.fType
) == MF_STRING
) && mi
.dwTypeData
)
952 Status
= HEAP_strdupAtoW ( &mi
.dwTypeData
, (LPCSTR
)mi
.dwTypeData
, &mi
.cch
);
953 if (!NT_SUCCESS (Status
))
955 SetLastError (RtlNtStatusToDosError(Status
));
958 RtlInitUnicodeString(&MenuText
, (PWSTR
)mi
.dwTypeData
);
959 mi
.dwTypeData
= (LPWSTR
)&MenuText
;
963 res
= NtUserInsertMenuItem(hMenu
, uItem
, fByPosition
, &mi
);
965 if ( CleanHeap
) HEAP_free ( mi
.dwTypeData
);
980 LPCMENUITEMINFOW lpmii
)
983 UNICODE_STRING MenuText
;
985 BOOL CleanHeap
= FALSE
;
986 HANDLE hHeap
= RtlGetProcessHeap();
987 mi
.hbmpItem
= (HBITMAP
)0;
989 // while we could just pass 'lpmii' to win32k, we make a copy so that
990 // if a bad user passes bad data, we crash his process instead of the
993 if((lpmii
->cbSize
== sizeof(MENUITEMINFOW
)) ||
994 (lpmii
->cbSize
== sizeof(MENUITEMINFOW
) - sizeof(HBITMAP
)))
996 memcpy(&mi
, lpmii
, lpmii
->cbSize
);
998 /* copy the text string */
999 if((mi
.fMask
& (MIIM_TYPE
| MIIM_STRING
)) &&
1000 (MENU_ITEM_TYPE(mi
.fType
) == MF_STRING
) && mi
.dwTypeData
)
1004 if(!RtlCreateUnicodeString(&MenuText
, (PWSTR
)lpmii
->dwTypeData
))
1006 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
1009 mi
.dwTypeData
= (LPWSTR
)&MenuText
;
1010 mi
.cch
= MenuText
.Length
/ sizeof(WCHAR
);
1015 res
= NtUserInsertMenuItem(hMenu
, uItem
, fByPosition
, &mi
);
1017 if(CleanHeap
) RtlFreeHeap (hHeap
, 0, mi
.dwTypeData
);
1032 UINT_PTR uIDNewItem
,
1036 mii
.cbSize
= sizeof(MENUITEMINFOW
);
1037 mii
.fMask
= MIIM_FTYPE
| MIIM_STRING
;
1040 if(uFlags
& MF_BITMAP
)
1042 mii
.fType
|= MFT_BITMAP
;
1044 else if(uFlags
& MF_OWNERDRAW
)
1046 mii
.fType
|= MFT_OWNERDRAW
;
1048 mii
.dwTypeData
= (LPWSTR
)lpNewItem
;
1049 if(uFlags
& MF_POPUP
)
1051 mii
.fMask
|= MIIM_SUBMENU
;
1052 mii
.hSubMenu
= (HMENU
)uIDNewItem
;
1056 mii
.fMask
|= MIIM_ID
;
1057 mii
.wID
= (UINT
)uIDNewItem
;
1059 return InsertMenuItemW(hMenu
, uPosition
, (WINBOOL
)!(MF_BYPOSITION
& uFlags
), &mii
);
1072 SetLastError(ERROR_SUCCESS
);
1073 ret
= NtUserBuildMenuItemList(hMenu
, NULL
, 0, 0);
1074 return ((ret
== (DWORD
)-1) || (GetLastError() == ERROR_INVALID_MENU_HANDLE
));
1082 LoadMenuA(HINSTANCE hInstance
,
1085 HANDLE Resource
= FindResourceA(hInstance
, lpMenuName
, MAKEINTRESOURCEA(4));
1086 if (Resource
== NULL
)
1090 return(LoadMenuIndirectA((PVOID
)LoadResource(hInstance
, Resource
)));
1098 LoadMenuIndirectA(CONST MENUTEMPLATE
*lpMenuTemplate
)
1100 return(LoadMenuIndirectW(lpMenuTemplate
));
1108 LoadMenuIndirectW(CONST MENUTEMPLATE
*lpMenuTemplate
)
1111 WORD version
, offset
;
1112 LPCSTR p
= (LPCSTR
)lpMenuTemplate
;
1114 version
= GET_WORD(p
);
1119 case 0: /* standard format is version of 0 */
1120 offset
= GET_WORD(p
);
1121 p
+= sizeof(WORD
) + offset
;
1122 if (!(hMenu
= CreateMenu())) return 0;
1123 if (!MENU_ParseResource(p
, hMenu
, TRUE
))
1129 case 1: /* extended format is version of 1 */
1130 offset
= GET_WORD(p
);
1131 p
+= sizeof(WORD
) + offset
;
1132 if (!(hMenu
= CreateMenu())) return 0;
1133 if (!MENUEX_ParseResource(p
, hMenu
))
1135 DestroyMenu( hMenu
);
1140 DbgPrint("LoadMenuIndirectW(): version %d not supported.\n", version
);
1150 LoadMenuW(HINSTANCE hInstance
,
1153 HANDLE Resource
= FindResourceW(hInstance
, lpMenuName
, RT_MENU
);
1154 if (Resource
== NULL
)
1158 return(LoadMenuIndirectW((PVOID
)LoadResource(hInstance
, Resource
)));
1186 UINT_PTR uIDNewItem
,
1203 UINT_PTR uIDNewItem
,
1221 return NtUserRemoveMenu(hMenu
, uPosition
, uFlags
);
1232 return NtUserSetMenu(hWnd
, hMenu
, TRUE
);
1246 return NtUserSetMenuDefaultItem(hMenu
, uItem
, fByPos
);
1261 if(lpcmi
->cbSize
!= sizeof(MENUINFO
))
1264 memcpy(&mi
, lpcmi
, sizeof(MENUINFO
));
1265 return NtUserMenuInfo(hmenu
, &mi
, TRUE
);
1278 HBITMAP hBitmapUnchecked
,
1279 HBITMAP hBitmapChecked
)
1294 WINBOOL fByPosition
,
1295 LPMENUITEMINFOA lpmii
)
1310 WINBOOL fByPosition
,
1311 LPMENUITEMINFOW lpmii
)
1330 CONST RECT
*prcRect
)
1360 SetMenuContextHelpId(HMENU hmenu
,
1361 DWORD dwContextHelpId
)
1363 return NtUserSetMenuContextHelpId(hmenu
, dwContextHelpId
);
1372 GetMenuContextHelpId(HMENU hmenu
)
1375 mi
.cbSize
= sizeof(MENUINFO
);
1376 mi
.fMask
= MIM_HELPID
;
1378 if(NtUserMenuInfo(hmenu
, &mi
, FALSE
))
1380 return mi
.dwContextHelpID
;