Jump to content

Onclick event bug(?) in Shell.Explorer.2


LionH
 Share

Go to solution Solved by SmOke_N,

Recommended Posts

Hello,

I am working on an interface that requires IE9+ for HTML5 CSS/JS elements.

Standard, the function:

$Obj = ObjCreate("Shell.Explorer.2")

will load an IE instance in the background but it will use by default IE7.0

So i change it in the register when starting my interface but then the onclick event stops working. Is this a bug? Is there a way to fix it?

 

in the following example i use an existing online webpage, where the onclick Event doesnt fire when you click on the element with id="user-agent" but it is what i ask for...

I commented away the RegEdit block, it does change the used IE version, but that didnt fix the problem.

Where did i get the RegWrite info? http://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version

Did the IE version change when i used the RegWrite function? Yes, from IE7 to IE9... But still it couldnt fire a click event when i clicked on the specified element with id="user-agent.

#RequireAdmin
#include <IE.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <String.au3>
#include <Array.au3>
#include <Misc.au3>    
#include <Process.au3>
;RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", _ProcessGetName(@AutoItPID), "REG_DWORD", "0x270F")
;RegWrite("HKEY_LOCAL_MACHINESOFTWARE\Wow64\32\Node\Microsoft\Internet ExplorerMAINFeatureControlFEATURE_BROWSER_EMULATION", _ProcessGetName(@AutoItPID), "REG_DWORD", "0x270F")



$hGui = GUICreate("Browser-test",500,500,0,0,$WS_POPUP)
$Obj = ObjCreate("Shell.Explorer.2")
$CtrlObj = GUICtrlCreateObj($Obj,-1,-1,500,500)
GUISetState (@SW_SHOW)
_IENavigate($Obj, "https://www.whatismybrowser.com/what-is-my-user-agent")
;_IELoadWait($Obj)


$oButton1 = _IEGetObjById($Obj, 'user-agent');
ObjEvent($oButton1, "shutdown_");


Func shutdown_onclick()
    MsgBox(0, "Yo", "Clicked on Shutdown.")
    exit;
EndFunc
    
While 1
    Sleep(100)
WEnd

Please help, i tried almost everything!

Thanks,

 

Kind regards,

Lion H.

Edited by LionH
Link to comment
Share on other sites

Yeah, it looks that way from the helpfile.

By the way, you should reduce the full screen size

of the browser window for testing here, because it's

covering everything, including the taskbar.

Some people won't know how to get out of it.

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

  • Moderators

I'm curious on what's expected here.

I do not see an event for "onclick" set for that DIV-ID.

What exactly do you think ObjEvent does?

You'll need this for a reference:

http://msdn.microsoft.com/en-us/library/hh801967(v=vs.85).aspx

And probably specifically this from that:

http://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx

Do a search for ObjEvent and HTMLDocumentEvents2, I bet someone has an example.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Ok, yes I was bored...

#include <IE.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>


;### OP's code - Start
$hGui = GUICreate("Browser-test",500,500,0,0)
$Obj = ObjCreate("Shell.Explorer.2")
$CtrlObj = GUICtrlCreateObj($Obj,-1,-1,500,500)
GUISetState (@SW_SHOW)
_IENavigate($Obj, "https://www.whatismybrowser.com/what-is-my-user-agent")
_IELoadWait($Obj)
;### OP's code - End

;[n][0] = object id string name
;[n][1] = object (by _iegetobjbyid)
;[n][2] = clicked (bool, 1 = true, 0 = false)
Global $ga_ObjsOnClick
Global $go_ObjDoc = $obj.document

; I'd probably create more preceise functions to add to/remove
;  from the global array to make it somewhat more dynamic,
;  something like the below
_myIE_AddClickObjData($Obj, "user-agent", $ga_ObjsOnClick)
ObjEvent($go_ObjDoc, "shutdown_", "HTMLDocumentEvents2");

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "user-agent") Then
        MsgBox(64 + 262144, "Clicked", "You clicked user-agent object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "user-agent")
    EndIf
WEnd

Volatile Func shutdown_onclick($o_obj)

    If Not IsObj($o_obj) Then Return

    If String(Execute("$o_obj.type")) <> "click" Then Return

    ; obviously you'd have something like objects by name/id/class/etc
    ;  system setup in an array or multiple functions to achieve your goal
    ;  where you're not interfering with the callback (with something like
    ;  a msgbox call)
    ; for simplicity, I'm only going to show an id method

    ; I would normally iterate through all of what I felt needed to be
    ;   but I know this works, so I'll keep it simple

    Local $o_psrc = $o_obj.srcElement.parentNode

    For $iobjs = 0 To UBound($ga_ObjsOnClick) - 1
        If String($o_psrc.id) = $ga_ObjsOnClick[$iobjs][0] Then
            ; I'm not sold on using this ID method unless you'll religously
            ;  check the id's yourself with _IEGetObjByID when pages load and reload
            If $ga_ObjsOnClick[$iobjs][1] = $o_psrc Then
                $ga_ObjsOnClick[$iobjs][2] = 1
                Return
            EndIf
        EndIf
    Next
