我正在尝试阅读活动应用程序中菜单项的标签名称,并将它们存储在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;
答案 0 :(得分:1)
a)循环应为for (int i = Win32.GetMenuItemCount(hMenu) - 1; i >= 0; i--)
b)在第一次调用GetMenuItemInfo()
之前,您需要将mif.dwTypeData
设置为NULL(零)
c)在第二次调用GetMenuItemInfo()
之前,mif.dwTypeData
应指向分配了mif.cch + 1
- see MSDN documentation
确保之后释放内存!
答案 1 :(得分:0)
您的问题是您尝试在其他进程中执行此操作。当您致电GetMenuItemInfo
时,您会传递MENUITEMINFO
结构的地址。但该地址仅在您的过程中有效。因为每个进程都有自己的私有虚拟内存空间,所以发送的指针在另一个进程中没有任何意义。
您可以使用VirtualAllocEx
,WriteProcessMemory
和ReadProcessMemory
在其他进程的地址空间中分配,写入和读取MENUITEMINFO
结构的实例。这是让这个机制发挥作用的唯一希望。有很多例子可以使用网络搜索来说明这种技术。
但是,我不建议您这样做。您应该使用其中一个标准自动化接口来解决您的实际问题。例如UIAutomation。
答案 2 :(得分:0)
尝试替换
mif.fMask = MIIM_TYPE;
mif.fType = MFT_STRING;
使用
mif.fMask = MIIM_FTYPE;
mif.fType = MIIM_STRING;
MFT_STRING 替换为 MIIM_STRING 。