C#如何通过api获取其他程序listview控件各列的标题

时间:2022-06-01 14:38:22
如:如何获取windows任务管理器中 “进程” 项目下的listview中的列名
称 “映像名称”、“用户名、“CPU”.....等 

9 个解决方案

#1


先查查百度有没有代码吧
你要是能把VC的代码转成C#,我可以给你一份VC的代码

#2


谢谢,
请传xuntong2003@163.com

#3



VC2010测试通过
自己修改为C#的吧

void GetListViewInfo(HWND h)
{

if(h==NULL)
{
return;
}

//目标进程ID与句柄
DWORD PID;
HANDLE hProcess;
int nBufferLength=50; //缓冲区大小

int nRowCount=0;        //行数
nRowCount   =(int)::SendMessage(h,LVM_GETITEMCOUNT,0,0);      //获取ListView行数
if(nRowCount<=0)
return;

int nColCount=0;        //列数
HWND hHeader = (HWND)::SendMessage(h,LVM_GETHEADER, 0,0);
nColCount   =(int)::SendMessage(hHeader,HDM_GETITEMCOUNT,0,0);      //获取ListView列数
if(nColCount<=0)
return;

//远程虚拟空间地址
LVITEM  *pVirtualItem;
wchar_t *pVirtualBuffer;

GetWindowThreadProcessId(h,&PID);
hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);              //获取目标进程句柄失败
if(!hProcess)
return;

//在目标进程地址空间分配内存
pVirtualItem  =(LVITEM  *)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM) , MEM_COMMIT, PAGE_READWRITE);
pVirtualBuffer=(wchar_t *)VirtualAllocEx(hProcess, NULL, nBufferLength*2, MEM_COMMIT, PAGE_READWRITE);
if ((!pVirtualItem)||(!pVirtualBuffer))
{
return;
}

for(int i=0;i<nRowCount;i++)

CString strInfo = L"";
for(int j=0;j<nColCount;j++)
{
wchar_t *buffer  =new wchar_t[nBufferLength];
wmemset(buffer,0,nBufferLength);

LVITEM lvitem;
lvitem.cchTextMax=nBufferLength*2;
lvitem.iSubItem=j;
lvitem.pszText=pVirtualBuffer;
//核心技术:将LVITEM结构体插入目标进程里,然后通过LVM_GETITEMTEXT消息获取指定项的文本
WriteProcessMemory(hProcess, pVirtualItem, &lvitem, sizeof(LVITEM), NULL);
::SendMessage(h, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pVirtualItem);
ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength*2,NULL);

CString strTemp(buffer);

strInfo+=strTemp+ L" ";
 
delete []buffer;
}
AfxMessageBox(strInfo);
}

//释放目标进程里分配的内存
VirtualFreeEx(hProcess,pVirtualItem  ,sizeof(LVITEM) ,MEM_RELEASE);
VirtualFreeEx(hProcess,pVirtualBuffer,nBufferLength*2,MEM_RELEASE);
CloseHandle(hProcess);
}

BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam) 

TCHAR szBuffer[255];
GetClassName(hwndChild,szBuffer,sizeof(szBuffer)); 

CString strBuffer = L"";
strBuffer.Format(L"%s",szBuffer);
if(strBuffer.MakeLower()==L"#32770")
{
HWND h = ::FindWindowEx(hwndChild,NULL,L"BUTTON",L"结束进程(&E)");
if(h!=NULL)
{
HWND hListView = ::FindWindowEx(hwndChild,NULL,L"SysListView32",NULL);
if(hListView!=NULL)
{
GetListViewInfo(hListView);
return false;
}
}
}
return true; 
}

void CtsssDlg::OnBnClickedOk()
{
// 查找任务管理器句柄
HWND h = 0;
h=::FindWindow(NULL,L"Windows 任务管理器");
if(h==NULL)
{
AfxMessageBox(L"请运行任务管理器");
return;
}

// 遍历所有控件,找到ListView
::EnumChildWindows(h, EnumChildProc, NULL); 
}

#4


该回复于2010-12-03 10:24:48被版主删除

#5


该回复于2010-12-03 10:21:14被版主删除

#6


谢谢,ZengHD回复,不是很清楚,再问一下?

 LVITEM lvitem;
            lvitem.cchTextMax=nBufferLength*2;
            lvitem.iSubItem=j;
            lvitem.pszText=pVirtualBuffer;
            //核心技术:将LVITEM结构体插入目标进程里,然后通过LVM_GETITEMTEXT消息获取指定项的文本
            WriteProcessMemory(hProcess, pVirtualItem, &lvitem, sizeof(LVITEM), NULL);
            ::SendMessage(h, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pVirtualItem);
            ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength*2,NULL);

            CString strTemp(buffer);

取得的内容应是 列表项的内容,不是列名(列名称或列标题)

#7


该回复于2010-12-03 11:06:44被版主删除

#8



哦,原来只是获取表头文字啊,你用下面的代码更换GetListViewInfo函数