EndFunc

; these functions were primarily for my own amusement
Func _myIE_AddClickObjData(ByRef $o_obj, $s_idstr, ByRef $a_objsclick)

    If Not IsObj($o_obj) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $o_id = _IEGetObjById($o_obj, $s_idstr)
    If Not IsObj($o_id) Then
        Return SetError(2, 0, 0)
    EndIf

    Local $i_ub = UBound($a_objsclick)
    If Not $i_ub Then
        Dim $a_objsclick[1][3]; ugh, magic numbers... fun (Not!)
    Else
        ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick)]
    EndIf

    $a_objsclick[$i_ub][0] = $s_idstr
    $a_objsclick[$i_ub][1] = $o_id
    $a_objsclick[$i_ub][2] = 0

    Return 1
EndFunc

Func _myIE_ResetClickObjBool(ByRef $a_objsclick, $v_index = 0)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        $a_objsclick[$v_index][2] = 0
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    EndIf
EndFunc

Func _myIE_IsClickObjBool(ByRef $a_objsclick, $v_index)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        Return $a_objsclick[$v_index][2]
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    EndIf

EndFunc
Edited by SmOke_N
Didn't validate event was a click

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

 

Ok, yes I was bored...

#include <IE.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>


;### OP's code - Start
$hGui = GUICreate("Browser-test",500,500,0,0)
$Obj = ObjCreate("Shell.Explorer.2")
$CtrlObj = GUICtrlCreateObj($Obj,-1,-1,500,500)
GUISetState (@SW_SHOW)
_IENavigate($Obj, "https://www.whatismybrowser.com/what-is-my-user-agent")
_IELoadWait($Obj)
;### OP's code - End

;[n][0] = object id string name
;[n][1] = object (by _iegetobjbyid)
;[n][2] = clicked (bool, 1 = true, 0 = false)
Global $ga_ObjsOnClick
Global $go_ObjDoc = $obj.document

; I'd probably create more preceise functions to add to/remove
;  from the global array to make it somewhat more dynamic,
;  something like the below
_myIE_AddClickObjData($Obj, "user-agent", $ga_ObjsOnClick)
ObjEvent($go_ObjDoc, "shutdown_", "HTMLDocumentEvents2");

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "user-agent") Then
        MsgBox(64 + 262144, "Clicked", "You clicked user-agent object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "user-agent")
    EndIf
WEnd

Volatile Func shutdown_onclick($o_obj)

    If Not IsObj($o_obj) Then Return

    If String(Execute("$o_obj.type")) <> "click" Then Return

    ; obviously you'd have something like objects by name/id/class/etc
    ;  system setup in an array or multiple functions to achieve your goal
    ;  where you're not interfering with the callback (with something like
    ;  a msgbox call)
    ; for simplicity, I'm only going to show an id method

    ; I would normally iterate through all of what I felt needed to be
    ;   but I know this works, so I'll keep it simple

    Local $o_psrc = $o_obj.srcElement.parentNode

    For $iobjs = 0 To UBound($ga_ObjsOnClick) - 1
        If String($o_psrc.id) = $ga_ObjsOnClick[$iobjs][0] Then
            ; I'm not sold on using this ID method unless you'll religously
            ;  check the id's yourself with _IEGetObjByID when pages load and reload
            If $ga_ObjsOnClick[$iobjs][1] = $o_psrc Then
                $ga_ObjsOnClick[$iobjs][2] = 1
                Return
            EndIf
        EndIf
    Next
EndFunc

; these functions were primarily for my own amusement
Func _myIE_AddClickObjData(ByRef $o_obj, $s_idstr, ByRef $a_objsclick)

    If Not IsObj($o_obj) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $o_id = _IEGetObjById($o_obj, $s_idstr)
    If Not IsObj($o_id) Then
        Return SetError(2, 0, 0)
    EndIf

    Local $i_ub = UBound($a_objsclick)
    If Not $i_ub Then
        Dim $a_objsclick[1][3]; ugh, magic numbers... fun (Not!)
    Else
        ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick)]
    EndIf

    $a_objsclick[$i_ub][0] = $s_idstr
    $a_objsclick[$i_ub][1] = $o_id
    $a_objsclick[$i_ub][2] = 0

    Return 1
EndFunc

Func _myIE_ResetClickObjBool(ByRef $a_objsclick, $v_index = 0)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        $a_objsclick[$v_index][2] = 0
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    EndIf
EndFunc

Func _myIE_IsClickObjBool(ByRef $a_objsclick, $v_index)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        Return $a_objsclick[$v_index][2]
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    EndIf

EndFunc

