如何捕获外部程序LISTVIEW鼠标单击事件,获取该LISTVIEW当前选中行的某列的值
现有一个外部程序,其界面上有个LISTVIEW控件,里面有若干行数据,我想通过自己的程序,捕获该外部程序中LISTVIEW的鼠标点击事件,同时获取其当前选中行的某列的值。
现在的初步思路是使用 SetWindowsHookEx 进行注入,但是不确定是使用 WH_MOUSE,还是 WH_CALLWNDPROC 来实现。
或者,我本身的思路就问题,请大家多指教,谢谢。
[解决办法]
WH_MOUSE,并判断点击的是否为TListView,然后进一步可以做其他处理
[解决办法]
cchTextMax := 255;
pszText := Pointer(Cardinal(vPointer) + SizeOf(TLVItem));
end;
WriteProcessMemory(vProcess, vPointer, @vItem,
SizeOf(TLVItem), vNumberOfBytesRead);
SendMessage(vHandle, LVM_GETITEM, I, lparam(vPointer));
pBuffer := vBuffer;
ReadProcessMemory(vProcess, Pointer(Cardinal(vPointer) + SizeOf(TLVItem)),
pBuffer, DWORD(256), vNumberOfBytesRead);
S := S + #9 + vBuffer;
end;
Delete(S, 1, 1);
MemoText.Lines.Add(S);
end;
finally
VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
CloseHandle(vProcess);
end;
end;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnRegisterHotKey(Handle, cHotKeyWinF2);
end;
end.
[解决办法]
目前我也有这样的要求。不过我采用了另一种方法
[解决办法]
WH_MOUSE,并判断点击的是否为TListView
[解决办法]
注入DLL, Subclass这个窗口就可以了
[解决办法]
参考http://bbs.aisnote.com/viewtopic.php?f=2&t=14
[解决办法]
太高深了!
[解决办法]
用WH_MOUSE吧!
WH_CALLWNDPROC可以吗?我记得 WH_CALLWNDPROC只能捕获SendMessage的消息,
而鼠标消息是系统PostMessage的消息。
当然你还可以用WH_GETMESSAGE。
从性能来说,不要使用全局钩子,太耗资源,用线程钩子。
更好的方法如楼上说的,注入后再子类化那个窗口(前提是你这个窗口
的生存期是整个程序的,否则还是用钩子好),这样就不需要钩子了。
[解决办法]
使用WriteProcessMemory()和ReadProcessMemory()读写其他程序内存信息。从国外网站COPY的(英文)
The solution? Use WriteProcessMemory() and ReadProcessMemory() to use the other programs memory, perform LVM_GETITEMTEXT on it, and read it back. Hackish yes, but then again reading items from another program's listview control is one giant hack.
First, we get the process of the listview like this:
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(listview, &pid);
process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|
PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);
Next We create three pointers, LVITEM *_lvi, char *_item, and char *_subitem and allocate them in the other program's virtual memory space with VirtualAllocEx():
LVITEM *_lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM),
MEM_COMMIT, PAGE_READWRITE);
char *_item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
PAGE_READWRITE);
char *_subitem=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
PAGE_READWRITE);
Now we point lvi.pszText to _item, and copy it's memory to _lvi using WriteMemoryProcess():
lvi.pszText=_item;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
Now that we have an LVITEM pointer that is valid in the other programs virtual memory, we can shoot off LVM_GETITEMTEXT to listview and copy _item's text into item so we can read it in our program:
SendMessage(hwnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
ReadProcessMemory(process, _item, item, max, NULL);
------解决方案--------------------
都是玩高科技的
[解决办法]
原来老妖有一个minispy想必你应该知道,能够捕获外部句柄,并能取出一些简单控件中的内容,源码可以从老妖网站下载。我曾因为需要作了个读取listview的内容地例子。
在狗狗图标的MouseMove事件里增加下面的代码:(一些名称可能需要替换)
//如果对象为ListView
if (edtName->Text.Pos("ListView")>0)
{
edtCaption->Text = "nocaption";
TLVItem *it = new TLVItem;
it->mask = LVIF_STATE;
it->state = LVIS_SELECTED + LVIS_FOCUSED + LVIS_ACTIVATING;
it->stateMask = DWord(-1);
int iItem;
iItem=SendMessage(hWindow,LVM_GETNEXTITEM,-1,LVNI_SELECTED);
if (iItem==-1)
MessageBox(NULL,"没有指定目标进程 !","错误!",NULL);
//char strCBStr[65535];
//SendMessage(hWindow, LVM_GETITEMTEXT, 0, (LPARAM)strCBStr);
String s;
GetLvItemText(hWindow, iItem, 1, s);
Memo1->Lines->Add(s );
}
其中GetLvItemText函数代码如下:
bool TForm3::GetLvItemText(HANDLE Lv, int Index, int SubItem, String& Text)
{
const int bufferLength = 4000;
bool result = false;
DWORD processId = NULL;
GetWindowThreadProcessId(Lv, &processId);
if (processId == NULL) return false;
HANDLE process = ::OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, processId);
if (process == NULL) return false;
PVOID buffer = VirtualAllocEx(process, NULL, bufferLength, MEM_COMMIT, PAGE_READWRITE);
if (buffer != NULL)
{
LPLVITEM item = (LPLVITEM)new BYTE[bufferLength];
item->mask = LVIF_TEXT;
item->iSubItem = SubItem;
item->pszText = (LPTSTR)((PBYTE)buffer+sizeof(LVITEM));
item->cchTextMax = (bufferLength - sizeof(LVITEM)) / sizeof(TCHAR);
WriteProcessMemory(process, buffer, item, sizeof(LVITEM), NULL);
if (SendMessage(Lv, LVM_GETITEMTEXT, Index, (LPARAM)buffer) != 0)
{
ReadProcessMemory(process, buffer, item, 1024, NULL);
Text = (LPTSTR)((PBYTE)item+sizeof(LVITEM));
result = true;
}
delete item;
VirtualFreeEx(process, buffer, sizeof(LVITEM), MEM_DECOMMIT);
}
CloseHandle(process);
return result;
}
这样应该够你用了,根据自己的需要调整使用吧
[解决办法]
这个更简单,几句代码搞定
http://www.aau.cn/thread-58-1-1.html
[解决办法]
14楼..学习~~
话说..22楼的看不懂- -!郁闷勒...