home *** CD-ROM | disk | FTP | other *** search
- // MenuCtrl.lib - Functions for controlling PM menus.
- // ver.1
- //
- //**** GetMenu(): Retrieve handle to menu of window
- // SYNTAX: int GetMenu([int FrameWindowHandle[,int MenuWindowID]])
- // WHERE: FrameWindowHandle: Handle of frame window, if 0 or not supplied
- // default to active window
- // MenuWindowID: Child ID of MenuWindow from within frame; if 0 or not
- // supplied then default to FID_MENU; likely values are:
- #define FID_MENU 0x8005 // standard Frame window menu
- #define FID_SYSMENU 0x8002 // standard Frame window system menu (upper-left corner)
- // RETURN: Return handle to menu for this window, or NULL if no menu
- //
- //
- //**** MenuCommand(): Send a menu command to window
- // SYNTAX: bool MenuCommand(int FrameWindowHandle,int MenuWindowID,string MenuID[,bool Post,[int Result]])
- // bool MenuCommand(int FrameWindowHandle,int MenuWindowID,int MenuID[,bool Post,[int Result]])
- // WHERE: FrameWindowHandle: Handle of frame window, if 0 then default to active window
- // MenuWindowID: Child ID of MenuWindow from within frame. If this is
- // 0 then will search all children of frame window that may
- // be menu, else specify specify ID, which will likely be FID_MENU or FID_SYSMENU
- // MenuID: If integer then choose that menu id, els string and so
- // will search through menu items for string with case
- // insensitive match to start of string and ignoring the
- // '~' character
- // Post: Optional, True to WinPostMsg(), else WinSendMsg(); default False
- // Result: If supplied then put result of WinSendMsg() or WinPostMsg() here
- // RETURN: Return FALSE if menu item wasn't found, else TRUE
- // MODIFY: set Result if supplied
- //
- //
- //**** FindMenuItem(): find menu item in menu of a frame window
- // SYNTAX: int MenuCommand(int FrameWindowHandle,int MenuWindowID,string MenuID,struct ItemData,int MenuHwnd)
- // int MenuCommand(int FrameWindowHandle,int MenuWindowID,int MenuID,struct ItemData,int MenuHwnd)
- // WHERE: same as MenuCommand(), except ItemData set as in MenuQueryItem(), and
- // MenuHwnd which is set to the menu hwnd in which this item was found
- // RETURN: MenuID, or 0 if not found
- //
- //
- //**** GetMenuItemCount()
- // SYNTAX: int GetMenuItemCount(int MenuHandle)
- // WHERE: MenuHandle: as retrieved by GetMenu()
- // RETURN: Return number of items in menu
- //
- //
- //**** GetMenuItemID(): Get Menu item ID based on ordinal position
- // SYNTAX: int GetMenuItemID(int MenuHandle,int Pos)
- // WHERE: MenuHandle: as retrieved by GetMenu()
- // Pos: ordinal position of this menu item
- // RETURN: Return item ID, or -1 if MenuHandle is or index is invalid
- //
- //
- //**** GetMenuString(): Get string of a menu item
- // SYNTAX: string GetMenuString(int MenuHandle,int id)
- // WHERE: MenuHandle: as retrieved by GetMenu()
- // id: integer ID of menu item
- // RETURN: Return string for this menu item, will not be NULL but may be ""
- //
- //
- //**** MenuQueryItem(): Get settings and attributes for menu item
- // SYNTAX: struct GetMenuState(int MenuHandle,int ItemID)
- // WHERE: MenuHandle: as retrieved by GetMenu()
- // ItemID: menu-item by ID
- // RETURN: Return structure with the following member elements
- // .Position
- // .Style see below
- // .Attribute see below
- // .id item iD
- // .SubMenu Handle to submenu
- // .Item
- // .Style can have following attributes
- #define MIS_SUBMENU 0x0010
- #define MIS_SEPARATOR 0x0004
- #define MIS_BITMAP 0x0002
- #define MIS_TEXT 0x0001
- #define MIS_BUTTONSEPARATOR 0x0200
- #define MIS_BREAK 0x0400
- #define MIS_BREAKSEPARATOR 0x0800
- #define MIS_SYSCOMMAND 0x0040 // send syscommand if selected
- #define MIS_OWNERDRAW 0x0008
- #define MIS_HELP 0x0080
- #define MIS_STATIC 0x0100
- #define MIS_MULTMENU 0x0020 // multiple choice submenu
- #define MIS_GROUP 0x1000 // multiple choice group start
- // .Attribute can have following attributes
- #define MIA_HILITED 0x8000
- #define MIA_CHECKED 0x2000
- #define MIA_DISABLED 0x4000
- #define MIA_FRAMED 0x1000
- #define MIA_NODISMISS 0x0020
- //
- //
- //**** FindMenuString(): Among menus and submenus, find ID for string
- // SYNTAX: int FindMenuString(int MenuHandle,string PartialString,struct ItemData,int MenuHwnd)
- // WHERE: MenuHandle: as retrieved by GetMenu()
- // PartialString: string to match menu (case-insensitive) up up to length
- // of this string
- // ItemData: if item found, will be set as returned by MenuQueryItem()
- // MenuHwnd: if found, then set this to handle of menu found
- // RETURN: 0 if not found, else ID of matching menu item
- // MODIFY: Modify ItemData if menu item found
- // NOTE: This compares menu item string without the special ~ character, and
- // so this is not very fast
- //
- //
-
-
- #include <WinMsg.lib>
- #include <GiveMem.lib>
- #define HWND_DESKTOP 1
-
- _GetActiveWindow()
- {
- #define ORD_WIN32QUERYACTIVEWINDOW 799
- return PMDynamicLink("PMWIN",ORD_WIN32QUERYACTIVEWINDOW,BIT32,CDECL,HWND_DESKTOP);
- }
-
- GetMenu(pFrameHandle,pMenuWindowID)
- {
- lFHwnd = ( va_arg() && pFrameHandle ) ? pFrameHandle : _GetActiveWindow() ;
- lMenuHwndID = ( 1 < va_arg() && pMenuWindowID ) ? pMenuWindowID : FID_MENU ;
- #define ORD_WIN32WINDOWFROMID 899
- return PMDynamicLink("PMWIN",ORD_WIN32WINDOWFROMID,BIT32,CDECL,lFHwnd,lMenuHwndID);
- }
-
- GetMenuItemCount(pMenu)
- {
- #define MM_QUERYITEMCOUNT 0x0184
- return ( 0xFFFF & WinSendMsg(pMenu,MM_QUERYITEMCOUNT,0,0) );
- }
-
- GetMenuItemID(pMenu,pPos)
- {
- #define MM_ITEMIDFROMPOSITION 0x0190
- lID = ( 0xFFFF & WinSendMsg(pMenu,MM_ITEMIDFROMPOSITION,pPos,0) );
- return ( 0xFFFF == lID ? -1 : lID );
- }
-
- MenuQueryItem(pMenu,pItemID)
- {
- BLObSize(lRetBLOb,16);
- memset(lRetBLOb,0,16);
- poke(lSharedMem = GiveMemoryToWindow(pMenu),lRetBLOb,16);
- #define MM_QUERYITEM 0x0182
- #define MM_STARTMENUMODE 0x0185
- #define MM_ENDMENUMODE 0x0186
- WinSendMsg(pMenu,MM_QUERYITEM,MakeLongFromShorts(pItemID,True),lSharedMem);
- lRetBLOb = peek(lSharedMem,16);
- lRet.Position = BLObGet(lRetBLOb,0,SWORD16);
- lRet.Style = BLObGet(lRetBLOb,2,UWORD16);
- lRet.Attribute = BLObGet(lRetBLOb,4,UWORD16);
- lRet.id = BLObGet(lRetBLOb,6,UWORD16);
- lRet.SubMenu = BLObGet(lRetBLOb,8,UWORD32);
- lRet.Item = BLObGet(lRetBLOb,12,UWORD32);
- return lRet;
- }
-
- GetMenuString(pMenu,pID)
- {
- #define MM_QUERYITEMTEXT 0x018B
- lSharedMem = GiveMemoryToWindow(pMenu);
- if ( lTextLen = WinSendMsg(pMenu,MM_QUERYITEMTEXT,MakeLongFromShorts(pID,1000),lSharedMem) )
- lString = peek(lSharedMem,lTextLen);
- lString[lTextLen] = '\0';
- return lString;
- }
-
- FindMenuString(pMenu,pPartialString,pItemData,pFoundMenuHwnd)
- {
- lPartialLen = strlen(pPartialString);
- lCount = GetMenuItemCount(pMenu);
- for ( lOrd = 0; lOrd < lCount; lOrd++ ) {
- if ( -1 != (lMenuID = GetMenuItemID(pMenu,lOrd)) ) {
- lMenu = MenuQueryItem(pMenu,lMenuID);
- if ( lMenu.Style & MIS_SUBMENU ) {
- // this is a submenu, so check down this submenu
- if ( lMenuID = FindMenuString(lMenu.SubMenu,pPartialString,pItemData,pFoundMenuHwnd) ) {
- return lMenuID;
- }
- } else {
- // get string for this item, and compare against partial string with all '&'
- lMenuString = GetMenuString(pMenu,lMenuID);
- if ( lMenuString[0] ) {
- // remove all '~' characters
- lFindTilde = lMenuString;
- while ( lFindTilde = strchr(lFindTilde,'~') )
- strcpy(lFindTilde,lFindTilde+1);
- // compare new found string against our source
- if ( !strnicmp(lMenuString,pPartialString,lPartialLen) ) {
- // YEA!!!! it is found
- pFoundMenuHwnd = pMenu;
- pItemData = lMenu;
- return lMenuID;
- }
- }
- }
- }
- }
- return 0;
- }
-
- FindMenuItem(pFrameHwnd,pMenWinID,pMenuID,pItemData,pFoundMenuHwnd)
- {
- lFHwnd = pFrameHwnd ? pFrameHwnd : _GetActiveWindow() ;
- lMenuID = 0; // assume failure
-
- if ( pMenWinID ) {
- // try on this one window ID
- if ( lMenuHwnd = GetMenu(lFHwnd,pMenWinID) ) {
- pFoundMenuHwnd = lMenuHwnd;
- lMenuID = ( 0 == DataDimension(pMenuID) )
- ? (pItemData = MenuQueryItem(lMenuHwnd,pMenuID)).id
- : FindMenuString(lMenuHwnd,pMenuID,pItemData,pFoundMenuHwnd);
- }
- } else {
- // must try all children
- #define ORD_WIN32BEGINENUMWINDOWS 702
- #define ORD_WIN32GETNEXTWINDOW 756
- #define ORD_WIN32ENDENUMWINDOWS 737
- lEnumHandle = DynamicLink("PMWIN",ORD_WIN32BEGINENUMWINDOWS,BIT32,CDECL,lFHwnd);
- while ( lChild = DynamicLink("PMWIN",ORD_WIN32GETNEXTWINDOW,BIT32,CDECL,lEnumHandle) ) {
- pFoundMenuHwnd = lChild;
- if ( lMenuID = ( 0 == DataDimension(pMenuID) )
- ? (pItemData = MenuQueryItem(lMenuHwnd,pMenuID)).id
- : FindMenuString(lChild,pMenuID,pItemData,pFoundMenuHwnd) )
- break;
- }
- DynamicLink("PMWIN",ORD_WIN32ENDENUMWINDOWS,BIT32,CDECL,lEnumHandle)
- }
- return lMenuID;
- }
-
- MenuCommand(pFrameHwnd,pMenWinID,pMenuID,pPost,pResult)
- {
- lFHwnd = pFrameHwnd ? pFrameHwnd : _GetActiveWindow() ;
- if ( !(lMenuID = FindMenuItem(lFHwnd,pMenWinID,pMenuID,lItemData,lFoundMenuHwnd)) )
- return FALSE;
-
- // send menu_select message
- // #define WM_MENUSELECT 0x34
- // if ( !WinSendMsg(lFHwnd,WM_MENUSELECT,MakeLongFromShorts(lMenuID,True),lFoundMenuHwnd) )
- // return FALSE;
-
- // item info will tell whether messase is wm_command or wm_syscommand
- #define WM_COMMAND 0x20
- #define WM_SYSCOMMAND 0x21
- lMsg = (lItemData.Style & MIS_SYSCOMMAND) ? WM_SYSCOMMAND : WM_COMMAND ;
- #define CMDSRC_MENU 2
- lParam2 = MakeLongFromShorts(CMDSRC_MENU,False);
-
- lResult = ( 3 < va_arg() && pPost )
- ? WinPostMsg(lFHwnd,lMsg,lMenuID,lParam2)
- : WinSendMsg(lFHwnd,lMsg,lMenuID,lParam2) ;
- if ( 4 < va_arg() )
- pResult = lResult;
- return(TRUE);
- }
-