Thanks A LOT for helping out! Your source DOES work on that site. But then i switched to a other site and it stopped working. What am i missing here?

See my source:

#include <IE.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>


;### OP's code - Start
$hGui = GUICreate("Browser-test",500,500,0,0)
$Obj = ObjCreate("Shell.Explorer.2")
$CtrlObj = GUICtrlCreateObj($Obj,-1,-1,500,500)
GUISetState (@SW_SHOW)
_IENavigate($Obj, "http://test.xjz.nl/")
_IELoadWait($Obj)
;### OP's code - End

;[n][0] = object id string name
;[n][1] = object (by _iegetobjbyid)
;[n][2] = clicked (bool, 1 = true, 0 = false)
Global $ga_ObjsOnClick
Global $go_ObjDoc = $obj.document

; I'd probably create more preceise functions to add to/remove
;  from the global array to make it somewhat more dynamic,
;  something like the below
_myIE_AddClickObjData($Obj, "closeWindow", $ga_ObjsOnClick)
ObjEvent($go_ObjDoc, "shutdown_", "HTMLDocumentEvents2");

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "closeWindow") Then
        MsgBox(64 + 262144, "Clicked", "You clicked closeWindow object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "closeWindow")
        exit;
    EndIf
WEnd

Volatile Func shutdown_onclick($o_obj)

    If Not IsObj($o_obj) Then Return

    If String(Execute("$o_obj.type")) <> "click" Then Return

    ; obviously you'd have something like objects by name/id/class/etc
    ;  system setup in an array or multiple functions to achieve your goal
    ;  where you're not interfering with the callback (with something like
    ;  a msgbox call)
    ; for simplicity, I'm only going to show an id method

    ; I would normally iterate through all of what I felt needed to be
    ;   but I know this works, so I'll keep it simple

    Local $o_psrc = $o_obj.srcElement.parentNode

    For $iobjs = 0 To UBound($ga_ObjsOnClick) - 1
        If String($o_psrc.id) = $ga_ObjsOnClick[$iobjs][0] Then
            ; I'm not sold on using this ID method unless you'll religously
            ;  check the id's yourself with _IEGetObjByID when pages load and reload
            If $ga_ObjsOnClick[$iobjs][1] = $o_psrc Then
                $ga_ObjsOnClick[$iobjs][2] = 1
                Return
            EndIf
        EndIf
    Next
EndFunc

; these functions were primarily for my own amusement
Func _myIE_AddClickObjData(ByRef $o_obj, $s_idstr, ByRef $a_objsclick)

    If Not IsObj($o_obj) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $o_id = _IEGetObjById($o_obj, $s_idstr)
    If Not IsObj($o_id) Then
        Return SetError(2, 0, 0)
    EndIf

    Local $i_ub = UBound($a_objsclick)
    If Not $i_ub Then
        Dim $a_objsclick[1][3]; ugh, magic numbers... fun (Not!)
    Else
        ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick)]
    EndIf

    $a_objsclick[$i_ub][0] = $s_idstr
    $a_objsclick[$i_ub][1] = $o_id
    $a_objsclick[$i_ub][2] = 0

    Return 1
EndFunc

Func _myIE_ResetClickObjBool(ByRef $a_objsclick, $v_index = 0)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        $a_objsclick[$v_index][2] = 0
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    EndIf
EndFunc

Func _myIE_IsClickObjBool(ByRef $a_objsclick, $v_index)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        Return $a_objsclick[$v_index][2]
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    EndIf

EndFunc

The click didnt get detected. Also, it is important that i use HTML5/CSS3 functionality in my final version of this page, but it doesnt switch to IE9 even when i try to force it with a META ...

Please run my source code to understand my problem.

 

I hope someone can help me out further.

 

SmOke_N, many many thanks for helping out! You are the best! ;-)

 

Kind regards,

Lion H

Link to comment
Share on other sites

  • Moderators

Without direct access to the website, there's no way to be specific on what is wrong.

I assume you'll need to debug data in the event call function (the onclick one).

Probably something to do with the parentnode area.

I did all of that generic as I stated in my comments within the code, you would need to spend quite some time putting in ever variation within there.

But I would start with if it even shows up within that event first.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

#include <IE.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>


;### OP's code - Start
$hGui = GUICreate("Browser-test",500,500,0,0)
$Obj = ObjCreate("Shell.Explorer.2")
$CtrlObj = GUICtrlCreateObj($Obj,-1,-1,500,500)
GUISetState (@SW_SHOW)
_IENavigate($Obj, "http://test.xjz.nl/")
_IELoadWait($Obj)
;### OP's code - End

;[n][0] = object id string name
;[n][1] = object (by _iegetobjbyid)
;[n][2] = clicked (bool, 1 = true, 0 = false)
Global $ga_ObjsOnClick
Global $go_ObjDoc = $obj.document
Global $gs_ObjId = "closeWindow"

