• Welcome to Valhalla Legends Archive.
 

[win32] Getting menu items of topmost window?

Started by Banana fanna fo fanna, November 18, 2003, 07:19 PM

Previous topic - Next topic

Banana fanna fo fanna

Was wondering if there is a way to get a list of all the menu items of the active window (got the handle using GetActiveWindow) and their key shortcuts.

Thanks a bunch.

Skywing

Quote from: St0rm.iD on November 18, 2003, 07:19 PM
Was wondering if there is a way to get a list of all the menu items of the active window (got the handle using GetActiveWindow) and their key shortcuts.

Thanks a bunch.
Try GetSystemMenu.  If you can't use this function on the window residing in a different process (the documentation doesn't say anything about this that I can see), you'll have to use code injection to access the menu.

dev invisible

Public Type MENUITEMINFO
   cbSize As Long
   fMask As Long
   fType As Long
   fState As Long
   wID As Long
   hSubMenu As Long
   hbmpChecked As Long
   hbmpUnchecked As Long
   dwItemData As Long
   dwTypeData As String
   cch As Long
End Type

Public Declare Function GetActiveWindow Lib "user32" () As Long
Public Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
Public Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal b As Long, lpMenuItemInfo As MENUITEMINFO) As Long
Public Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long

Public Const MIIM_TYPE = &H10
------------------------------------------------------------

These are all the declarations you should need to do what you want.  Your using GetActiveWindow to grab the hWnd of a program.  GetMenu gets the hWnd of the menu.  GetMenuItemCount gets the number of menu items for the menu hWnd passed to it.  GetSubMenu gets the menu hWnd for the index of the submenu of the hWnd you pass in.  GetMenuItemInfo is passed a menu hWnd, the index of the menu item to get info for, false (to state that the previous paramater is a menu location and not a menuID), and a menuInfo object.  The menuInfo object should have its cbSize parameter set to the length of itself (len(menuInfo)), its dwType data initialized large enough to hold your menu info (i use string(128, chr(0)), its cch parameter set to len(menuInfo.dwTypeData), and its fMask set to the MIIM_TYPE constant.  After passing this object to the GetMenuItemInfo function, the dwTypeData parameter will be filled with the info for that menu.  The easiest way to get at the info you want (the name and shortcut), do a replace chr(0) with "".


Private Sub DisplayMenuItems(lngMenuHwnd As Long)
   Dim i As Integer, j As Integer
   Dim s As String
   Dim menuInfo As MENUITEMINFO
   
   For i = 0 To GetMenuItemCount(lngMenuHwnd) - 1
       menuInfo.cbSize = Len(menuInfo)
       menuInfo.dwTypeData = String(128, Chr(0))
       menuInfo.cch = Len(menuInfo.dwTypeData)
       menuInfo.fMask = MIIM_TYPE
       Call GetMenuItemInfo(lngMenuHwnd, i, True, menuInfo)
       menuInfo.dwTypeData = Replace(menuInfo.dwTypeData, Chr(0), "")
       s = ""
       For j = 1 To Len(menuInfo.dwTypeData)
           s = s & " " & Asc(Mid(menuInfo.dwTypeData, j, 1))
       Next
       Debug.Print "Length: " & Len(menuInfo.dwTypeData) & vbCrLf & "Data: " & menuInfo.dwTypeData & vbCrLf & s
   Next
   
End Sub


outputs
----------
Length: 11
Data: Cu&t  Ctrl+X
67 117 38 116 9 67 116 114 108 43 88
Length: 12
Data: &Copy Ctrl+C
38 67 111 112 121 9 67 116 114 108 43 67
Length: 13
Data: &Paste    Ctrl+P
38 80 97 115 116 101 9 67 116 114 108 43 80
Length: 18
Data: Select &All   Ctrl+A
83 101 108 101 99 116 32 38 65 108 108 9 67 116 114 108 43 65
-------------------
Note: chr(9) is used to seperate the text from the shortcut

Banana fanna fo fanna

Although a dead thread, I have been searching forever for that. Thanks a lot...I'll gogo port to python immediately :)