使用winAPI

时间:2016-04-28 14:19:26

标签: c# listview winapi sendmessage

所以我有这个代码使用sendmessage为另一个应用程序中的列表视图设置所有项目(甚至是我说明项目编号3的代码的单个项目),我已经设法成功获取listview的项目窗口句柄和得到项目计数正确,但当我使用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;
}

这是used(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);

对此有何帮助?

编辑:

应用程序错误有一个日志文件,上面写着以下消息: “该线程试图读取或写入一个没有相应访问权限的虚拟地址”

1 个答案:

答案 0 :(得分:0)

有些邮件仅使用WPARAMLPARAM并返回LRESULT来传递数据,例如适合您的LVM_GETITEMCOUNT

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

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