void GetListViewInfo(HWND h)
{
if(h==NULL)
{
return;
}

//目标进程ID与句柄
DWORD PID;
HANDLE hProcess;
int nBufferLength=50; //缓冲区大小

int nColCount=0;        //列数
HWND hHeader = (HWND)::SendMessage(h,LVM_GETHEADER, 0,0);//获得标题头句柄
if(hHeader==NULL)
{
return;
}

nColCount =(int)::SendMessage(hHeader,HDM_GETITEMCOUNT,0,0);      //获取ListView列数
if(nColCount<=0)
return;

//远程虚拟空间地址
HDITEM  *pVirtualItem;
wchar_t *pVirtualBuffer;

GetWindowThreadProcessId(h,&PID);
hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);              //获取目标进程句柄失败
if(!hProcess)
return;

//在目标进程地址空间分配内存
pVirtualItem  =(HDITEM  *)VirtualAllocEx(hProcess, NULL, sizeof(HDITEM) , MEM_COMMIT, PAGE_READWRITE);
pVirtualBuffer=(wchar_t *)VirtualAllocEx(hProcess, NULL, nBufferLength, MEM_COMMIT, PAGE_READWRITE);
if ((!pVirtualItem)||(!pVirtualBuffer))
{
return;
}
 
CString strInfo = L"";
for(int j=0;j<nColCount;j++)
{
wchar_t *buffer  =new wchar_t[nBufferLength];
wmemset(buffer,0,nBufferLength);

HDITEM hdItem;

hdItem.mask=HDI_TEXT;
hdItem.fmt=0;
hdItem.cchTextMax=nBufferLength;
hdItem.pszText=pVirtualBuffer; 
WriteProcessMemory(hProcess, pVirtualItem, &hdItem, sizeof(HDITEM), NULL);
::SendMessage(hHeader, HDM_GETITEM, (WPARAM)j, (LPARAM)(LPHDITEM)pVirtualItem);
ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength,NULL);
ReadProcessMemory(hProcess,pVirtualItem,(LPVOID)&hdItem,sizeof(HDITEM),NULL); 

CString strTemp(buffer);

strInfo+=strTemp+ L" ";
 
delete []buffer;
}
AfxMessageBox(strInfo);

//释放目标进程里分配的内存
VirtualFreeEx(hProcess,pVirtualItem  ,sizeof(HDITEM) ,MEM_RELEASE);
VirtualFreeEx(hProcess,pVirtualBuffer,nBufferLength,MEM_RELEASE);
CloseHandle(hProcess);
}

#9


谢谢!!!!!

#1


先查查百度有没有代码吧
你要是能把VC的代码转成C#,我可以给你一份VC的代码

#2


谢谢,
请传xuntong2003@163.com

#3



VC2010测试通过
自己修改为C#的吧

void GetListViewInfo(HWND h)
{

if(h==NULL)
{
return;
}

//目标进程ID与句柄
DWORD PID;
HANDLE hProcess;
int nBufferLength=50; //缓冲区大小

int nRowCount=0;        //行数
nRowCount   =(int)::SendMessage(h,LVM_GETITEMCOUNT,0,0);      //获取ListView行数
if(nRowCount<=0)
return;

int nColCount=0;        //列数
HWND hHeader = (HWND)::SendMessage(h,LVM_GETHEADER, 0,0);
nColCount   =(int)::SendMessage(hHeader,HDM_GETITEMCOUNT,0,0);      //获取ListView列数
if(nColCount<=0)
return;

//远程虚拟空间地址
LVITEM  *pVirtualItem;
wchar_t *pVirtualBuffer;

GetWindowThreadProcessId(h,&PID);
hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);              //获取目标进程句柄失败
if(!hProcess)
return;

//在目标进程地址空间分配内存
pVirtualItem  =(LVITEM  *)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM) , MEM_COMMIT, PAGE_READWRITE);
pVirtualBuffer=(wchar_t *)VirtualAllocEx(hProcess, NULL, nBufferLength*2, MEM_COMMIT, PAGE_READWRITE);
if ((!pVirtualItem)||(!pVirtualBuffer))
{
return;
}

for(int i=0;i<nRowCount;i++)

CString strInfo = L"";
for(int j=0;j<nColCount;j++)
{
wchar_t *buffer  =new wchar_t[nBufferLength];
wmemset(buffer,0,nBufferLength);

LVITEM lvitem;
lvitem.cchTextMax=nBufferLength*2;
lvitem.iSubItem=j;
lvitem.pszText=pVirtualBuffer;
//核心技术:将LVITEM结构体插入目标进程里,然后通过LVM_GETITEMTEXT消息获取指定项的文本
WriteProcessMemory(hProcess, pVirtualItem, &lvitem, sizeof(LVITEM), NULL);
::SendMessage(h, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pVirtualItem);
ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength*2,NULL);

CString strTemp(buffer);

strInfo+=strTemp+ L" ";
 