; I'd probably create more preceise functions to add to/remove
;  from the global array to make it somewhat more dynamic,
;  something like the below
_myIE_AddClickObjData($Obj, $gs_ObjId, $ga_ObjsOnClick)
ObjEvent($go_ObjDoc, "shutdown_", "HTMLDocumentEvents2");

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    If _myIE_IsClickObjBool($ga_ObjsOnClick, $gs_ObjId) Then
        MsgBox(64 + 262144, "Clicked", "You clicked closeWindow object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, $gs_ObjId)
        exit;
    EndIf
WEnd

Volatile Func shutdown_onclick($o_obj)

    If Not IsObj($o_obj) Then Return

    If String(Execute("$o_obj.type")) <> "click" Then Return

    ; obviously you'd have something like objects by name/id/class/etc
    ;  system setup in an array or multiple functions to achieve your goal
    ;  where you're not interfering with the callback (with something like
    ;  a msgbox call)
    ; for simplicity, I'm only going to show an id method

    ; I would normally iterate through all of what I felt needed to be
    ;   but I know this works, so I'll keep it simple

    Local $o_src = $o_obj.srcElement
    Local $o_psrc = $o_obj.srcElement.parentNode

    Local $o_id = $o_src.id
    Local $o_objelem = $o_src

    If Not $o_id Then
        $o_id = $o_psrc.id
        $o_objelem = $o_psrc
    EndIf

    For $iobjs = 0 To UBound($ga_ObjsOnClick) - 1
        If String($o_id) = $ga_ObjsOnClick[$iobjs][0] Then
            ; I'm not sold on using this ID method unless you'll religously
            ;  check the id's yourself with _IEGetObjByID when pages load and reload
            If $ga_ObjsOnClick[$iobjs][1] = $o_objelem Then
                $ga_ObjsOnClick[$iobjs][2] = 1
                Return
            EndIf
        EndIf
    Next
EndFunc

; these functions were primarily for my own amusement
Func _myIE_AddClickObjData(ByRef $o_obj, $s_idstr, ByRef $a_objsclick)

    If Not IsObj($o_obj) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $o_id = _IEGetObjById($o_obj, $s_idstr)
    If Not IsObj($o_id) Then
        Return SetError(2, 0, 0)
    EndIf

    Local $i_ub = UBound($a_objsclick)
    If Not $i_ub Then
        Dim $a_objsclick[1][3]; ugh, magic numbers... fun (Not!)
    Else
        ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick)]
    EndIf

    $a_objsclick[$i_ub][0] = $s_idstr
    $a_objsclick[$i_ub][1] = $o_id
    $a_objsclick[$i_ub][2] = 0

    Return 1
EndFunc

Func _myIE_ResetClickObjBool(ByRef $a_objsclick, $v_index = 0)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        $a_objsclick[$v_index][2] = 0
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    EndIf
EndFunc

Func _myIE_IsClickObjBool(ByRef $a_objsclick, $v_index)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        Return $a_objsclick[$v_index][2]
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    EndIf

EndFunc

Edited by SmOke_N
editing code on here is silly

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

SmOke_N, You are truely amazing, THANKS! But the more i try to understand how your source works, the more i can return confused. So i will keep playing with it for a while. I am sure i will need this source more in the future, and probaly the same for other people... again... THANKS A LOT!

My problem is solved... One more issue, but i try to find out myself: what if i want to use a event on other id's as well? My easy answer to that is just copy/paste your functions and but a 2 at the end of every variable. This isnt the nicest solution, but maybe you could show me some more code to use? I started using AutoIt a few months ago, and learned a lot by playing with existing code from the pro's like you. I'll keep doing this until i can help people in need just like you did for me! And again... THANKS!

If you could help me out, what to do when there are more buttons, like closeWindow, i also need buttons with id's like: openWindow, startNotepad, startPaint, etc... They will be included in my interface as well...

 

Also... You got any idea why the standard wasnt working? I dont think i ask too much at all:

$hGui = GUICreate("window",500,500,0,0,$WS_POPUP)
$Obj = ObjCreate("Shell.Explorer.2")
$CtrlObj = GUICtrlCreateObj($Obj,0,0,500,500)
GUISetState (@SW_SHOW)
_IENavigate($Obj, "http://link-to-webserver/index.php")
_IELoadWait($Obj)

$Button1 = _IEGetObjById($Obj, '_myButtonID');
$oEvtButton1 = ObjEvent($Button1, "myFunction_");

Func myFunction_onclick()
    ;function contents    
EndFunc

Many many many thanks, i hope i can someday do something for you in return..!

Kind regards,

Lion H

Edited by LionH
Link to comment
Share on other sites

  • Moderators
This is why I took the time to create the array, functions, and the comments I did.
 
They were supposed to give you an idea on how to approach adding more items for onclick, monitoring as many items as you needed, and the ability to reset them and continue on with the rest of your script.
 
