menuhelp.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 9k
Category:

Windows Kernel

Development Platform:

Visual C++

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