///

//Author:  aaashun

//Date:    23/2/2009

//Email:   aaashun@gmail.com

///

测试环境:VC2005,xp
    欢迎批评指正.

最近在做一个很xxx的项目,需要把以前一个窗体里的一个ListView的所有内容抓下来然后存在本地的数据库里.
由于涉及到一些底层的知识.于是研究了一下,并在前人的基础上加以改进.废话不多说了.

首先需要用到Spy++来查看目标窗体信息

大家看到了吧,主窗体Caption是"ListDemo"
    接下来是一个ListView class是"SysListView32"
    还有一个ListHeader   class是"SysHeader32"
    好了,接下来开始编码

  1. //窗口句柄
  2. HWND hwnd=NULL;
  3. //目标进程ID与句柄
  4. DWORD PID;
  5. HANDLE hProcess;
  6. int nColumnCount=0;     //列数
  7. int nRowCount=0;        //行数
  8. int nColumnIndex=0;     //列索引
  9. int nRowIndex=0;        //行索引
  10. int nBufferLength=1024; //缓冲区大小
  11. LVITEM lvitem;
  12. wchar_t *buffer  =new wchar_t[nBufferLength];   //UNICODE
  13. wmemset(buffer,0,nBufferLength);
  14. //远程虚拟空间地址
  15. LVITEM  *pVirtualItem;
  16. wchar_t *pVirtualBuffer;
  17. hwnd=::FindWindow(NULL,_T("ListDemo"));
  18. if(hwnd)
  19. {
  20. hwnd=::FindWindowEx(hwnd,NULL,_T("SysListView32"),NULL);
  21. }
  22. if(!hwnd)
  23. {
  24. AfxMessageBox(L"目标程序没有打开!");
  25. return;
  26. }
  27. GetWindowThreadProcessId(hwnd,&PID);
  28. hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);              //获取目标进程句柄失败
  29. if(!hProcess)
  30. return;
  31. HWND hLVHeader=(HWND)::SendMessage(hwnd,LVM_GETHEADER,0,0);     //获取ListView列头句柄
  32. nColumnCount=(int)::SendMessage(hLVHeader,HDM_GETITEMCOUNT,0,0); //获取ListView行数
  33. nRowCount   =(int)::SendMessage(hwnd,LVM_GETITEMCOUNT,0,0);      //获取ListView列数
  34. //在目标进程地址空间分配内存
  35. pVirtualItem  =(LVITEM  *)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM) , MEM_COMMIT, PAGE_READWRITE);
  36. pVirtualBuffer=(wchar_t *)VirtualAllocEx(hProcess, NULL, nBufferLength*2, MEM_COMMIT, PAGE_READWRITE);
  37. if ((!pVirtualItem)||(!pVirtualBuffer))
  38. {
  39. MessageBox(L"内存分配失败!");
  40. return;
  41. }
  42. CFile file;
  43. file.Open(L"listdata.txt",CFile::modeCreate|CFile::modeReadWrite);
  44. for(int i=0;i<nRowCount;i++)
  45. {
  46. for(int j=0;j<nColumnCount;j++)
  47. {
  48. nColumnIndex=i;
  49. nRowIndex=j;
  50. lvitem.cchTextMax=nBufferLength*2;
  51. lvitem.iSubItem=nRowIndex;
  52. lvitem.pszText=pVirtualBuffer;
  53. //核心技术:将LVITEM结构体插入目标进程里,然后通过LVM_GETITEMTEXT消息获取指定项的文本
  54. WriteProcessMemory(hProcess, pVirtualItem, &lvitem, sizeof(LVITEM), NULL);
  55. ::SendMessage(hwnd, LVM_GETITEMTEXT, (WPARAM)nColumnIndex, (LPARAM)pVirtualItem);
  56. ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength*2,NULL);
  57. //转换成ANSI编码
  58. char *ansiBuffer=ShunW2A(buffer);
  59. file.Write(ansiBuffer,(UINT)strlen(ansiBuffer));
  60. file.Write("/t",1);
  61. delete []ansiBuffer;
  62. }
  63. file.Write("/r/n",2);
  64. }
  65. file.Close();
  66. //释放目标进程里分配的内存
  67. VirtualFreeEx(hProcess,pVirtualItem  ,sizeof(LVITEM) ,MEM_RELEASE);
  68. VirtualFreeEx(hProcess,pVirtualBuffer,nBufferLength*2,MEM_RELEASE);
  69. CloseHandle(hProcess);
  70. delete []buffer;

这里还用到了UNICODE 转 ANSI的一个函数 LPSTR ShunW2A(LPCWSTR lpcwszStrIn),是在函数内部自动分配空间的,所以需要在使用后释放一下

  1. LPSTR ShunW2A(LPCWSTR lpcwszStrIn)
  2. {
  3. LPSTR pszOut = NULL;
  4. if (lpcwszStrIn != NULL)
  5. {
  6. int nInputStrLen = (int)wcslen (lpcwszStrIn);
  7. //获得缓冲所需的字节数大小
  8. int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, lpcwszStrIn, nInputStrLen, NULL, 0, 0, 0) + 2;
  9. pszOut = new char [nOutputStrLen];
  10. if (pszOut)
  11. {
  12. memset (pszOut,0,nOutputStrLen);
  13. WideCharToMultiByte(CP_ACP, 0, lpcwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
  14. }
  15. }
  16. return pszOut;
  17. }

