rovingeyes has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to use AuoIt in Perl to perform some windows automation. I am using its ActiveX control, which only provides core functionality but leaves out most of the more useful functionality, which are provided through User Defined Functions. Anyhoo, I have a windows application that has an embedded IE and I want to get control to its object to fill forms, read data - all the usual automation stuff.

Here is how I am approaching the problem. I use the AutoIt ActiveX control to get the handle (HWND) to the embedded IE. After this point, we use the the steps described here http://support.microsoft.com/default.aspx/kb/q249232/ to get the IE Object. To summarize, the whole process involves the following steps:

  • Get the HWND of IE using AutoIt
  • Send the window the WM_HTML_GETOBJECT message using RegisterWindowMessage
  • Pass the result of SendMessageTimeout to GetObjectFromLresult
  • Some code...

    use strict; use warnings; use Win32::API; use Win32::OLE; my $autoIt = Win32::OLE->new("AutoItX3.Control"); my $app_title = "Test App"; my $win_title_match = $autoIt->Opt("WinTitleMatchMode", 1); my $hwnd = $autoIt->ControlGetHandle($app_title, "", "[CLASS:Internet +Explorer_Server; INSTANCE:1]"); # At this point we should have the HWND 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,0 +xC9,0x08,0x26,0x37); my $obj = new Win32::API('oleacc', 'ObjectFromLresult', 'PPIP' , 'N'); my $idisp = " " x 80; 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";

    Towards the end of the script, I do get a value for $idisp, which should be a pointer to the IHTMLDocument2 object. If you look at the example in the link I provided to Microsoft site, it is CComPtr<IHTMLDocument2> spDoc, which is $idisp.

    Here is where I am stuck. When I unpack $idisp, I get a numeric value. Is this the memory location that the pointer is pointing to? It definitely is not an object since I cannot call methods like spDoc->put_bgColor() or in my script $idisp->put_bgColor(). So I am definitely confused here. Could some one help me understand how to use that pointer in my script?

    Replies are listed 'Best First'.
    Re: Win32: Get COM object (for IE in this case) from HWND
    by Anonymous Monk on Nov 04, 2009 at 09:19 UTC
      Use Win32::API to call Win32/OLE.dll CreatePerlObject function
        Aha! I knew I was missing some thing. Thank you.