回复 11# cyl675
2种方法可以读取第三方进程的RichEdit控件内容。
#include <SendMessage.au3>
#include <WindowsConstants.au3>
Local $hWnd, $tBuffer
$hWnd = ControlGetHandle("QQ游戏", "", "RichEdit20A2")
$tBuffer = DllStructCreate("wchar Text[1024]")
_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所指出的地址,在目标进程中可能是一块不可读写的区域,所以引起崩溃。
第二种方法则是先在目标进程中分配了一块可以读写的缓存区,然后系统将这缓存区的地址传递给目标窗口过程,因为是目标进程自身空间内的,所以可以正常工作。 |