外部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);//关闭打开的进程对象
}