You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中用LVM_GETITEMRECT获桌面图标仅得位置,如何获取边界?

解决LVM_GETITEMRECT获取桌面图标完整边界的问题

你当前代码只能获取图标坐标、宽高始终为0的原因是未按要求初始化远程内存中RECT结构的Left成员。根据LVM_GETITEMRECT的规则,必须将RECT的Left设置为LVIR枚举值,才能指定要获取的边界类型(完整边界、图标区域等)。

核心修改步骤

  1. 发送消息前,构造Rectangle实例,将其Left属性设为目标LVIR枚举值(比如LVIR_BOUNDS用于获取完整边界)
  2. 将初始化后的Rectangle写入远程分配的内存
  3. 发送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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:22:43