QTP+SendMessage操作自定义无法定位的控件
C/S架构中被测试对象,有很多是在窗口中自绘的或自定义控件,用SYP++这类工具只能定位到窗体,无法再定位到窗体里的控件了。一开始并不知道如何处理。问了很多人,最后用windows API 中的SendMessage函数给被测试对象句柄发消息达到和被测试对象的通讯,就可以做一些操作。下面分享一下具体实现
首先说一下,由于QTP中调试实在是太慢了。所以下了个VB6来调试。又由于在百度上了很久没有VBS使用sendmessage的写法。只好又查VB中sendmessage的写法。过程真是费事。
然后测试了VB用Sendmessage发送消息实现了关闭窗口,记事本输入文字的例子。先保证使用方法是对的。再去做向被测试对象发消息,由于被测试对象发的消息是自定义的,一直没被接收到。
就又百度VB接收自定义消息,做了个接收的程序。自己在VB中调试接收到的消息对不对。发现自定义消息是按16进制来定义的。就是接收端自定义的消息WM_USER+1。WM_USER=&H400这个是16进制的表达式。&H400+1转成十进制是1025。我用sendmessage的第二个参数msg就要用WM_USER+1,或者用1025。
1.VB中发送消息例子
在VB6的模块中写入下面代码,这个定义如果放在form1上面,就不能定义为public .要定义为private
Public Const WM_USER = &H400
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
在Form1写入以下代码Private Sub Command1_Click()
Dim hwnd As Long
Shell "E:……\接收消息的.exe", vbNormalFocus '打开接收消息的程序
hwnd = FindWindow(vbNullString, "Form1") '这个参数的第一个是类名称,第二个市窗体的标题得到接收消息程序的句柄
SendMessage hwnd, 1025, 0, 0 '向hwnd这个句柄发消息
End Sub
2.接收消息的代码'模块中代码
Public prevWndProc As Long
Public Const GWL_WNDPROC = (-4)
Public Const WM_USER = &H400
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If Msg = WM_USER + 1 Then '在这里处理你的消息(嘿!!!!别看花眼了,向这看!!!!!!!)--尊重原作 ,这个是原作的注释挺有意思的。
MsgBox Msg
Else
WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
'MsgBox Msg & "消息不对"'这个打开发现很有意思的一个现象,原来不断地会有不同的消息发过来。估计是window有此消息是广播的方式
End If
End Function
’在Form1中的代码
'这个是测试用的。
Private Sub Command1_Click()
SendMessage Me.hwnd, 1024, 0, 0
End Sub
Private Sub Form_Load()
Me.AutoRedraw = True
Print Me.hwnd '打印本窗口真实句柄,对照发消息findWindow获取的句柄是否正确
prevWndProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
SetWindowLong Me.hwnd, GWL_WNDPROC, AddressOf WndProc
End Sub
'正常关闭窗口
Private Sub Form_Unload(Cancel As Integer)
SetWindowLong Me.hwnd, GWL_WNDPROC, prevWndProc
End Sub
SendMessage(句柄,消息,参数1,参数2)是发消息函数,
FindWindow (类名,窗口标题名) 得到窗口句柄
CallWindowProc 是将消息信息传送给指定的窗口过程的函数
GetWindowLong 该函数获得指定窗口的有关信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值。得到窗口新地址值GWL_WNDPROC = (-4)
SetWindowLong 该函数用来改变指定窗口的属性.函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置?设置窗口新地址为值GWL_WNDPROC = (-4)
详细查VB API。Window API
===========================华 丽 丽 的 分 划 线===========================================================================QTP中不能直接用VB的写法,要转为VBS写法。想想挺麻烦的,为什么不一个语言一统天下。VBS sendmessage使用方法’脚本在公司下周补上。~可以根据发送的消息让被测试程序做一些操作如重启,打开啊。也可以返回消息如控件属性。这些都需要和开发沟通。慢慢也就成了测试开发了。
还有个方法是用进程注入测试后门,通过socket和后门通信实现测试,还没研究,研究后再分享。其它没想到还有什么办法。请分享更好的方法。如果用UIAoutomotion框架是不是会更简单一些?
页:
[1]