由于上篇C#操作QQ的TreeView控件以及详细讲解过如何操作其他进程的控件的流程,所以关于如何操作我就不在啰嗦了
主要实现流程如下
1), 获取列数
获取列数需先获取列的索引指针
columnIndex = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETHEADER, 0, 0);
利用列索引指针去获取列数量
columnCount = WinAPIHelper.SendMessage(new IntPtr(columnIndex), (int)WinAPIHelper.HDM.HDM_GETITEMCOUNT, 0, 0);
2), 获取行数
rowCount = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETITEMCOUNT, 0, 0);
3), 遍历所有cell,使用LVITEM获取需要的数据
iRet = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETITEMW, j, pItemMemory);
像这些没有技术难点的东西我会讲的少一点,大家可以查MSDN,需要我的APIHelper类,请留言
源代码
public class WinListViewRow
{
public string[] Cells { get; set; }
}
public class WinListView
{
public WinListView()
{
Rows = new List<WinListViewRow>();
ColumnHeaders = new List<string>();
}
public int RowCount { get; set; }
public int ColumnCount { get; set; }
public List<string> ColumnHeaders { get; set; }
public List<WinListViewRow> Rows { get; set; }
}
public class ListViewHelper
{
const int MAX_LVMSTRING = 512;
public static int GetRowCount(IntPtr lvHwnd)
{
int iRet = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETITEMCOUNT, 0, 0);
return iRet;
}
public static string GetItemText(IntPtr lvHwnd, int pRow, int pColumn)
{
byte[] strBuffer = new byte[MAX_LVMSTRING + 1];
IntPtr hPro = WinAPIHelper.OpenProcess(WinAPIHelper.PROCESS_ALL_ACCESS, false, WndHelper.GetProcessId(lvHwnd));
IntPtr pStrBufferMemory = WinAPIHelper.VirtualAllocEx(hPro, IntPtr.Zero, MAX_LVMSTRING, WinAPIHelper.AllocationType.Commit, WinAPIHelper.MemoryProtection.ReadWrite);
WinAPIHelper.LVITEM item = new WinAPIHelper.LVITEM();
item.iSubItem = pColumn;
item.cchTextMax = MAX_LVMSTRING;
item.pszText = pStrBufferMemory;
item.mask = WinAPIHelper.LVIF_TEXT;
IntPtr pItemMemory = WinAPIHelper.VirtualAllocEx(hPro, IntPtr.Zero, Marshal.SizeOf(typeof(WinAPIHelper.LV_ITEM)), WinAPIHelper.AllocationType.Commit, WinAPIHelper.MemoryProtection.ReadWrite);
bool result = WinAPIHelper.WriteProcessMemory(hPro, pItemMemory, ref item, Marshal.SizeOf(item), IntPtr.Zero);
IntPtr pStrLocaAddress = Marshal.AllocHGlobal(MAX_LVMSTRING);
int iRet = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETITEMTEXTW, pRow, pItemMemory);
int readLen = 0;
result = WinAPIHelper.ReadProcessMemory(hPro, pStrBufferMemory, pStrLocaAddress, MAX_LVMSTRING, out readLen);
result = WinAPIHelper.ReadProcessMemory(hPro, pItemMemory, ref item, Marshal.SizeOf(item), IntPtr.Zero);
string tmpString2 = Marshal.PtrToStringAuto(pStrLocaAddress);
if (pStrLocaAddress != IntPtr.Zero)
{
try { Marshal.FreeHGlobal(pStrLocaAddress); }
catch { }
}
if (pItemMemory != IntPtr.Zero)
{
try { WinAPIHelper.VirtualFreeEx(hPro, pItemMemory, 0, WinAPIHelper.MEM_RELEASE); }
catch { }
}
if (pStrBufferMemory != IntPtr.Zero)
{
try { WinAPIHelper.VirtualFreeEx(hPro, pStrBufferMemory, 0, WinAPIHelper.MEM_RELEASE); }
catch { }
}
if (hPro != IntPtr.Zero)
{
try { WinAPIHelper.CloseHandle(hPro); }
catch { }
}
return tmpString2;
}
public static WinListView GetListView(IntPtr lvHwnd)
{
WinListView lv = new WinListView();
byte[] strBuffer = new byte[MAX_LVMSTRING + 1];
IntPtr hPro = WinAPIHelper.OpenProcess(WinAPIHelper.PROCESS_ALL_ACCESS, false, WndHelper.GetProcessId(lvHwnd));
IntPtr pStrBufferMemory = WinAPIHelper.VirtualAllocEx(hPro, IntPtr.Zero, MAX_LVMSTRING, WinAPIHelper.AllocationType.Commit, WinAPIHelper.MemoryProtection.ReadWrite);
IntPtr pItemMemory = WinAPIHelper.VirtualAllocEx(hPro, IntPtr.Zero, Marshal.SizeOf(typeof(WinAPIHelper.LV_ITEM)), WinAPIHelper.AllocationType.Commit, WinAPIHelper.MemoryProtection.ReadWrite);
IntPtr pStrLocaAddress = Marshal.AllocHGlobal(MAX_LVMSTRING);
WinAPIHelper.LVITEM item = new WinAPIHelper.LVITEM();
item.cchTextMax = MAX_LVMSTRING;
item.pszText = pStrBufferMemory;
item.mask = WinAPIHelper.LVIF_TEXT;
int columnIndex = 0;
int tryCount = 0;
GETCOLUMNINDEX:
if (columnIndex == 0)
{
tryCount++;
if (tryCount > SysConfig.ListViewItemFindTryCount) { return lv; }
columnIndex = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETHEADER, 0, 0);//列的index指针
Console.WriteLine("列指针为" + columnIndex);
Thread.Sleep(1000);
goto GETCOLUMNINDEX;
}
int columnCount = 0;
tryCount = 0;
//获取总列数
GETCOLUMNCOUNT:
if (columnCount == 0)
{
tryCount++;
if (tryCount > SysConfig.ListViewItemFindTryCount) { return lv; }
columnCount = WinAPIHelper.SendMessage(new IntPtr(columnIndex), (int)WinAPIHelper.HDM.HDM_GETITEMCOUNT, 0, 0);
Console.WriteLine("列数量为" + columnCount);
Thread.Sleep(1000);
goto GETCOLUMNCOUNT;
}
int rowCount = 0;
tryCount = 0;
//获取总行数
GETROWCOUNT:
if (rowCount == 0)
{
tryCount++;
if (tryCount > SysConfig.ListViewItemFindTryCount) { return lv; }
rowCount = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETITEMCOUNT, 0, 0);
Console.WriteLine("行数量为" + rowCount);
Thread.Sleep(1000);
goto GETROWCOUNT;
}
lv.ColumnCount = columnCount;
lv.RowCount = rowCount;
for (int j = 0; j < rowCount; j++)
{
var row = new WinListViewRow();
row.Cells = new string[columnCount];
for (int i = 0; i < columnCount; i++)
{
item.iSubItem = i;
bool result = WinAPIHelper.WriteProcessMemory(hPro, pItemMemory, ref item, Marshal.SizeOf(item), IntPtr.Zero);
int iRet = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETITEMTEXTW, j, pItemMemory);
iRet = WinAPIHelper.SendMessage(lvHwnd, (int)WinAPIHelper.LVM.GETITEMW, j, pItemMemory);
int readLen = 0;
result = WinAPIHelper.ReadProcessMemory(hPro, pStrBufferMemory, pStrLocaAddress, MAX_LVMSTRING, out readLen);
result = WinAPIHelper.ReadProcessMemory(hPro, pItemMemory, ref item, Marshal.SizeOf(item), IntPtr.Zero);
string tmpString2 = Marshal.PtrToStringAuto(pStrLocaAddress);
row.Cells[i] = tmpString2;
}
if (row.Cells.Length > 0)
{
lv.Rows.Add(row);
}
}
if (pStrLocaAddress != IntPtr.Zero)
{
try { Marshal.FreeHGlobal(pStrLocaAddress); }
catch { }
}
if (pItemMemory != IntPtr.Zero)
{
try { WinAPIHelper.VirtualFreeEx(hPro, pItemMemory, 0, WinAPIHelper.MEM_RELEASE); }
catch { }
}
if (pStrBufferMemory != IntPtr.Zero)
{
try { WinAPIHelper.VirtualFreeEx(hPro, pStrBufferMemory, 0, WinAPIHelper.MEM_RELEASE); }
catch { }
}
if (hPro != IntPtr.Zero)
{
try { WinAPIHelper.CloseHandle(hPro); }
catch { }
}
return lv;
}
}
这篇代码实现比较滥,大家可以自己拿去改
转载请注明:http://www.cnblogs.com/Rolends
HAPPY EVERY DAY ! !