OK,结束了

跨进程读取ListView(CListCtrl)内容相关推荐

  1. linux 跨进程读取内存,Android之Linux跨进程通信的方式

    As we all know,Android是基于Linux内核开发的,而市面上几乎所有的App都离开跨进程通信.可能你会说Android是通过Binder完成进程之间的通信的.但是Binder是怎么 ...

  2. android listview 滑动黑屏,Android 跨进程启动Activity黑屏(白屏)的三种解决方案

    当Android跨进程启动Activity时,过程界面很黑屏(白屏)短暂时间(几百毫秒?).当然从桌面Lunacher启动一个App时也会出现相同情况,那是因为App冷启动也属于跨进程启动Activi ...

  3. VirtualAllocEx 跨进程读写数据 代码注入

    VirtualAllocEx 函数的作用是在指定进程的虚拟空间保留或提交内存区域,除非指定MEM_RESET参数,否则将该内存区域置0. LPVOID VirtualAllocEx(  HANDLE  ...

  4. Android中的跨进程通信方法实例及特点分析(二):ContentProvider

    1.ContentProvider简单介绍 在Android中有些数据(如通讯录.音频.视频文件等)是要供非常多应用程序使用的.为了更好地对外提供数据,Android系统给我们提供了Content P ...

  5. Android的跨进程通信

    Android系统的跨进程简介 为什么不能直接跨进程通信? 为了安全考虑,应用之间的内存是无法互相访问的,各自的数据都存在于自身的内存区域内. 如何跨进程通信? 要想跨进程通信,就要找到一个大家都能访 ...

  6. android remoteviews 设置背景,Android通过RemoteViews实现跨进程更新UI示例

    一.概述 前面一篇文章Android通过AIDL实现跨进程更新UI我们学习了aidl跨进程更新ui,这种传统方式实现跨进程更新UI是可行的,但有以下弊端: View中的方法数比较多,在IPC中需要增加 ...

  7. 进程线程007 进程挂靠与跨进程读写内存

    文章目录 进程挂靠 进程与线程的关系 线程与进程如何关联 为什么需要ApcState.Process CR3的值可以随便改吗 分析NtReadVirtualMemory函数 总结 跨进程读写内存 跨进 ...

  8. Android 跨进程通信大总结

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/111553746 本文出自[赵彦军的博客] 文章目录 1.Android进程 2.修 ...

  9. 微信小游戏直播在Android端的跨进程渲染推流实践

    本文由微信开发团队工程师"virwu"分享. 1.引言 近期,微信小游戏支持了视频号一键开播,将微信升级到最新版本,打开腾讯系小游戏(如跳一跳.欢乐斗地主等),在右上角菜单就可以看 ...

最新文章

  1. RedHat5下scrumworks pro 5.0安装详细说明
  2. Hibernate调用存储过程
  3. linux修改时间指令,Linux 修改时间的指令
  4. ruby hash方法_Ruby中带有示例的Hash.default(key = nil)方法
  5. hdu 2014鞍山赛区 5073 Galaxy
  6. jsp java循环读取json_JAVA JSON遍历问题,求解(内附代码)
  7. cmake make
  8. RocketMQ(七)——消息的消费
  9. PHP技术的优缺点(转载)
  10. 计算机网络基础 — Bypass 网卡
  11. 黄杏元《地理信息系统概论》考研复习考点精讲(八)
  12. HearthBuddy 召唤随从的问题
  13. 电脑重装系统后U6连不上服务器了,重装系统后电脑怎么连不上网络?电脑连接网络步骤...
  14. 物联网控制卡学习资料第465篇:基于STM32F429多路RS232 物联网控制卡
  15. 有n个人围成一圈,从第1个人开始,1、2、3报数,报至3出局,余下的人继续从1、2、3报数,问:最后剩下的一人是原来的第几号?同时求出被淘汰编号的序列。(要求:用循环队列解决该问题。)
  16. java中getchars是什么意思_java中的getChars()方法
  17. 48张帮助程序员梳理知识框架结构图谱
  18. 2007全球杀毒软件排名 + 2007全球防火墙排名
  19. 2021-06-16 节点电压为极坐标下的牛顿-拉夫逊法潮流计算学习
  20. 2023年5月电信高性价比流量卡推荐 不限速、费用低、流量多!

热门文章

  1. 使用Python玩转ROS2参数
  2. 制作启动盘(带数据,不用格式化)
  3. 用java实现原神自动弹琴(附谱)
  4. Tuxera NTFS Mac2022强大的mac读写硬盘/U盘工具
  5. Mac数据恢复首选easyrecovery
  6. 怎样让你的软文更有说服力?四个办法帮你赢得用户信任
  7. python 判断excel单元格为空_用python检测空白Excel单元格
  8. 计算机编程 寒假项目总结,我的软件工程之路--寒假总结
  9. 逆向工程实验_lab0(密码学算法逆向)
  10. 2018 年 5 月