如何将此功能从AutoIt的IE.au3 UDF转换为Ruby?意图是将Watir与Internet Explorer浏览器一起使用(嵌入在另一个应用程序中)。
AutoIt功能正常但我更喜欢Watir(这是Ruby)。我可以使用ControlGetHandle()
来获取嵌入式浏览器的句柄,这是AutoIt dll无法提供的。
以下是翻译功能(还有2个我不需要的功能)。
;===============================================================================
;
; Function Name: __IEControlGetObjFromHWND()
; Description: Returns a COM Object Window reference to an embebedded Webbrowser control
; Parameter(s): $hWin - HWND of a Internet Explorer_Server1 control obtained for example:
; $hwnd = ControlGetHandle("MyApp","","Internet Explorer_Server1")
; Requirement(s): Windows XP, Windows 2003 or higher.
; Windows 2000; Windows 98; Windows ME; Windows NT may install the
; Microsoft Active Accessibility 2.0 Redistributable:
; http://www.microsoft.com/downloads/details.aspx?FamilyId=9B14F6E1-888A-4F1D-B1A1-DA08EE4077DF&displaylang=en
; Return Value(s): On Success - Returns DOM Window object
; On Failure - 0 and sets @ERROR = 1
; Author(s): Larry with thanks to Valik
;
;===============================================================================
Func __IEControlGetObjFromHWND(ByRef $hWin)
DllCall("ole32.dll", "int", "CoInitialize", "ptr", 0)
Local Const $WM_HTML_GETOBJECT = __IERegisterWindowMessage("WM_HTML_GETOBJECT")
Local Const $SMTO_ABORTIFHUNG = 0x0002
Local $lResult, $typUUID, $aRet, $oIE
MsgBox(0, "msg", $WM_HTML_GETOBJECT)
__IESendMessageTimeout($hWin, $WM_HTML_GETOBJECT, 0, 0, $SMTO_ABORTIFHUNG, 1000, $lResult)
$typUUID = DllStructCreate("int;short;short;byte[8]")
DllStructSetData($typUUID, 1, 0x626FC520)
DllStructSetData($typUUID, 2, 0xA41E)
DllStructSetData($typUUID, 3, 0x11CF)
DllStructSetData($typUUID, 4, 0xA7, 1)
DllStructSetData($typUUID, 4, 0x31, 2)
DllStructSetData($typUUID, 4, 0x0, 3)
DllStructSetData($typUUID, 4, 0xA0, 4)
DllStructSetData($typUUID, 4, 0xC9, 5)
DllStructSetData($typUUID, 4, 0x8, 6)
DllStructSetData($typUUID, 4, 0x26, 7)
DllStructSetData($typUUID, 4, 0x37, 8)
MsgBox(0, "lResult", $lResult)
$aRet = DllCall("oleacc.dll", "long", "ObjectFromLresult", "lresult", $lResult, "ptr", DllStructGetPtr($typUUID), _
"wparam", 0, "idispatch*", 0)
MsgBox(0, "aRet4", $aRet[4])
If IsObj($aRet[4]) Then
$oIE = $aRet[4] .Script()
; $oIE is now a valid IDispatch object
Return $oIE.Document.parentwindow
Else
SetError(1)
Return 0
EndIf
EndFunc ;==>__IEControlGetObjFromHWND
;===============================================================================
; Function Name: __IERegisterWindowMessage()
; Description: Required by __IEControlGetObjFromHWND()
; Author(s): Larry with thanks to Valik
;===============================================================================
Func __IERegisterWindowMessage($sMsg)
Local $aRet = DllCall("user32.dll", "int", "RegisterWindowMessage", "str", $sMsg)
If @error Then Return SetError(@error, @extended, 0)
Return $aRet[0]
EndFunc ;==>__IERegisterWindowMessage
;===============================================================================
; Function Name: __IESendMessageTimeout()
; Description: Required by __IEControlGetObjFromHWND()
; Author(s): Larry with thanks to Valik
;===============================================================================
Func __IESendMessageTimeout($hWnd, $msg, $wParam, $lParam, $nFlags, $nTimeout, ByRef $vOut, $r = 0, $t1 = "int", $t2 = "int")
Local $aRet
$aRet = DllCall("user32.dll", "long", "SendMessageTimeout", "hwnd", $hWnd, "int", $msg, $t1, $wParam, _
$t2, $lParam, "int", $nFlags, "int", $nTimeout, "int*", "")
If @error Then
$vOut = 0
Return SetError(@error, @extended, 0)
EndIf
$vOut = $aRet[7]
If $r >= 0 And $r <= 4 Then Return $aRet[$r]
Return $aRet
EndFunc ;==>__IESendMessageTimeout
到目前为止我的代码:
def get_control_from_hwnd(hnd)
Win32API.new("ole32", "CoInitialize", ['P'] , 'I').call(0)
reg_msg = Win32API.new("user32", "RegisterWindowMessage", ['P'] ,'I').call("WM_HTML_GETOBJECT")
puts "msg: " + reg_msg.to_s
result=" "*16
aInt = [0xA7, 0x31, 0x0, 0xA0, 0xC9, 0x8, 0x26, 0x37].pack 'I*'
a = [0x626FC520, 0xA41E, 0x11CF, aInt].pack 'IIIP'
sendMessagetimeout = Win32API.new("user32", "SendMessageTimeout", ['L','I','I','I','I','I','P'] , 'L')
sendMessagetimeout.call(hnd.hex, reg_msg, 0, 0, SMTO_ABORTIFHUNG, 1000, result)
puts "result unpacked: " + result.unpack("L").to_s #i can confirm this is the same as the lResult from the autoit functioin
idisp=0
#the problem is likely either here or the next line afterwards
oIE = Win32API.new("oleacc", "ObjectFromLresult", ['P','P','I','P'] , 'L')
oIE.call(result, a, 0, idisp)
puts "idisp: " + idisp.to_s
# returning zero
puts idisp.unpack("L")
end
答案 0 :(得分:0)
无法相信我们正在做同样的事情,尽管我正试图在Perl中做到这一点。我不知道Ruby,但看着脚本,它几乎看起来像Perl。请看一下autoIt上的这个主题,我仍在努力解决问题http://www.autoitscript.com/forum/index.php?showtopic=104894。但我想我可能已经得到了这个idisp。两个变化:
1)我打包结构的方式有点不同。我的$ iid看起来像这样: 包( 'LSSC8',0x626FC520,0xA41E,0x11CF,0xA7,0x31,0x00,0xA0,0xC9,0x08,0x26,0x37)。所以在Ruby中我想它会是[0x626FC520,0xA41E,0x11CF,0xA7,0x31,0x00,0xA0,0xC9,0x08,0x26,0x37] .pack'LSSC8'?我不知道正确的语法,但你明白了。 2)我从SendMessageTimeout&amp;中解压缩“结果”。然后将它传递给ObjectFromLresult。如果我直接传递结果,那么当你得到它时我得到0。
但就我已经离去而言。