Source code of Windows XP (NT5)
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.

1636 lines
51 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WUMENU.C
  8. * WOW32 16-bit User API support
  9. *
  10. * History:
  11. * Created 07-Mar-1991 by Jeff Parsons (jeffpar)
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. MODNAME(wumenu.c);
  16. /*++
  17. BOOL AppendMenu(<hMenu>, <wFlags>, <wIDNewItem>, <lpNewItem>)
  18. HMENU <hMenu>;
  19. WORD <wFlags>;
  20. WORD <wIDNewItem>;
  21. LPSTR <lpNewItem>;
  22. The %AppendMenu% function appends a new item to the end of a menu. The
  23. application can specify the state of the menu item by setting values in the
  24. <wFlags> parameter.
  25. <hMenu>
  26. Identifies the menu to be changed.
  27. <wFlags>
  28. Specifies information about the state of the new menu item when
  29. it is added to the menu. It consists of one or more values listed in the
  30. following Comments section.
  31. <wIDNewItem>
  32. Specifies either the command ID of the new menu item or, if
  33. <wFlags> is set to MF_POPUP, the menu handle of the pop-up menu.
  34. <lpNewItem>
  35. Specifies the content of the new menu item. The interpretation
  36. of the <lpNewItem> parameter depends upon the setting of the <wFlags>
  37. parameter.
  38. MF_STRING
  39. Contains a long pointer to a null-terminated string.
  40. MF_BITMAP
  41. Contains a bitmap handle in its low-order word.
  42. MF_OWNERDRAW
  43. Contains an application-supplied 32-bit value which the application can
  44. use to maintain additional data associated with the menu item. This
  45. 32-bit value is available to the application in the %itemData% member of
  46. the structure pointed to by the <lParam> parameter of the WM_MEASUREITEM
  47. and WM_DRAWITEM messages sent when the menu item is initially displayed
  48. or is changed.
  49. The return value specifies the outcome of the function. It is TRUE if the
  50. function is successful. Otherwise, it is FALSE.
  51. Whenever a menu changes (whether or not the menu resides in a window that is
  52. displayed), the application should call %DrawMenuBar%.
  53. Each of the following groups list flags that are mutually exclusive and
  54. cannot be used together:
  55. o MF_BYCOMMAND and MF_BYPOSITION
  56. o MF_DISABLED, MF_ENABLED, and MF_GRAYED
  57. o MF_BITMAP, MF_STRING, and MF_OWNERDRAW
  58. o MF_MENUBARBREAK and MF_MENUBREAK
  59. o MF_CHECKED and MF_UNCHECKED
  60. .cmt
  61. 16-Sep-1990 [ralphw]
  62. Some of the above flags aren't documented as valid values for the wFlags
  63. parameter. If they are valid, they should be documented, otherwise, they
  64. should be removed from the list.
  65. .endcmt
  66. The following list describes the flags which may be set in the <wFlags>
  67. parameter:
  68. MF_BITMAP
  69. Uses a bitmap as the item. The low-order word of the lpNewItem parameter
  70. contains the handle of the bitmap.
  71. MF_CHECKED
  72. Places a checkmark next to the item. If the application has supplied
  73. checkmark bitmaps (see %SetMenuItemBitmaps%), setting this flag displays
  74. the checkmark on bitmap next to the menu item.
  75. MF_DISABLED
  76. Disables the menu item so that it cannot be selected, but does not gray
  77. it.
  78. MF_ENABLED
  79. Enables the menu item so that it can be selected and restores it from
  80. its grayed state.
  81. MF_GRAYED
  82. Disables the menu item so that it cannot be selected and grays it.
  83. MF_MENUBARBREAK
  84. Same as MF_MENUBREAK except that for pop-up menus, separates the new
  85. column from the old column with a vertical line.
  86. MF_MENUBREAK
  87. Places the item on a new line for static menu-bar items. For pop-up
  88. menus, places the item in a new column, with no dividing line between
  89. the columns.
  90. MF_OWNERDRAW
  91. Specifies that the item is an owner-draw item. The window that owns the
  92. menu receives a WM_MEASUREITEM message when the menu is displayed for
  93. the first time to retrieve the height and width of the menu item. The
  94. WM_DRAWITEM message is then sent whenever the owner must update the
  95. visual appearance of the menu item. This option is not valid for a
  96. top-level menu item.
  97. MF_POPUP
  98. Specifies that the menu item has a pop-up menu associated with it. The
  99. <wIDNewItem> parameter specifies a handle to a pop-up menu to be
  100. associated with the item. This is used for adding either a top-level
  101. pop-up menu or adding a hierarchical pop-up menu to a pop-up menu item.
  102. MF_SEPARATOR
  103. Draws a horizontal dividing line. Can only be used in a pop-up menu.
  104. This line cannot be grayed, disabled, or highlighted. The <lpNewItem>
  105. and <wIDNewItem> parameters are ignored.
  106. MF_STRING
  107. Specifies that the menu item is a character string; the <lpNewItem>
  108. parameter points to the string for the menu item.
  109. MF_UNCHECKED
  110. Does not place a checkmark next to the item (default). If the
  111. application has supplied checkmark bitmaps (see %SetMenuItemBitmaps%),
  112. setting this flag displays the checkmark off bitmap next to the menu
  113. item.
  114. --*/
  115. ULONG FASTCALL WU32AppendMenu(PVDMFRAME pFrame)
  116. {
  117. ULONG ul;
  118. PSZ psz4;
  119. register PAPPENDMENU16 parg16;
  120. UINT wIDNewItem;
  121. GETARGPTR(pFrame, sizeof(APPENDMENU16), parg16);
  122. // USER has some internal bitmap identifiers for menu item bitmaps so
  123. // it doesn't have to store multiple copies of these bitmaps when they
  124. // appear in multiple menus. WinProj does its own MDI and uses these
  125. // bitmaps.
  126. // #define MENUHBM_CHILDCLOSE (UINT)1
  127. // #define MENUHBM_RESTORE (UINT)2
  128. // #define MENUHBM_MINIMIZE (UINT)3
  129. // #define MENUHBM_MAX (UINT)4
  130. if (parg16->f2 & MF_BITMAP) {
  131. if (LOW(parg16->f4) >= 4)
  132. psz4 = (PSZ)HBITMAP32(LOW(parg16->f4));
  133. else
  134. psz4 = (PSZ)WORD32(parg16->f4);
  135. }
  136. else if (parg16->f2 & MF_OWNERDRAW)
  137. psz4 = (PSZ)DWORD32(parg16->f4);
  138. else
  139. GETPSZPTR(parg16->f4, psz4);
  140. wIDNewItem = (UINT) WORD32(parg16->f3);
  141. if (parg16->f2 & MF_POPUP)
  142. wIDNewItem = (UINT) HMENU32(parg16->f3);
  143. ul = GETBOOL16(AppendMenu(HMENU32(parg16->f1),
  144. WORD32(parg16->f2),
  145. wIDNewItem,
  146. psz4));
  147. #ifdef FE_SB
  148. // For AutherWare Star ( APP BUG ) MAKKBUG:3203
  149. if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_ASWHELPER) { if (parg16->f2 & MF_POPUP) {
  150. HWND hWnd;
  151. if (!(hWnd=GetActiveWindow())) {
  152. hWnd = GetForegroundWindow();
  153. }
  154. SetMenu(hWnd , HMENU32(parg16->f1));
  155. }
  156. }
  157. #endif // FE_SB
  158. FREEPSZPTR(psz4);
  159. FREEARGPTR(parg16);
  160. RETURN(ul);
  161. }
  162. /*++
  163. BOOL ChangeMenu(<hMenu>,<wIDChangeItem>,<lpNewItem>,<wIDNewItem>,<wFlags>)
  164. HMENU <hMenu>;
  165. WORD <wIDChangeItem>;
  166. LPSTR <lpNewItem>;
  167. WORD <wIDNewItem>;
  168. WORD <wFlags>;
  169. The %ChangeMenu% function appends, inserts, deletes, or modifies a menu
  170. item in the menu given by the <hMenu> parameter. The <wIDChangeItem>,
  171. <lpNewItem>, <wIDNewItem> and <wFlags> parameters define which item to
  172. change and how to change it.
  173. <hMenu>
  174. Identifies the menu to be changed.
  175. <wIDChangeItem>
  176. Specifies the item to be changed. If MF_BYPOSITION is specified,
  177. <wIDChangeItem> gives the position of the menu item to be
  178. changed (the first item is at position zero). If MF_BYCOMMAND is
  179. specified instead, <wIDChangeItem> specifies the menu-item ID.
  180. The menu-item ID can specify any popup-menu item (that is, an item
  181. in a popup menu associated with an item of <hMenu>). If neither
  182. flag is given, the default is MF_BYCOMMAND. When MF_INSERT is used,
  183. <wIDChangeItem> identifies the item before which the new item is to
  184. be inserted. When MF_APPEND is used, <wIDChangeItem> is NULL.
  185. <lpNewItem>
  186. Specifies the content of the new menu item. The interpretation
  187. of the <lpNewItem> parameter depends upon the setting of the <wFlags>
  188. parameter. The <lpNewItem> parameter is never a handle to a menu.
  189. The MF_POPUP flag applies to the <wIDNewItem> parameter only.
  190. MF_BITMAP
  191. <lpNewItem> contains a bitmap handle in its low-order word.
  192. MF_STRING
  193. <lpNewItem> contains a long pointer to a null-terminated string.
  194. The default is MF_STRING. A NULL value for <lpNewItem> creates a
  195. horizontal break (the same effect as using the MF_SEPARATOR flag).
  196. Note that MF_OWNERDRAW is not allowed on ChangeMenu; it conflicts with
  197. the ChangeMenu command bit MF_APPEND.
  198. <wIDNewItem>
  199. Specifies either the command ID of the new menu item or, if
  200. <wFlags> is set to MF_POPUP, the menu handle of the pop-up menu.
  201. It is never a menu-item position.
  202. <wFlags>
  203. Specifies information about the state of the new menu item when it
  204. is added to the menu. It consists of one or more values listed in
  205. the following Comments section.
  206. The return value specifies the outcome of the function. It is TRUE if the
  207. function is successful. Otherwise, it is FALSE.
  208. Whenever a menu changes (whether or not the menu resides in a window that is
  209. displayed), the application should call %DrawMenuBar%.
  210. Each of the following groups list flags that are mutually exclusive and
  211. cannot be used together:
  212. o MF_APPEND, MF_CHANGE, MF_DELETE, MF_INSERT and MF_REMOVE
  213. o MF_BYCOMMAND and MF_BYPOSITION
  214. o MF_DISABLED, MF_ENABLED, and MF_GRAYED
  215. o MF_BITMAP, MF_POPUP and MF_STRING
  216. o MF_MENUBARBREAK and MF_MENUBREAK
  217. o MF_CHECKED and MF_UNCHECKED
  218. .cmt
  219. 16-Sep-1990 [ralphw]
  220. Some of the above flags aren't documented as valid values for the wFlags
  221. parameter. If they are valid, they should be documented, otherwise, they
  222. should be removed from the list.
  223. .endcmt
  224. The following list describes the flags which may be set in the <wFlags>
  225. parameter:
  226. MF_APPEND
  227. Appends the new item to the end of the menu.
  228. MF_BITMAP
  229. Uses a bitmap as the item. The low-order word of the lpNewItem parameter
  230. contains the handle of the bitmap.
  231. MF_BYCOMMAND
  232. Specifies that the <wIDChangeItem> parameter gives the menu-item ID
  233. number (default).
  234. MF_BYPOSITION
  235. Specifies that the <wIDChangeItem> parameter gives the position of
  236. the menu item to be changed.
  237. MF_CHANGE
  238. Changes or replaces the specified item.
  239. MF_CHECKED
  240. Places a checkmark next to the item. If the application has supplied
  241. checkmark bitmaps (see %SetMenuItemBitmaps%), setting this flag displays
  242. the checkmark on bitmap next to the menu item.
  243. MF_DELETE
  244. Deletes the item.
  245. MF_DISABLED
  246. Disables the menu item so that it cannot be selected, but does not gray
  247. it.
  248. MF_ENABLED
  249. Enables the menu item so that it can be selected and restores it from
  250. its grayed state.
  251. MF_GRAYED
  252. Disables the menu item so that it cannot be selected and grays it.
  253. MF_INSERT
  254. Inserts a new item, just before the specified item.
  255. MF_MENUBARBREAK
  256. Same as MF_MENUBREAK except that for pop-up menus, separates the new
  257. column from the old column with a vertical line.
  258. MF_MENUBREAK
  259. Places the item on a new line for static menu-bar items. For pop-up
  260. menus, places the item in a new column, with no dividing line between
  261. the columns.
  262. MF_POPUP
  263. Specifies that the menu item has a pop-up menu associated with it. The
  264. <wIDNewItem> parameter specifies a handle to a pop-up menu to be
  265. associated with the item. This is used for adding either a top-level
  266. pop-up menu or adding a hierarchical pop-up menu to a pop-up menu item.
  267. MF_REMOVE
  268. Removes the item but does not delete it.
  269. MF_SEPARATOR
  270. Draws a horizontal dividing line. Can only be used in a pop-up menu.
  271. This line cannot be grayed, disabled, or highlighted. The <lpNewItem>
  272. and <wIDNewItem> parameters are ignored.
  273. MF_STRING
  274. Specifies that the menu item is a character string; the <lpNewItem>
  275. parameter points to the string for the menu item.
  276. MF_UNCHECKED
  277. Does not place a checkmark next to the item (default). If the
  278. application has supplied checkmark bitmaps (see %SetMenuItemBitmaps%),
  279. setting this flag displays the checkmark off bitmap next to the menu
  280. item.
  281. --*/
  282. ULONG FASTCALL WU32ChangeMenu(PVDMFRAME pFrame)
  283. {
  284. ULONG ul;
  285. PSZ psz3;
  286. DWORD dw4;
  287. register PCHANGEMENU16 parg16;
  288. GETARGPTR(pFrame, sizeof(CHANGEMENU16), parg16);
  289. if (parg16->f5 & MF_BITMAP) {
  290. if (LOW(parg16->f3) >= 4)
  291. psz3 = (PSZ)HBITMAP32(LOW(parg16->f3));
  292. else
  293. psz3 = (PSZ)WORD32(parg16->f3);
  294. }
  295. else
  296. GETPSZPTR(parg16->f3, psz3);
  297. dw4 = WORD32(parg16->f4);
  298. if (WORD32(parg16->f5) & MF_POPUP)
  299. dw4 = (DWORD)HMENU32(parg16->f4);
  300. ul = GETBOOL16(ChangeMenu(
  301. HMENU32(parg16->f1),
  302. WORD32(parg16->f2),
  303. psz3,
  304. dw4,
  305. WORD32(parg16->f5)
  306. ));
  307. FREEPSZPTR(psz3);
  308. FREEARGPTR(parg16);
  309. RETURN(ul);
  310. }
  311. /*++
  312. BOOL CheckMenuItem(<hMenu>, <wIDCheckItem>, <wCheck>)
  313. HMENU <hMenu>;
  314. WORD <wIDCheckItem>;
  315. WORD <wCheck>;
  316. The %CheckMenuItem% function places checkmarks next to or removes checkmarks
  317. from menu items in the pop-up menu specified by the <hMenu> parameter. The
  318. <wIDCheckItem> parameter specifies the item to be modified.
  319. <hMenu>
  320. Identifies the menu.
  321. <wIDCheckItem>
  322. Specifies the menu item to be checked.
  323. <wCheck>
  324. Specifies how to check the menu item and how to determine the item's
  325. position in the menu. The <wCheck> parameter can be a combination of the
  326. MF_CHECKED or MF_UNCHECKED with MF_BYPOSITION or MF_BYCOMMAND flags.
  327. These flags can be combined by using the bitwise OR operator. They have
  328. the following meanings:
  329. MF_BYCOMMAND
  330. Specifies that the <wIDCheckItem> parameter gives the menu-item ID
  331. (MF_BYCOMMAND is the default).
  332. MF_BYPOSITION
  333. Specifies that the <wIDCheckItem > parameter gives the position of the
  334. menu item (the first item is at position zero).
  335. MF_CHECKED
  336. Adds checkmark.
  337. MF_UNCHECKED
  338. Removes checkmark.
  339. The return value specifies the previous state of the item. It is either
  340. MF_CHECKED or MF_UNCHECKED. The return value is -1 if the menu item does not
  341. exist.
  342. The <wIDCheckItem> parameter may identify a pop-up menu item as well as a
  343. menu item. No special steps are required to check a pop-up menu item.
  344. Top-level menu items cannot be checked.
  345. A pop-up menu item should be checked by position since it does not have a
  346. menu-item identifier associated with it.
  347. --*/
  348. ULONG FASTCALL WU32CheckMenuItem(PVDMFRAME pFrame)
  349. {
  350. ULONG ul;
  351. register PCHECKMENUITEM16 parg16;
  352. GETARGPTR(pFrame, sizeof(CHECKMENUITEM16), parg16);
  353. ul = GETBOOL16(CheckMenuItem(
  354. HMENU32(parg16->f1),
  355. WORD32(parg16->f2),
  356. WORD32(parg16->f3)
  357. ));
  358. FREEARGPTR(parg16);
  359. RETURN(ul);
  360. }
  361. /*++
  362. HMENU CreateMenu(VOID)
  363. The %CreateMenu% function creates a menu. The menu is initially empty, but
  364. can be filled with menu items by using the %AppendMenu% or %InsertMenu%
  365. function.
  366. This function has no parameters.
  367. The return value identifies the newly created menu. It is NULL if the menu
  368. cannot be created.
  369. --*/
  370. ULONG FASTCALL WU32CreateMenu(PVDMFRAME pFrame)
  371. {
  372. ULONG ul;
  373. UNREFERENCED_PARAMETER(pFrame);
  374. ul = GETHMENU16(CreateMenu());
  375. RETURN(ul);
  376. }
  377. /*++
  378. HMENU CreatePopupMenu(VOID)
  379. The %CreatePopupMenu% function creates and returns a handle to an empty
  380. pop-up menu.
  381. An application adds items to the pop-up menu by calling %InsertMenu% and
  382. %AppendMenu%. The application can add the pop-up menu to an existing menu or
  383. pop-up menu, or it may display and track selections on the pop-up menu by
  384. calling %TrackPopupMenu%.
  385. This function has no parameters.
  386. The return value identifies the newly created menu. It is NULL if the menu
  387. cannot be created.
  388. --*/
  389. ULONG FASTCALL WU32CreatePopupMenu(PVDMFRAME pFrame)
  390. {
  391. ULONG ul;
  392. UNREFERENCED_PARAMETER(pFrame);
  393. ul = GETHMENU16(CreatePopupMenu());
  394. RETURN(ul);
  395. }
  396. /*++
  397. BOOL DeleteMenu(<hMenu>, <nPosition>, <wFlags>)
  398. HMENU <hMenu>;
  399. WORD <nPosition>;
  400. WORD <wFlags>;
  401. The %DeleteMenu% function deletes an item from the menu identified by the
  402. <hMenu> parameter; if the menu item has an associated pop-up menu,
  403. %DeleteMenu% destroys the handle by the pop-up menu and frees the memory
  404. used by the pop-up menu.
  405. <hMenu>
  406. Identifies the menu to be changed.
  407. <nPosition>
  408. Specifies the menu item which is to be deleted, as determined by the
  409. <wFlags> parameter:
  410. MF_BYPOSITION
  411. Specifies the position of the menu item; the first item in the menu is
  412. at position 0.
  413. MF_BYCOMMAND
  414. Specifies the command ID of the existing menu item.
  415. <wFlags>
  416. Specifies how the <nPosition> parameter is interpreted. It may be
  417. set to either MF_BYCOMMAND or MF_BYPOSITION.
  418. The return value specifies the outcome of the function. It is TRUE if the
  419. function is successful. Otherwise, it is FALSE.
  420. Whenever a menu changes (whether or not the menu resides in a window that is
  421. displayed), the application should call %DrawMenuBar%.
  422. --*/
  423. ULONG FASTCALL WU32DeleteMenu(PVDMFRAME pFrame)
  424. {
  425. ULONG ul;
  426. register PDELETEMENU16 parg16;
  427. PSZ pszModName;
  428. GETARGPTR(pFrame, sizeof(DELETEMENU16), parg16);
  429. // Nasty Hack to fix MSVC 1.5, they remove the close item
  430. // from their system menu, so we prevent them from doing
  431. // this and act like nothing happened ( ie return TRUE ).
  432. // From Win 95, Bug#8154, [t-arthb]
  433. if ((parg16->f2 == 6) && (parg16->f3 & MF_BYPOSITION)) {
  434. pszModName = ((PTDB)SEGPTR(CURRENTPTD()->htask16,0))->TDB_ModName;
  435. if (!WOW32_strncmp(pszModName, "MSVC", 4)) {
  436. FREEARGPTR(parg16);
  437. RETURN(GETBOOL16(TRUE));
  438. }
  439. }
  440. ul = GETBOOL16(DeleteMenu(HMENU32(parg16->f1),
  441. WORD32(parg16->f2),
  442. WORD32(parg16->f3)));
  443. FREEARGPTR(parg16);
  444. RETURN(ul);
  445. }
  446. /*++
  447. BOOL DestroyMenu(<hMenu>)
  448. HMENU <hMenu>;
  449. The %DestroyMenu% function destroys the menu specified by the <hMenu>
  450. parameter and frees any memory that the menu occupied.
  451. <hMenu>
  452. Identifies the menu to be destroyed.
  453. The return value specifies whether or not the specified menu is destroyed.
  454. It is TRUE if the menu is destroyed. Otherwise, it is FALSE.
  455. --*/
  456. ULONG FASTCALL WU32DestroyMenu(PVDMFRAME pFrame)
  457. {
  458. ULONG ul;
  459. register PDESTROYMENU16 parg16;
  460. GETARGPTR(pFrame, sizeof(DESTROYMENU16), parg16);
  461. ul = GETBOOL16(DestroyMenu(HMENU32(parg16->f1)));
  462. FREEARGPTR(parg16);
  463. RETURN(ul);
  464. }
  465. /*++
  466. void DrawMenuBar(<hwnd>)
  467. HWND <hwnd>;
  468. The %DrawMenuBar% function redraws the menu bar. If a menu bar is changed
  469. <after> Windows has created the window, this function should be called to
  470. draw the changed menu bar.
  471. <hwnd>
  472. Identifies the window whose menu needs redrawing.
  473. This function does not return a value.
  474. --*/
  475. ULONG FASTCALL WU32DrawMenuBar(PVDMFRAME pFrame)
  476. {
  477. register PDRAWMENUBAR16 parg16;
  478. GETARGPTR(pFrame, sizeof(DRAWMENUBAR16), parg16);
  479. DrawMenuBar(HWND32(parg16->f1));
  480. FREEARGPTR(parg16);
  481. RETURN(TRUE);
  482. }
  483. /*++
  484. DWORD GetMenuCheckMarkDimensions(VOID)
  485. The %GetMenuCheckMarkDimensions% function returns the dimensions of the
  486. default checkmark bitmap. Windows displays this bitmap next to checked menu
  487. items. Before calling the %SetMenuItemBitmaps% function to replace the
  488. default checkmark, an application should call the
  489. %GetMenuCheckMarkDimensions% function to determine the correct size for the
  490. bitmaps.
  491. This function has no parameters.
  492. The return value specifies the height and width of the default checkmark
  493. bitmap. The high-order word contains the height in pixels and the low-order
  494. word contains the width.
  495. --*/
  496. ULONG FASTCALL WU32GetMenuCheckMarkDimensions(PVDMFRAME pFrame)
  497. {
  498. ULONG ul;
  499. UNREFERENCED_PARAMETER(pFrame);
  500. ul = GETLONG16(GetMenuCheckMarkDimensions());
  501. RETURN(ul);
  502. }
  503. /*++
  504. int GetMenuString(<hMenu>, <wIDItem>, <lpString>, <nMaxCount>, <wFlag>)
  505. HMENU <hMenu>;
  506. WORD <wIDItem>;
  507. LPSTR <lpString>;
  508. int <nMaxCount>;
  509. WORD <wFlag>;
  510. The %GetMenuString% function copies the label of the specified menu item
  511. into the <lpString> parameter.
  512. <hMenu>
  513. Identifies the menu.
  514. <wIDItem>
  515. Specifies the integer identifier of the menu item (from the
  516. resource file) or the offset of the menu item in the menu, depending on
  517. the value of the <wFlag> parameter.
  518. <lpString>
  519. Points to the buffer that is to receive the label.
  520. <nMaxCount>
  521. Specifies the maximum length of the label to be copied. If the
  522. label is longer than the maximum specified in <nMaxCount>, the extra
  523. characters are truncated.
  524. <wFlag>
  525. Specifies the nature of the <wID> parameter. If <wFlags> contains
  526. MF_BYPOSITION, <wId> specifies a (zero-based) relative position; if the
  527. <wFlags> parameter contains MF_BYCOMMAND, <wId> specifies the item ID.
  528. The return value specifies the actual number of bytes copied to the buffer.
  529. The <nMaxCount> parameter should be one larger than the number of characters
  530. in the label to accommodate the null character that terminates a string.
  531. --*/
  532. #define GMS32_LIMIT 2000
  533. ULONG FASTCALL WU32GetMenuString(PVDMFRAME pFrame)
  534. {
  535. ULONG ul;
  536. PSZ psz3;
  537. register PGETMENUSTRING16 parg16;
  538. GETARGPTR(pFrame, sizeof(GETMENUSTRING16), parg16);
  539. ALLOCVDMPTR(parg16->f3, parg16->f4, psz3);
  540. // limit nMaxCount to a reasonable amount so it does not fail in client
  541. // server. Some wow apps passed in -1.
  542. ul = GETINT16(GetMenuString(
  543. HMENU32(parg16->f1),
  544. WORD32(parg16->f2),
  545. psz3,
  546. (WORD32(parg16->f4) > GMS32_LIMIT) ? GMS32_LIMIT : WORD32(parg16->f4),
  547. WORD32(parg16->f5)
  548. ));
  549. FLUSHVDMPTR(parg16->f3, strlen(psz3)+1, psz3);
  550. FREEVDMPTR(psz3);
  551. FREEARGPTR(parg16);
  552. RETURN(ul);
  553. }
  554. /*++
  555. HMENU GetSystemMenu(<hwnd>, <bRevert>)
  556. HWND <hwnd>;
  557. BOOL <bRevert>;
  558. The %GetSystemMenu% function allows the application to access the System
  559. menu for copying and modification.
  560. <hwnd>
  561. Identifies the window that will own a copy of the System menu.
  562. <bRevert>
  563. Specifies the action to be taken.
  564. If <bRevert> is FALSE, the %GetSystemMenu% returns a handle to a copy of
  565. the System menu currently in use. This copy is initially identical to
  566. the System menu, but can be modified.
  567. If <bRevert> is TRUE, the %GetSystemMenu% function destroys the possibly
  568. modified copy of the System menu (if there is one) that belongs to the
  569. specified window and returns a handle to the original, unmodified
  570. version of the System menu.
  571. The return value identifies the System menu if <bRevert> is TRUE and the
  572. System menu has been modified. If <bRevert> is TRUE and the System menu
  573. has <not> been modified, the return value is NULL. If <bRevert> is FALSE, the
  574. return value identifies a copy of the System menu.
  575. Any window that does not use the %GetSystemMenu% function to make its own
  576. copy of the System menu receives the standard System menu.
  577. The handle returned by the %GetSystemMenu% function can be used with the
  578. %AppendMenu%, %InsertMenu% or %ModifyMenu% functions to change the System
  579. menu. The System menu initially contains items identified with various ID
  580. values such as SC_CLOSE, SC_MOVE, and SC_SIZE. Menu items on the System menu
  581. send WM_SYSCOMMAND messages. All predefined System-menu items have ID
  582. numbers greater than 0xF000. If an application adds commands to the System
  583. menu, it should use ID numbers less than F000.
  584. Windows automatically grays items on the standard System menu, depending on
  585. the situation. The application can carry out its own checking or graying by
  586. responding to the WM_INITMENU message, which is sent before any menu is
  587. displayed.
  588. --*/
  589. ULONG FASTCALL WU32GetSystemMenu(PVDMFRAME pFrame)
  590. {
  591. ULONG ul;
  592. register PGETSYSTEMMENU16 parg16;
  593. GETARGPTR(pFrame, sizeof(GETSYSTEMMENU16), parg16);
  594. ul = GETHMENU16(GetSystemMenu(HWND32(parg16->f1),
  595. BOOL32(parg16->f2)));
  596. FREEARGPTR(parg16);
  597. RETURN(ul);
  598. }
  599. /*++
  600. BOOL HiliteMenuItem(<hwnd>, <hMenu>, <wIDHiliteItem>, <wHilite>)
  601. HWND <hwnd>;
  602. HMENU <hMenu>;
  603. WORD <wIDHiliteItem>;
  604. WORD <wHilite>;
  605. The %HiliteMenuItem% function highlights or removes the highlighting from a
  606. top-level (menu-bar) menu item.
  607. <hwnd>
  608. Identifies the window that contains the menu.
  609. <hMenu>
  610. Identifies the top-level menu that contains the item to be
  611. highlighted.
  612. <wIDHiliteItem>
  613. Specifies the integer identifier of the menu item or the offset
  614. of the menu item in the menu, depending on the value of the <wHilite>
  615. parameter.
  616. <wHilite>
  617. Specifies whether the menu item is highlighted or the highlight
  618. is removed. It can be a combination of MF_HILITE or MF_UNHILITE with
  619. MF_BYCOMMAND or MF_BYPOSITION. The values can be combined using the
  620. bitwise OR operator. These values have the following meanings:
  621. MF_BYCOMMAND
  622. Interprets wIDHiliteItem as the menu-item ID (the default
  623. interpretation).
  624. MF_BYPOSITION
  625. Interprets <wIDHiliteItem> as an offset.
  626. MF_HILITE
  627. Highlights the item. If this value is not given, highlighting is removed
  628. from the item.
  629. MF_UNHILITE
  630. Removes highlighting from the item.
  631. The return value specifies whether or not the menu item is highlighted the
  632. outcome of the function. It is TRUE if the item is highlighted was set to
  633. the specified highlight state. Otherwise, it is FALSE.
  634. The MF_HILITE and MF_UNHILITE flags can be used only with the
  635. %HiliteMenuItem% function; they cannot be used with the %ModifyMenu%
  636. function.
  637. --*/
  638. ULONG FASTCALL WU32HiliteMenuItem(PVDMFRAME pFrame)
  639. {
  640. ULONG ul;
  641. register PHILITEMENUITEM16 parg16;
  642. GETARGPTR(pFrame, sizeof(HILITEMENUITEM16), parg16);
  643. ul = GETBOOL16(HiliteMenuItem(
  644. HWND32(parg16->f1),
  645. HMENU32(parg16->f2),
  646. WORD32(parg16->f3),
  647. WORD32(parg16->f4)
  648. ));
  649. FREEARGPTR(parg16);
  650. RETURN(ul);
  651. }
  652. /*++
  653. BOOL InsertMenu(<hMenu>, <nPosition>, <wFlags>, <wIDNewItem>, <lpNewItem>)
  654. HMENU <hMenu>;
  655. WORD <nPosition>;
  656. WORD <wFlags>;
  657. WORD <wIDNewItem>;
  658. LPSTR <lpNewItem>;
  659. The %InsertMenu% function inserts a new menu item at the position specified
  660. by the <nPosition> parameter, moving other items down the menu. The
  661. application can specify the state of the menu item by setting values in the
  662. <wFlags> parameter.
  663. <hMenu>
  664. Identifies the menu to be changed.
  665. <nPosition>
  666. Specifies the menu item before which the new menu item is to be
  667. inserted. The interpretation of the <nPosition> parameter depends upon
  668. the setting of the <wFlags> parameter.
  669. MF_BYPOSITION
  670. Specifies the position of the existing menu item. The first item in the
  671. menu is at position zero.
  672. If nPosition is -1, the new menu item is appended to the end of the
  673. menu.
  674. MF_BYCOMMAND
  675. Specifies the command ID of the existing menu item.
  676. <wFlags>
  677. Specifies how the <nPosition> parameter is interpreted and
  678. information about the state of the new menu item when it is added to the
  679. menu. It consists of one or more values listed in the following Comments
  680. section.
  681. <wIDNewItem>
  682. Specifies either the command ID of the new menu item or, if
  683. <wFlags> is set to MF_POPUP, the menu handle of the pop-up menu.
  684. <lpNewItem>
  685. Specifies the content of the new menu item. If <wFlags> is set
  686. to MF_STRING (the default), then <lpNewItem> is a long pointer to a
  687. null-terminated string. If <wFlags> is set to MF_BITMAP instead, then
  688. <lpNewItem> contains a bitmap handle (%HBITMAP%) in its low-order word.
  689. If <wFlags> is set to MF_OWNERDRAW, <lpNewItem> specifies an
  690. application-supplied 32-bit value which the application can use to
  691. maintain additional data associated with the menu item. This 32-bit
  692. value is available to the application in the %itemData% member of the
  693. structure pointed to by the <lParam> parameter of the following
  694. messages:
  695. WM_MEASUREITEM
  696. WM_DRAWITEM
  697. These messages are sent when the menu item is initially displayed, or is
  698. changed.
  699. The return value specifies the outcome of the function. It is TRUE if the
  700. function is successful. Otherwise, it is FALSE.
  701. Whenever a menu changes (whether or not the menu resides in a window that is
  702. displayed), the application should call %DrawMenuBar%.
  703. Each of the following groups lists flags that should not be used together:
  704. o MF_BYCOMMAND and MF_BYPOSITION
  705. o MF_DISABLED, MF_ENABLED, and MF_GRAYED
  706. o MF_BITMAP, MF_STRING, MF_OWNERDRAW, and MF_SEPARATOR
  707. o MF_MENUBARBREAK and MF_MENUBREAK
  708. o MF_CHECKED and MF_UNCHECKED
  709. The following list describes the flags which may be set in the <wFlags>
  710. parameter:
  711. MF_BITMAP
  712. Uses a bitmap as the item. The low-order word of the lpNewItem parameter
  713. contains the handle of the bitmap. MF_BYCOMMAND Specifies that the
  714. <nPosition> parameter gives the menu-item control ID number (default).
  715. MF_BYPOSITION
  716. Specifies that the <nPosition> parameter gives the position of the menu
  717. item to be changed rather than an ID number.
  718. MF_CHECKED
  719. Places a checkmark next to the menu item. If the application has
  720. supplied checkmark bitmaps (see the %SetMenuItemBitmaps% function),
  721. setting this flag displays the checkmark on bitmap next to the menu
  722. item.
  723. MF_DISABLED
  724. Disables the menu item so that it cannot be selected, but does not gray
  725. it.
  726. MF_ENABLED
  727. Enables the menu item so that it can be selected and restores it from
  728. its grayed state.
  729. MF_GRAYED
  730. Disables the menu item so that it cannot be selected and grays it.
  731. MF_MENUBARBREAK
  732. Same as MF_MENUBREAK except that for pop-up menus, separates the new
  733. column from the old column with a vertical line.
  734. MF_MENUBREAK
  735. Places the menu item on a new line for static menu-bar items. For pop-up
  736. menus, places the menu item in a new column, with no dividing line
  737. between the columns.
  738. MF_OWNERDRAW
  739. Specifies that the item is an owner-draw item. The window that owns the
  740. menu receives a WM_MEASUREITEM message when the menu is displayed for
  741. the first time to retrieve the height and width of the menu item. The
  742. WM_DRAWITEM message is then sent to the owner whenever the owner must
  743. update the visual appearance of the menu item. This option is not valid
  744. for a top-level menu item.
  745. MF_POPUP
  746. Specifies that the menu item has a pop-up menu associated with it. The
  747. <wIDNewItem> parameter specifies a handle to a pop-up menu to be
  748. associated with the item. Use the MF_OWNERDRAW flag to add either a
  749. top-level pop-up menu or a hierarchical pop-up menu to a pop-up menu
  750. item.
  751. MF_SEPARATOR
  752. Draws a horizontal dividing line. You can use this flag in a pop-up
  753. menu. This line cannot be grayed, disabled, or highlighted. Windows
  754. ignores the <lpNewItem> and <wIDNewItem> parameters.
  755. MF_STRING
  756. Specifies that the menu item is a character string; the <lpNewItem>
  757. parameter points to the string for the item.
  758. MF_UNCHECKED
  759. Does not place a checkmark next to the item (default). If the
  760. application has supplied checkmark bitmaps (see %SetMenuItemBitmaps%),
  761. setting this flag displays the "checkmark off" bitmap next to the menu
  762. item.
  763. --*/
  764. ULONG FASTCALL WU32InsertMenu(PVDMFRAME pFrame)
  765. {
  766. BOOL fNeedToFreePsz5 = FALSE;
  767. ULONG ul;
  768. PSZ psz5;
  769. UINT w4;
  770. register PINSERTMENU16 parg16;
  771. GETARGPTR(pFrame, sizeof(INSERTMENU16), parg16);
  772. if (parg16->f3 & MF_BITMAP) {
  773. if (LOW(parg16->f5) >= 4)
  774. psz5 = (PSZ)HBITMAP32(LOW(parg16->f5));
  775. else
  776. psz5 = (PSZ)WORD32(parg16->f5);
  777. }
  778. else if (parg16->f3 & MF_OWNERDRAW) {
  779. psz5 = (PSZ)DWORD32(parg16->f5);
  780. }
  781. else if (parg16->f3 & MF_SEPARATOR) {
  782. // lpszNewItem is ignored when inserting a separator bar.
  783. psz5 = NULL;
  784. }
  785. else {
  786. GETPSZPTR(parg16->f5, psz5);
  787. fNeedToFreePsz5 = TRUE;
  788. }
  789. w4 = (parg16->f3 & MF_POPUP) ? (UINT)HMENU32(parg16->f4) : WORD32(parg16->f4);
  790. ul = GETBOOL16(InsertMenu(
  791. HMENU32(parg16->f1),
  792. WORD32(parg16->f2),
  793. WORD32(parg16->f3),
  794. w4,
  795. psz5
  796. ));
  797. if (fNeedToFreePsz5) {
  798. FREEPSZPTR(psz5);
  799. }
  800. FREEARGPTR(parg16);
  801. RETURN(ul);
  802. }
  803. /*++
  804. HMENU LoadMenu(<hInstance>, <lpMenuName>)
  805. HANDLE <hInstance>;
  806. LPSTR <lpMenuName>;
  807. This function loads the menu resource named by the <lpMenuName> parameter
  808. from the executable file associated with the module specified by the
  809. <hInstance> parameter.
  810. <hInstance>
  811. Identifies an instance of the module whose executable file contains the
  812. menu.
  813. <lpMenuName>
  814. Points to a character string that names the menu resource. The
  815. string must be a null-terminated string.
  816. The return value identifies a menu resource if the function is successful.
  817. Otherwise, it is NULL.
  818. The <lpMenuName> parameter can contain a value created by the
  819. %MAKEINTRESOURCE% macro. If it does, the ID must reside in the low-order
  820. word of <lpMenuName>, and the high-order word must be set to zero.
  821. --*/
  822. ULONG FASTCALL WU32LoadMenu(PVDMFRAME pFrame)
  823. {
  824. ULONG ul = 0;
  825. PSZ psz2;
  826. register PLOADMENU16 parg16;
  827. DWORD cb;
  828. LPBYTE lpResData;
  829. LPWSTR lpUniName_Menu;
  830. GETARGPTR(pFrame, sizeof(LOADMENU16), parg16);
  831. psz2 = (PSZ)DWORD32(parg16->f2);
  832. GETPSZIDPTR(parg16->f2, psz2);
  833. if (HIWORD(psz2) != (WORD) NULL) {
  834. if (!(MBToWCS(psz2, -1, &lpUniName_Menu, -1, TRUE))) {
  835. FREEPSZIDPTR(psz2);
  836. FREEARGPTR(parg16);
  837. RETURN(ul);
  838. }
  839. }
  840. else {
  841. lpUniName_Menu = (LPWSTR) psz2;
  842. }
  843. cb = parg16->f4 * sizeof(WCHAR); // see SizeofResource16
  844. if (cb && (lpResData = malloc_w(cb))) {
  845. ConvertMenu16(parg16->f5, lpResData, parg16->f3, cb, parg16->f4);
  846. ul = GETHMENU16((pfnOut.pfnServerLoadCreateMenu)(HMODINST32(parg16->f1),
  847. (LPTSTR) lpUniName_Menu,
  848. lpResData,
  849. cb,
  850. FALSE));
  851. free_w (lpResData);
  852. }
  853. if (HIWORD(psz2) != (WORD) NULL) {
  854. LocalFree (lpUniName_Menu);
  855. }
  856. FREEPSZIDPTR(psz2);
  857. FREEARGPTR(parg16);
  858. RETURN(ul);
  859. }
  860. /*++
  861. HMENU LoadMenuIndirect(<lpMenuTemplate>)
  862. LPSTR <lpMenuTemplate>;
  863. The %LoadMenuIndirect% function loads into memory the menu named by the
  864. <lpMenuTemplate> parameter. The template specified by <lpMenuTemplate> is a
  865. header followed by a collection of one or more %MENUITEMTEMPLATE%
  866. structures, each of which may contain one or more menu items and pop-up
  867. menus.
  868. <lpMenuTemplate>
  869. Points to a menu template (which is a collection of one or more
  870. %MENUITEMTEMPLATE% structures).
  871. The return value identifies the menu if the function is successful.
  872. Otherwise, it is NULL.
  873. --*/
  874. ULONG FASTCALL WU32LoadMenuIndirect(PVDMFRAME pFrame)
  875. {
  876. ULONG ul = 0;
  877. DWORD cb = 0;
  878. PVOID pMenu32;
  879. PLOADMENUINDIRECT16 parg16;
  880. GETARGPTR(pFrame, sizeof(LOADMENUINDIRECT16), parg16);
  881. /*
  882. * we need to convert this randomly created 16-bit resource into a
  883. * 32-bit resource so that NT user will be able to use it.
  884. */
  885. if ((cb = (DWORD)ConvertMenu16((WORD)0x300, NULL, (VPBYTE)parg16->f1, cb, 0)) != 0) {
  886. pMenu32 = malloc_w(cb);
  887. if (pMenu32 != NULL) {
  888. ConvertMenu16((WORD)0x300, pMenu32, (VPBYTE)parg16->f1, cb, 0);
  889. ul = GETHMENU16(LoadMenuIndirect(pMenu32));
  890. free_w(pMenu32);
  891. }
  892. }
  893. FREEARGPTR(parg16);
  894. RETURN(ul);
  895. }
  896. /*++
  897. BOOL ModifyMenu(<hMenu>, <nPosition>, <wFlags>, <wIDNewItem>, <lpNewItem>)
  898. HMENU <hMenu>;
  899. WORD <nPosition>;
  900. WORD <wFlags>;
  901. WORD <wIDNewItem>;
  902. LPSTR <lpNewItem>;
  903. The %ModifyMenu% function changes an existing menu item at the position
  904. specified by the <nPosition> parameter. The application specifies the new
  905. state of the menu item by setting values in the <wFlags> parameter. If this
  906. function replaces a pop-up menu associated with the menu item, it destroys
  907. the old pop-up menu and frees the memory used by the pop-up menu.
  908. <hMenu>
  909. Identifies the menu to be changed.
  910. <nPosition>
  911. Specifies the menu item to be changed. The interpretation of the
  912. <nPosition> parameter depends upon the setting of the <wFlags>
  913. parameter.
  914. MF_BYPOSITION
  915. Specifies the position of the existing menu item. The first item in the
  916. menu is at position zero.
  917. MF_BYCOMMAND
  918. Specifies the command ID of the existing menu item.
  919. <wFlags>
  920. Specifies how the <nPosition> parameter is interpreted and
  921. information about the changes to be made to the menu item. It consists
  922. of one or more values listed in the following Comments section.
  923. <wIDNewItem>
  924. Specifies either the command ID of the modified menu item or, if
  925. <wFlags> is set to MF_POPUP, the menu handle of the pop-up menu.
  926. <lpNewItem>
  927. Specifies the content of the changed menu item. If <wFlags> is
  928. set to MF_STRING (the default), then <lpNewItem> is a long pointer to a
  929. null-terminated string. If <wFlags> is set to MF_BITMAP instead, then
  930. <lpNewItem> contains a bitmap handle (%HBITMAP%) in its low-order word.
  931. If <wFlags> is set to MF_OWNERDRAW, <lpNewItem> specifies an
  932. application-supplied 32-bit value which the application can use to
  933. maintain additional data associated with the menu item. This 32-bit
  934. value is available to the application in the %itemData% field of the
  935. structure, pointed to by the <lParam> parameter of the following
  936. messages:
  937. WM_MEASUREITEM
  938. WM_DRAWITEM
  939. These messages are sent when the menu item is initially displayed, or is
  940. changed.
  941. The return value specifies the outcome of the function. It is TRUE if the
  942. function is successful. Otherwise, it is FALSE.
  943. Whenever a menu changes (whether or not the menu resides in a window that is
  944. displayed), the application should call %DrawMenuBar%. In order to change
  945. the attributes of existing menu items, it is much faster to use the
  946. %CheckMenuItem% and %EnableMenuItem% functions.
  947. Each of the following groups lists flags that should not be used together:
  948. o MF_BYCOMMAND and MF_BYPOSITION
  949. o MF_DISABLED, MF_ENABLED, and MF_GRAYED
  950. o MF_BITMAP, MF_STRING, MF_OWNERDRAW, and MF_SEPARATOR
  951. o MF_MENUBARBREAK and MF_MENUBREAK
  952. o MF_CHECKED and MF_UNCHECKED
  953. The following list describes the flags which may be set in the <wFlags>
  954. parameter:
  955. MF_BITMAP
  956. Uses a bitmap as the menu item. The low-order word of the lpNewItem
  957. parameter contains the handle of the bitmap.
  958. MF_BYCOMMAND
  959. Specifies that the <nPosition> parameter gives the menu item control ID
  960. number. This is the default if neither MF_BYCOMMAND nor MF_POSITION is
  961. set.
  962. MF_BYPOSITION
  963. Specifies that the <nPosition> parameter gives the position of the menu
  964. item to be changed rather than an ID number.
  965. MF_CHECKED
  966. Places a checkmark next to the menu item. If the application has
  967. supplied checkmark bitmaps (see %SetMenuItemBitmaps%), setting this flag
  968. displays the checkmark on bitmap next to the menu item.
  969. MF_DISABLED
  970. Disables the menu item so that it cannot be selected, but does not gray
  971. it.
  972. MF_ENABLED
  973. Enables the menu item so that it can be selected and restores it from
  974. its grayed state.
  975. MF_GRAYED
  976. Disables the menu item so that it cannot be selected and grays it.
  977. MF_MENUBARBREAK
  978. Same as MF_MENUBREAK except that for pop-up menus, separates the new
  979. column from the old column with a vertical line.
  980. MF_MENUBREAK
  981. Places the menu item on a new line for static menu-bar items. For pop-up
  982. menus, this flag places the item in a new column, with no dividing line
  983. between the columns.
  984. MF_OWNERDRAW
  985. Specifies that the menu item is an owner-draw item. The window that owns
  986. the menu receives a WM_MEASUREITEM message when the menu is displayed
  987. for the first time to retrieve the height and width of the menu item.
  988. The WM_DRAWITEM message is then sent whenever the owner must update the
  989. visual appearance of the menu item. This option is not valid for a
  990. top-level menu item.
  991. MF_POPUP
  992. Specifies that the item has a pop-up menu associated with it. The
  993. <wIDNewItem> parameter specifies a handle to a pop-up menu to be
  994. associated with the menu item. Use this flag for adding either a
  995. top-level pop-up menu or adding a hierarchical pop-up menu to a pop-up
  996. menu item.
  997. MF_SEPARATOR
  998. Draws a horizontal dividing line. You can only use this flag in a pop-up
  999. menu. This line cannot be grayed, disabled, or highlighted. The
  1000. <lpNewItem> and <wIDNewItem> parameters are ignored.
  1001. MF_STRING
  1002. Specifies that the menu item is a character string; the <lpNewItem>
  1003. parameter points to the string for the menu item.
  1004. MF_UNCHECKED
  1005. Does not place a checkmark next to the menu item. No checkmark is the
  1006. default if neither MF_CHECKED nor MF_UNCHECKED is set. If the
  1007. application has supplied checkmark bitmaps (see %SetMenuItemBitmaps%),
  1008. setting this flag displays the checkmark off bitmap next to the menu
  1009. item.
  1010. --*/
  1011. ULONG FASTCALL WU32ModifyMenu(PVDMFRAME pFrame)
  1012. {
  1013. ULONG ul;
  1014. PSZ psz5;
  1015. register PMODIFYMENU16 parg16;
  1016. UINT wIDNewItem;
  1017. GETARGPTR(pFrame, sizeof(MODIFYMENU16), parg16);
  1018. if (parg16->f3 & MF_BITMAP) {
  1019. if (LOW16(parg16->f5) >= 4)
  1020. psz5 = (PSZ)HBITMAP32(LOW(parg16->f5));
  1021. else
  1022. psz5 = (PSZ)WORD32(parg16->f5);
  1023. }
  1024. else if (parg16->f3 & MF_OWNERDRAW)
  1025. psz5 = (PSZ)DWORD32(parg16->f5);
  1026. else
  1027. GETPSZPTR(parg16->f5, psz5);
  1028. wIDNewItem = (UINT) WORD32(parg16->f4);
  1029. if (parg16->f3 & MF_POPUP)
  1030. wIDNewItem = (UINT) HMENU32(parg16->f4);
  1031. ul = GETBOOL16(ModifyMenu(
  1032. HMENU32(parg16->f1),
  1033. WORD32(parg16->f2),
  1034. WORD32(parg16->f3),
  1035. wIDNewItem,
  1036. psz5
  1037. ));
  1038. if ( ul == FALSE && (parg16->f3 & MF_POPUP) ) {
  1039. //
  1040. // PowerPoint v4.0c passes an wIDNewItem which is not a menu handle
  1041. // when they do pass MF_POPUP. This hack allows it to avoid the
  1042. // error path in WINSRV. On Win 3.1, they never validated it so it
  1043. // got through. Luckily they quickly modify the menu to not have
  1044. // a popup menu soon after that.
  1045. //
  1046. if ( !IsMenu((HMENU) wIDNewItem) ) {
  1047. //
  1048. // Try again with a better sub-menu handle.
  1049. //
  1050. wIDNewItem = (UINT)GetSubMenu( HMENU32(parg16->f1),
  1051. WORD32(parg16->f2) );
  1052. ul = GETBOOL16(ModifyMenu( HMENU32(parg16->f1),
  1053. WORD32(parg16->f2),
  1054. WORD32(parg16->f3),
  1055. wIDNewItem,
  1056. psz5 ));
  1057. }
  1058. }
  1059. FREEPSZPTR(psz5);
  1060. FREEARGPTR(parg16);
  1061. RETURN(ul);
  1062. }
  1063. /*++
  1064. BOOL RemoveMenu(<hMenu>, <nPosition>, <wFlags>)
  1065. HMENU <hMenu>;
  1066. WORD <nPosition>;
  1067. WORD <wFlags>;
  1068. The %RemoveMenu% function deletes an menu item with an associated pop-up
  1069. menu from the menu identified by the <hMenu> parameter but does not destroy
  1070. the handle for the pop-up menu, allowing the menu to be reused. Before
  1071. calling this function, the application should call %GetSubMenu% to retrieve
  1072. the pop-up menu handle.
  1073. <hMenu>
  1074. Identifies the menu to be changed.
  1075. <nPosition>
  1076. Specifies the menu item to be removed. The interpretation of the
  1077. <nPosition> parameter depends upon the setting of the <wFlags>
  1078. parameter.
  1079. MF_BYCOMMAND
  1080. Specifies the command ID of the existing menu item.
  1081. MF_BYPOSITION
  1082. Specifies the position of the menu item. The first item in the menu is
  1083. at position zero.
  1084. <wFlags>
  1085. Specifies how the <nPosition> parameter is interpreted. It must
  1086. be either MF_BYCOMMAND or MF_BYPOSITION.
  1087. The return value specifies the outcome of the function. It is TRUE if the
  1088. function is successful. Otherwise, it is FALSE.
  1089. Whenever a menu changes (whether or not the menu resides in a window that is
  1090. displayed), the application should call %DrawMenuBar%.
  1091. --*/
  1092. ULONG FASTCALL WU32RemoveMenu(PVDMFRAME pFrame)
  1093. {
  1094. ULONG ul;
  1095. register PREMOVEMENU16 parg16;
  1096. GETARGPTR(pFrame, sizeof(REMOVEMENU16), parg16);
  1097. ul = GETBOOL16(RemoveMenu(
  1098. HMENU32(parg16->f1),
  1099. WORD32(parg16->f2),
  1100. WORD32(parg16->f3)
  1101. ));
  1102. FREEARGPTR(parg16);
  1103. RETURN(ul);
  1104. }
  1105. /*++
  1106. BOOL SetMenu(<hwnd>, <hMenu>)
  1107. HWND <hwnd>;
  1108. HMENU <hMenu>;
  1109. The %SetMenu% function sets the given window's menu to the menu specified by
  1110. the <hMenu> parameter. If <hMenu> is NULL, the window's current menu is
  1111. removed. The %SetMenu% function causes the window to be redrawn to reflect
  1112. the menu change.
  1113. <hwnd>
  1114. Identifies the window whose menu is to be changed.
  1115. <hMenu>
  1116. Identifies the new menu.
  1117. The return value specifies whether the menu is changed. It is TRUE if the
  1118. menu is changed. Otherwise, it is FALSE.
  1119. %SetMenu% will not destroy a previous menu. An application should call the
  1120. %DestroyMenu% function to accomplish this task.
  1121. --*/
  1122. ULONG FASTCALL WU32SetMenu(PVDMFRAME pFrame)
  1123. {
  1124. ULONG ul;
  1125. register PSETMENU16 parg16;
  1126. GETARGPTR(pFrame, sizeof(SETMENU16), parg16);
  1127. ul = GETBOOL16(SetMenu(
  1128. HWND32(parg16->f1),
  1129. HMENU32(parg16->f2)
  1130. ));
  1131. FREEARGPTR(parg16);
  1132. RETURN(ul);
  1133. }
  1134. /*++
  1135. BOOL SetMenuItemBitmaps(<hMenu>, <nPosition>, <wFlags>,
  1136. <hBitmapUnchecked>, <hBitmapChecked>)
  1137. HMENU <hMenu>;
  1138. WORD <nPosition>;
  1139. WORD <wFlags>;
  1140. HBITMAP <hBitmapUnchecked>;
  1141. HBITMAP <hBitmapChecked>;
  1142. The %SetMenuItemBitmaps% function associates the specified bitmaps with a
  1143. menu item. Whether the menu item is checked or unchecked, Windows displays
  1144. the appropriate bitmap next to the menu item.
  1145. <hMenu>
  1146. Identifies the menu to be changed.
  1147. <nPosition>
  1148. Specifies the menu item to be changed. If <wFlags> is set to
  1149. MF_BYPOSITION, <nPosition> specifies the position of the menu item; the
  1150. first item in the menu is at position 0. If <wFlags> is set to
  1151. MF_BYCOMMAND, then <nPosition> specifies the command ID of the menu
  1152. item.
  1153. <wFlags>
  1154. Specifies how the <nPosition> parameter is interpreted. It may be
  1155. set to MF_BYCOMMAND (the default) or MF_BYPOSITION.
  1156. <hBitmapUnchecked>
  1157. Identifies the bitmap to be displayed when the menu item is
  1158. not checked.
  1159. <hBitmapChecked>
  1160. Identifies the bitmap to be displayed when the menu item is
  1161. checked.
  1162. The return value specifies the outcome of the function. It is TRUE if the
  1163. function is successful. Otherwise, it is FALSE.
  1164. If either the <hBitmapUnchecked> or the <hBitmapChecked> parameters is NULL,
  1165. then Windows displays nothing next to the menu item for the corresponding
  1166. attribute. If both parameters are NULL, Windows uses the default checkmark
  1167. when the item is checked and removes the checkmark when the item is
  1168. unchecked.
  1169. When the menu is destroyed, these bitmaps are not destroyed; it is the
  1170. responsibility of the application to destroy them.
  1171. The %GetMenuCheckMarkDimensions% function retrieves the dimensions of the
  1172. default checkmark used for menu items. The application should use these
  1173. values to determine the appropriate size for the bitmaps supplied with this
  1174. function.
  1175. --*/
  1176. ULONG FASTCALL WU32SetMenuItemBitmaps(PVDMFRAME pFrame)
  1177. {
  1178. ULONG ul;
  1179. register PSETMENUITEMBITMAPS16 parg16;
  1180. GETARGPTR(pFrame, sizeof(SETMENUITEMBITMAPS16), parg16);
  1181. ul = GETBOOL16(SetMenuItemBitmaps(
  1182. HMENU32(parg16->f1),
  1183. WORD32(parg16->f2),
  1184. WORD32(parg16->f3),
  1185. HBITMAP32(parg16->f4),
  1186. HBITMAP32(parg16->f5)
  1187. ));
  1188. FREEARGPTR(parg16);
  1189. RETURN(ul);
  1190. }
  1191. /*++
  1192. BOOL TrackPopupMenu(<hMenu>, <wFlags>, <x>, <y>, <nReserved>, <hwnd>,
  1193. <lpReserved>)
  1194. The %TrackPopupMenu% function displays a floating pop-up menu at the
  1195. specified location and tracks the selection of items on the pop-up menu. A
  1196. floating pop-up menu can appear anywhere on the screen. The <hMenu>
  1197. parameter specifies the handle of the menu to be displayed; the application
  1198. obtains this handle by calling %CreatePopupMenu% to create a new pop-up menu
  1199. or by calling %GetSubMenu% to retrieve the handle of a pop-up menu
  1200. associated with an existing menu item.
  1201. Windows sends messages generated by the menu to the window identified by the
  1202. <hwnd> parameter.
  1203. <hMenu>
  1204. Identifies the pop-up menu to be displayed.
  1205. <wFlags>
  1206. Not used. This parameter must be set to zero.
  1207. <x>
  1208. Specifies the horizontal position in screen coordinates of the
  1209. left side of the menu on the screen.
  1210. <y>
  1211. Specifies the vertical position in screen coordinates of the top
  1212. of the menu on the screen.
  1213. <nReserved>
  1214. Is reserved and must be set to zero.
  1215. <hwnd>
  1216. Identifies the window which owns the pop-up menu. This window
  1217. receives all WM_COMMAND messages from the menu.
  1218. <lpReserved>
  1219. Is reserved and must be set to NULL.
  1220. The return value specifies the outcome of the function. It is TRUE if the
  1221. function is successful. Otherwise, it is FALSE.
  1222. --*/
  1223. ULONG FASTCALL WU32TrackPopupMenu(PVDMFRAME pFrame)
  1224. {
  1225. ULONG ul;
  1226. RECT t7, *p7;
  1227. register PTRACKPOPUPMENU16 parg16;
  1228. GETARGPTR(pFrame, sizeof(TRACKPOPUPMENU16), parg16);
  1229. p7 = GETRECT16(parg16->f7, &t7);
  1230. ul = GETBOOL16(TrackPopupMenu(
  1231. HMENU32(parg16->f1),
  1232. WORD32(parg16->f2),
  1233. INT32(parg16->f3),
  1234. INT32(parg16->f4),
  1235. INT32(parg16->f5),
  1236. HWND32(parg16->f6),
  1237. p7
  1238. ));
  1239. FREEARGPTR(parg16);
  1240. RETURN(ul);
  1241. }