AutoIt Forums: com & Perl - AutoIt Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

com & Perl Using AutoIt (COM) in Perl

#1 User is online   Aditya 

  • Member
  • Pip
  • Group: Full Members
  • Posts: 14
  • Joined: 02-November 09

Posted 02 November 2009 - 12:56 AM

First of all I am not a windows programmer, so some of my terminology might be off. So bear with me. I am trying to translate IE.au3 UDF in to Perl - specifically _IEAttach function. I got as far as to get the HWND of an embedded IE in Perl. The code is pretty simple:

[ code='text' ]    ( Popup )
use strict; use warnings; use Win32::API; use Win32::OLE; my $autoIt = Win32::OLE->new("AutoItX3.Control"); my $app_title = "Test App"; my $nc_path = "C:/Program Files/Test App/TestApp.exe"; my $win_title_match = $autoIt->Opt("WinTitleMatchMode", 1); my $hwnd = $autoIt->ControlGetHandle($nc_title, "", "[CLASS:Internet Explorer_Server; INSTANCE:1]");  


Now that I have got the HWND of the embedded IE in my test application, the next step is to get the COM object or rather IDispatch object using that HWND. In IE.au3, __IEControlGetObjFromHWND() does that job & as I was reading that code, it was making calls to DllCall(). Where is this method from? Is is part of the AutoItX? I couldn't find it in the AutoItX help file. Or is it from the Win32 API?

Or even better, does any one know how to get IDispatch object from a HWND directly in Perl? I am guessing, probably Win32::API but I am not sure. Any ideas?
0

#2 User is online   Aditya 

  • Member
  • Pip
  • Group: Full Members
  • Posts: 14
  • Joined: 02-November 09

Posted 02 November 2009 - 09:35 AM

Here is how far I got and the code below is continued from the post above.

[ code='text' ]    ( Popup )
my $reg_window = new Win32::API('user32', 'RegisterWindowMessage', 'P', 'I'); my $html_obj = $reg_window->Call('WM_HTML_GETOBJECT'); my $SMTO_ABORTIFHUNG = 0x0002; my $lresult = " " x 80; my $send_msg = new Win32::API('user32', 'SendMessageTimeout', 'NIIIIIP', 'N'); $send_msg->Call(hex($hwnd), $html_obj, 0, 0, $SMTO_ABORTIFHUNG, 1000, $lresult); my $aInt = pack('IIII', 0x626FC520, 0xA41E, 0x11CF, [0xA7, 0x31, 0x0, 0xA0, 0xC9, 0x8, 0x26, 0x37]); my $obj = new Win32::API('oleacc', 'ObjectFromLresult', 'PPIP' , 'N'); my $idisp = 0; my $ret = $obj->Call($lresult, $aInt, 0, $idisp); print "ret: ", $ret, "\n", "ie: ", $idisp, "\n";  


But $idsp is always 0. So something is wrong in my code. Any suggestions?
0

#3 User is online   Authenticity 

  • Mass Spammer!
  • Icon
  • Group: AutoIt MVPs(MVP)
  • Posts: 2,378
  • Joined: 22-January 09
  • Gender:Male

Posted 02 November 2009 - 01:31 PM

Seems you're missing CoInitializeEx before you call ObjectFromLresult. Refer to trancexx's post here
0

#4 User is online   Aditya 

  • Member
  • Pip
  • Group: Full Members
  • Posts: 14
  • Joined: 02-November 09

Posted 02 November 2009 - 10:34 PM

View PostAuthenticity, on 02 November 2009 - 04:31 AM, said:

Seems you're missing CoInitializeEx before you call ObjectFromLresult. Refer to trancexx's post here


Thanks for pointing it out, but adding that didn't help. Also the solution in the link you provided uses SendMessage, which works only with Vista & higher. I am trying to make this work in XP.
0

#5 User is online   Authenticity 

  • Mass Spammer!
  • Icon
  • Group: AutoIt MVPs(MVP)
  • Posts: 2,378
  • Joined: 22-January 09
  • Gender:Male

Posted 02 November 2009 - 11:24 PM

The value you set to $aInt should be so or it should be IID_IHTMLDocument?

IID_IHTMLDocument is 626FC520-A41E-11CF-A731-00A0C9082637.

Edit Anyway, you said you need to use SendMessageTimeout instead right? This is from the same topic I've linked to, just a minor fix to someone's wrong DllCall() arguments types:

[ autoIt ]    ( ExpandCollapse - Popup )
#include <WinAPI.au3> ShellExecute('iexplore.exe', 'www.google.com') WinWaitActive('[CLASS:IEFrame]') $hWnd = WinGetHandle('[CLASS:IEFrame]') $IE_hWnd = 0 Do     $IE_hWnd = ControlGetHandle($hWnd, '', 'Internet Explorer_Server1')     Sleep(200) Until $IE_hWnd Sleep(2000) $oIE = _ObjGetFromHWND($IE_hWnd) $oIE.navigate('http://www.autoitscript.com')   Func _RegisterWindowMessage($sMsg)     Local $aRet = DllCall("user32.dll", "int", "RegisterWindowMessage", "str", $sMsg)     If @error Then Return SetError(@error, @extended, 0)     Return $aRet[0] EndFunc Func _SendMessageTimeout($hWnd, $msg, $wParam, $lParam, $nFlags, $nTimeout, ByRef $vOut, $r = 0, $t1 = "int", $t2 = "int")     Local $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 Func _ObjGetFromHWND(ByRef $hWin)     DLLCall("ole32.dll","int","CoInitialize","ptr",0)     If @error Then Return SetError(@error,@extended,0)     Local Const $WM_HTML_GETOBJECT = _RegisterWindowMessage("WM_HTML_GETOBJECT")         If @error Then Return SetError(@error,@extended,0)         Local Const $SMTO_ABORTIFHUNG = 0x0002     Local $lResult, $typUUID, $aRet, $oIE     _SendMessageTimeout($hWin, $WM_HTML_GETOBJECT, 0, 0, $SMTO_ABORTIFHUNG, 1000, $lResult)     If @error Then Return SetError(@error,@extended,0)     $typUUID = _WinAPI_GUIDFromString('{626FC520-A41E-11cf-A731-00A0C9082637}')     $aRet = DllCall("oleacc.dll", "int", "ObjectFromLresult", "int", $lResult, _             "ptr", DLLStructGetPtr($typUUID), "int", 0, "idispatch*", "")     If @error Then Return SetError(@error,@extended,0)    ; If Not IsObj($aRet[4]) Then Return SetError(1,@extended,0)     $oIE = $aRet[4].Script() ; $oIE is now a valid IDispatch object ;Return $oIE.Document.parentwindow     Return $oIE EndFunc  


