C中x32和x64的LVM_GETITEMTEXT
我一直在尝试获取listview中项目的文本,这是另一个过程。我发现了一个很棒的教程。多亏了这篇文章,我才能够在x32上做到这一点。但是,当尝试在x64上运行时,它会在调用SendMessage时使我尝试访问的应用程序崩溃。在文章评论中,由于指针大小不同,人们遇到了类似的问题。有些人建议使用我不能使用的x64编译器。我需要我的程序在两个x32/x64上运行。一个人建议: 我有答案。LV项目 64位以下的结构错误 系统。指针现在是64位的,所以 文本指针后面必须跟有 用于偏移长度的虚拟值 成员正确 我认为这将是最好的解决方案,因为我可以用一个exe为x32和x64运行它。我只是不知道该怎么做他所说的。我已经包括了我目前在x32上工作的代码。如果有人能帮我的话。那太好了C中x32和x64的LVM_GETITEMTEXT,c,listview,C,Listview,我一直在尝试获取listview中项目的文本,这是另一个过程。我发现了一个很棒的教程。多亏了这篇文章,我才能够在x32上做到这一点。但是,当尝试在x64上运行时,它会在调用SendMessage时使我尝试访问的应用程序崩溃。在文章评论中,由于指针大小不同,人们遇到了类似的问题。有些人建议使用我不能使用的x64编译器。我需要我的程序在两个x32/x64上运行。一个人建议: 我有答案。LV项目 64位以下的结构错误 系统。指针现在是64位的,所以 文本指针后面必须跟有 用于偏移长度的虚拟值 成员正确
LVITEMLVITEM lvi, *_lvi;
char item[512];
char *_item;
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(procList, &pid);
process = OpenProcess(0x001f0fff, FALSE, pid);
_lvi = (LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), 0x1000, 4);
_item = (char*)VirtualAllocEx(process, NULL, 512, 0x1000, 4);
lvi.cchTextMax = 512;
int r, c;
for (r = 0; r < rowCount; r++)
{
for (c = 0; c < columnCount; c++)
{
lvi.iSubItem = c;
lvi.pszText =_item;
// Insert lvi into programs's memory
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
// Have program write text to in its memory where we told it to
SendMessage(procList, LVM_GETITEMTEXT, (WPARAM)r, (LPARAM)_lvi);
// Get TVITEM back from programs
ReadProcessMemory(process, _item, item, 512, NULL);
}
}
// Clean up the mess we made
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
CloseHandle(process);
lvitemlvi,*\u lvi;
字符项[512];
字符*(u)项;
无符号长pid;
处理过程;
GetWindowThreadProcessId(procList,&pid);
process=OpenProcess(0x001f0fff,FALSE,pid);
_lvi=(LVITEM*)VirtualAllocEx(进程,NULL,sizeof(LVITEM),0x1000,4);
_item=(char*)VirtualAllocEx(进程,NULL,512,0x1000,4);
lvi.cchTextMax=512;
int r,c;
对于(r=0;r
我认为你无法做到这一点。在32位进程中,指针将太短。我相信当从32位进程调用VirtualAllocEx并将64位进程句柄作为其第一个参数时,VirtualAllocEx将失败。如果在代码中添加错误检查,我想您会看到这一点
您唯一的解决方案将是有两个版本,x86和x64。这应该不是真正的问题-通常可以使用单个源完成。将LVM_GETITEMTEXT消息从32位应用程序发送到64位ListView实际上是可能的 我不是使用原始的LVITEM(60字节长),而是使用LVITEM结构(88字节长),在成员之间插入了七个4字节的占位符,从而实现了这一点。它在我的Win7 Pro 64位上工作,尽管我还没有在其他机器上测试过这种方法 结构如下。这是C++,但是没有什么能阻止我们在.NET ./p>中做同样的事情。
typedef struct {
UINT mask;
int iItem;
int iSubItem;
UINT state;
UINT stateMask;
int placeholder1;
LPTSTR pszText;
int placeholder11;
int cchTextMax;
int iImage;
LPARAM lParam;
int placeholder2;
#if (_WIN32_IE >= 0x0300)
int iIndent;
#endif
#if (_WIN32_WINNT >= 0x0501)
int iGroupId;
UINT cColumns;
int placeholder3;
UINT puColumns;
int placeholder4;
#endif
#if (_WIN32_WINNT >= 0x0600)
int piColFmt;
int placeholder5;
int iGroup;
int placeholder6;
#endif
} LVITEM64, *LPLVITEM64;
这是如何编译的?如果这实际上是一个64位进程,则无论如何都不会工作。您需要一个64位编译器。它们非常丰富。嗯,通过使用VirtualAllocEx的lpAddress参数来请求内存,无需截断即可装入32位指针,您可能可以在x86中找到一些地方。但是您需要检测到另一个进程是64位进程,并相应地修改结构布局。即使如此,如果它仍然失败,我也不会感到惊讶!当我注释掉SendMessage时,另一个程序不会崩溃。所以我认为问题不在于VirtualAllocEx。我知道x32和x64的编译都可以解决这个问题,但如果可能的话,我更愿意使用我在问题中引用的codeproject文章评论中建议的解决方案。@Lienau当然,只有当您将数据发送到另一个进程时,它才会崩溃。这并不意味着SendMessage调用是错误的,只是数据是错误的。你做了我建议的所有事情了吗?@Lienau不,我真的不认为你会让这件事起作用。正如Hans所说,你应该有两个版本,一个是32位的,一个是64位的。我想我只需要使用两个版本。谢谢你的帮助。你能提供一个包含上述结构并在32位进程和64位进程之间发送“LVM_GETITEMTEXT”的示例源代码吗?