使用 winAPI 在另一个应用程序的 listView 中设置所有复选框

Setting all checkboxes in a listView in another application with winAPI

所以我有这段代码可以使用 sendmessage 为另一个应用程序中的列表视图设置所有项目(甚至是我为项目编号 3 声明的单个项目),我已经成功地获得了该项目 window 列表视图的句柄并获得正确的项目计数,但是当我使用 setitemstate 时,另一个应用程序给我错误并关闭(假设有另一个应用程序我可以很好地完成这项工作,但我没有它的源代码)

这是我的代码:

if (windowName.Contains("Invite to Room")) {
    IntPtr hwndChild0 = FindWindowEx(hWnd, IntPtr.Zero, "SysListView32", "");

    int itemCount = SendMessage(hwndChild0, LVM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero);

    LV_ITEM lvItem = new LV_ITEM();
    lvItem.Index = 3;
    lvItem.SubIndex = 2;
    lvItem.TextLength = 50;
    lvItem.Mask = LVIF_STATE;
    lvItem.State = LVIS_SELECTED;
    lvItem.StateMask = LVIS_SELECTED;

    SendMessage(hwndChild0, LVM_SETITEMSTATE, 3, IntPtr.Zero);
}

这是我的LV_ITEM结构

public struct LV_ITEM
{
    public uint Mask;
    public int Index;
    public int SubIndex;
    public int State;
    public IntPtr StateMask;
    public string Text;
    public int TextLength;
    public int ImageIndex;
    public IntPtr LParam;
}

这是使用的声明(sendmessage 和 setitemstate)

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, string lParam);

private const uint LVM_FIRST = 0x1000;
private const uint LVM_SETITEMSTATE = (LVM_FIRST + 43);

有什么帮助吗?

编辑:

应用程序错误有一个日志文件,其中包含以下消息: "The thread tried to read from or write to a virtual address for which it doesn't have the appropriate access"

有些消息仅使用 WPARAMLPARAM 和 return LRESULT 来传递数据,例如 LVM_GETITEMCOUNT 对您有用。

其他消息使用指向要使用或填充的某些数据结构的指针,例如LVM_SETITEMSTATE。当您传递 IntPtr.Zero 时,它需要一个指向 LPARAM 中预先填充的 LV_ITEM 结构的指针 - 因此您在试图取消引用该零指针的其他应用程序中导致访问冲突。

但是,您不能简单地将指针传递给您的 lvItem,因为它在另一个进程中没有任何意义。您需要在第二个进程中为该结构分配内存,初始化它,向您发送消息并读回该内存(如果您期望任何响应)。