Jump to content

IE: Get element of current focus.


Recommended Posts

Hi all,

I want to write a script that does the following:

I click into textarea of a webpage e.g. to write this post.

I activate my script.

The script identifies the DOM element I clicked into (that has focus).

Fetches any existing content (innerHTML/innerText).

It opens my favorit text editor.

It pastes the fetched content into the editor.

A second hot key copies the text editor's content into the textarea in the browser.

What I am missing is the part of getting a handle on the DOM object that currently has focus.

Any idea as to how I could get it?

Thanks,

Juergen

Link to comment
Share on other sites

Hi there, and welcome!

This is just a very basic example of how you could try to get a handle on the DOM object that currently has focus. Not all elements have all properties so you need to play around with it to get it to work the way you want...

#include <IE.au3>

$oIE = _IECreate("http://www.Google.com")   ;http://www.google.com
$oDoc = _IEDocGetObj($oIE)
$oActiveElement = $oDoc.activeElement
ConsoleWrite("Name of active element: " & $oActiveElement.name & @CRLF) ;Should return "q"
ConsoleWrite("Tagname of active element: " & $oActiveElement.tagname & @CRLF) ;Should return "INPUT"
ConsoleWrite("Title of active element: " & $oActiveElement.title & @CRLF) ;Should return "Google Search"

Edit/Add: Better example:

Edited by MrMitchell
Link to comment
Share on other sites

Hi MrMitchell,

sorry for my late reply and thanks a lot! This was exactly what I was looking for!

Please have a look at the script, would you improve anything?

#include <IE.au3> 
#include <ClipBoard.au3>

HotKeySet( "{F9}", "getContent")
HotKeySet( "{F10}", "writeBack")
HotKeySet( "{F11}", "stop")

While 1
    Sleep(20)
WEnd

Func stop()
    Exit
EndFunc

Func getContent()
    
    WinWaitActive( "[CLASS:IEFrame]" )
    $olsHandle = WinGetHandle ( "[CLASS:IEFrame]" )
    $oIE = _IEAttach ( $olsHandle, "HWND" )
    $oFrame = _IEFrameGetCollection ($oIE, 2)
    $oDoc = _IEDocGetObj( $oIE );
    Global $oActiveElement = $oDoc.activeElement;
    
    $sContent = $oActiveElement.innerText;
    _ClipBoard_SetData ( $sContent );

    Run("C:\Program Files\Vim\vim72\gvim.exe")
    WinWaitActive( "[Title:[No Name]]" )
    Global $hdViM = WinActivate( "[Title:[No Name]]" )
    If $hdViM = 0 Then
        MsgBox(0, "Cannot open ViM" )
    Else
        Send( "{Enter}" )
        Send( "^a" )
        Send( "^v" )
        Send( "{ESC}" )
    EndIf
EndFunc

Func writeBack()
    if( WinActivate( $hdViM ) = 0 ) Then
        MsgBox(0, "Cannot open ViM" )
    Else
        Send( "^a" )
        Send( "^c" )
        Send( "{ESC}" )
    EndIf
    $sContent = _ClipBoard_GetData ();
    $oActiveElement.innerText = $sContent;
EndFunc

I would have one further question though, if the element resides in an iframe this script won't work, I'd have to add sg like:

$oFrame = _IEFrameGetCollection ($oIE, 2)
    if( $oFrame = 0 ) then
        $oDoc = _IEDocGetObj( $oIE );
    Else
        $oDoc = _IEDocGetObj( $oFrame );
    EndIf

Is there a way to figure out that the active element sits inside an iframe so that we can deal in a generic way with this problem?

Thanks,

Juergen

Link to comment
Share on other sites

Maybe you could loop through the iFrames until you get one that has an ActiveElement. Hopefully only one iframe can have an active element at a time. If that's the case then loop though the iframes and test for an active element in each one. If IsObj($oActiveElement) = 0 then presumably that iframe hasn't got an active element so move on to the next iframe. Once IsObj($oActiveElement) returns a 1 you will exit the loop and end up with the object variable you need. So you might be able to do something like this:

