Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

690 lines
21 KiB

  1. /****************************** Module Header ******************************\
  2. *
  3. * Module Name: clmenu.c
  4. *
  5. * Copyright (c) 1985 - 1999, Microsoft Corporation
  6. *
  7. * Menu Loading Routines
  8. *
  9. * History:
  10. * 24-Sep-1990 mikeke From win30
  11. * 29-Nov-1994 JimA Moved from server.
  12. \***************************************************************************/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. /***************************************************************************\
  16. * MenuLoadWinTemplates
  17. *
  18. * Recursive routine that loads in the new style menu template and
  19. * builds the menu. Assumes that the menu template header has already been
  20. * read in and processed elsewhere...
  21. *
  22. * History:
  23. * 28-Sep-1990 mikeke from win30
  24. \***************************************************************************/
  25. LPBYTE MenuLoadWinTemplates(
  26. LPBYTE lpMenuTemplate,
  27. HMENU *phMenu)
  28. {
  29. HMENU hMenu;
  30. UINT menuFlags = 0;
  31. ULONG_PTR menuId = 0;
  32. LPWSTR lpmenuText;
  33. MENUITEMINFO mii;
  34. UNICODE_STRING str;
  35. if (!(hMenu = NtUserCreateMenu()))
  36. goto memoryerror;
  37. do {
  38. /*
  39. * Get the menu flags.
  40. */
  41. menuFlags = (UINT)(*(WORD *)lpMenuTemplate);
  42. lpMenuTemplate += 2;
  43. if (menuFlags & ~MF_VALID) {
  44. RIPERR1(ERROR_INVALID_DATA, RIP_WARNING, "Menu Flags %lX are invalid", menuFlags);
  45. goto memoryerror;
  46. }
  47. if (!(menuFlags & MF_POPUP)) {
  48. menuId = *(WORD *)lpMenuTemplate;
  49. lpMenuTemplate += 2;
  50. }
  51. lpmenuText = (LPWSTR)lpMenuTemplate;
  52. if (*lpmenuText) {
  53. /*
  54. * Some Win3.1 and Win95 16 bit apps (chessmaster, mavis typing) know that
  55. * dwItemData for MFT_OWNERDRAW items is a pointer to a string in the resource data.
  56. * So WOW has given us the proper pointer from the 16 bit resource.
  57. *
  58. * Sundown Note:
  59. * __unaligned unsigned long value pointed by lpMenuTemplate is zero-extended to
  60. * update lpmenuText. WOW restrictions.
  61. */
  62. if ((menuFlags & MFT_OWNERDRAW)
  63. && (GetClientInfo()->dwTIFlags & TIF_16BIT)) {
  64. lpmenuText = (LPWSTR)ULongToPtr( (*(DWORD UNALIGNED *)lpMenuTemplate) );
  65. /*
  66. * We'll skip one WCHAR later; so skip only the difference now.
  67. */
  68. lpMenuTemplate += sizeof(DWORD) - sizeof(WCHAR);
  69. } else {
  70. /*
  71. * If a string exists, then skip to the end of it.
  72. */
  73. RtlInitUnicodeString(&str, lpmenuText);
  74. lpMenuTemplate = lpMenuTemplate + str.Length;
  75. }
  76. } else {
  77. lpmenuText = NULL;
  78. }
  79. /*
  80. * Skip over terminating NULL of the string (or the single NULL
  81. * if empty string).
  82. */
  83. lpMenuTemplate += sizeof(WCHAR);
  84. lpMenuTemplate = NextWordBoundary(lpMenuTemplate);
  85. RtlZeroMemory(&mii, sizeof(mii));
  86. mii.cbSize = sizeof(MENUITEMINFO);
  87. mii.fMask = MIIM_ID | MIIM_STATE | MIIM_FTYPE;
  88. if (lpmenuText) {
  89. mii.fMask |= MIIM_STRING;
  90. }
  91. if (menuFlags & MF_POPUP) {
  92. mii.fMask |= MIIM_SUBMENU;
  93. lpMenuTemplate = MenuLoadWinTemplates(lpMenuTemplate,
  94. (HMENU *)&menuId);
  95. if (!lpMenuTemplate)
  96. goto memoryerror;
  97. mii.hSubMenu = (HMENU)menuId;
  98. }
  99. /*
  100. * We have to take out MF_HILITE since that bit marks the end of a
  101. * menu in a resource file. Since we shouldn't have any pre hilited
  102. * items in the menu anyway, this is no big deal.
  103. */
  104. if (menuFlags & MF_BITMAP) {
  105. /*
  106. * Don't allow bitmaps from the resource file.
  107. */
  108. menuFlags = (UINT)((menuFlags | MFT_RIGHTJUSTIFY) & ~MF_BITMAP);
  109. }
  110. // We have to take out MFS_HILITE since that bit marks the end of a menu in
  111. // a resource file. Since we shouldn't have any pre hilited items in the
  112. // menu anyway, this is no big deal.
  113. mii.fState = (menuFlags & MFS_OLDAPI_MASK) & ~MFS_HILITE;
  114. mii.fType = (menuFlags & MFT_OLDAPI_MASK);
  115. if (menuFlags & MFT_OWNERDRAW)
  116. {
  117. mii.fMask |= MIIM_DATA;
  118. mii.dwItemData = (ULONG_PTR) lpmenuText;
  119. lpmenuText = 0;
  120. }
  121. mii.dwTypeData = (LPWSTR) lpmenuText;
  122. mii.cch = (UINT)-1;
  123. mii.wID = (UINT)menuId;
  124. if (!NtUserThunkedMenuItemInfo(hMenu, MFMWFP_NOITEM, TRUE, TRUE,
  125. &mii, lpmenuText ? &str : NULL)) {
  126. if (menuFlags & MF_POPUP)
  127. NtUserDestroyMenu(mii.hSubMenu);
  128. goto memoryerror;
  129. }
  130. } while (!(menuFlags & MF_END));
  131. *phMenu = hMenu;
  132. return lpMenuTemplate;
  133. memoryerror:
  134. if (hMenu != NULL)
  135. NtUserDestroyMenu(hMenu);
  136. *phMenu = NULL;
  137. return NULL;
  138. }
  139. /***************************************************************************\
  140. * MenuLoadChicagoTemplates
  141. *
  142. * Recursive routine that loads in the new new style menu template and
  143. * builds the menu. Assumes that the menu template header has already been
  144. * read in and processed elsewhere...
  145. *
  146. * History:
  147. * 15-Dec-93 SanfordS Created
  148. \***************************************************************************/
  149. PMENUITEMTEMPLATE2 MenuLoadChicagoTemplates(
  150. PMENUITEMTEMPLATE2 lpMenuTemplate,
  151. HMENU *phMenu,
  152. WORD wResInfo,
  153. UINT mftRtl)
  154. {
  155. HMENU hMenu;
  156. HMENU hSubMenu;
  157. long menuId = 0;
  158. LPWSTR lpmenuText;
  159. MENUITEMINFO mii;
  160. UNICODE_STRING str;
  161. DWORD dwHelpID;
  162. if (!(hMenu = NtUserCreateMenu()))
  163. goto memoryerror;
  164. do {
  165. if (!(wResInfo & MFR_POPUP)) {
  166. /*
  167. * If the PREVIOUS wResInfo field was not a POPUP, the
  168. * dwHelpID field is not there. Back up so things fit.
  169. */
  170. lpMenuTemplate = (PMENUITEMTEMPLATE2)(((LPBYTE)lpMenuTemplate) -
  171. sizeof(lpMenuTemplate->dwHelpID));
  172. dwHelpID = 0;
  173. } else
  174. dwHelpID = lpMenuTemplate->dwHelpID;
  175. menuId = lpMenuTemplate->menuId;
  176. RtlZeroMemory(&mii, sizeof(mii));
  177. mii.cbSize = sizeof(MENUITEMINFO);
  178. mii.fMask = MIIM_ID | MIIM_STATE | MIIM_FTYPE ;
  179. mii.fType = lpMenuTemplate->fType | mftRtl;
  180. if (mii.fType & ~MFT_MASK) {
  181. RIPERR1(ERROR_INVALID_DATA, RIP_WARNING, "Menu Type flags %lX are invalid", mii.fType);
  182. goto memoryerror;
  183. }
  184. mii.fState = lpMenuTemplate->fState;
  185. if (mii.fState & ~MFS_MASK) {
  186. RIPERR1(ERROR_INVALID_DATA, RIP_WARNING, "Menu State flags %lX are invalid", mii.fState);
  187. goto memoryerror;
  188. }
  189. wResInfo = lpMenuTemplate->wResInfo;
  190. if (wResInfo & ~(MF_END | MFR_POPUP)) {
  191. RIPERR1(ERROR_INVALID_DATA, RIP_WARNING, "Menu ResInfo flags %lX are invalid", wResInfo);
  192. goto memoryerror;
  193. }
  194. if (dwHelpID) {
  195. NtUserSetMenuContextHelpId(hMenu,dwHelpID);
  196. }
  197. if (lpMenuTemplate->mtString[0]) {
  198. lpmenuText = lpMenuTemplate->mtString;
  199. mii.fMask |= MIIM_STRING;
  200. } else {
  201. lpmenuText = NULL;
  202. }
  203. RtlInitUnicodeString(&str, lpmenuText);
  204. mii.dwTypeData = (LPWSTR) lpmenuText;
  205. /*
  206. * skip to next menu item template (DWORD boundary)
  207. */
  208. lpMenuTemplate = (PMENUITEMTEMPLATE2)
  209. (((LPBYTE)lpMenuTemplate) +
  210. sizeof(MENUITEMTEMPLATE2) +
  211. ((str.Length + 3) & ~3));
  212. if (mii.fType & MFT_OWNERDRAW)
  213. {
  214. mii.fMask |= MIIM_DATA;
  215. mii.dwItemData = (ULONG_PTR) mii.dwTypeData;
  216. mii.dwTypeData = 0;
  217. }
  218. /*
  219. * If MFT_RIGHTORDER is specified then all subsequent
  220. * menus are right-to-left as well.
  221. */
  222. if (mii.fType & MFT_RIGHTORDER)
  223. {
  224. mftRtl = MFT_RIGHTORDER;
  225. NtUserSetMenuFlagRtoL(hMenu);
  226. }
  227. if (wResInfo & MFR_POPUP) {
  228. mii.fMask |= MIIM_SUBMENU;
  229. lpMenuTemplate = MenuLoadChicagoTemplates(lpMenuTemplate,
  230. &hSubMenu, MFR_POPUP, mftRtl);
  231. if (lpMenuTemplate == NULL)
  232. goto memoryerror;
  233. mii.hSubMenu = hSubMenu;
  234. }
  235. if (mii.fType & MFT_BITMAP) {
  236. /*
  237. * Don't allow bitmaps from the resource file.
  238. */
  239. mii.fType = (mii.fType | MFT_RIGHTJUSTIFY) & ~MFT_BITMAP;
  240. }
  241. mii.cch = (UINT)-1;
  242. mii.wID = menuId;
  243. if (!NtUserThunkedMenuItemInfo(hMenu, MFMWFP_NOITEM, TRUE, TRUE,
  244. &mii, &str)) {
  245. if (wResInfo & MFR_POPUP)
  246. NtUserDestroyMenu(mii.hSubMenu);
  247. goto memoryerror;
  248. }
  249. wResInfo &= ~MFR_POPUP;
  250. } while (!(wResInfo & MFR_END));
  251. *phMenu = hMenu;
  252. return lpMenuTemplate;
  253. memoryerror:
  254. if (hMenu != NULL)
  255. NtUserDestroyMenu(hMenu);
  256. *phMenu = NULL;
  257. return NULL;
  258. }
  259. /***************************************************************************\
  260. * CreateMenuFromResource
  261. *
  262. * Loads the menu resource named by the lpMenuTemplate parameter. The
  263. * template specified by lpMenuTemplate is a collection of one or more
  264. * MENUITEMTEMPLATE structures, each of which may contain one or more items
  265. * and popup menus. If successful, returns a handle to the menu otherwise
  266. * returns NULL.
  267. *
  268. * History:
  269. * 28-Sep-1990 mikeke from win30
  270. \***************************************************************************/
  271. HMENU CreateMenuFromResource(
  272. LPBYTE lpMenuTemplate)
  273. {
  274. HMENU hMenu = NULL;
  275. UINT menuTemplateVersion;
  276. UINT menuTemplateHeaderSize;
  277. /*
  278. * Win3 menu resource: First, strip version number word out of the menu
  279. * template. This value should be 0 for Win3, 1 for win4.
  280. */
  281. menuTemplateVersion = *((WORD *)lpMenuTemplate)++;
  282. if (menuTemplateVersion > 1) {
  283. RIPMSG0(RIP_WARNING, "Menu Version number > 1");
  284. return NULL;
  285. }
  286. menuTemplateHeaderSize = *((WORD *)lpMenuTemplate)++;
  287. lpMenuTemplate += menuTemplateHeaderSize;
  288. switch (menuTemplateVersion) {
  289. case 0:
  290. MenuLoadWinTemplates(lpMenuTemplate, &hMenu);
  291. break;
  292. case 1:
  293. MenuLoadChicagoTemplates((PMENUITEMTEMPLATE2)lpMenuTemplate, &hMenu, 0, 0);
  294. break;
  295. }
  296. return hMenu;
  297. }
  298. /***************************************************************************\
  299. * SetMenu (API)
  300. *
  301. * Sets the menu for the hwnd.
  302. *
  303. * History:
  304. * 10-Mar-1996 ChrisWil Created.
  305. \***************************************************************************/
  306. FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetMenu, HWND, hwnd, HMENU, hmenu)
  307. BOOL SetMenu(
  308. HWND hwnd,
  309. HMENU hmenu)
  310. {
  311. return NtUserSetMenu(hwnd, hmenu, TRUE);
  312. }
  313. /***************************************************************************\
  314. * LoadMenu (API)
  315. *
  316. * Loads the menu resource named by lpMenuName from the executable
  317. * file associated by the module specified by the hInstance parameter. The
  318. * menu is loaded only if it hasn't been previously loaded. Otherwise it
  319. * retrieves a handle to the loaded resource. Returns NULL if unsuccessful.
  320. *
  321. * History:
  322. * 04-05-91 ScottLu Fixed to work with client/server.
  323. * 28-Sep-1990 mikeke from win30
  324. \***************************************************************************/
  325. HMENU CommonLoadMenu(
  326. HINSTANCE hmod,
  327. HANDLE hResInfo
  328. )
  329. {
  330. HANDLE h;
  331. PVOID p;
  332. HMENU hMenu = NULL;
  333. if (h = LOADRESOURCE(hmod, hResInfo)) {
  334. if (p = LOCKRESOURCE(h, hmod)) {
  335. hMenu = CreateMenuFromResource(p);
  336. UNLOCKRESOURCE(h, hmod);
  337. }
  338. /*
  339. * Win95 and Win3.1 do not free this resource; some 16 bit apps (chessmaster
  340. * and mavis typing) require this for their ownerdraw menu stuff.
  341. * For 32 bit apps, FreeResource is a nop anyway. For 16 bit apps,
  342. * Wow frees the 32 bit resource (returned by LockResource16)
  343. * in UnlockResource16; the actual 16 bit resource is freed when the task
  344. * goes away.
  345. *
  346. * FREERESOURCE(h, hmod);
  347. */
  348. }
  349. return (hMenu);
  350. }
  351. FUNCLOG2(LOG_GENERAL, HMENU, WINAPI, LoadMenuA, HINSTANCE, hmod, LPCSTR, lpName)
  352. HMENU WINAPI LoadMenuA(
  353. HINSTANCE hmod,
  354. LPCSTR lpName)
  355. {
  356. HANDLE hRes;
  357. if (hRes = FINDRESOURCEA(hmod, (LPSTR)lpName, (LPSTR)RT_MENU))
  358. return CommonLoadMenu(hmod, hRes);
  359. else
  360. return NULL;
  361. }
  362. FUNCLOG2(LOG_GENERAL, HMENU, WINAPI, LoadMenuW, HINSTANCE, hmod, LPCWSTR, lpName)
  363. HMENU WINAPI LoadMenuW(
  364. HINSTANCE hmod,
  365. LPCWSTR lpName)
  366. {
  367. HANDLE hRes;
  368. if (hRes = FINDRESOURCEW(hmod, (LPWSTR)lpName, RT_MENU))
  369. return CommonLoadMenu(hmod, hRes);
  370. else
  371. return NULL;
  372. }
  373. /***************************************************************************\
  374. * InternalInsertMenuItem
  375. *
  376. * History:
  377. * 09/20/96 GerardoB - Created
  378. \***************************************************************************/
  379. BOOL InternalInsertMenuItem (HMENU hMenu, UINT uID, BOOL fByPosition, LPCMENUITEMINFO lpmii)
  380. {
  381. return ThunkedMenuItemInfo(hMenu, uID, fByPosition, TRUE, (LPMENUITEMINFOW)lpmii, FALSE);
  382. }
  383. /***************************************************************************\
  384. * ValidateMENUITEMINFO() -
  385. * it converts and validates a MENUITEMINFO95 or a new-MENUITEMINFO-with-old-flags
  386. * to a new MENUITEMINFO -- this way all internal code can assume one look for the
  387. * structure
  388. *
  389. * History:
  390. * 12-08-95 Ported from Nashville - jjk
  391. * 07-19-96 GerardoB - Fixed up for 5.0
  392. \***************************************************************************/
  393. BOOL ValidateMENUITEMINFO(LPMENUITEMINFO lpmiiIn, LPMENUITEMINFO lpmii, DWORD dwAPICode)
  394. {
  395. BOOL fOldApp;
  396. if (lpmiiIn == NULL) {
  397. VALIDATIONFAIL(lpmiiIn);
  398. }
  399. /*
  400. * In order to map the old flags to the new ones, we might have to modify
  401. * the lpmiiIn structure. So we make a copy to avoid breaking anyone.
  402. */
  403. fOldApp = (lpmiiIn->cbSize == SIZEOFMENUITEMINFO95);
  404. UserAssert(SIZEOFMENUITEMINFO95 < sizeof(MENUITEMINFO));
  405. RtlCopyMemory(lpmii, lpmiiIn, SIZEOFMENUITEMINFO95);
  406. if (fOldApp) {
  407. lpmii->cbSize = sizeof(MENUITEMINFO);
  408. lpmii->hbmpItem = NULL;
  409. } else if (lpmiiIn->cbSize == sizeof(MENUITEMINFO)) {
  410. lpmii->hbmpItem = lpmiiIn->hbmpItem;
  411. } else {
  412. VALIDATIONFAIL(lpmiiIn->cbSize);
  413. }
  414. if (lpmii->fMask & ~MIIM_MASK) {
  415. VALIDATIONFAIL(lpmii->fMask);
  416. } else if ((lpmii->fMask & MIIM_TYPE)
  417. && (lpmii->fMask & (MIIM_FTYPE | MIIM_STRING | MIIM_BITMAP))) {
  418. /*
  419. * Don't let them mix new and old flags
  420. */
  421. VALIDATIONFAIL(lpmii->fMask);
  422. }
  423. /*
  424. * No more validation needed for Get calls
  425. */
  426. if (dwAPICode == MENUAPI_GET) {
  427. /*
  428. * Map MIIM_TYPE for old apps doing a Get.
  429. * Keep the MIIM_TYPE flag so we'll know this guy passed the old flags.
  430. * GetMenuItemInfo uses lpmii->hbmpItem to determine if a bitmap
  431. * was returned. So we NULL it out here. The caller is using the
  432. * old flags so he shouldn't care about it.
  433. */
  434. if (lpmii->fMask & MIIM_TYPE) {
  435. lpmii->fMask |= MIIM_FTYPE | MIIM_BITMAP | MIIM_STRING;
  436. lpmii->hbmpItem = NULL;
  437. }
  438. return TRUE;
  439. }
  440. /*
  441. * Map MIIM_TYPE to MIIM_FTYPE
  442. */
  443. if (lpmii->fMask & MIIM_TYPE) {
  444. lpmii->fMask |= MIIM_FTYPE;
  445. }
  446. if (lpmii->fMask & MIIM_FTYPE) {
  447. if (lpmii->fType & ~MFT_MASK) {
  448. VALIDATIONFAIL(lpmii->fType);
  449. }
  450. /*
  451. * If using MIIM_TYPE, Map MFT_BITMAP to MIIM_BITMAP
  452. * and MFT_NONSTRING to MIIM_STRING.
  453. * Old applications couldn't use string and bitmap simultaneously
  454. * so setting one implies clearing the other.
  455. */
  456. if (lpmii->fMask & MIIM_TYPE) {
  457. if (lpmii->fType & MFT_BITMAP) {
  458. /*
  459. * Don't display a warning. A lot of shell menus hit this
  460. * if (!fOldApp) {
  461. * VALIDATIONOBSOLETE(MFT_BITMAP, MIIM_BITMAP);
  462. * }
  463. */
  464. lpmii->fMask |= MIIM_BITMAP | MIIM_STRING;
  465. lpmii->hbmpItem = (HBITMAP)lpmii->dwTypeData;
  466. lpmii->dwTypeData = 0;
  467. } else if (!(lpmii->fType & MFT_NONSTRING)) {
  468. /*
  469. * Don't display a warning. A lot of shell menus hit this
  470. * if (!fOldApp) {
  471. * VALIDATIONOBSOLETE(MFT_STRING, MIIM_STRING);
  472. * }
  473. */
  474. lpmii->fMask |= MIIM_BITMAP | MIIM_STRING;
  475. lpmii->hbmpItem = NULL;
  476. }
  477. } else if (lpmii->fType & MFT_BITMAP) {
  478. /*
  479. * Don't let them mix new and old flags
  480. */
  481. VALIDATIONFAIL(lpmii->fType);
  482. }
  483. }
  484. if ((lpmii->fMask & MIIM_STATE) && (lpmii->fState & ~MFS_MASK)){
  485. VALIDATIONFAIL(lpmii->fState);
  486. }
  487. if (lpmii->fMask & MIIM_CHECKMARKS) {
  488. if ((lpmii->hbmpChecked != NULL) && !GdiValidateHandle((HBITMAP)lpmii->hbmpChecked)) {
  489. VALIDATIONFAIL(lpmii->hbmpChecked);
  490. }
  491. if ((lpmii->hbmpUnchecked != NULL) && !GdiValidateHandle((HBITMAP)lpmii->hbmpUnchecked)) {
  492. VALIDATIONFAIL(lpmii->hbmpUnchecked);
  493. }
  494. }
  495. if (lpmii->fMask & MIIM_SUBMENU) {
  496. if ((lpmii->hSubMenu != NULL) && !VALIDATEHMENU(lpmii->hSubMenu)) {
  497. VALIDATIONFAIL(lpmii->hSubMenu);
  498. }
  499. }
  500. /*
  501. * Warning: NULL lpmii->hbmpItem accepted as valid (or the explorer breaks)
  502. */
  503. if (lpmii->fMask & MIIM_BITMAP) {
  504. if ((lpmii->hbmpItem != HBMMENU_CALLBACK)
  505. && (lpmii->hbmpItem >= HBMMENU_MAX)
  506. && !GdiValidateHandle(lpmii->hbmpItem)) {
  507. /*
  508. * Compatibility hack
  509. */
  510. if (((HBITMAP)LOWORD(HandleToUlong(lpmii->hbmpItem)) >= HBMMENU_MAX) || !IS_PTR(lpmii->hbmpItem)) {
  511. VALIDATIONFAIL(lpmii->hbmpItem);
  512. }
  513. }
  514. }
  515. /*
  516. * Warning: No dwTypeData / cch validation
  517. */
  518. return TRUE;
  519. VALIDATIONERROR(FALSE);
  520. }
  521. /***************************************************************************\
  522. * ValidateMENUINFO() -
  523. *
  524. * History:
  525. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  526. \***************************************************************************/
  527. BOOL ValidateMENUINFO(LPCMENUINFO lpmi, DWORD dwAPICode)
  528. {
  529. if (lpmi == NULL) {
  530. VALIDATIONFAIL(lpmi);
  531. }
  532. if (lpmi->cbSize != sizeof(MENUINFO)) {
  533. VALIDATIONFAIL(lpmi->cbSize);
  534. }
  535. if (lpmi->fMask & ~MIM_MASK) {
  536. VALIDATIONFAIL(lpmi->fMask);
  537. }
  538. /*
  539. * No more validation needed for Get calls
  540. */
  541. if (dwAPICode == MENUAPI_GET){
  542. return TRUE;
  543. }
  544. if ((lpmi->fMask & MIM_STYLE) && (lpmi->dwStyle & ~MNS_VALID)) {
  545. VALIDATIONFAIL(lpmi->dwStyle);
  546. }
  547. if (lpmi->fMask & MIM_BACKGROUND) {
  548. if ((lpmi->hbrBack != NULL)
  549. && !GdiValidateHandle((HBRUSH)lpmi->hbrBack)) {
  550. VALIDATIONFAIL(lpmi->hbrBack);
  551. }
  552. }
  553. return TRUE;
  554. VALIDATIONERROR(FALSE);
  555. }
  556. /***************************************************************************\
  557. * GetMenuInfo
  558. *
  559. * History:
  560. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  561. \***************************************************************************/
  562. FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetMenuInfo, HMENU, hMenu, LPMENUINFO, lpmi)
  563. BOOL GetMenuInfo(HMENU hMenu, LPMENUINFO lpmi)
  564. {
  565. PMENU pMenu;
  566. if (!ValidateMENUINFO(lpmi, MENUAPI_GET)) {
  567. return FALSE;
  568. }
  569. pMenu = VALIDATEHMENU(hMenu);
  570. if (pMenu == NULL) {
  571. return FALSE;
  572. }
  573. if (lpmi->fMask & MIM_STYLE) {
  574. lpmi->dwStyle = pMenu->fFlags & MNS_VALID;
  575. }
  576. if (lpmi->fMask & MIM_MAXHEIGHT) {
  577. lpmi->cyMax = pMenu->cyMax;
  578. }
  579. if (lpmi->fMask & MIM_BACKGROUND) {
  580. lpmi->hbrBack = KHBRUSH_TO_HBRUSH(pMenu->hbrBack);
  581. }
  582. if (lpmi->fMask & MIM_HELPID) {
  583. lpmi->dwContextHelpID = pMenu->dwContextHelpId;
  584. }
  585. if (lpmi->fMask & MIM_MENUDATA) {
  586. lpmi->dwMenuData = KERNEL_ULONG_PTR_TO_ULONG_PTR(pMenu->dwMenuData);
  587. }
  588. return TRUE;
  589. }