外部sysListView32内容获取及设置选中状态

public void SetLisSelected(IntPtr listView,List<string> fcusers)
        {
            //该listview总行数
            int rowcnt = API.SendMessage(listView, API.LVM_GETITEMCOUNT, 0, 0);

            //listview的列头句柄
            int lvHeader = API.SendMessage(listView, API.LVM_GETHEADER, 0, 0);

            uint hProcessId = 0; //列头的processid
            API.GetWindowThreadProcessId((IntPtr)lvHeader, out hProcessId);    //lvHeader是SysListView的子窗SysHeader32的句柄,lvParent是SysListView的句柄
            IntPtr hProcess = API.OpenProcess(API.PROCESS_VM_OPERATION | API.PROCESS_VM_READ | API.PROCESS_VM_WRITE, false, hProcessId);
            IntPtr hPointer = API.VirtualAllocEx(hProcess, IntPtr.Zero, 4096, API.MEM_RESERVE | API.MEM_COMMIT, API.PAGE_READWRITE);
           
            uint processId; //进程pid 
            API.GetWindowThreadProcessId(listView, out processId);

            //获取Listview的process句柄
            IntPtr process = API.OpenProcess(API.PROCESS_VM_OPERATION | API.PROCESS_VM_READ | API.PROCESS_VM_WRITE, false, processId);
            //申请代码的内存区,返回申请到的虚拟内存首地址
            IntPtr pointer = API.VirtualAllocEx(process, IntPtr.Zero, 4096, API.MEM_RESERVE | API.MEM_COMMIT, API.PAGE_READWRITE);

            //取出每行第一列,判断是否满足条件
            for (int i = 0; i < rowcnt; i++)
            {
                //如果要返回ListView所有内容,这里加上加上 for (int j = 0; j < cols; j++) 并将下面的 vItem[0].iSubItem = 0 改为=j;
                byte[] vBuffer = new byte[256];//定义一个临时缓冲区
                API.LVITEM[] vItem = new API.LVITEM[1];
                vItem[0].mask = API.LVIF_TEXT;//说明pszText是有效的
                vItem[0].iItem = i;     //行号
                vItem[0].iSubItem = 0;  //列号
                vItem[0].cchTextMax = vBuffer.Length;//所能存储的最大的文本为256字节
                vItem[0].pszText = (IntPtr)((int)pointer + Marshal.SizeOf(typeof(API.LVITEM)));
                uint vNumberOfBytesRead = 0;

                //把数据写到vItem中
                //pointer为申请到的内存的首地址
                //UnsafeAddrOfPinnedArrayElement:获取指定数组中指定索引处的元素的地址
                API.WriteProcessMemory(process, pointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(API.LVITEM)), ref vNumberOfBytesRead);

                //发送LVM_GETITEMW消息给hwnd,将返回的结果写入pointer指向的内存空间
                API.SendMessage(listView, API.LVM_GETITEMW, i, (int)pointer);

                //从pointer指向的内存地址开始读取数据,写入缓冲区vBuffer中
                API.ReadProcessMemory(process, (IntPtr)((int)pointer + Marshal.SizeOf(typeof(API.LVITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, ref vNumberOfBytesRead);

                //string vText = Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead); //此方法获取的内容是乱码                   
                string vText = Marshal.PtrToStringUni(Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0)); //不能用Marshal.PtrToStringAnsi等其他方法,否则内容是乱码

                string userName = vText;

                if (fcusers.Any(c=>c==userName)) //第一列内容在目标列表中,选中该行
                {
                    int iItem = i; //行号
                    vItem[0].state = API.LVIS_SELECTED;
                    vItem[0].stateMask = API.LVIS_SELECTED;      

                    uint vNumberOfBytesRead0 = 0;
                    API.WriteProcessMemory(hProcess, hPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(API.LVITEM)), ref vNumberOfBytesRead0);
                    API.SendMessage(listView, (uint)API.LVM_SETITEMSTATE, iItem, hPointer.ToInt32());//此处发送消息使得该item被选中
                    //System.Threading.Thread.Sleep(100);
                }
            }

            API.VirtualFreeEx(hProcess, hPointer, 0, API.MEM_RELEASE);
            API.CloseHandle(hProcess);

            API.VirtualFreeEx(process, pointer, 0, API.MEM_RELEASE);//在其它进程中释放申请的虚拟内存空间,MEM_RELEASE方式很彻底,完全回收
            API.CloseHandle(process);//关闭打开的进程对象
        }

原文地址:https://www.cnblogs.com/mol1995/p/12270175.html