[已解决]关于GuiRichEdit.au3获取QQ游戏中RichEdit20A中文本的问题
本帖最后由 cyl675 于 2010-10-10 18:25 编辑代码如下:#include <GuiRichEdit.au3>
$hwnd=ControlGetHandle("QQ游戏","","")
$txt=_GUICtrlRichEdit_GetText($hwnd)
MsgBox(1,@error,$txt)测试中不仅不能获得控件中的文本还能让QQ游戏崩溃,不知是什么问题,请会的给个指点 查看的那么多,怎么就没有一人回复呢,难道你们都可顺利获取 没用过 class ,但文档例子好像是这种引用是两个参数。。。。。。。。。 回复 3# 131738
句柄是没错的,可完全定位到RichEdit控件,@error错误提示是700内部错误 这种引用是两个参数----------- "" 回复 5# 131738
句柄是没有错的,加了""这些参数也没用,就算是直接用控件ID也一样,QQGAME崩溃@error返回700内部错误 本帖最后由 pusofalse 于 2010-10-10 00:57 编辑
GUIRichEdit.au3只能用于AutoIt自身进程,获取第三方窗口的文本时,会导致目标进程崩溃。
_GUICtrlRichEdit_GetText函数,最关键的一句是:
_SendMessage($hWnd, $EM_GETTEXTEX, DllStructGetPtr($tGetTextEx), DllStructGetPtr($tText))
目标窗口的确是接收到了EM_GETTEXTEX消息,但$tGetTextEx、$tText却是AutoIt自身进程空间内的,这个地址在目标进程中可能是不可读写的,所以会引起崩溃。传递的$tGetTextEx、$tText缓存区必须位于$hWnd所属的进程空间中。 我的3..3.6。1怎么没_GUIRichEdit_GetText "" 这个只是例句,具体参数值要修正的
_GUIRichEdit_GetText 应该是 _GUICtrlRichEdit_GetText 吧。。。。。。。。 "" 这个只是例句,具体参数值要修正的
_GUIRichEdit_GetText 应该是 _GUICtrlR ...
131738 发表于 2010-10-9 15:24 http://www.autoitx.com/images/common/back.gif
_GUICtrlRichEdit_GetText 这个有 本帖最后由 cyl675 于 2010-10-9 21:49 编辑
回复 7# pusofalse
原来是这样的“GUIRichEdit.au3只能用于AutoIt自身进程,获取第三方窗口的文本时,会导致目标进程崩溃。”那我明白了,超版研究的很透彻
看来要想个办法把目标的$tGetTextEx、$tText地地传进去 回复 9# 131738
感谢提醒,已经修正。 回复 11# cyl675
2种方法可以读取第三方进程的RichEdit控件内容。
#include <SendMessage.au3>
#include <WindowsConstants.au3>
Local $hWnd, $tBuffer
$hWnd = ControlGetHandle("QQ游戏", "", "RichEdit20A2")
$tBuffer = DllStructCreate("wchar Text")
_SendMessage($hWnd, $WM_GETTEXT, 2048, DllStructGetPtr($tBuffer))
MsgBox(0, $hWnd, DllStructGetData($tBuffer, "Text"))
$tBuffer = 0
#include <Thread.au3>
#include <GUIRichEdit.au3>
Local $hWnd, $iProcessId, $pBuffer, $sText
$hWnd = ControlGetHandle("QQ游戏", "", "RichEdit20A2")
$iProcessId = _RTGetWindowThreadProcessId($hWnd)
$hProcess = _RTOpenProcess($iProcessId)
$pBuffer = _RTVirtualAllocEx($hProcess, 2048 + 20)
_RTWriteProcessMemory($hProcess, $pBuffer + 0, 1024, 4, "dword*")
_RTWriteProcessMemory($hProcess, $pBuffer + 8, 1200, 4, "dword*")
_SendMessage($hWnd, $EM_GETTEXTEX, $pBuffer, $pBuffer + 20)
$sText = _RTReadProcessMemory($hProcess, $pBuffer + 20, "", 2048, "wstr")
_RTVirtualFreeEx($hProcess, $pBuffer, 4096)
_RTCloseHandle($hProcess)
MsgBox(0, $pBuffer, $sText)
第一种通过发送WM_GETTEXT消息读取控件内容,与_GUICtrlRichEdit_GetText一样,只是在自身进程空间中创建了一个缓存区,但WM_GETTEXT就可以读取到,这是因为系统在处理SendMessage时,会检查一次消息的类型,并根据消息的不同做出不同的处理。当消息的参数是一个普通的32位数时,系统仅仅将这个32位数传递给目标窗口过程;如果消息的参数是一个指针,系统则会对这个指针进行一次处理,在发送WM_GETTEXT消息时,流程如下:
1、系统首先会在目标进程空间中分配一块缓存区,区域的大小由wparam指定。
2、系统将这个缓存区的首地址传递给目标窗口过程,在窗口过程中,因为目标进程是读取了自身进程空间内的内存,所以不会引起崩溃。
3、在窗口过程返回后,缓存区中的内容就是希望得到的文本(前提是目标窗口过程没有对消息进行特殊处理)。
4、系统将这个缓存区中的内容复制到AutoIt进程内的缓存区中(由lparam指定)。
5、最后释放目标进程空间内的缓存区。
_GUICtrlRichEdit_GetText在发送EM_GETTEXTEX消息时,EM_GETTEXTEX消息的wparam和lparam参数被系统当成了普通的32位数,直接传递给了目标窗口过程。而wparam和lparam所指出的地址,在目标进程中可能是一块不可读写的区域,所以引起崩溃。
第二种方法则是先在目标进程中分配了一块可以读写的缓存区,然后系统将这缓存区的地址传递给目标窗口过程,因为是目标进程自身空间内的,所以可以正常工作。 回复131738
感谢提醒,已经修正。
pusofalse 发表于 2010-10-10 00:57 http://www.autoitx.com/images/common/back.gif
树叶升级到指点江山了。。。。。 回复 13# pusofalse
完美解决问题,谢谢 pusofalse大牛,你怎么学的这么精通呢?呵呵
页:
[1]
2