delete []buffer;
}
AfxMessageBox(strInfo);
}

//释放目标进程里分配的内存
VirtualFreeEx(hProcess,pVirtualItem  ,sizeof(LVITEM) ,MEM_RELEASE);
VirtualFreeEx(hProcess,pVirtualBuffer,nBufferLength*2,MEM_RELEASE);
CloseHandle(hProcess);
}

BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam) 

TCHAR szBuffer[255];
GetClassName(hwndChild,szBuffer,sizeof(szBuffer)); 

CString strBuffer = L"";
strBuffer.Format(L"%s",szBuffer);
if(strBuffer.MakeLower()==L"#32770")
{
HWND h = ::FindWindowEx(hwndChild,NULL,L"BUTTON",L"结束进程(&E)");
if(h!=NULL)
{
HWND hListView = ::FindWindowEx(hwndChild,NULL,L"SysListView32",NULL);
if(hListView!=NULL)
{
GetListViewInfo(hListView);
return false;
}
}
}
return true; 
}

void CtsssDlg::OnBnClickedOk()
{
// 查找任务管理器句柄
HWND h = 0;
h=::FindWindow(NULL,L"Windows 任务管理器");
if(h==NULL)
{
AfxMessageBox(L"请运行任务管理器");
return;
}

// 遍历所有控件,找到ListView
::EnumChildWindows(h, EnumChildProc, NULL); 
}

#4


该回复于2010-12-03 10:24:48被版主删除

#5


该回复于2010-12-03 10:21:14被版主删除

#6


谢谢,ZengHD回复,不是很清楚,再问一下?

 LVITEM lvitem;
            lvitem.cchTextMax=nBufferLength*2;
            lvitem.iSubItem=j;
            lvitem.pszText=pVirtualBuffer;
            //核心技术:将LVITEM结构体插入目标进程里,然后通过LVM_GETITEMTEXT消息获取指定项的文本
            WriteProcessMemory(hProcess, pVirtualItem, &lvitem, sizeof(LVITEM), NULL);
            ::SendMessage(h, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pVirtualItem);
            ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength*2,NULL);

            CString strTemp(buffer);

取得的内容应是 列表项的内容,不是列名(列名称或列标题)

#7


该回复于2010-12-03 11:06:44被版主删除

#8



哦,原来只是获取表头文字啊,你用下面的代码更换GetListViewInfo函数

void GetListViewInfo(HWND h)
{
if(h==NULL)
{
return;
}

//目标进程ID与句柄
DWORD PID;
HANDLE hProcess;
int nBufferLength=50; //缓冲区大小

int nColCount=0;        //列数
HWND hHeader = (HWND)::SendMessage(h,LVM_GETHEADER, 0,0);//获得标题头句柄
if(hHeader==NULL)
{
return;
}

nColCount =(int)::SendMessage(hHeader,HDM_GETITEMCOUNT,0,0);      //获取ListView列数
if(nColCount<=0)
return;

//远程虚拟空间地址
HDITEM  *pVirtualItem;
wchar_t *pVirtualBuffer;

GetWindowThreadProcessId(h,&PID);
hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);              //获取目标进程句柄失败
if(!hProcess)
return;

//在目标进程地址空间分配内存
pVirtualItem  =(HDITEM  *)VirtualAllocEx(hProcess, NULL, sizeof(HDITEM) , MEM_COMMIT, PAGE_READWRITE);
pVirtualBuffer=(wchar_t *)VirtualAllocEx(hProcess, NULL, nBufferLength, MEM_COMMIT, PAGE_READWRITE);
if ((!pVirtualItem)||(!pVirtualBuffer))
{
return;
}
 
CString strInfo = L"";
for(int j=0;j<nColCount;j++)
{
wchar_t *buffer  =new wchar_t[nBufferLength];
wmemset(buffer,0,nBufferLength);

HDITEM hdItem;

hdItem.mask=HDI_TEXT;
hdItem.fmt=0;
hdItem.cchTextMax=nBufferLength;
hdItem.pszText=pVirtualBuffer; 
WriteProcessMemory(hProcess, pVirtualItem, &hdItem, sizeof(HDITEM), NULL);
::SendMessage(hHeader, HDM_GETITEM, (WPARAM)j, (LPARAM)(LPHDITEM)pVirtualItem);
ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength,NULL);
ReadProcessMemory(hProcess,pVirtualItem,(LPVOID)&hdItem,sizeof(HDITEM),NULL); 

CString strTemp(buffer);

strInfo+=strTemp+ L" ";
 
delete []buffer;
}
AfxMessageBox(strInfo);

//释放目标进程里分配的内存
VirtualFreeEx(hProcess,pVirtualItem  ,sizeof(HDITEM) ,MEM_RELEASE);
VirtualFreeEx(hProcess,pVirtualBuffer,nBufferLength,MEM_RELEASE);
CloseHandle(hProcess);
}

#9


谢谢!!!!!