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);//關閉打開的進程對象
}