在C#中用LVM_GETITEMRECT获桌面图标仅得位置,如何获取边界?
解决LVM_GETITEMRECT获取桌面图标完整边界的问题
你当前代码只能获取图标坐标、宽高始终为0的原因是未按要求初始化远程内存中RECT结构的Left成员。根据LVM_GETITEMRECT的规则,必须将RECT的Left设置为LVIR枚举值,才能指定要获取的边界类型(完整边界、图标区域等)。
核心修改步骤
- 发送消息前,构造
Rectangle实例,将其Left属性设为目标LVIR枚举值(比如LVIR_BOUNDS用于获取完整边界) - 将初始化后的
Rectangle写入远程分配的内存 - 发送
LVM_GETITEMRECT消息,最后读取远程内存中的结果
修改后的代码片段
// 分配远程内存 genericPtr = VirtualAllocEx( processHandle, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(Rectangle)), AllocationType.Commit, MemoryProtection.ReadWrite); // 初始化Rectangle,设置Left为LVIR_BOUNDS以获取完整边界 Rectangle initRect = new Rectangle(); initRect.Left = (int)LVIR_Message.LVIR_BOUNDS; // 将初始化后的Rectangle写入远程内存 int rectSize = Marshal.SizeOf(typeof(Rectangle)); IntPtr initPtr = Marshal.AllocHGlobal(rectSize); Marshal.StructureToPtr(initRect, initPtr, false); WriteProcessMemory(processHandle, genericPtr, initPtr, rectSize, out _); Marshal.FreeHGlobal(initPtr); // 发送消息获取边界 CWindow.SendMessage(listViewPtr, (uint)LVM_Message.LVM_GETITEMRECT, itemId, genericPtr.ToInt32()); // 读取远程内存中的结果 Rectangle[] vRectangle = new Rectangle[1]; ReadProcessMemory(processHandle, genericPtr, Marshal.UnsafeAddrOfPinnedArrayElement(vRectangle, 0), rectSize, out vNumberOfBytes);
LVIR枚举说明
LVIR_BOUNDS:获取项的完整边界(包含图标和标签)LVIR_ICON:仅获取图标所在区域的边界LVIR_LABEL:仅获取标签文本所在区域的边界LVIR_SELECTBOUNDS:获取选中状态下的边界框
根据需求选择对应枚举值即可,比如要获取图标本身的宽高用LVIR_ICON,要获取整个项(图标+文字)的范围用LVIR_BOUNDS。
内容的提问来源于stack exchange,提问作者Horst Walter
相关产品推荐
相关产品推荐

