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

I'm trying to get the current URL in the topmost Internet Explorer window (I know which one).

So, I'm trying to get the text of the hwnd that contains the URL (I know wich one).

So, Win32::GUI::Text() doesn't work.

So, I can't use the Win32::API call to GetWindowText, because "This function cannot retrieve the text of an edit control in another application.". VB examples I've found use SendMessage to do this.

So, I'd like to send the WM_GETTEXT message to the window and have it fill a buffer with the text.

These are the parameters:

WM_GETTEXT  
wParam = (WPARAM) cchTextMax;   // number of characters to copy 
lParam = (LPARAM) lpszText;     // address of buffer for text 

So, I'd like to get the address of a Perl scalar to send as the second parameter. Everything works but this last part.

Can I do that?

Do I have to enter Inline::C and XS land to do that, or is there a nifty module available? (haven't found any on CPAN, possibly because I don't know what to look for)

If you can short circuit the problem, so much the better :)

/J

Replies are listed 'Best First'.
Re: Getting the actuall address of a scalar
by diotalevi (Canon) on Sep 30, 2002 at 23:59 UTC

    You'll just die for $address = pack 'L!', pack 'p', $scalar;. That will stuff $address with a pointer to the actual null terminated char[] in the $scalar variable. This is also the point at which it is immensely helpful to read perlguts and sv.h to see how perl actually works. That char[] array can contain null values as data so if you are working with binary data then you'd use $address = pack 'L!', pack 'P', $scalar instead.

    That example assumes you can already send that message to the window and just need the char* for the data. If you aren't at *that* point yet then you probably want to check out win32 and see about any message passing modules. If you're using ActiveState perl then apparently some of those modules already come bundled but I've never tried them. If all else fails whip out Inline::C and if *that* fails go to XS where anything is possible.

    Update: forgot to put the last paragraph in

      That got me going in the right direction. After unpacking the long value it is suitable to pass on to SendMessage. Many thanks!!!

      =head2 GetWindowText($hwind) Return text of $hwind, or undef on errors. =cut sub GetWindowText { my ($hwind) = @_; my $len = Win32::GUI::SendMessage($hwind, 0x000E, 0, 0) or return( +""); #WM_GETTEXTLENGTH my $buf = " " x ($len + 1); my $addrBuf = unpack("L", pack('p', $buf)); Win32::GUI::SendMessage($hwind, 0x000D, $len + 1, $addrBuf) or ret +urn(undef); #WM_GETTEXT return( substr($buf, 0, $len) ); }

      I guess the rest (catching the IE URL) will become a module some day. Please /msg me if you are interested in code before that.

      /J

Re: Getting the actuall address of a scalar
by BrowserUk (Patriarch) on Oct 01, 2002 at 00:24 UTC

    Is there some reason that you can't use Win32::GUI::SendMessage()?


    Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
Re: Getting the actual address of a scalar
by boo_radley (Parson) on Oct 01, 2002 at 03:47 UTC
    you may be interested in the setupsup module for win32 before resorting to this :)
Re: Getting the actuall address of a scalar
by hossman (Prior) on Sep 30, 2002 at 23:06 UTC
    Do I have to enter Inline::C and XS land to do that, or is there a nifty module available? (haven't found any on CPAN, possibly because I don't know what to look for)

    Inline::C seems like a nifty module to me.