为什么GetMenuItemInfo不能工作?
本文关键字:工作 不能 GetMenuItemInfo 为什么 | 更新日期: 2023-09-27 18:17:32
我正在尝试读取活动应用程序中菜单项的标签名称并将它们存储在List<String>
中。
不幸的是,dwTypeData
总是返回null
。为什么会这样?
List<string> ls = new List<string>();
IntPtr hMenu = Win32.GetMenu(hWnd);
if (hMenu.ToInt32() != 0)
{
for (int i = Win32.GetMenuItemCount(hMenu); i >= 0; i--)
{
try
{
uint MIIM_STRING = 0x00000040;
uint MFT_STRING = 0x00000000;
uint MIIM_TYPE = 0x00000010;
Win32.MENUITEMINFO mif = new Win32.MENUITEMINFO();
mif.cbSize = (uint)Marshal.SizeOf(typeof(Win32.MENUITEMINFO));
mif.fMask = MIIM_TYPE;
mif.fType = MFT_STRING;
mif.cch = 256;
mif.dwTypeData = "";
Win32.GetMenuItemInfo(hMenu, (uint)i, true, ref mif); //To load cch into memory
Win32.GetMenuItemInfo(hMenu, (uint)i, true, ref mif); //To fill dwTypeData
ls.Add(mif.dwTypeData);
}
catch { }
}
}
return ls;
a)循环应为for (int i = Win32.GetMenuItemCount(hMenu) - 1; i >= 0; i--)
b)在第一次调用GetMenuItemInfo()
之前,您需要将mif.dwTypeData
设置为NULL(零)
c)在第二次调用GetMenuItemInfo()
之前,mif.dwTypeData
应该指向一个分配了mif.cch + 1
大小的缓冲区——参见MSDN文档
确保你释放内存之后!
您的问题是您试图在不同的进程中执行此操作。当调用GetMenuItemInfo
时,传递的是MENUITEMINFO
结构体的地址。但是这个地址只在你的进程中有效。因为每个进程都有自己的私有虚拟内存空间,所以你发送的指针在其他进程中是没有意义的。
您可以使用VirtualAllocEx
, WriteProcessMemory
和ReadProcessMemory
在另一个进程的地址空间中分配,写入和读取MENUITEMINFO
结构体的实例。这是让这个机制工作的唯一希望。有很多使用网络搜索的例子来说明这个技术。
但是,我不建议你那样做。您应该使用一个标准的自动化接口来解决实际问题。例如UIAutomation。
尝试替换
mif.fMask = MIIM_TYPE;
mif.fType = MFT_STRING;
mif.fMask = MIIM_FTYPE;
mif.fType = MIIM_STRING;
Win32 API MENUITEMINFOA文档说明
MFT_STRING 被 MIIM_STRING 。