Update 2
Code found in System.Windows.Forms.MenuItem
using reflection. Seems that they use string also.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MENUITEMINFO_T
{
public int cbSize = Marshal.SizeOf(typeof(NativeMethods.MENUITEMINFO_T));
public int fMask;
public int fType;
public int fState;
public int wID;
public IntPtr hSubMenu;
public IntPtr hbmpChecked;
public IntPtr hbmpUnchecked;
public IntPtr dwItemData;
public string dwTypeData;
public int cch;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetMenuItemInfo(HandleRef hMenu, int uItem, bool fByPosition, [In, Out] MENUITEMINFO_T lpmii);
................
MENUITEMINFO_T menuiteminfo_t;
menuiteminfo_t = new MENUITEMINFO_T();
menuiteminfo_t.fMask = MIIM_STRING;
menuiteminfo_t.dwTypeData = new string('\0', 256);
menuiteminfo_t.cch = menuiteminfo_t.dwTypeData.Length - 1;
bool result = GetMenuItemInfo(new HandleRef(null, hMenu), 0, true, menuiteminfo_t);
Update 1
As @Remy Lebeau suggested, there was a differences between String marshaling vs char[] marshaling. After I added CharSet=CharSet.Auto
attribute to the structure everything was working fine using your code.
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct MENUITEMINFO
{
public uint cbSize;
public uint fMask;
public uint fType;
public uint fState;
public uint wID;
public IntPtr hSubMenu;
public IntPtr hbmpChecked;
public IntPtr hbmpUnchecked;
public IntPtr dwItemData;
public string dwTypeData;
public uint cch;
public IntPtr hbmpItem;
// return the size of the structure
public static uint sizeOf
{
get { return (uint)Marshal.SizeOf(typeof(MENUITEMINFO)); }
}
}
IntPtr hWnd = FindWindow(null, "untitled - notepad");
IntPtr hMenu = GetMenu(hWnd);
MENUITEMINFO mif = new MENUITEMINFO();
uint MIIM_STRING = 0x00000040;
uint MFT_STRING = 0x00000000;
mif.cbSize = MENUITEMINFO.sizeOf;//(uint)Marshal.SizeOf(typeof(MENUITEMINFO));
mif.fMask = MIIM_STRING;
mif.fType = MFT_STRING;
mif.dwTypeData = null;
//IntPtr hMenu = menuStrip1.Handle;
//1st call to get the text length into (cch)
bool res = GetMenuItemInfo(hMenu, (uint)0, true, ref mif); //To load cch into memory
if (res)
{
mif.cch += 1;
//Set the length of the buffer to cch + 1
mif.dwTypeData = new string(' ', (int)(mif.cch));
res = GetMenuItemInfo(hMenu, (uint)0, true, ref mif); //To fill dwTypeData
}
Check this link for more details about Default Marshaling for Strings
OLD:
You need to initialize dwTypeData and cch data members.
Get Menu items string example (working with the new MENUITEMINFO structure):
List<string> ls = new List<string>();
IntPtr hMenu = Win32.GetMenu(hWnd);
if (hMenu.ToInt32() != 0)
{
for (int i = Win32.GetMenuItemCount(hMenu); i >= 0; i--)
{
uint MIIM_STRING = 0x00000040;
uint MFT_STRING = 0x00000000;
Win32.MENUITEMINFO mif = new Win32.MENUITEMINFO();
mif.cbSize = (uint)Marshal.SizeOf(typeof(Win32.MENUITEMINFO));
mif.fMask = MIIM_STRING;
mif.fType = MFT_STRING;
mif.cch = 256;
mif.dwTypeData = new string(' ', (int)(mif.cch));
bool a = Win32.GetMenuItemInfo(hMenu, 0, true, ref mif);
ls.Add(mif.dwTypeData);
}
}