读取Windows桌面图标的名字和位置,32bit程序读取64bit进程

这篇博客讨论了在64位Windows系统中,32位程序如何读取桌面图标的名称和位置。通常的方法在64位环境下无法工作,原因是跨位数进程操作时数据结构不兼容。解决的关键在于适应64位进程的数据结构。通过找到桌面句柄并使用SendMessage(LVM_GETITEMTEXT)函数,可以获取桌面图标的文字。文章引用了相关资源并指出一些解决方案存在的不严谨之处。

关于读取Windows桌面的图标名字和位置,网上能找到很多现成的程序

例如

http://stackoverflow.com/questions/5369155/getting-text-from-syslistview32-in-64bit

http://bbs.csdn.net/topics/390624481?page=1

还能找到很多,但是程序都有一个问题,就是在64位win7下,程序编译成32位模式,无法获取。(32位编译32位运行,或者64位编译64位运行都没问题。但是,现在的软件应该都是这个模式,因为要支持xp,又想只出一个版本,只出一个32位版本的方法性价比最高)

这个问题的关键在于跨32位和64位进程操作的时候,比如32位进程读写64位进程(这是最常见的情况),传递的数据结构需要适应64位进程。

回到题目的问题

读取Windows桌面图标的原理很简单

核心就是找到桌面句柄,通过SendMessage(LVM_GETITEMTEXT)获得文字

LVITEM结构定义

typedef struct tagLVITEMW
{
    UINT mask;
    int iItem;
    int iSubItem;
    UINT state;
    UINT stateMask;
    LPWSTR pszText;
    int cchTextMax;
    int iImage;
    LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
    int iIndent;
#endif
#if (_WIN32_WINNT >= 0x0501)
    int iGroupId;
    UINT cColumns; // tile view columns
    PUINT puColumns;
#endif
#if _WIN32_WINNT >= 0x0600
    int* piColFmt;
    int iGroup; // readonly. only valid for owner data.
#endif
} LVITEMW, *LPLVITEMW;

这里有几个指针类型,在64位中,需要改为定义64长度的类型,比如_int64,

typedef struct tagLVITEM64
{
    UINT mask;
    int iItem;
    int iSubItem;
    UINT state;
    UINT stateMask;
    _int64 pszText;
    int cchTextMax;
    int iImage;
    _int64 lParam;
#if (_WIN32_IE >= 0x0300)
    int iIndent;
#endif
#if (_WIN32_WINNT >= 0x0501)
    int iGroupId;
    UINT cColumns; // tile view columns
    _int64 puColumns;
#endif
#if _WIN32_WINNT >= 0x0600
    _int64 piColFmt;
    int iGroup; // readonly. only valid for owner data.
#endif
} LVITEM64;



给出完整的示例代码,可以保证32位或者64位程序在64位操作系统正常运行,32位在32位运行,只需要采用原始的LVITEM定义就可以。

typedef struct tagLVITEM64
{
    UINT mask;
    int iItem;
    int iSubItem;
    UINT state;
    UINT stateMask;
    _int64 pszText;
    int cchTextMax;
    int iImage;
    _int64 lParam;
#if (_WIN32_IE >= 0x0300)
    int iIndent;
#endif
#if (_WIN32_WINNT >= 0x0501)
    int iGroupId;
    UINT cColumns; // tile view columns
    _int64 puColumns;
#endif
#if _WIN32_WINNT >= 0x0600
    _int64 piColFmt;
    int iGroup; // readonly. only valid for owner data.
#endif
} LVITEM64;


void main(){
    HWND hDestTop; 
    hDestTop = ::FindWindow(L"progman", NULL); 
    hDestTop = ::FindWindowEx(hDestTop, 0, L"shelldll_defview", NULL); 
    hDestTop = ::FindWindowEx(hDestTop, 0, L"syslistview32", NULL); 
     
    int count=(int)::SendMessage( hDestTop, LVM_GETITEMCOUNT, 0, 0);
 
    LVITEM64 lvi, *_lvi;
    wchar_t item[512], subitem[512];
    wchar_t *_item, *_subitem;
    unsigned long pid;
    HANDLE process;
     
    GetWindowThreadProcessId( hDestTop, &pid);
    process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);
     
    _lvi=(LVITEM64*)VirtualAllocEx(process, NULL, sizeof(LVITEM64), MEM_COMMIT, PAGE_READWRITE);
    _item=(wchar_t*)VirtualAllocEx(process, NULL, 512*sizeof(wchar_t), MEM_COMMIT, PAGE_READWRITE);
    _subitem=(wchar_t*)VirtualAllocEx(process, NULL, 512*sizeof(wchar_t), MEM_COMMIT, PAGE_READWRITE);
 
    RECT  rc;
    rc.left = LVIR_ICON;  //这个一定要设定 可以去看MSDN关于LVM_GETITEMRECT的说明
    RECT* _rc =(RECT*)VirtualAllocEx( process, NULL, sizeof(RECT), MEM_COMMIT, PAGE_READWRITE); 
 
    lvi.cchTextMax=512;
     
    for( int i=0; i< count; i++) {
 
        lvi.iSubItem=0;
        lvi.pszText=(_int64)_item;
        WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM64), NULL);
        ::SendMessage( hDestTop, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
         
        lvi.iSubItem=1;
        lvi.pszText=(_int64)_subitem;
        WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM64), NULL);
        ::SendMessage( hDestTop, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
         
        ::WriteProcessMemory( process, _rc, &rc, sizeof(rc), NULL);
        ::SendMessage( hDestTop, LVM_GETITEMRECT, (WPARAM)i, (LPARAM)_rc);
 
        ReadProcessMemory(process, _item, item, 512*sizeof(wchar_t), NULL);
        ReadProcessMemory(process, _subitem, subitem, 512*sizeof(wchar_t), NULL);
 
         
        ReadProcessMemory(process, _rc, &rc, sizeof(rc), NULL);
        _cwprintf(L"%s - %s LF:%d TP:%d RT:%d BT:%d\n", item, subitem, rc.left,rc.top,rc.right,rc.bottom);

    }
     
    VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
    VirtualFreeEx(process, _item, 0, MEM_RELEASE);
    VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);
    VirtualFreeEx(process, _rc, 0, MEM_RELEASE);
 
    CloseHandle( process );

}


————————————————————————————————————————————————————————————————————

发现这篇文章也解决这个问题了,但是结构定义只是能正常运行,但是不严谨

http://blog.csdn.net/cometnet/article/details/6969019

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值