设置另一个程序的listview选择项

时间:2009-06-10 15:22:30

标签: c++ listview sendmessage

我希望能够选择在另一个程序的列表视图中选择的项目(我无法访问其代码)。实际上,它是一个SysListView32,我认为它是相同的。我已经有了下面的代码,尽管编译不幸,似乎什么也没做(尽管SendMessage()返回1)。

process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, 0xD14); 

 _lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE); 

 lvi.state = LVIS_SELECTED | LVIS_FOCUSED;
 lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED; 

 WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL); 
 int abc = ::SendMessage((HWND)0x00050D30, LVM_SETITEMSTATE, (WPARAM)2, (LPARAM)_lvi); 
 VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);

4 个答案:

答案 0 :(得分:1)

以下代码对我来说就像一个魅力:

HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, 0x0000c130);
LPVOID epLvi = VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

LVITEM lvi;
lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
SIZE_T cbWritten = 0;
WriteProcessMemory(hProcess, epLvi, &lvi, sizeof(lvi), &cbWritten);
DWORD dw = SendMessage((HWND)0x00020C4C, LVM_SETITEMSTATE, 1, (LPARAM)epLvi);

VirtualFreeEx(hProcess, epLvi, 4096, MEM_DECOMMIT | MEM_RELEASE);
CloseHandle(hProcess);

您的代码可能无法正常工作的原因有多种:

  • 正如Michael Dunn所说,你需要保留并提交地址空间。有趣的是,您的示例仅尝试MEM_COMMIT内存,但后来MEM_RELEASE是它(与MEM_RESERVE相反);
  • 您可能没有足够的权限来拥有该窗口的进程;
  • 您的流程和目标流程可能有点不同。在这种情况下可能需要一些结构尺寸技巧。

如果所有这些都不起作用,我建议您尝试不同的方法:IAccessible在这里可能会有所帮助。这里通常的免责声明:弄乱其他进程窗口和地址空间需要谨慎处理,如果可能应该避免。

答案 1 :(得分:0)

如何初始化正在复制到目标进程内存中的源LV_ITEM的其余成员?您是否在源LV_ITEM的“掩码”成员中包含LVIF_STATE标志?如果没有,那么ListView将忽略您尝试指定的“state”和“stateMask”值。

答案 2 :(得分:0)

如果你遇到困难,有一个名为AutoHotKey的开源项目可以创建可以轻松选择列表中项目的脚本。

答案 3 :(得分:0)

在提交内存之前必须保留地址空间。您可以通过将MEM_COMMIT更改为MEM_RESERVE|MEM_COMMIT

来同时执行这两项操作