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.

313 lines
8.7 KiB

  1. #include "ctlspriv.h"
  2. #define MAININSYS
  3. #ifndef WIN32
  4. /* This returns the index of a submenu in a parent menu. The return is
  5. * < 0 if the submenu does not exist in the parent menu
  6. */
  7. int GetMenuIndex(HMENU hMenu, HMENU hSubMenu)
  8. {
  9. int i;
  10. if (!hMenu || !hSubMenu)
  11. return(-1);
  12. for (i=GetMenuItemCount(hMenu)-1; i>=0; --i)
  13. {
  14. if (hSubMenu == GetSubMenu(hMenu, i))
  15. break;
  16. }
  17. return(i);
  18. }
  19. #endif // WIN32
  20. BOOL IsMaxedMDI(HMENU hMenu)
  21. {
  22. return(GetMenuItemID(hMenu, GetMenuItemCount(hMenu)-1) == SC_RESTORE);
  23. }
  24. /* Note that if iMessage is WM_COMMAND, it is assumed to have come from
  25. * a header bar or toolbar; do not pass in WM_COMMAND messages from any
  26. * other controls.
  27. */
  28. #define MS_ID GET_WM_MENUSELECT_CMD
  29. #define MS_FLAGS GET_WM_MENUSELECT_FLAGS
  30. #define MS_MENU GET_WM_MENUSELECT_HMENU
  31. #define CMD_NOTIFY GET_WM_COMMAND_CMD
  32. #define CMD_ID GET_WM_COMMAND_ID
  33. #define CMD_CTRL GET_WM_COMMAND_HWND
  34. void WINAPI MenuHelp(UINT iMessage, WPARAM wParam, LPARAM lParam,
  35. HMENU hMainMenu, HINSTANCE hAppInst, HWND hwndStatus, UINT *lpwIDs)
  36. {
  37. UINT wID;
  38. UINT *lpwPopups;
  39. int i;
  40. TCHAR szString[256];
  41. BOOL bUpdateNow = TRUE;
  42. #if defined(WINDOWS_ME)
  43. MENUITEMINFO mii;
  44. #endif
  45. switch (iMessage)
  46. {
  47. case WM_MENUSELECT:
  48. if ((WORD)MS_FLAGS(wParam, lParam)==(WORD)-1 && MS_MENU(wParam, lParam)==0)
  49. {
  50. #ifndef WIN32
  51. EndMenuHelp:
  52. #endif
  53. SendMessage(hwndStatus, SB_SIMPLE, 0, 0L);
  54. break;
  55. }
  56. szString[0] = TEXT('\0');
  57. #if defined(WINDOWS_ME)
  58. i = MS_ID(wParam, lParam);
  59. memset(&mii, 0, SIZEOF(MENUITEMINFO ));
  60. mii.cbSize = sizeof(mii);
  61. mii.fMask = MIIM_TYPE;
  62. mii.cch = 0; //If we ask for MIIM_TYPE, this must be set to zero!
  63. //Otherwise, win95 attempts to copy the string too!
  64. if (GetMenuItemInfo((HMENU)MS_MENU(wParam, lParam), i, TRUE, &mii))
  65. mii.fState = mii.fType & MFT_RIGHTORDER ?SBT_RTLREADING :0;
  66. #endif
  67. if (!(MS_FLAGS(wParam, lParam)&MF_SEPARATOR))
  68. {
  69. if (MS_FLAGS(wParam, lParam)&MF_POPUP)
  70. {
  71. /* We don't want to update immediately in case the menu is
  72. * about to pop down, with an item selected. This gets rid
  73. * of some flashing text.
  74. */
  75. bUpdateNow = FALSE;
  76. /* First check if this popup is in our list of popup menus
  77. */
  78. for (lpwPopups=lpwIDs+2; *lpwPopups; lpwPopups+=2)
  79. {
  80. /* lpwPopups is a list of string ID/menu handle pairs
  81. * and MS_ID(wParam, lParam) is the menu handle of the selected popup
  82. */
  83. if (*(lpwPopups+1) == (UINT)MS_ID(wParam, lParam))
  84. {
  85. wID = *lpwPopups;
  86. goto LoadTheString;
  87. }
  88. }
  89. /* Check if the specified popup is in the main menu;
  90. * note that if the "main" menu is in the system menu,
  91. * we will be OK as long as the menu is passed in correctly.
  92. * In fact, an app could handle all popups by just passing in
  93. * the proper hMainMenu.
  94. */
  95. if ((HMENU)MS_MENU(wParam, lParam) == hMainMenu)
  96. {
  97. #ifdef WIN32
  98. i = MS_ID(wParam, lParam);
  99. #else // WIN32
  100. i = GetMenuIndex((HMENU)MS_MENU(wParam, lParam), (HMENU)MS_ID(wParam, lParam));
  101. if (i >= 0)
  102. #endif // WIN32
  103. {
  104. if (IsMaxedMDI(hMainMenu))
  105. {
  106. if (!i)
  107. {
  108. wID = IDS_SYSMENU;
  109. hAppInst = HINST_THISDLL;
  110. goto LoadTheString;
  111. }
  112. else
  113. --i;
  114. }
  115. wID = (UINT)(i + lpwIDs[1]);
  116. goto LoadTheString;
  117. }
  118. }
  119. /* This assumes all app defined popups in the system menu
  120. * have been listed above
  121. */
  122. if ((MS_FLAGS(wParam, lParam)&MF_SYSMENU))
  123. {
  124. wID = IDS_SYSMENU;
  125. hAppInst = HINST_THISDLL;
  126. goto LoadTheString;
  127. }
  128. goto NoString;
  129. }
  130. else if (MS_ID(wParam, lParam) >= MINSYSCOMMAND)
  131. {
  132. wID = (UINT)(MS_ID(wParam, lParam) + MH_SYSMENU);
  133. hAppInst = HINST_THISDLL;
  134. }
  135. else
  136. {
  137. wID = (UINT)(MS_ID(wParam, lParam) + lpwIDs[0]);
  138. }
  139. LoadTheString:
  140. if (hAppInst == HINST_THISDLL)
  141. LocalizedLoadString(wID, szString, ARRAYSIZE(szString));
  142. else
  143. LoadString(hAppInst, wID, szString, ARRAYSIZE(szString));
  144. }
  145. NoString:
  146. #if defined(WINDOWS_ME)
  147. SendMessage(hwndStatus, SB_SETTEXT, mii.fState|SBT_NOBORDERS|255,
  148. (LPARAM)(LPSTR)szString);
  149. #else
  150. SendMessage(hwndStatus, SB_SETTEXT, SBT_NOBORDERS|255,
  151. (LPARAM)(LPTSTR)szString);
  152. #endif
  153. SendMessage(hwndStatus, SB_SIMPLE, 1, 0L);
  154. if (bUpdateNow)
  155. UpdateWindow(hwndStatus);
  156. break;
  157. #ifndef WIN32
  158. case WM_COMMAND:
  159. switch (CMD_NOTIFY(wParam, lParam))
  160. {
  161. #ifdef WANT_SUCKY_HEADER
  162. case HBN_BEGINDRAG:
  163. bUpdateNow = FALSE;
  164. wID = IDS_HEADER;
  165. goto BeginSomething;
  166. case HBN_BEGINADJUST:
  167. wID = IDS_HEADERADJ;
  168. goto BeginSomething;
  169. #endif
  170. case TBN_BEGINADJUST:
  171. /* We don't want to update immediately in case the operation is
  172. * aborted immediately.
  173. */
  174. bUpdateNow = FALSE;
  175. wID = IDS_TOOLBARADJ;
  176. goto BeginSomething;
  177. BeginSomething:
  178. SendMessage(hwndStatus, SB_SIMPLE, 1, 0L);
  179. hAppInst = HINST_THISDLL;
  180. goto LoadTheString;
  181. case TBN_BEGINDRAG:
  182. MenuHelp(WM_MENUSELECT, (WPARAM)CMD_CTRL(wParam, lParam), 0L,
  183. hMainMenu, hAppInst, hwndStatus, lpwIDs);
  184. break;
  185. #ifdef WANT_SUCKY_HEADER
  186. case HBN_ENDDRAG:
  187. case HBN_ENDADJUST:
  188. #endif
  189. case TBN_ENDDRAG:
  190. case TBN_ENDADJUST:
  191. goto EndMenuHelp;
  192. default:
  193. break;
  194. }
  195. break;
  196. #endif // !WIN32
  197. default:
  198. break;
  199. }
  200. }
  201. BOOL WINAPI ShowHideMenuCtl(HWND hWnd, WPARAM wParam, LPINT lpInfo)
  202. {
  203. HWND hCtl;
  204. UINT uTool, uShow = MF_UNCHECKED | MF_BYCOMMAND;
  205. HMENU hMainMenu;
  206. BOOL bRet = FALSE;
  207. hMainMenu = IntToPtr_(HMENU, lpInfo[1]);
  208. for (uTool=0; ; ++uTool, lpInfo+=2)
  209. {
  210. if ((WPARAM)lpInfo[0] == wParam)
  211. break;
  212. if (!lpInfo[0])
  213. goto DoTheCheck;
  214. }
  215. if (!(GetMenuState(hMainMenu, (UINT) wParam, MF_BYCOMMAND)&MF_CHECKED))
  216. uShow = MF_CHECKED | MF_BYCOMMAND;
  217. switch (uTool)
  218. {
  219. case 0:
  220. bRet = SetMenu(hWnd, (HMENU)((uShow&MF_CHECKED) ? hMainMenu : 0));
  221. break;
  222. default:
  223. hCtl = GetDlgItem(hWnd, lpInfo[1]);
  224. if (hCtl)
  225. {
  226. ShowWindow(hCtl, (uShow&MF_CHECKED) ? SW_SHOW : SW_HIDE);
  227. bRet = TRUE;
  228. }
  229. else
  230. uShow = MF_UNCHECKED | MF_BYCOMMAND;
  231. break;
  232. }
  233. DoTheCheck:
  234. CheckMenuItem(hMainMenu, (UINT) wParam, uShow);
  235. #ifdef MAININSYS
  236. hMainMenu = GetSubMenu(GetSystemMenu(hWnd, FALSE), 0);
  237. if (hMainMenu)
  238. CheckMenuItem(hMainMenu, (UINT) wParam, uShow);
  239. #endif
  240. return(bRet);
  241. }
  242. void WINAPI GetEffectiveClientRect(HWND hWnd, LPRECT lprc, LPINT lpInfo)
  243. {
  244. RECT rc;
  245. HWND hCtl;
  246. GetClientRect(hWnd, lprc);
  247. /* Get past the menu
  248. */
  249. for (lpInfo+=2; lpInfo[0]; lpInfo+=2)
  250. {
  251. hCtl = GetDlgItem(hWnd, lpInfo[1]);
  252. /* We check the style bit because the parent window may not be visible
  253. * yet (still in the create message)
  254. */
  255. if (!hCtl || !(GetWindowStyle(hCtl) & WS_VISIBLE))
  256. continue;
  257. GetWindowRect(hCtl, &rc);
  258. //
  259. // This will do the ScrrenToClient functionality, plus
  260. // it will return a good rect (left < right) when the
  261. // hWnd parent is RTL mirrored. [samera]
  262. //
  263. MapWindowPoints(HWND_DESKTOP, hWnd, (PPOINT)&rc, 2);
  264. SubtractRect(lprc, lprc, &rc);
  265. }
  266. }