x32的LVM_GETITEMTEXT和C的x64

时间:2010-12-24 20:23:57

标签: c listview

我一直在努力让listview中的项目文本成为另一个过程。我在CodeProject找到了一个很棒的教程。感谢这篇文章,我能够在x32上做到这一点。但是当尝试在x64上运行时,它会在调用SendMessage时崩溃我正在尝试访问的应用程序。在文章评论中,由于指针大小不同,人们有类似的问题。有人建议使用我不能使用的x64编译器。我需要我的程序在x32 / x64上运行。一个人建议:

  

我有答案。 LVITEM   结构在64位下是错误的   系统。指针现在是64位,所以   必须跟随文本指针   一个虚拟值,用于抵消长度   会员正确。

我认为这将是最好的解决方案,因为我可以使用一个exe来运行x32和x64。我只是不知道如何做他正在谈论的事情。我已经包含了目前适用于x32的代码。如果有人可以帮助我。那太棒了。

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);

2 个答案:

答案 0 :(得分:2)

我认为你无法做到这一点。在32位进程中,指针太短。我相信VirtualAllocEx在从32位进程调用并且使用64位进程句柄作为其第一个参数时将失败。如果您在代码中添加了错误检查,我想您会看到这一点。

您唯一的解决方案是拥有2个版本,x86和x64。这应该不是真正的麻烦 - 通常可以用单一来源完成。

答案 1 :(得分:2)

从32位应用程序向64位ListView发送LVM_GETITEMTEXT消息 实际可能

我能够通过使用原始的LVITEM(60字节长)而不是LVITEM结构(88字节长)以及在成员之间插入七个4字节占位符来实现这一点。它适用于我的Win7 Pro 64位,但我还没有在其他机器上测试过这种方法。

以下是结构。这是C ++,但没有什么能阻止我们在.NET中做同样的事情。

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;