1.  $ga_ObjsOnClick (note the $ga <-) the "a" there represents an array variable, I labled the rest ObjsOnClick, with OnClick being the event I wanted to monitor, it's a reference visually for myself. This array allows you to add multiple items for "onclick" using the "add" function I've provided for "click" events.
2.  The functions: _myIE_AddClickObjData, _myIE_ResetClickObjBool, _myIE_IsClickObjBool.  These are used to add, reset, and validate if an event of "onclick/click" was fired.
 
If you were going to add multiple event items for "click", you'd simply use the _myIE_AddClickObjData, it will control the size of the array of data and allow you to continuously add items.  You'd need to monitor them by either a unique "id" (user-agent) or by the "id" object (_IEGetObjById).
 
You can create more arrays for the different events, you can create more functions for the different events.
 
You could write a multi-purpose udf that would be much less functions using strings and a container array that would take care of the several event types.  This whole concept could be done much more efficient, but I don't feel like writing an entire udf on it.
 
For your convenience, I've changed the shutdown_onclick function to add all the different events that HTMLDocumentEvents2 will return to a multi-purpose function.  Hopefully this provides you some sort of roadmap and a aha! moment.
 
I'm half asleep as I write this, so I hope it makes sense.
 
Good luck.
 
#include <IE.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>


;### OP's code - Start
$hGui = GUICreate("Browser-test",500,500,0,0)
$Obj = ObjCreate("Shell.Explorer.2")
$CtrlObj = GUICtrlCreateObj($Obj,-1,-1,500,500)
GUISetState (@SW_SHOW)
_IENavigate($Obj, "http://test.xjz.nl/")
_IELoadWait($Obj)
;### OP's code - End

;[n][0] = object id string name
;[n][1] = object (by _iegetobjbyid)
;[n][2] = clicked (bool, 1 = true, 0 = false)
Global $ga_ObjsOnClick
Global $go_ObjDoc = $obj.document
Global $gs_ObjId = "closeWindow"

; I'd probably create more preceise functions to add to/remove
;  from the global array to make it somewhat more dynamic,
;  something like the below
_myIE_AddClickObjData($Obj, $gs_ObjId, $ga_ObjsOnClick)
ObjEvent($go_ObjDoc, "_myevent_", "HTMLDocumentEvents2");

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    If _myIE_IsClickObjBool($ga_ObjsOnClick, $gs_ObjId) Then
        MsgBox(64 + 262144, "Clicked", "You clicked closeWindow object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, $gs_ObjId)
        exit;
    EndIf
WEnd

; these volatile functions would be from all the options in
;   the _mymultipurposeevent_functionhandler function
Volatile Func _myevent_afterupdate($o_obj)
    _mymultipurposeevent_functionhandler($o_obj)
EndFunc

Volatile Func _myevent_beforeactivate($o_obj)
    _mymultipurposeevent_functionhandler($o_obj)
EndFunc

Volatile Func _myevent_onclick($o_obj)
    _mymultipurposeevent_functionhandler($o_obj)
EndFunc


Func _mymultipurposeevent_functionhandler($o_obj)

    If Not IsObj($o_obj) Then Return

    Local $s_objtype = String(Execute("$o_obj.type"))

    If Not $s_objtype Then Return

    ; obviously you'd have something like objects by name/id/class/etc
    ;  system setup in an array or multiple functions to achieve your goal
    ;  where you're not interfering with the callback (with something like
    ;  a msgbox call)
    ; for simplicity, I'm only going to show an id method

    ; I would normally iterate through all of what I felt needed to be
    ;   but I know this works, so I'll keep it simple

    Local $o_src = $o_obj.srcElement
    Local $o_psrc = $o_obj.srcElement.parentNode

    Local $o_id = $o_src.id
    Local $o_objelem = $o_src

    If Not $o_id Then
        $o_id = $o_psrc.id
        $o_objelem = $o_psrc
    EndIf

    Switch StringLower($s_objtype)
        Case "afterupdate" ; onafterupdate
            ; put action data here
        Case "beforeactivate" ; onbeforeactivate
            ; put action data here
        Case "beforeeditfocus" ; onbeforeeditfocus
            ; put action data here
        Case "beforeupdate" ; onbeforeupdate
            ; put action data here
        Case "cellchange" ; onbeforecellchange
            ; put action data here
        Case "click" ; onclick
            ; here is action data
            For $iobjs = 0 To UBound($ga_ObjsOnClick) - 1
                If String($o_id) = $ga_ObjsOnClick[$iobjs][0] Then
                    ; I'm not sold on using this ID method unless you'll religously
                    ;  check the id's yourself with _IEGetObjByID when pages load and reload
                    If $ga_ObjsOnClick[$iobjs][1] = $o_objelem Then
                        $ga_ObjsOnClick[$iobjs][2] = 1
                        Return
                    EndIf
                EndIf
            Next
        Case "contextmenu" ; oncontextmenu
            ; put action data here
        Case "dataavailable" ; ondataavailable
            ; put action data here
        Case "datasetchanged" ; ondatasetchanged
            ; put action data here
        Case "dblclick" ; ondblclick
            ; put action data here
        Case "dragstart" ; ondragstart
            ; put action data here
        Case "errorupdate" ; onerrorupdate
            ; put action data here
        Case "focusin" ; onfocusin
            ; put action data here
        Case "focusout" ; onfocusout
            ; put action data here
        Case "help" ; onhelp
            ; put action data here
        Case "keypress" ; onkeypress
            ; put action data here
        Case "mousedown" ; onmousedown
            ; put action data here
        Case "mousemove" ; onmousemove
            ; put action data here
        Case "mouseout" ; onmouseout
            ; put action data here
        Case "mouseover" ; onmouseover
            ; put action data here
        Case "mouseup" ; onmouseup
            ; put action data here
        Case "mousewheel" ; onmousewheel
            ; put action data here
        Case "ondatasetcomplete" ; onondatasetcomplete
            ; put action data here
        Case "onkeyup" ; ononkeyup
            ; put action data here
        Case "propertychange" ; onpropertychange
            ; put action data here
        Case "readystatechange" ; onreadystatechange
            ; put action data here
        Case "rowenter" ; onrowenter
            ; put action data here
        Case "rowexit" ; onrowexit
            ; put action data here
        Case "rowsdelete" ; onrowsdelete
            ; put action data here
        Case "rowsinserted" ; onrowsinserted
            ; put action data here
        Case "selectionchange" ; onselectionchange
            ; put action data here
        Case "selectstart" ; onselectstart
            ; put action data here
        Case "stop" ; onstop
            ; put action data here
    EndSwitch
