读取Windows桌面图标的名字和位置,32bit程序读取64bit进程
2015-12-06 22:08
369 查看
关于读取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结构定义
这里有几个指针类型,在64位中,需要改为定义64长度的类型,比如_int64,
给出完整的示例代码,可以保证32位或者64位程序在64位操作系统正常运行,32位在32位运行,只需要采用原始的LVITEM定义就可以。
————————————————————————————————————————————————————————————————————
发现这篇文章也解决这个问题了,但是结构定义只是能正常运行,但是不严谨
http://blog.csdn.net/cometnet/article/details/6969019
例如
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
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性
- C++ Custom Control控件向父窗体发送对应的消息