User ( posted:

The FindMenuItem function posted by Mark Butler awhile back causes Robot
to crash when the specified menuPath is DISABLED. This occurs because it
passes the empty itemString returned by GetMenuString to
CleanUpMenuString, which in turn passes it to the SQABasic GetField
function. GetField causes an invalid page fault in SQA7BL.DLL, which
crashes Robot.

Here's a modified version that avoids this problem:

Private Function FindMenuItem& (pos&, hMenu&, menuPath$)
'Author: Luke Goodwin (based on code from Mark Butler)
'Purpose: This is the function that does most of the work (and
' Finds the position of first element in menuPath. If the
' item is a sub-menu then call again.
' hMenu: Handle of menu to search.
' menuPath: Menu path string, search for first element.
' pos: Position of item if found, 0 otherwise.
'Return Value: Handle of menu containing found element, 0 otherwise.

Dim menuPathHead$, menuPathRemainder$
Dim hCurrentMenu&, hSubMenu&
Dim numItems&, i&
Dim itemString as string *256
Dim menuString$, strLen&
const maxSize& = 255

FindMenuItem = 0

'Get top-level menu from menu path and save remainder:
menuPathHead = GetMenuPathHead(menuPath, menuPathRemainder)

'Save the current menu we're working on so it's not overwritten
'while scanning through its items:
hCurrentMenu = hMenu
numItems = GetMenuItemCount(hCurrentMenu) 'Win32 API call
For i = 0 To (numItems - 1)
'Get the menu string of the i'th item in the menu specified
'by hCurrentMenu. Test if it matches what we're looking for:

'Skip this iteration if strLen = 0. Will get fatal error if empty
'itemString passed to GetField() (e.g., if menuItem is DISABLED)!
If strLen > 0 Then
strLen = GetMenuString(hCurrentMenu, i, itemString, maxSize, _
menuString = CleanUpMenuString(Left$(itemString, strLen))
If (StrComp(menuString, menuPathHead) = 0) Then
'It matches! If this item is NOT a sub-menu then we're
hSubMenu = GetSubMenu(hCurrentMenu, i) ' Win32 API

If (hSubMenu = 0) Then
'Double-check to make sure there's nothing
'left to look for:
If (menuPathRemainder = "") Then
FindMenuItem = hCurrentMenu
pos = i
End If

'Either way, we're bailing out now:
Exit For
'It IS a sub-menu, so check-out this sub menu using
'path remainder (here's the recursion):
hMenu = FindMenuItem(pos, hSubMenu, menuPathRemainder
If ( hMenu <> 0 ) Then
FindMenuItem = hMenu
Exit For
End If
End If
End If
End If
Next i

Exit Function
End Function