EndFunc

; these functions were primarily for my own amusement
Func _myIE_AddClickObjData(ByRef $o_obj, $s_idstr, ByRef $a_objsclick)

    If Not IsObj($o_obj) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $o_id = _IEGetObjById($o_obj, $s_idstr)
    If Not IsObj($o_id) Then
        Return SetError(2, 0, 0)
    EndIf

    Local $i_ub = UBound($a_objsclick)
    If Not $i_ub Then
        Dim $a_objsclick[1][3]; ugh, magic numbers... fun (Not!)
    Else
        ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick)]
    EndIf

    $a_objsclick[$i_ub][0] = $s_idstr
    $a_objsclick[$i_ub][1] = $o_id
    $a_objsclick[$i_ub][2] = 0

    Return 1
EndFunc

Func _myIE_ResetClickObjBool(ByRef $a_objsclick, $v_index = 0)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        $a_objsclick[$v_index][2] = 0
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    EndIf
EndFunc

Func _myIE_IsClickObjBool(ByRef $a_objsclick, $v_index)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        Return $a_objsclick[$v_index][2]
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    EndIf

EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Thanks again!

I found out, when reloading the page in the dialog, it stops monitoring for the button clicks.

Using the information you provided, is it so that by simply replacing:

_myIE_AddClickObjData($Obj, $gs_ObjId, $ga_ObjsOnClick)
ObjEvent($go_ObjDoc, "_myevent_", "HTMLDocumentEvents2");

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    If _myIE_IsClickObjBool($ga_ObjsOnClick, $gs_ObjId) Then
        MsgBox(64 + 262144, "Clicked", "You clicked closeWindow object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, $gs_ObjId)
        exit;
    EndIf
WEnd

into:

_myIE_AddClickObjData($Obj, "htmlidname1", $ga_ObjsOnClick)
_myIE_AddClickObjData($Obj, "htmlidname2", $ga_ObjsOnClick)
_myIE_AddClickObjData($Obj, "htmlidname3", $ga_ObjsOnClick)
ObjEvent($go_ObjDoc, "_myevent_", "HTMLDocumentEvents2");

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "htmlidname1") Then
        MsgBox(64 + 262144, "Clicked", "You clicked htmlidname1 object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "htmlidname1")
        exit;
    EndIf
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "htmlidname2") Then
        MsgBox(64 + 262144, "Clicked", "You clicked htmlidname2 object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "htmlidname2")
        exit;
    EndIf
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "htmlidname3") Then
        MsgBox(64 + 262144, "Clicked", "You clicked htmlidname3 object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "htmlidname3")
        exit;
    EndIf

WEnd

it will monitor 3 html buttons with id, htmlidname1, 2 and 3?

 

Also, do you understand why the basic way doesn't work when its an IE8+ document?

I have made IE7 documents before, including over 20 buttons.

Many thanks,

 

Kind regards,

Lion H

Link to comment
Share on other sites

  • Moderators

it will monitor 3 html buttons with id, htmlidname1, 2 and 3?

Yes, you understand it seems.

 

Also, do you understand why the basic way doesn't work when its an IE8+ document?

I have made IE7 documents before, including over 20 buttons.

The same reason that website designers have to change their own methods for different IE versions.  You see often them not only checking what browser it is they are working in with code, but what version as well.

Things start failing more and more throughout the higher versions.

DaleHohm, the author of IE.au3, makes a valiant effort in keeping all the functions up to date, but in all seriousness, that's more than a full time job (with no pay mind you).

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 3 months later...

Sorry but multiple id's doesn't work, i get this error:

Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$a_objsclick[$i_ub][1] = $o_id
^ ERROR

Since everything is connected to each other, i don't know how to fix it myself. Can someone please check this out?

#include <IE.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>


;### OP's code - Start
$hGui = GUICreate("Browser-test",500,500,0,0)
$Obj = ObjCreate("Shell.Explorer.2")
$CtrlObj = GUICtrlCreateObj($Obj,-1,-1,500,500)
GUISetState (@SW_SHOW)
_IENavigate($Obj, "http://test.xjz.nl/")
_IELoadWait($Obj)
;### OP's code - End

;[n][0] = object id string name
;[n][1] = object (by _iegetobjbyid)
;[n][2] = clicked (bool, 1 = true, 0 = false)
Global $ga_ObjsOnClick
Global $go_ObjDoc = $obj.document
Global $gs_ObjId = "closeWindow"

; I'd probably create more preceise functions to add to/remove
;  from the global array to make it somewhat more dynamic,
;  something like the below
_myIE_AddClickObjData($Obj, "htmlidname1", $ga_ObjsOnClick)
_myIE_AddClickObjData($Obj, "htmlidname2", $ga_ObjsOnClick)
_myIE_AddClickObjData($Obj, "htmlidname3", $ga_ObjsOnClick)
ObjEvent($go_ObjDoc, "_myevent_", "HTMLDocumentEvents2");

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "htmlidname1") Then
        MsgBox(64 + 262144, "Clicked", "You clicked htmlidname1 object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "htmlidname1")
        exit;
    EndIf
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "htmlidname2") Then
        MsgBox(64 + 262144, "Clicked", "You clicked htmlidname2 object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "htmlidname2")
        exit;
    EndIf
    If _myIE_IsClickObjBool($ga_ObjsOnClick, "htmlidname3") Then
        MsgBox(64 + 262144, "Clicked", "You clicked htmlidname3 object.")
        ; clear out bool
        _myIE_ResetClickObjBool($ga_ObjsOnClick, "htmlidname3")
        exit;
    EndIf

WEnd

; these volatile functions would be from all the options in
;   the _mymultipurposeevent_functionhandler function
Volatile Func _myevent_afterupdate($o_obj)
    _mymultipurposeevent_functionhandler($o_obj)
EndFunc

Volatile Func _myevent_beforeactivate($o_obj)
    _mymultipurposeevent_functionhandler($o_obj)
EndFunc

Volatile Func _myevent_onclick($o_obj)
    _mymultipurposeevent_functionhandler($o_obj)
EndFunc


Func _mymultipurposeevent_functionhandler($o_obj)

    If Not IsObj($o_obj) Then Return

    Local $s_objtype = String(Execute("$o_obj.type"))

    If Not $s_objtype Then Return

    ; obviously you'd have something like objects by name/id/class/etc
    ;  system setup in an array or multiple functions to achieve your goal
    ;  where you're not interfering with the callback (with something like
    ;  a msgbox call)
    ; for simplicity, I'm only going to show an id method

    ; I would normally iterate through all of what I felt needed to be
    ;   but I know this works, so I'll keep it simple

    Local $o_src = $o_obj.srcElement
    Local $o_psrc = $o_obj.srcElement.parentNode

    Local $o_id = $o_src.id
    Local $o_objelem = $o_src

    If Not $o_id Then
        $o_id = $o_psrc.id
        $o_objelem = $o_psrc
    EndIf

    Switch StringLower($s_objtype)
        Case "afterupdate" ; onafterupdate
            ; put action data here
        Case "beforeactivate" ; onbeforeactivate
            ; put action data here
        Case "beforeeditfocus" ; onbeforeeditfocus
            ; put action data here
        Case "beforeupdate" ; onbeforeupdate
            ; put action data here
        Case "cellchange" ; onbeforecellchange
            ; put action data here
        Case "click" ; onclick
            ; here is action data
            For $iobjs = 0 To UBound($ga_ObjsOnClick) - 1
                If String($o_id) = $ga_ObjsOnClick[$iobjs][0] Then
                    ; I'm not sold on using this ID method unless you'll religously
                    ;  check the id's yourself with _IEGetObjByID when pages load and reload
                    If $ga_ObjsOnClick[$iobjs][1] = $o_objelem Then
                        $ga_ObjsOnClick[$iobjs][2] = 1
                        Return
                    EndIf
                EndIf
            Next
        Case "contextmenu" ; oncontextmenu
            ; put action data here
        Case "dataavailable" ; ondataavailable
            ; put action data here
        Case "datasetchanged" ; ondatasetchanged
            ; put action data here
        Case "dblclick" ; ondblclick
            ; put action data here
        Case "dragstart" ; ondragstart
            ; put action data here
        Case "errorupdate" ; onerrorupdate
            ; put action data here
        Case "focusin" ; onfocusin
            ; put action data here
        Case "focusout" ; onfocusout
            ; put action data here
        Case "help" ; onhelp
            ; put action data here
        Case "keypress" ; onkeypress
            ; put action data here
        Case "mousedown" ; onmousedown
            ; put action data here
        Case "mousemove" ; onmousemove
            ; put action data here
        Case "mouseout" ; onmouseout
            ; put action data here
        Case "mouseover" ; onmouseover
            ; put action data here
        Case "mouseup" ; onmouseup
            ; put action data here
        Case "mousewheel" ; onmousewheel
            ; put action data here
        Case "ondatasetcomplete" ; onondatasetcomplete
            ; put action data here
        Case "onkeyup" ; ononkeyup
            ; put action data here
        Case "propertychange" ; onpropertychange
            ; put action data here
        Case "readystatechange" ; onreadystatechange
            ; put action data here
        Case "rowenter" ; onrowenter
            ; put action data here
        Case "rowexit" ; onrowexit
            ; put action data here
        Case "rowsdelete" ; onrowsdelete
            ; put action data here
        Case "rowsinserted" ; onrowsinserted
            ; put action data here
        Case "selectionchange" ; onselectionchange
            ; put action data here
        Case "selectstart" ; onselectstart
            ; put action data here
        Case "stop" ; onstop
            ; put action data here
    EndSwitch
