我正在尝试使用下面显示的代码枚举并随后从提供的hMenu中删除所有项目。但是,对于许多项目,我收到1456错误,表示找不到菜单项,但我不知道为什么。
对于我的特定菜单,对GetMenuItemCount()的调用返回34,我假设这意味着有34个菜单项可供迭代。显然,情况并非如此,因为迭代在第18项中停止生成有效的菜单项信息。
这是我的代码:
private IEnumerable<string> EnumerateItems(IntPtr hMenu)
{
var count = User32.GetMenuItemCount(hMenu);
for (int i = 0; i < count; i++)
{
MENUITEMINFO_I mif = new MENUITEMINFO_I();
mif.fMask = User32.MIIM_STRING;
mif.fType = User32.MFT_STRING;
mif.dwTypeData = IntPtr.Zero;
bool res = GetMenuItemInfo(hMenu, i, true, mif);
if (!res)
{
Debug.WriteLine("Get String Info Error: " + Marshal.GetLastWin32Error());
continue;
}
mif.cch++;
mif.dwTypeData = Marshal.AllocHGlobal((IntPtr)(mif.cch * 2));
try
{
res = GetMenuItemInfo(hMenu, i, true, mif);
if (!res)
{
Debug.WriteLine("Get Caption Error: " + Marshal.GetLastWin32Error());
continue;
}
string caption = Marshal.PtrToStringUni(mif.dwTypeData);
if (res)
{
yield return caption;
}
}
finally
{
Marshal.FreeHGlobal(mif.dwTypeData);
}
if (!DeleteMenu(hMenu, i, MF_BYPOSITION))
{
Debug.WriteLine("Delete Error: " + Marshal.GetLastWin32Error());
}
}
}
产生以下输出:
Exp&and
<no caption>
<no caption>
Restore previous &versions
KDiff3
&Pin to Start
Add &to "Archive.rar"
Compress to "Archive.rar" and email
<no caption>
{A4756F80-4AE7-4A1F-A776-F5E9D9B04406}
{A4756F80-4AE7-4A1F-A776-F5E9D9B04406}
&Copy
Create &shortcut
<no caption>
{A4756F80-4AE7-4A1F-A776-F5E9D9B04406}
P&roperties
{A4756F80-4AE7-4A1F-A776-F5E9D9B04406}
{A4756F80-4AE7-4A1F-A776-F5E9D9B04406}
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
Get String Info Error: 1456
编辑:
按要求包括MENUITEMINFO:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MENUITEMINFO_I
{
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_I()
{
cbSize = Marshal.SizeOf(typeof(MENUITEMINFO));
}
}
请记住,前18个项目的所有内容都符合预期,我正在测试Win 10盒子。
编辑2:
我修改了代码以始终使用元素0,因为我在每次传递时删除菜单项,现在迭代按预期工作。但是,我留下了一些不想删除的菜单项。见下文:
DeleteMenu没有为这些项目生成错误,但我需要它们消失。
谢谢!