It seems you're using to correct object GUID but I know nothing about perl so it may be something with how you set the variables.

This post has been edited by Authenticity: 03 November 2009 - 12:07 AM

0

#6 User is online   Aditya 

  • Member
  • Pip
  • Group: Full Members
  • Posts: 14
  • Joined: 02-November 09

Posted 03 November 2009 - 12:50 AM

View PostAuthenticity, on 02 November 2009 - 02:24 PM, said:

The value you set to $aInt should be so or it should be IID_IHTMLDocument?

IID_IHTMLDocument is 626FC520-A41E-11CF-A731-00A0C9082637.


Yup, my packing was wrong - here is the updated one:

my $aInt = pack('LSSC8',0x626FC520,0xA41E,0x11CF,0xA7,0x31,0x00,0xA0,0xC9,0x08,0x26,0x37);

Another change I made was to unpack the $lresult (I dunno why it was accepting the unpacked lresult) that I get back from SendMessageTimeout. So my updated code looks like this:

[ code='text' ]    ( ExpandCollapse - Popup )
my $co_init = new Win32::API('ole32', 'CoInitialize', 'P', 'I'); $co_init->Call(0); my $reg_window = new Win32::API('user32', 'RegisterWindowMessage', 'P', 'I'); my $html_obj = $reg_window->Call('WM_HTML_GETOBJECT'); my $SMTO_ABORTIFHUNG = 0x0002; my $lresult = " " x 80; my $send_msg = new Win32::API('user32', 'SendMessageTimeout', 'NIIIIIP', 'N'); $send_msg->Call(hex($hwnd), $html_obj, 0, 0, $SMTO_ABORTIFHUNG, 1000, $lresult); $lresult = unpack('L', $lresult); my $aInt = pack('LSSC8',0x626FC520,0xA41E,0x11CF,0xA7,0x31,0x00,0xA0,0xC9,0x08,0x26,0x37); my $obj = new Win32::API('oleacc', 'ObjectFromLresult', 'PPIP' , 'N'); my $idisp = " " x 8; my $obj = new Win32::API('oleacc', 'ObjectFromLresult', 'NPIP' , 'N'); my $ret = $obj->Call($lresult, $aInt, 0, $idisp); print "Error: ", $autoIt->error(), "\n"; print "ret: ", $ret, "\n", "ie: ", $idisp, "\n", "idisp: ", unpack('L', $idisp), "\n";  


Now, I do get some value set for $idisp and is a scalar reference. I guess this is the COM object I am looking for, but I am unable to call methods like Script.Document etc on it directly. So I guess I have to dig a little more.

This post has been edited by Aditya: 03 November 2009 - 12:52 AM

0

#7 User is online   Authenticity 

  • Mass Spammer!
  • Icon
  • Group: AutoIt MVPs(MVP)
  • Posts: 2,378
  • Joined: 22-January 09
  • Gender:Male

Posted 03 November 2009 - 01:03 AM

Can you show the way you're using the object?
0

#8 User is online   Aditya 

  • Member
  • Pip
  • Group: Full Members
  • Posts: 14
  • Joined: 02-November 09

Posted 03 November 2009 - 01:06 AM

View PostAuthenticity, on 02 November 2009 - 04:03 PM, said:

Can you show the way you're using the object?


$idisp->Script();

But, Perl complains that it cannot locate the method - most probably because it is not an object reference.

This post has been edited by Aditya: 03 November 2009 - 01:07 AM

0

#9 User is online   Aditya 

  • Member
  • Pip
  • Group: Full Members
  • Posts: 14
  • Joined: 02-November 09

Posted 03 November 2009 - 01:53 AM

Looking at it from another angle, can't I just convert the IE.au3 to a dll & call the methods directly from Perl (or any other language for that matter)? Will that work?
0

#10 User is online   Aditya 

  • Member
  • Pip
  • Group: Full Members
  • Posts: 14
  • Joined: 02-November 09

Posted 03 November 2009 - 02:08 AM

View PostAditya, on 02 November 2009 - 04:53 PM, said:

Looking at it from another angle, can't I just convert the IE.au3 to a dll & call the methods directly from Perl (or any other language for that matter)? Will that work?


Never mind, I got the answer to that question in the forums.
0

#11 User is online   Aditya 

  • Member
  • Pip
  • Group: Full Members
  • Posts: 14
  • Joined: 02-November 09

Posted 04 November 2009 - 08:15 PM

I think I finally got the answer to my original question, when I posted it here - http://perlmonks.org/?node_id=804864. The function was returning a pointer and not a Perl object. So I have to create a Perl object from that pointer. I still have to do that part but it is the answer I was looking for. When I finish my code, I'll post it here for future reference. Thanks for all your help.

This post has been edited by Aditya: 04 November 2009 - 08:16 PM

0

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users