[Win32utils-devel] [Fwd: [win32utils-open-discussion][69904] using win32api to get com object embedded IE]

Heesob Park phasis at gmail.com
Sat May 2 00:58:47 EDT 2009


Hi,

2009/5/2 Daniel Berger <djberg96 at gmail.com>:
> Forwarded from the open-discussion forum...
>
> I don't know how many of you follow the discussion forum, but please take a
> peak from time to time if you have the chance. :)
>
> Dan
>
>
> ---------- 전달된 메시지 ----------
> From: matt wolfe <noreply at rubyforge.org>
> To: noreply at rubyforge.org
> Date: Fri, 1 May 2009 16:29:01 -0400 (EDT)
> Subject: [win32utils-open-discussion][69904] using win32api to get com
> object embedded IE
>
> Read and respond to this message at:
> http://rubyforge.org/forum/message.php?msg_id=69904
> By: matt wolfe
>
> I'm trying to use win32api to get a com handle from an embedded IE window.
> Does
> anyone have an idea how to do this.
> I've seen this done with autoit and the function which does it I've been
> trying
> to translate to ruby (well someone else tried already and failed, however
> they
> were on the right track it seems from my testing). I was wondering what does
> it mean that this version of win32api has callback support? Basically I
> believe
> that may be what I need but I'm unsure.
>
> here is the function i'm trying to transalte from autoit to ruby:
>
> 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
>
>        __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)
>
>
>        $aRet = DllCall("oleacc.dll", "long", "ObjectFromLresult", "lresult",
> $lResult,
> "ptr", DllStructGetPtr($typUUID), _
>                        "wparam", 0, "idispatch*", 0)
>
>        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
>
>
> Any ideas on this?
>
>
>
>
>
> also note the following 2 functions:
> Func __IERegisterWindowMessage($sMsg)
>        Local $aRet = DllCall("user32.dll", "int", "RegisterWindowMessage",
> "str",
> $sMsg)
>        If @error Then Return SetError(@error, @extended, 0)
>        Return $aRet[0]
> EndFunc   ;==>
>
> 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
>
>
>
> And what I have so far:
> 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: " + result.to_s
>        puts "result unpacked: " + result.unpack("L").to_s
>
> #this is correct (confirmed by testing the same window with autoit)
> puts result.unpack("L").class
>
>
>        idisp=0
>        oIE = Win32API.new("oleacc", "ObjectFromLresult", ['P','P','I','P'] ,
> 'L')
>        puts "oIE: " + oIE.to_s
>        #puts oIE.methods
>        abc = oIE.call(result, a, 0, idisp)
>        puts "abc: " + abc.to_s
>        puts "idisp: " + idisp.to_s
>        # returning zero
>        puts idisp.unpack("L")
>        puts idisp
> end
>
Here is a sample code to get a com handle from an embedded IE window.
Does anyone know how to get WIN32OLE object from the com handle?

require 'win32/api'

SMTO_ABORTIFHUNG = 0x0002
CoInitialize = Win32::API.new('CoInitialize', 'P', 'L', 'ole32')
RegisterWindowMessage = Win32::API.new('RegisterWindowMessage', 'P',
'I', 'user32')
SendMessageTimeout = Win32::API.new('SendMessageTimeout', 'LILLIIP',
'L', 'user32')
ObjectFromLresult = Win32::API.new('ObjectFromLresult', 'LPIP', 'L', 'oleacc')
IIDFromString = Win32::API.new('IIDFromString', 'PP', 'L', 'ole32')

def get_control_from_hwnd(hnd)
   CoInitialize.call(0)
   reg_msg = RegisterWindowMessage.call("WM_HTML_GETOBJECT")
   puts "msg: " + reg_msg.to_s

   iid =[0x626FC520,0xA41E,0x11CF,0xA7,0x31,0x00,0xA0,0xC9,0x08,0x26,0x37].pack('LSSC8')

   result = 0.chr*4
   SendMessageTimeout.call(hnd.hex, reg_msg, 0, 0, SMTO_ABORTIFHUNG,
1000, result)
   puts "result unpacked: " + result.unpack("L").to_s

   result = result.unpack('L')[0]
   idisp = 0.chr * 4
   r = ObjectFromLresult.call(result, iid, 0, idisp)
   if r == 0
     idisp = idisp.unpack('L').first
     puts "idisp: " + idisp.to_s
   end
   idisp
end

p get_control_from_hwnd(handle)


Regards,

Park Heesob


More information about the win32utils-devel mailing list