$oFrameCol = _IEFrameGetCollection($oIE)
$iNumFrames = @extended
ConsoleWrite("Number of frames: " & $iNumFrames & @CRLF)
If IsObj($oFrameCol) Then
;~ If $iNumFrames > 0       ;Or use this "IF"? Guess it doesn't matter...
    For $i = 0 To ( $iNumFrames - 1 )               ;Loop through the frames
        $oFrame = _IEFrameGetCollection($oIE, $i)   ;Get the current frame
        $oDoc = _IEDocGetObj($oFrame)               ;Get DOC of current frame
        $oActiveElement = $oDoc.activeElement       ;Get activeElement of current DOC
        If IsObj($oActiveElement) Then              ;Test if activeElement is actually an object
            $sTagName = $oActiveElement.tagname     ;If so, get it's tagname
            If StringCompare($sTagName, "INPUT") = 0 Then   ;If it's an "INPUT" tag (which is what you want, right?)
                ConsoleWrite("URL of iframe: " & _IEPropertyGet($oFrame, "locationurl") & @CRLF)    ;Then read the frame's URL or whatever
                ConsoleWrite("Tagname of active element in iframe: " & $sTagName & @CRLF)           ;Name of the "INPUT" tag
                ConsoleWrite("Contents of the active element: " & $oActiveElement.value & @CRLF)    ;Value of the "INPUT" tag
            EndIf
            ExitLoop    ;Once we've got a positive on the IsObj($oActiveElement) test exit the loop
        EndIf               ;Leaving you with $oFrame, $oDoc, and $oActiveElement to use as needed
    Next
Else
    ;No frames?
EndIf

There's probably a better way to do it but IE (or nothing else for that matter :huh2: ) isn't really my thing. So hopefully someone else chips in

Link to comment
Share on other sites

MrMitchell,

thanks again for your support! It worked like a charm; the only modification a made was to move the ExitLoop inside the comparison for the TEXTAREA field.. Great thanks a lot!

Cheers,

Juergen

PS: it is truly amazing who this tool is making my life easier!

Func getActiveTextarea()
    $oActiveElement = false 
    $oFrameCol = _IEFrameGetCollection($oIE)
    $iNumFrames = @extended
    ConsoleWrite("Number of frames: " & $iNumFrames & @CRLF)
    If IsObj($oFrameCol) Then
        ConsoleWrite("frame " &  @CRLF)
    ;~ If $iNumFrames > 0       ;Or use this "IF"? Guess it doesn't matter...
        For $i = 0 To ( $iNumFrames - 1 )               ;Loop through the frames
            $oFrame = _IEFrameGetCollection($oIE, $i)   ;Get the current frame
            $oDoc = _IEDocGetObj($oFrame)               ;Get DOC of current frame
            $oActiveElement = $oDoc.activeElement       ;Get activeElement of current DOC
            If IsObj($oActiveElement) Then              ;Test if activeElement is actually an object
                $sTagName = $oActiveElement.tagname     ;If so, get it's tagname
                If StringCompare($sTagName, "TEXTAREA") = 0 Then   ;If it's an "INPUT" tag (which is what you want, right?)
                    ExitLoop    ;Once we've got a positive on the IsObj($oActiveElement) test exit the loop
                EndIf
            EndIf               ;Leaving you with $oFrame, $oDoc, and $oActiveElement to use as needed
        Next
    Else
    EndIf
    If ($oActiveElement = false) Then  
        ConsoleWrite(" no frame " & $oActiveElement & @CRLF)
        $oDoc = _IEDocGetObj( $oIE );
        $oActiveElement = $oDoc.activeElement;
    EndIf
return $oActiveElement;

EndFunc
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...