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.

419 lines
11 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 NEAR PASCAL 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 NEAR PASCAL 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 FAR *lpwIDs)
  36. {
  37. UINT wID;
  38. UINT FAR *lpwPopups;
  39. int i;
  40. TCHAR szString[256];
  41. BOOL bUpdateNow = TRUE;
  42. #if defined(WINDOWS_ME)
  43. MENUITEMINFO mii;
  44. //BugBug: this line should be in
  45. // BOOL bByPos;
  46. #endif
  47. switch (iMessage)
  48. {
  49. case WM_MENUSELECT:
  50. if ((WORD)MS_FLAGS(wParam, lParam)==(WORD)-1 && MS_MENU(wParam, lParam)==0)
  51. {
  52. #ifndef WIN32
  53. EndMenuHelp:
  54. #endif
  55. SendMessage(hwndStatus, SB_SIMPLE, 0, 0L);
  56. break;
  57. }
  58. szString[0] = TEXT('\0');
  59. #if defined(WINDOWS_ME)
  60. i = MS_ID(wParam, lParam);
  61. //BugBug: this line should be in
  62. //bByPos = (MS_FLAGS(wParam, lParam) & MF_POPUP);
  63. memset(&mii, 0, SIZEOF(MENUITEMINFO ));
  64. mii.cbSize = sizeof(mii);
  65. mii.fMask = MIIM_TYPE;
  66. mii.cch = 0; //If we ask for MIIM_TYPE, this must be set to zero!
  67. //Otherwise, win95 attempts to copy the string too!
  68. if (GetMenuItemInfo((HMENU)MS_MENU(wParam, lParam), i, TRUE /*bByPos*/, &mii))
  69. mii.fState = mii.fType & MFT_RIGHTORDER ?SBT_RTLREADING :0;
  70. #endif
  71. if (!(MS_FLAGS(wParam, lParam)&MF_SEPARATOR))
  72. {
  73. if (MS_FLAGS(wParam, lParam)&MF_POPUP)
  74. {
  75. /* We don't want to update immediately in case the menu is
  76. * about to pop down, with an item selected. This gets rid
  77. * of some flashing text.
  78. */
  79. bUpdateNow = FALSE;
  80. /* First check if this popup is in our list of popup menus
  81. */
  82. for (lpwPopups=lpwIDs+2; *lpwPopups; lpwPopups+=2)
  83. {
  84. /* lpwPopups is a list of string ID/menu handle pairs
  85. * and MS_ID(wParam, lParam) is the menu handle of the selected popup
  86. */
  87. if (*(lpwPopups+1) == (UINT)MS_ID(wParam, lParam))
  88. {
  89. wID = *lpwPopups;
  90. goto LoadTheString;
  91. }
  92. }
  93. /* Check if the specified popup is in the main menu;
  94. * note that if the "main" menu is in the system menu,
  95. * we will be OK as long as the menu is passed in correctly.
  96. * In fact, an app could handle all popups by just passing in
  97. * the proper hMainMenu.
  98. */
  99. if ((HMENU)MS_MENU(wParam, lParam) == hMainMenu)
  100. {
  101. #ifdef WIN32
  102. i = MS_ID(wParam, lParam);
  103. #else // WIN32
  104. i = GetMenuIndex((HMENU)MS_MENU(wParam, lParam), (HMENU)MS_ID(wParam, lParam));
  105. if (i >= 0)
  106. #endif // WIN32
  107. {
  108. if (IsMaxedMDI(hMainMenu))
  109. {
  110. if (!i)
  111. {
  112. wID = IDS_SYSMENU;
  113. hAppInst = HINST_THISDLL;
  114. goto LoadTheString;
  115. }
  116. else
  117. --i;
  118. }
  119. wID = (UINT)(i + lpwIDs[1]);
  120. goto LoadTheString;
  121. }
  122. }
  123. /* This assumes all app defined popups in the system menu
  124. * have been listed above
  125. */
  126. if ((MS_FLAGS(wParam, lParam)&MF_SYSMENU))
  127. {
  128. wID = IDS_SYSMENU;
  129. hAppInst = HINST_THISDLL;
  130. goto LoadTheString;
  131. }
  132. goto NoString;
  133. }
  134. else if (MS_ID(wParam, lParam) >= MINSYSCOMMAND)
  135. {
  136. wID = (UINT)(MS_ID(wParam, lParam) + MH_SYSMENU);
  137. hAppInst = HINST_THISDLL;
  138. }
  139. else
  140. {
  141. wID = (UINT)(MS_ID(wParam, lParam) + lpwIDs[0]);
  142. }
  143. LoadTheString:
  144. if (hAppInst == HINST_THISDLL)
  145. LocalizedLoadString(wID, szString, ARRAYSIZE(szString));
  146. else
  147. LoadString(hAppInst, wID, szString, ARRAYSIZE(szString));
  148. }
  149. NoString:
  150. #if defined(WINDOWS_ME)
  151. SendMessage(hwndStatus, SB_SETTEXT, mii.fState|SBT_NOBORDERS|255,
  152. (LPARAM)(LPSTR)szString);
  153. #else
  154. SendMessage(hwndStatus, SB_SETTEXT, SBT_NOBORDERS|255,
  155. (LPARAM)(LPTSTR)szString);
  156. #endif
  157. SendMessage(hwndStatus, SB_SIMPLE, 1, 0L);
  158. if (bUpdateNow)
  159. UpdateWindow(hwndStatus);
  160. break;
  161. #ifndef WIN32
  162. case WM_COMMAND:
  163. switch (CMD_NOTIFY(wParam, lParam))
  164. {
  165. #ifdef WANT_SUCKY_HEADER
  166. // BUGBUG: these are now WM_NOTIFY messages
  167. case HBN_BEGINDRAG:
  168. bUpdateNow = FALSE;
  169. wID = IDS_HEADER;
  170. goto BeginSomething;
  171. case HBN_BEGINADJUST:
  172. wID = IDS_HEADERADJ;
  173. goto BeginSomething;
  174. #endif
  175. case TBN_BEGINADJUST:
  176. /* We don't want to update immediately in case the operation is
  177. * aborted immediately.
  178. */
  179. bUpdateNow = FALSE;
  180. wID = IDS_TOOLBARADJ;
  181. goto BeginSomething;
  182. BeginSomething:
  183. SendMessage(hwndStatus, SB_SIMPLE, 1, 0L);
  184. hAppInst = HINST_THISDLL;
  185. goto LoadTheString;
  186. case TBN_BEGINDRAG:
  187. MenuHelp(WM_MENUSELECT, (WPARAM)CMD_CTRL(wParam, lParam), 0L,
  188. hMainMenu, hAppInst, hwndStatus, lpwIDs);
  189. break;
  190. #ifdef WANT_SUCKY_HEADER
  191. case HBN_ENDDRAG:
  192. case HBN_ENDADJUST:
  193. #endif
  194. case TBN_ENDDRAG:
  195. case TBN_ENDADJUST:
  196. goto EndMenuHelp;
  197. default:
  198. break;
  199. }
  200. break;
  201. #endif // !WIN32
  202. default:
  203. break;
  204. }
  205. }
  206. BOOL WINAPI ShowHideMenuCtl(HWND hWnd, WPARAM wParam, LPINT lpInfo)
  207. {
  208. HWND hCtl;
  209. UINT uTool, uShow = MF_UNCHECKED | MF_BYCOMMAND;
  210. HMENU hMainMenu;
  211. BOOL bRet = FALSE;
  212. hMainMenu = IntToPtr_(HMENU, lpInfo[1]);
  213. for (uTool=0; ; ++uTool, lpInfo+=2)
  214. {
  215. if ((WPARAM)lpInfo[0] == wParam)
  216. break;
  217. if (!lpInfo[0])
  218. goto DoTheCheck;
  219. }
  220. if (!(GetMenuState(hMainMenu, (UINT) wParam, MF_BYCOMMAND)&MF_CHECKED))
  221. uShow = MF_CHECKED | MF_BYCOMMAND;
  222. switch (uTool)
  223. {
  224. case 0:
  225. bRet = SetMenu(hWnd, (HMENU)((uShow&MF_CHECKED) ? hMainMenu : 0));
  226. break;
  227. default:
  228. hCtl = GetDlgItem(hWnd, lpInfo[1]);
  229. if (hCtl)
  230. {
  231. ShowWindow(hCtl, (uShow&MF_CHECKED) ? SW_SHOW : SW_HIDE);
  232. bRet = TRUE;
  233. }
  234. else
  235. uShow = MF_UNCHECKED | MF_BYCOMMAND;
  236. break;
  237. }
  238. DoTheCheck:
  239. CheckMenuItem(hMainMenu, (UINT) wParam, uShow);
  240. #ifdef MAININSYS
  241. hMainMenu = GetSubMenu(GetSystemMenu(hWnd, FALSE), 0);
  242. if (hMainMenu)
  243. CheckMenuItem(hMainMenu, (UINT) wParam, uShow);
  244. #endif
  245. return(bRet);
  246. }
  247. void WINAPI GetEffectiveClientRect(HWND hWnd, LPRECT lprc, LPINT lpInfo)
  248. {
  249. RECT rc;
  250. HWND hCtl;
  251. GetClientRect(hWnd, lprc);
  252. /* Get past the menu
  253. */
  254. for (lpInfo+=2; lpInfo[0]; lpInfo+=2)
  255. {
  256. hCtl = GetDlgItem(hWnd, lpInfo[1]);
  257. /* We check the style bit because the parent window may not be visible
  258. * yet (still in the create message)
  259. */
  260. if (!hCtl || !(GetWindowStyle(hCtl) & WS_VISIBLE))
  261. continue;
  262. GetWindowRect(hCtl, &rc);
  263. //
  264. // This will do the ScrrenToClient functionality, plus
  265. // it will return a good rect (left < right) when the
  266. // hWnd parent is RTL mirrored. [samera]
  267. //
  268. MapWindowPoints(HWND_DESKTOP, hWnd, (PPOINT)&rc, 2);
  269. SubtractRect(lprc, lprc, &rc);
  270. }
  271. }
  272. #if 0
  273. // BUGBUG: nuke this stuff for WIN32
  274. #define NibbleToChar(x) (N2C[x])
  275. static char N2C[] =
  276. {
  277. '0', '1', '2', '3', '4', '5', '6', '7',
  278. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
  279. } ;
  280. BOOL WINAPI MyWritePrivateProfileStruct(LPCSTR szSection, LPCSTR szKey,
  281. LPVOID lpStruct, UINT uSizeStruct, LPCSTR szFile)
  282. {
  283. PSTR pLocal, pTemp;
  284. BOOL bRet;
  285. BYTE FAR *lpByte;
  286. /* NULL lpStruct erases the the key */
  287. if (lpStruct == NULL) {
  288. if (szFile && *szFile)
  289. return WritePrivateProfileString(szSection, szKey, NULL, szFile);
  290. else
  291. WriteProfileString(szSection, szKey, NULL);
  292. }
  293. pLocal = (PSTR)LocalAlloc(LPTR, uSizeStruct*2 + 1);
  294. if (!pLocal)
  295. return(FALSE);
  296. lpByte = lpStruct;
  297. for (pTemp=pLocal; uSizeStruct>0; --uSizeStruct, ++lpByte)
  298. {
  299. BYTE bStruct;
  300. bStruct = *lpByte;
  301. *pTemp++ = NibbleToChar((bStruct>>4)&0x000f);
  302. *pTemp++ = NibbleToChar(bStruct&0x000f);
  303. }
  304. *pTemp = '\0';
  305. if (szFile && *szFile)
  306. bRet = WritePrivateProfileString(szSection, szKey, pLocal, szFile);
  307. else
  308. bRet = WriteProfileString(szSection, szKey, pLocal);
  309. LocalFree((HLOCAL)pLocal);
  310. return(bRet);
  311. }
  312. /* Note that the following works for both upper and lower case, and will
  313. * return valid values for garbage chars
  314. */
  315. #define CharToNibble(x) ((x)>='0'&&(x)<='9' ? (x)-'0' : ((10+(x)-'A')&0x000f))
  316. BOOL WINAPI MyGetPrivateProfileStruct(LPCSTR szSection, LPCSTR szKey,
  317. LPVOID lpStruct, UINT uSizeStruct, LPCSTR szFile)
  318. {
  319. PSTR pLocal, pTemp;
  320. int nLen;
  321. BYTE FAR *lpByte;
  322. nLen = uSizeStruct*2 + 10;
  323. pLocal = (PSTR)LocalAlloc(LPTR, nLen);
  324. if (!pLocal)
  325. return(FALSE);
  326. if (szFile && *szFile)
  327. nLen = GetPrivateProfileString(szSection, szKey, c_szNULL, pLocal, nLen,
  328. szFile);
  329. else
  330. nLen = GetProfileString(szSection, szKey, c_szNULL, pLocal, nLen);
  331. if ((UINT)nLen != uSizeStruct*2)
  332. {
  333. LocalFree((HLOCAL)pLocal);
  334. return(FALSE);
  335. }
  336. lpByte = lpStruct;
  337. for (pTemp=pLocal; uSizeStruct>0; --uSizeStruct, ++lpByte)
  338. {
  339. BYTE bStruct;
  340. char cTemp;
  341. cTemp = *pTemp++;
  342. bStruct = (BYTE)CharToNibble(cTemp);
  343. cTemp = *pTemp++;
  344. bStruct = (BYTE)((bStruct<<4) | CharToNibble(cTemp));
  345. *lpByte = bStruct;
  346. }
  347. LocalFree((HLOCAL)pLocal);
  348. return(TRUE);
  349. }
  350. #endif