朋友叫我帮忙写个从博易读取数据的工具,可无奈数据所在控件并不是Windows标准控件,也就是说没办法通过发送系统消息来获取

相关数据,于是乎试了一下从内存直接读取,可最后并不能达到预期目的,原因是笔者并不能从内存中找出和TDrawGrid对应的关系。

(如果有网友知道的可以赐教。)

最后实在没办法了,直接用上了Hook API,有的网友可能想到了,Hook Gdi32.dll中相应的文本输出函数,没错,我选择的是TextOutA。

思路如下:

1. 编写一个Dll,用于注入博易并Hook TextOutA。

TextOutA原型如下:  

BOOL TextOut(
HDC hdc, // 设备描述表句柄
int nXStart, // 字符串的开始位置 x坐标
int nYStart, // 字符串的开始位置 y坐标
LPCTSTR lpString, // 字符串
int cbString // 字符串中字符的个数
);

我们可以通过WindowFromDC来获取hdc相应的窗口的hWnd,并通过GetClassName来获取窗口的类,从而来判断当前所绘画的文本是不是输入TDrawGrid。
获取完数据后,通过WM_COPYDATA消息来发送相应的lpString到目标处理工具。

2. 编写用于接收数据的客户端。

部分代码如下:

__TextOutA proc hdc:DWORD,nXStart:DWORD,nYStart:DWORD,lpString:DWORD,cbString
local cds:COPYDATASTRUCT
local hwnd:DWORD invoke RestoreApi,hid_TextOutA,1
invoke WindowFromDC,hdc
mov hwnd,eax
invoke GetClassName,hwnd,offset szClassName,255
mov eax,offset szClassName
mov eax,[eax]
.if eax==061724454h
invoke IsWindowVisible,hwnd
.if eax
invoke FindWindow,0,offset szMainRecv
.if eax
push esi
push eax mov esi,offset sBuffer
invoke RtlZeroMemory,esi,255 mov eax,nXStart
mov [esi],eax
mov eax,nYStart
mov [esi+4],eax mov eax,esi
add eax,8 invoke RtlMoveMemory,eax,lpString,cbString mov eax,cbString
add eax,8
mov cds.cbData,eax
mov cds.lpData,esi
mov cds.dwData,0
invoke GetPixel,hdc,1,1
mov cds.dwData,eax pop eax
push ebx
mov ebx,eax
invoke SendMessage,ebx,WM_COPYDATA,0,addr cds
pop ebx pop esi
.endif
.endif
.endif invoke TextOut,hdc,nXStart,nYStart,lpString,cbString
invoke RestoreApi,hid_TextOutA,0
ret
__TextOutA endp
Public Function InterceptedCallBack(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_COPYDATA Then
Dim cbs As COPYDATASTRUCT
Dim md As MyData CopyMemory ByVal VarPtr(cbs), ByVal lParam, Len(cbs)
CopyMemory ByVal VarPtr(md), ByVal cbs.lpData, cbs.cbData
Debug.Print Hex(cbs.dwData), md.x, md.y, StrConv(md.d, vbUnicode)
End If
InterceptedCallBack = CallWindowProc(PrevWndProc, hwnd, uMsg, wParam, lParam)
End Function

VB+Asm代码,比较粗糙,见谅。

然而,TextOutA对于屏幕能看到的才画出来,那么整个TDrawGrid那么多行,要怎么获取所有的数据呢?
笔者通过SendMessage,发送相关滚动条的事件,来达到刷新整个TDrawGrid的目的,这样就OK了。
当然,这样获取到的数据是十分零散的,如下:

 12            355          07-01 09:24
122 355 48860
204 355 48860
286 355 48860
368 355 48860
462 355 0
535 355 3058
12 380 07-01 09:25
122 380 48860
204 380 48860
286 380 48860
368 380 48860
462 380 0
535 380 3058
12 405 07-01 09:26
122 405 48860
204 405 48860
286 405 48860
368 405 48860
462 405 0
535 405 3058
12 355 07-01 09:26
122 355 48860
204 355 48860
286 355 48860
368 355 48860
462 355 0
535 355 3058 .......
.......
.......

但实际上只要稍微观察,还是能找出规律,很容易地就能整理数据了。

下面是获取、整理并转换为excel文档的效果图:

OK,收工了。

读取TDrawGrid之获取博易数据的更多相关文章

  1. 获取博客积分排名,存入数据库,读取数据进行绘图(python,selenium,matplotlib)

    该脚本的目的:获取博客的排名和积分,将抓取时间,排名,积分存入数据库,然后把最近的积分和排名信息进行绘图,查看积分或者排名的变化情况. 整个脚本的流程:是利用python3来编写,利用selnium获 ...

  2. 程序间获取ALV显示数据(读取ALV GRID上的数据)

    程序间获取ALV数据的两种方法: 方法1:通过修改SUBMIT的目标程序,把内表EXPORT到内存,SUBMIT后IMPORT ,该方法需要修改目标程序,可以任意设置目标程序的中断点: * Execu ...

  3. 以多进程读取oss符合条件的数据为例,综合使用多进程间的通信、获取多进程的数据

    import datetime import sys import oss2 from itertools import islice import pandas as pd import re im ...

  4. js进阶ajax读取json数据(ajax读取json和读取普通文本,和获取服务器返回数据(链接)都是一样的,在url处放上json文件的地址即可)

    js进阶ajax读取json数据(ajax读取json和读取普通文本,和获取服务器返回数据(链接)都是一样的,在url处放上json文件的地址即可) 一.总结 ajax读取json和读取普通文本,和获 ...

  5. OpenGL ES无法获取贴图数据原因

    最近在做一个项目,要从贴图中获取图像数据,查了很多资料,也琢磨很久,获取到的数据都是0.终于在一次偶然的机会,发现了端倪,成功了. 不得不说这"一分灵感"真的很重要 以下是在获取贴 ...

  6. 使用腾讯开发平台获取QQ用户数据资料

    <今天是七夕:祝大家七夕嗨皮,前可么么哒,后可啪啪啪> Tips:本篇博客将教你如何使用腾讯开发平台获取QQ用户资料 ----------------------------------- ...

  7. java 正则表达式的应用:读取文件,获取其中的电话号码

    1.正则表达式 正则表达式,又称正规表示法.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符串来描 ...

  8. ajax post data 获取不到数据,注意 content-type的设置

    ajax post  data  获取不到数据,注意 content-type的设置 .post/get关于 jQuery data 传递数据.网上各种获取不到数据,乱码之类的.好吧今天我也遇到了,网 ...

  9. jQuery获取JSON格式数据方法

    getJSON方法: jQuery.getJSON(url,data,success(data,status,xhr)) $("button").click(function(){ ...

随机推荐

  1. python之最强王者(4)——字符串

    1.Python 中文编码 前面章节中我们已经学会了如何用 Python 输出 "Hello, World!",英文没有问题,但是如果你输出中文字符"你好,世界" ...

  2. .NET开发之快捷键篇

    引言:我们都知道快捷键使用得熟,将极大的提高我们的开发效率.可是我发现许多开发人员老喜欢用鼠标去点,不擅长使用快捷键. 1.VS常用快捷键 这个我们记住开发中常用的就可以了. F4:打开属性面板. F ...

  3. MySQL5.7 error log时间显示问题

    最近有两三套环境升级到了5.7.16,发现mysql.err中的时间好像有些问题,经查是mysql 5.7后的变更,如下: root@localhost [(none)]>select now( ...

  4. C++01.类的引入

    1.假设我们要输出张三,李四两个人的基本信息,包括姓名,年龄,可以用以下的C程序实现: eg: #include <stdio.h> int main(int argc,char **ar ...

  5. 移动Web触摸与运动解决方案AlloyTouch开源啦

    传送门 Github地址:https://github.com/AlloyTeam/AlloyTouch 简介 AlloyTouch的本质是运动一个数字,把数字的物理变化映射到你想映射的任何属性上.所 ...

  6. Web报表工具FineReport的JS开发之字符串

    在报表开发过程中,有些需求可能无法通过现有的功能来实现,需要开发人员二次开发,以FineReport为例,可以使用网页脚本.API接口等进行深入的开发与控制. 考虑到JS脚本开发的使用较多,这里先先简 ...

  7. UITextField

    UITextFieldDemo 效果 特点 1.有效定制键盘的样式 2.处理键盘对文本框的遮挡 用法 1.导入文件(UITextField+CreateInputAccessoryView.h/.m) ...

  8. 靠谱的datatable转json方法

    今天有之前同事问我要datatable转json的方法,以前自己也弄过,但感觉网上有很多不靠谱的方法.所以自己在博客里记录一个,当然也是网上找的,但是这个靠谱一点,起码可以用不会报错,所以叫他靠谱的d ...

  9. iOS从零开始学习直播之音频2.后台播放和在线播放

    本篇主要讲音频的后台播放和在线播放. 后台播放   上一篇写的工程运行之后程序退至后台,发现运行不了,歌停止了,这显然不行,音乐后台播放是标配啊.今天就来讲一下后台播放. 1.在plist文件里,告诉 ...

  10. 完全删除TFS2013上的项目

    必备条件:您必须是 Team Foundation Server Administrators 组的成员或待删除项目的 Project Administrators 组的成员. 解决方法:打开&quo ...