EndFunc

; these functions were primarily for my own amusement
Func _myIE_AddClickObjData(ByRef $o_obj, $s_idstr, ByRef $a_objsclick)

    If Not IsObj($o_obj) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $o_id = _IEGetObjById($o_obj, $s_idstr)
    If Not IsObj($o_id) Then
        Return SetError(2, 0, 0)
    EndIf

    Local $i_ub = UBound($a_objsclick)
    If Not $i_ub Then
        Dim $a_objsclick[1][3]; ugh, magic numbers... fun (Not!)
    Else
        ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick)]
    EndIf

    $a_objsclick[$i_ub][0] = $s_idstr
    $a_objsclick[$i_ub][1] = $o_id
    $a_objsclick[$i_ub][2] = 0

    Return 1
EndFunc

Func _myIE_ResetClickObjBool(ByRef $a_objsclick, $v_index = 0)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        $a_objsclick[$v_index][2] = 0
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                $a_objsclick[$i][2] = 0
                Return
            EndIf
        Next
    EndIf
EndFunc

Func _myIE_IsClickObjBool(ByRef $a_objsclick, $v_index)

    If IsObj($v_index) Then
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][1] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    ElseIf IsInt($v_index) Then
        ;normally I'd check scope, but meh
        Return $a_objsclick[$v_index][2]
    Else
        For $i = 0 To UBound($a_objsclick) - 1
            If $a_objsclick[$i][0] = $v_index Then
                Return $a_objsclick[$i][2]
            EndIf
        Next
    EndIf

