c# - Win32 API GetMenuItemInfo 仅返回项目文本的第一个字符

标签 c# winapi pinvoke

我正在尝试使用 GetMenuItemInfo API 收集菜单项的文本。

这是我正在使用的代码:

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool GetMenuItemInfo(IntPtr hMenu, uint uItem, bool fByPosition, ref MENUITEMINFO lpmii);

[StructLayout(LayoutKind.Sequential)]
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)); }
    }
}

MENUITEMINFO mif = new MENUITEMINFO();
mif.cbSize = MENUITEMINFO.sizeOf;
mif.fMask = MIIM_STRING; 
mif.fType = MFT_STRING;
mif.dwTypeData = null;
bool res = Win32.GetMenuItemInfo(hMenu, (uint)0, true, ref mif); //To load cch into memory

mif.cch += 1;
mif.fMask = MIIM_STRING;
mif.fType = MFT_STRING;
mif.dwTypeData = new String(' ', (Int32)(mif.cch));

res = Win32.GetMenuItemInfo(hMenu, (uint)i, true, ref mif); //To fill dwTypeData

不幸的是,在这些行之后,dwTypeData 结果是一个只有 1 个字符而不是 mif.cch 字符的字符串。注意:这个字符是菜单项的第一个字符!

返回 MENUITEMINFO 结构时,数据编码似乎有一些错位,不是吗?

请告诉我如何解决此类问题!

最佳

格格西

最佳答案

您的 header 翻译非常好,但您的dwTypeData 不太正确。不能使用 string 从调用者到被调用者编码。您需要像这样通过手动编码来做到这一点。

[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool GetMenuItemInfo(IntPtr hMenu, int uItem, bool fByPosition, MENUITEMINFO lpmii);

[StructLayout(LayoutKind.Sequential)]
public class MENUITEMINFO 
{
    public int 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 IntPtr dwTypeData;
    public uint cch;
    public IntPtr hbmpItem;

    public MENUITEMINFO()
    {
        cbSize = Marshal.SizeOf(typeof(MENUITEMINFO));
    }
}

....

MENUITEMINFO mif = new MENUITEMINFO();
mif.fMask = MIIM_STRING; 
mif.fType = MFT_STRING;

mif.dwTypeData = IntPtr.Zero;
bool res = GetMenuItemInfo(hMenu, 0, true, mif);
if (!res)
    throw new Win32Exception();
mif.cch++;
mif.dwTypeData = Marshal.AllocHGlobal((IntPtr)(mif.cch*2));
try
{
    res = GetMenuItemInfo(hMenu, 0, true, mif);
    if (!res)
        throw new Win32Exception();
    string caption = Marshal.PtrToStringUni(mif.dwTypeData);
}
finally
{
    Marshal.FreeHGlobal(mif.dwTypeData);
}

关于c# - Win32 API GetMenuItemInfo 仅返回项目文本的第一个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22852461/

相关文章:

c# - Entity Framework 加入与包含

c# - Azure:表脚本不是由 sql 执行触发的

c++ - 我应该使用 AcceptEx() 还是 WSAAccept()?

c# - P/调用 vkGetPhysicalDeviceFeatures 访问冲突

c# - 是否可以在应用程序设置中使用自定义枚举? (VS10)

windows - 如何使 CStatic 控件 (MFC) 透明?

windows - 在 Windows 上的软件中关闭 USB 设备

c# - 使用 pinvoke 将结构数组中的嵌入式 C 结构数组传递给 C#

c# - 是否有跨平台(x86 和 x64)PInvoke 和 windows 数据类型的权威指南?

c# - 在 C# 中将 JSON 数组反序列化为对象