GetMenuItemInfo not returning full string

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
Hello Everyone,
I am using the GetMenuItemInfo API in my program to get the menu text from external windows. I can get it to return the dwTypeData but it seems to be one character short. It gets the length of the menu text as it appears in the menu correctly but, when it returns the string it has the "&" in front of it that is used for the menu`s shortcut key. For example "Open... Cntl+O" will return as "&Open... Ctrl+". I tried setting the dwTypeData buffer to (+ 2) but, it returns the same string. I have been reading up on passing managed and unmanaged structures in and out but, i am not sure how to get it to ether ignore the "&" or to fool the buffer into getting the last character.
This example can be tested by opening notepad and then running this example.
Module1.vbOption Explicit On
Imports System.Runtime.InteropServices

Module Module1
Public Const MFT_STRING = &H0
Public Const MIIM_TYPE = &H10

<DllImport("user32.dll")> Public Function GetMenu(ByVal hWnd As IntPtr) As IntPtr
End Function

<DllImport("user32.dll")> Public Function GetSubMenu(ByVal hMenu As IntPtr, ByVal nPos As Integer) As IntPtr
End Function

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Public Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function

Public Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoW" (ByVal hMenu As Integer, ByVal unit As Integer, ByVal byPosition As Boolean, ByRef lpMenuItemInfo As MENUITEMINFO) As Integer

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure MENUITEMINFO
Public cbSize As Integer
Public fMask As Integer
Public fType As Integer
Public fState As Integer
Public wID As Integer
Public hSubMenu As Integer
Public hbmpChecked As Integer
Public hbmpUnchecked As Integer
Public dwItemData As Integer
Public dwTypeData As String
Public cch As Integer
End Structure
End Module
Form1.vbOption Explicit On

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim hWnd As IntPtr = FindWindow(Nothing, "untitled - notepad")
Dim hSubMenu As IntPtr = GetSubMenu(GetMenu(hWnd), 0)

Dim menuinfo As New MENUITEMINFO
menuinfo.cbSize = Len(menuinfo)
menuinfo.fMask = MIIM_TYPE
menuinfo.fType = MFT_STRING
menuinfo.dwTypeData = ""
menuinfo.cch = 0

1st call is to get the text length into (cch)
GetMenuItemInfo(hSubMenu, 0, True, menuinfo)
MessageBox.Show(menuinfo.cch.ToString)

Set the length of the buffer to cch + 1
menuinfo.dwTypeData = Space(menuinfo.cch + 1)

2nd call is to get the text into (dwTypeData)
GetMenuItemInfo(hSubMenu, 0, True, menuinfo)

MessageBox.Show(menuinfo.dwTypeData)
End Sub
End Class

View the full article
 
Back
Top