EndFunc

Many thanks for helping,

 

Kind regards,

Lion H

Link to comment
Share on other sites

  • Moderators
  • Solution

change:

ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick)]

to:

ReDim $a_objsclick[$i_ub + 1][3]

Or better yet, change:

Local $i_ub = UBound($a_objsclick)
    If Not $i_ub Then
        Dim $a_objsclick[1][3]; ugh, magic numbers... fun (Not!)
    Else
        ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick)]
    EndIf 

To:

Local $i_ub = UBound($a_objsclick)
    If Not $i_ub Then
        Dim $a_objsclick[1][3]; ugh, magic numbers... fun (Not!)
    Else
        If UBound($a_objsclick, 2) < 3 Then
            ReDim $a_objsclick[$i_ub + 1][3]
        Else
            ReDim $a_objsclick[$i_ub + 1][UBound($a_objsclick, 2)]
        EndIf
    EndIf
Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 4 weeks later...

Is it possible to detect clicks that are generated by javascript?

For example, i want to use jQuery to trigger a button click:

$( "#button1" ).click(function() {
   $( "#button2" ).click();
});
// AutoIT detects #button2 click, when clicked on #button1

I hope you can be a great help another time (:

 

Thanks a lot!

 

Kind regards,

Lion H

Link to comment
Share on other sites

  • Moderators

The event functions should capture any mouseevent if you call the correct event to capture.

However, on IE versions that are higher, you'll find you'll need to use the mspointerevent if you're running into issues.  I must admit however, I haven't worked with this yet.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

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...