home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cenvi23.zip / MENUCTRL.LIB < prev    next >
Text File  |  1994-08-19  |  12KB  |  291 lines

  1. // MenuCtrl.lib - Functions for controlling PM menus.
  2. // ver.3
  3. //
  4. //
  5.    gSubmenuBranch = "##";   // string to separate submenus in finding menu strings
  6. //
  7. //**** GetMenu(): Retrieve handle to menu of window
  8. // SYNTAX: int GetMenu([int FrameWindowHandle[,int MenuWindowID]])
  9. // WHERE: FrameWindowHandle: Handle of frame window, if 0 or not supplied
  10. //                           default to active window
  11. //        MenuWindowID: Child ID of MenuWindow from within frame; if 0 or not
  12. //                      supplied then default to FID_MENU; likely values are:
  13.             #define FID_MENU     0x8005   // standard Frame window menu
  14.             #define FID_SYSMENU  0x8002   // standard Frame window system menu (upper-left corner)
  15. // RETURN: Return handle to menu for this window, or NULL if no menu
  16. //
  17. //
  18. //**** MenuCommand(): Send a menu command to window
  19. // SYNTAX: bool MenuCommand(int FrameWindowHandle,int MenuWindowID,string MenuID[,bool Post[,int Result[,bool FullStringLength]]])
  20. //         bool MenuCommand(int FrameWindowHandle,int MenuWindowID,int MenuID[,bool Post,[int Result]])
  21. // WHERE: FrameWindowHandle: Handle of frame window, if 0 then default to active window
  22. //        MenuWindowID: Child ID of MenuWindow from within frame.  If this is
  23. //                      0 then will search all children of frame window that may
  24. //                      be menu, else specify specify ID, which will likely be FID_MENU or FID_SYSMENU
  25. //        MenuID: If integer then choose that menu id, else string and so
  26. //                will search through menu items for string with case
  27. //                insensitive match to start of string and ignoring the
  28. //                '~' character. Wherever string contains this gSubmenuBranch
  29. //                then parse down through menus.
  30. //        Post: Optional, True to WinPostMsg(), else WinSendMsg(); default False
  31. //        Result: If supplied then put result of WinSendMsg() or WinPostMsg() here
  32. //        FullStringLength: If True then match full string length, else only
  33. //                          partial. Default is False
  34. // RETURN: Return FALSE if menu item wasn't found, else TRUE
  35. // MODIFY: set Result if supplied
  36. //
  37. //
  38. //**** FindMenuItem(): find menu item in menu of a frame window
  39. // SYNTAX: int FindMenuItem(int FrameWindowHandle,int MenuWindowID,string MenuID,struct ItemData,int MenuHwnd[,bool FullStringLength])
  40. //         int FindMenuItem(int FrameWindowHandle,int MenuWindowID,int MenuID,struct ItemData,int MenuHwnd)
  41. // WHERE: same as MenuCommand(), except ItemData set as in MenuQueryItem(), and
  42. //        MenuHwnd which is set to the menu hwnd in which this item was found
  43. // RETURN: MenuID, or 0 if not found
  44. //
  45. //
  46. //**** GetMenuItemCount()
  47. // SYNTAX: int GetMenuItemCount(int MenuHandle)
  48. // WHERE: MenuHandle: as retrieved by GetMenu()
  49. // RETURN: Return number of items in menu
  50. //
  51. //
  52. //**** GetMenuItemID(): Get Menu item ID based on ordinal position
  53. // SYNTAX: int GetMenuItemID(int MenuHandle,int Pos)
  54. // WHERE: MenuHandle: as retrieved by GetMenu()
  55. //        Pos: ordinal position of this menu item
  56. // RETURN: Return item ID, or -1 if MenuHandle is or index is invalid
  57. //
  58. //
  59. //**** GetMenuString(): Get string of a menu item
  60. // SYNTAX: string GetMenuString(int MenuHandle,int id)
  61. // WHERE: MenuHandle: as retrieved by GetMenu()
  62. //        id: integer ID of menu item
  63. // RETURN: Return string for this menu item, will not be NULL but may be ""
  64. //
  65. //
  66. //**** MenuQueryItem(): Get settings and attributes for menu item
  67. // SYNTAX: struct MenuQueryItem(int MenuHandle,int ItemID)
  68. // WHERE: MenuHandle: as retrieved by GetMenu()
  69. //        ItemID: menu-item by ID
  70. // RETURN: Return structure with the following member elements
  71. //          .Position
  72. //          .Style      see below
  73. //          .Attribute  see below
  74. //          .id         item iD
  75. //          .SubMenu    Handle to submenu
  76. //          .Item
  77. //    .Style can have following attributes
  78.    #define MIS_SUBMENU           0x0010
  79.    #define MIS_SEPARATOR         0x0004
  80.    #define MIS_BITMAP            0x0002
  81.    #define MIS_TEXT              0x0001
  82.    #define MIS_BUTTONSEPARATOR   0x0200
  83.    #define MIS_BREAK             0x0400
  84.    #define MIS_BREAKSEPARATOR    0x0800
  85.    #define MIS_SYSCOMMAND        0x0040   // send syscommand if selected
  86.    #define MIS_OWNERDRAW         0x0008
  87.    #define MIS_HELP              0x0080
  88.    #define MIS_STATIC            0x0100
  89.    #define MIS_MULTMENU          0x0020   // multiple choice submenu
  90.    #define MIS_GROUP             0x1000   // multiple choice group start
  91. //    .Attribute can have following attributes
  92.    #define MIA_HILITED                0x8000
  93.    #define MIA_CHECKED                0x2000
  94.    #define MIA_DISABLED               0x4000
  95.    #define MIA_FRAMED                 0x1000
  96.    #define MIA_NODISMISS              0x0020
  97. //
  98. //
  99. //**** FindMenuString(): Among menus and submenus, find ID for string
  100. // SYNTAX: int FindMenuString(int MenuHandle,string PartialString,struct ItemData,int MenuHwnd[,bool FullStringLength])
  101. // WHERE: MenuHandle: as retrieved by GetMenu()
  102. //        PartialString: string to match menu (case-insensitive) up up to length
  103. //                       of this string
  104. //        ItemData: if item found, will be set as returned by MenuQueryItem()
  105. //        MenuHwnd: if found, then set this to handle of menu found
  106. //        FullStringLength: If True then match full string length, else only
  107. //                          partial. Default is False
  108. // RETURN: 0 if not found, else ID of matching menu item
  109. // MODIFY: Modify ItemData if menu item found
  110. // NOTE: This compares menu item string without the special ~ character, and
  111. //       so this is not very fast
  112. //
  113. //
  114.  
  115.  
  116. #include <WinMsg.lib>
  117. #include <GiveMem.lib>
  118. #define HWND_DESKTOP 1
  119.  
  120. _GetActiveWindow()
  121. {
  122.    #define ORD_WIN32QUERYACTIVEWINDOW  799
  123.    return PMDynamicLink("PMWIN",ORD_WIN32QUERYACTIVEWINDOW,BIT32,CDECL,HWND_DESKTOP);
  124. }
  125.  
  126. GetMenu(pFrameHandle,pMenuWindowID)
  127. {
  128.    lFHwnd = ( va_arg() && pFrameHandle ) ? pFrameHandle : _GetActiveWindow() ;
  129.    lMenuHwndID = ( 1 < va_arg() && pMenuWindowID ) ? pMenuWindowID : FID_MENU ;
  130.    #define ORD_WIN32WINDOWFROMID 899
  131.    return PMDynamicLink("PMWIN",ORD_WIN32WINDOWFROMID,BIT32,CDECL,lFHwnd,lMenuHwndID);
  132. }
  133.  
  134. GetMenuItemCount(pMenu)
  135. {
  136.    #define MM_QUERYITEMCOUNT  0x0184
  137.    return ( 0xFFFF & WinSendMsg(pMenu,MM_QUERYITEMCOUNT,0,0) );
  138. }
  139.  
  140. GetMenuItemID(pMenu,pPos)
  141. {
  142.    #define MM_ITEMIDFROMPOSITION      0x0190
  143.    lID = ( 0xFFFF & WinSendMsg(pMenu,MM_ITEMIDFROMPOSITION,pPos,0) );
  144.    return ( 0xFFFF == lID ? -1 : lID );
  145. }
  146.  
  147. MenuQueryItem(pMenu,pItemID)
  148. {
  149.    BLObSize(lRetBLOb,16);
  150.    memset(lRetBLOb,0,16);
  151.    poke(lSharedMem = GiveMemoryToWindow(pMenu),lRetBLOb,16);
  152.    #define MM_QUERYITEM    0x0182
  153.    #define MM_STARTMENUMODE           0x0185
  154.    #define MM_ENDMENUMODE             0x0186
  155.    WinSendMsg(pMenu,MM_QUERYITEM,MakeLongFromShorts(pItemID,True),lSharedMem);
  156.    lRetBLOb = peek(lSharedMem,16);
  157.    lRet.Position = BLObGet(lRetBLOb,0,SWORD16);
  158.    lRet.Style = BLObGet(lRetBLOb,2,UWORD16);
  159.    lRet.Attribute = BLObGet(lRetBLOb,4,UWORD16);
  160.    lRet.id = BLObGet(lRetBLOb,6,UWORD16);
  161.    lRet.SubMenu = BLObGet(lRetBLOb,8,UWORD32);
  162.    lRet.Item = BLObGet(lRetBLOb,12,UWORD32);
  163.    return lRet;
  164. }
  165.  
  166. GetMenuString(pMenu,pID)
  167. {
  168.    #define MM_QUERYITEMTEXT   0x018B
  169.    lSharedMem = GiveMemoryToWindow(pMenu);
  170.    if ( lTextLen = WinSendMsg(pMenu,MM_QUERYITEMTEXT,MakeLongFromShorts(pID,1000),lSharedMem) )
  171.       lString = peek(lSharedMem,lTextLen);
  172.    lString[lTextLen] = '\0';
  173.    return lString;
  174. }
  175.  
  176. MenuStringICompare(pMenu,pMenuID,pString,pCompareLen,pFullStringLength)
  177. {  // return True if i-compare, else false
  178.    lMenuString = GetMenuString(pMenu,pMenuID);
  179.    if ( lMenuString[0] ) {
  180.       // remove all '~' characters
  181.       lFindTilde = lMenuString;
  182.       while ( lFindTilde = strchr(lFindTilde,'~') )
  183.          strcpy(lFindTilde,lFindTilde+1);
  184.       // compare new found string against our source
  185.       if ( !strnicmp(lMenuString,pString,pCompareLen)
  186.         && (!pFullStringLength || '\0'==lMenuString[pCompareLen]) ) {
  187.          // YEA!!!! it is found
  188.          return True;
  189.       }
  190.    }
  191.    return False;
  192. }
  193.  
  194. FindMenuString(pMenu,pPartialString,pItemData,pFoundMenuHwnd,pFullStringLength)
  195. {
  196.    lFullStringLength = 4 < va_arg() ? pFullStringLength : False ;
  197.    // check if looking just for a menu or parsing down sub menus
  198.    if ( lNextMenuString = strstr(pPartialString,gSubmenuBranch) ) {
  199.       lCompareLen = lNextMenuString - pPartialString;
  200.       lNextMenuString += strlen(gSubmenuBranch);
  201.    } else {
  202.       lCompareLen = strlen(pPartialString);
  203.    }
  204.    lCount = GetMenuItemCount(pMenu);
  205.    for ( lOrd = 0; lOrd < lCount; lOrd++ ) {
  206.       if ( -1 != (lMenuID = GetMenuItemID(pMenu,lOrd)) ) {
  207.          lMenu = MenuQueryItem(pMenu,lMenuID);
  208.          if ( lMenu.Style & MIS_SUBMENU ) {
  209.             // this is a submenu, so check down this submenu
  210.             if ( lNextMenuString ) {
  211.                // go down in menus only if this matches
  212.                if ( MenuStringICompare(pMenu,lMenuID,pPartialString,lCompareLen,lFullStringLength) ) {
  213.                   if ( lMenuID = FindMenuString(lMenu.SubMenu,lNextMenuString,pItemData,pFoundMenuHwnd,lFullStringLength) )
  214.                      return lMenuID;
  215.                }
  216.             } else {
  217.                if ( lMenuID = FindMenuString(lMenu.SubMenu,pPartialString,pItemData,pFoundMenuHwnd,lFullStringLength) )
  218.                   return lMenuID;
  219.             }
  220.          } else if ( !lNextMenuString ) {
  221.             if ( MenuStringICompare(pMenu,lMenuID,pPartialString,lCompareLen,lFullStringLength) ) {
  222.                pFoundMenuHwnd = pMenu;
  223.                pItemData = lMenu;
  224.                return lMenuID;
  225.             }
  226.          }
  227.       }
  228.    }
  229.    return 0;
  230. }
  231.  
  232. FindMenuItem(pFrameHwnd,pMenWinID,pMenuID,pItemData,pFoundMenuHwnd,pFullStringLength)
  233. {
  234.    lFHwnd = pFrameHwnd ? pFrameHwnd : _GetActiveWindow() ;
  235.    lMenuID = 0;   // assume failure
  236.    lFullStringLength = 5 < va_arg() ? pFullStringLength : False ;
  237.  
  238.    if ( pMenWinID ) {
  239.       // try on this one window ID
  240.       if ( lMenuHwnd = GetMenu(lFHwnd,pMenWinID) ) {
  241.          pFoundMenuHwnd = lMenuHwnd;
  242.          lMenuID = ( 0 == DataDimension(pMenuID) )
  243.                  ? (pItemData = MenuQueryItem(lMenuHwnd,pMenuID)).id
  244.                  : FindMenuString(lMenuHwnd,pMenuID,pItemData,pFoundMenuHwnd,lFullStringLength);
  245.       }
  246.    } else {
  247.       // must try all children
  248.       #define ORD_WIN32BEGINENUMWINDOWS   702
  249.       #define ORD_WIN32GETNEXTWINDOW      756
  250.       #define ORD_WIN32ENDENUMWINDOWS     737
  251.       lEnumHandle = DynamicLink("PMWIN",ORD_WIN32BEGINENUMWINDOWS,BIT32,CDECL,lFHwnd);
  252.       while ( lChild = DynamicLink("PMWIN",ORD_WIN32GETNEXTWINDOW,BIT32,CDECL,lEnumHandle) ) {
  253.          pFoundMenuHwnd = lChild;
  254.          if ( lMenuID = ( 0 == DataDimension(pMenuID) )
  255.                       ? (pItemData = MenuQueryItem(lMenuHwnd,pMenuID)).id
  256.                       : FindMenuString(lChild,pMenuID,pItemData,pFoundMenuHwnd,lFullStringLength) )
  257.             break;
  258.       }
  259.       DynamicLink("PMWIN",ORD_WIN32ENDENUMWINDOWS,BIT32,CDECL,lEnumHandle)
  260.    }
  261.    return lMenuID;
  262. }
  263.  
  264. MenuCommand(pFrameHwnd,pMenWinID,pMenuID,pPost,pResult,pFullStringLength)
  265. {
  266.    lFHwnd = pFrameHwnd ? pFrameHwnd : _GetActiveWindow() ;
  267.    lFullStringLength = 5 < va_arg() ? pFullStringLength : False ;
  268.    if ( !(lMenuID = FindMenuItem(lFHwnd,pMenWinID,pMenuID,lItemData,lFoundMenuHwnd,lFullStringLength)) )
  269.       return FALSE;
  270.  
  271.    // send menu_select message
  272.    // #define WM_MENUSELECT   0x34
  273.    // if ( !WinSendMsg(lFHwnd,WM_MENUSELECT,MakeLongFromShorts(lMenuID,True),lFoundMenuHwnd) )
  274.    //    return FALSE;
  275.  
  276.    // item info will tell whether messase is wm_command or wm_syscommand
  277.    #define WM_COMMAND      0x20
  278.    #define WM_SYSCOMMAND   0x21
  279.    lMsg = (lItemData.Style & MIS_SYSCOMMAND) ? WM_SYSCOMMAND : WM_COMMAND ;
  280.    #define CMDSRC_MENU 2
  281.    lParam2 = MakeLongFromShorts(CMDSRC_MENU,False);
  282.  
  283.    lResult = ( 3 < va_arg() && pPost )
  284.            ? WinPostMsg(lFHwnd,lMsg,lMenuID,lParam2)
  285.            : WinSendMsg(lFHwnd,lMsg,lMenuID,lParam2) ;
  286.    if ( 4 < va_arg() )
  287.       pResult = lResult;
  288.    return(TRUE);
  289. }
  290.  
  291.