HTML5 Click / getElementByID not working on SAP Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

HTML5 Click / getElementByID not working on SAP

09 Oct 2017, 08:29

Hello,

I tried to automate a process on our SAP Webinterface but it did not work. I wanted a left-sided menu to show and to click into the search bar which appeared at the bottom with one Hotkey.
I used the following code which worked well on other Websites like Google calendar but not on SAP.

Code: Select all

	^!s::
		wb := ComObjCreate("InternetExplorer.Application")
		wb.Visible := True
		wb.Navigate("http://URL.com")
		while wb.busy
			sleep 100
			btn := wb.document.getElementById("__button0")
		btn.Click()
		
	Return
If it could help, here is the code of the button I try to click:

Code: Select all

<div tabindex="0" title="Work-Center-Navigation einblenden/ausblenden" class="sapBUiBelNavIcon sapBUiIcon-shellMenu sapUiIconMirrorInRTL" id="__button0" role="button" style="cursor: pointer" aria-label="Work-Center-Navigation einblenden/ausblenden" data-sap-ui="__button0"></div>
I would really appreciate some help because I need this for work.

Thanks in advance,

Sonic
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP

09 Oct 2017, 14:23

Hi, Sonic1305,
Launch this code:

Code: Select all

wb := ComObjCreate("InternetExplorer.Application")
wb.Visible := True
wb.Navigate("http://URL.com")  ; specify the correct url
while wb.busy
   sleep 100
btn := wb.document.getElementById("__button0")
MsgBox, % IsObject(btn)
try wb.Quit()
What number appears in MsgBox?
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

10 Oct 2017, 02:02

Hey teadrinker,

Thank for the help. The Number 1 appears but I had to modify the sleep time because the Webinterface wasn´t loading fast enough. I tried that yesterday already but I still don`t know what to do.
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP

10 Oct 2017, 16:32

Ok, if your IE object is supposed to be visible, we can try to emulate the click via ControlClick:

Code: Select all

#Persistent
wb := ComObjCreate("InternetExplorer.Application")
OnExit( Func("Exit").Bind(wb) )
wb.Visible := True
wb.Navigate("http://URL.com")  ; specify the correct url
while wb.busy
   sleep 100

Loop  {
   Sleep, 50
   button := wb.document.getElementById("__button0")
} until IsObject(button)

clientCoords := button.getBoundingClientRect()
ControlGet, hwnd, hwnd,, Internet Explorer_Server1, % "ahk_id" wb.hwnd
WinGetPos, x, y,,, ahk_id %hwnd%
ControlClick, % "x" x - wb.left + clientCoords.left + 5 " y" y - wb.top + clientCoords.top + 5, % "ahk_id" wb.hwnd

Exit(ie)  {
   try ie.Quit()
}
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

11 Oct 2017, 02:07

I tried your Code but it was not working. I also tried other Buttons of the Website but None of them worked.

How can a whole Website be resistent against simulated button clicks?
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP

11 Oct 2017, 12:04

Can you see the button you want to click when the site opens, or you need to scroll the page?
getBoundingClientRect() does not always work, check it:

Code: Select all

#Persistent
wb := ComObjCreate("InternetExplorer.Application")
OnExit( Func("Exit").Bind(wb) )
wb.Visible := True
wb.Navigate("http://URL.com")  ; specify the correct url
while wb.busy
   sleep 100

Loop  {
   Sleep, 50
   button := wb.document.getElementById("__button0")
} until IsObject(button)

clientCoords := button.getBoundingClientRect()

MsgBox, % clientCoords.left "`n" clientCoords.top


Exit(ie)  {
   try ie.Quit()
}
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 01:58

Ok I noticed that the coords do not always show, but even if the button is visible. It only works if the URL I specified brings me to the logon page first and after I logged in it works but if it opens directly, it won´t show the coords.
So how should I continue now? And the button is at the top left corner.

Thank you for your Patience.
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 03:30

the coords do not always show
Do you mean, the MsgBox does not appear? It means that the button with ID "__button0" was not found, I can't say, why. It's necessary to see the page.
It only works if the URL I specified brings me to the logon page first and after I logged in it works
Don't you want to consider the way: first to navigate to the logon page, to log in through filling the form, and then go to the needed page and trying to get the button?
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 03:42

The MsgBox does appear, but with the coords 0.0000/0.00000. And the way the coords did show correctly does unfortunately not fix the Problem that the button click does not work :/

I would show you the page, but (I don´t know if you know SAP?) you don´t have Access to it because it is a Business Software.
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 06:29

Ok, do you know, what Accessible Info Viewer is and how to use it?
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 06:34

I've not heard about it yet.
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 07:07

Accessible Info Viewer
Open your site in Internet Explorer, then launch Accessible Info Viewer. The window will appear:

Image

You need to drag-n-drop the crosshair from the top-left corner of the window to the button in IE. The information about the button will appear in the window. Then get the screenshot of the window and send it here.
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 07:32

Image
Attachments
Unbenannt.JPG
Unbenannt.JPG (51.37 KiB) Viewed 2396 times
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 09:06

At first try the next code:

Code: Select all

#Persistent
wb := ComObjCreate("InternetExplorer.Application")
OnExit( Func("Exit").Bind(wb) )
wb.Visible := True
wb.Navigate("http://URL.com")  ; specify the correct url
while wb.busy
   sleep 100

Loop  {
   Sleep, 50
   button := wb.document.getElementById("__button0")
} until IsObject(button)

ControlGet, hwnd, hwnd,, Internet Explorer_Server1, % "ahk_id" . wb.hwnd
accButton := Acc_Get("Object", "5.1", 0, "ahk_id " . hwnd)
if !IsObject(accButton)  {
   MsgBox, Failed to get an accessible object!
   Return
}
accButton.accDoDefaultAction(0)

Exit(ie)  {
   try ie.Quit()
}

Acc_Init()
{
   Static   h
   If Not   h
      h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild)
{
   Acc_Init()
   If   DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
   Return   ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
   Acc_Init()
   If   DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
   Return   ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromWindow(hWnd, idObject = 0)
{
   Acc_Init()
   If   DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
   Return   ComObjEnwrap(9,pacc,1)
}

Acc_WindowFromObject(pacc)
{
   If   DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
   Return   hWnd
}

Acc_GetRoleText(nRole)
{
   nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
   VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
   DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
   Return   sRole
}

Acc_GetStateText(nState)
{
   nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0)
   VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
   DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1)
   Return   sState
}

Acc_SetWinEventHook(eventMin, eventMax, pCallback)
{
   Return   DllCall("SetWinEventHook", "Uint", eventMin, "Uint", eventMax, "Uint", 0, "Ptr", pCallback, "Uint", 0, "Uint", 0, "Uint", 0)
}

Acc_UnhookWinEvent(hHook)
{
   Return   DllCall("UnhookWinEvent", "Ptr", hHook)
}
/*   Win Events:

   pCallback := RegisterCallback("WinEventProc")
   WinEventProc(hHook, event, hWnd, idObject, idChild, eventThread, eventTime)
   {
      Critical
      Acc := Acc_ObjectFromEvent(_idChild_, hWnd, idObject, idChild)
      ; Code Here:

   }
*/

; Written by jethrow
Acc_Role(Acc, ChildId=0) {
   try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
}
Acc_State(Acc, ChildId=0) {
   try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object"
}
Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
   try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
   catch
      return
   Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
   return   {x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
}
Acc_Parent(Acc) { 
   try parent:=Acc.accParent
   return parent?Acc_Query(parent):
}
Acc_Child(Acc, ChildId=0) {
   try child:=Acc.accChild(ChildId)
   return child?Acc_Query(child):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
   try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Error(p="") {
   static setting:=0
   return p=""?setting:setting:=p
}
Acc_Children(Acc) {
   if ComObjType(Acc,"Name") != "IAccessible"
      ErrorLevel := "Invalid IAccessible Object"
   else {
      Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
      if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
         Loop %cChildren%
            i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
         return Children.MaxIndex()?Children:
      } else
         ErrorLevel := "AccessibleChildren DllCall Failed"
   }
   if Acc_Error()
      throw Exception(ErrorLevel,-1)
}
Acc_ChildrenByRole(Acc, Role) {
   if ComObjType(Acc,"Name")!="IAccessible"
      ErrorLevel := "Invalid IAccessible Object"
   else {
      Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
      if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
         Loop %cChildren% {
            i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
            if NumGet(varChildren,i-8)=9
               AccChild:=Acc_Query(child), ObjRelease(child), Acc_Role(AccChild)=Role?Children.Insert(AccChild):
            else
               Acc_Role(Acc, child)=Role?Children.Insert(child):
         }
         return Children.MaxIndex()?Children:, ErrorLevel:=0
      } else
         ErrorLevel := "AccessibleChildren DllCall Failed"
   }
   if Acc_Error()
      throw Exception(ErrorLevel,-1)
}
Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") {
   static properties := {Action:"DefaultAction", DoAction:"DoDefaultAction", Keyboard:"KeyboardShortcut"}
   AccObj :=   IsObject(WinTitle)? WinTitle
         :   Acc_ObjectFromWindow( WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText), 0 )
   if ComObjType(AccObj, "Name") != "IAccessible"
      ErrorLevel := "Could not access an IAccessible Object"
   else {
      StringReplace, ChildPath, ChildPath, _, %A_Space%, All
      AccError:=Acc_Error(), Acc_Error(true)
      Loop Parse, ChildPath, ., %A_Space%
         try {
            if A_LoopField is digit
               Children:=Acc_Children(AccObj), m2:=A_LoopField ; mimic "m2" output in else-statement
            else
               RegExMatch(A_LoopField, "(\D*)(\d*)", m), Children:=Acc_ChildrenByRole(AccObj, m1), m2:=(m2?m2:1)
            if Not Children.HasKey(m2)
               throw
            AccObj := Children[m2]
         } catch {
            ErrorLevel:="Cannot access ChildPath Item #" A_Index " -> " A_LoopField, Acc_Error(AccError)
            if Acc_Error()
               throw Exception("Cannot access ChildPath Item", -1, "Item #" A_Index " -> " A_LoopField)
            return
         }
      Acc_Error(AccError)
      StringReplace, Cmd, Cmd, %A_Space%, , All
      properties.HasKey(Cmd)? Cmd:=properties[Cmd]:
      try {
         if (Cmd = "Location")
            AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
           , ret_val := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
         else if (Cmd = "Object")
            ret_val := AccObj
         else if Cmd in Role,State
            ret_val := Acc_%Cmd%(AccObj, ChildID+0)
         else if Cmd in ChildCount,Selection,Focus
            ret_val := AccObj["acc" Cmd]
         else
            ret_val := AccObj["acc" Cmd](ChildID+0)
      } catch {
         ErrorLevel := """" Cmd """ Cmd Not Implemented"
         if Acc_Error()
            throw Exception("Cmd Not Implemented", -1, Cmd)
         return
      }
      return ret_val, ErrorLevel:=0
   }
   if Acc_Error()
      throw Exception(ErrorLevel,-1)
}
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 09:28

It Failed to get an accessible object.
There must be a way to Control this....
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP

12 Oct 2017, 09:43

Ok, one more:

Code: Select all

#Persistent
SetBatchLines, -1
wb := ComObjCreate("InternetExplorer.Application")
OnExit( Func("Exit").Bind(wb) )
wb.Visible := True
wb.Navigate("http://URL.com")  ; specify the correct url
while wb.busy
   sleep 100

Loop  {
   Sleep, 50
   button := wb.document.getElementById("__button0")
} until IsObject(button)

ControlGet, hwnd, hwnd,, Internet Explorer_Server1, % "ahk_id" . wb.hwnd
accWB := AccObjectFromWindow(hwnd)
accButton := SearchElement(accWB, ROLE_SYSTEM_PUSHBUTTON := 0x2B, "Work-Center-Navigation einblenden/ausblenden")
if !IsObject(accButton)  {
   MsgBox, Failed to get an accessible object!
   Return
}
accButton.accDoDefaultAction(0)

SearchElement(ParentElement, params*)
{
   found := 1
   for k, v in params  {
      try  {
         (k = 1 && ParentElement.accRole(0)  != v && found := "")
         (k = 2 && ParentElement.accName(0)  != v && found := "")
         (k = 3 && ParentElement.accValue(0) != v && found := "")
      }
   }
   if found
      Return ParentElement
   
   for k, v in Acc_Children(ParentElement)
      if obj := SearchElement(v, params*)
         Return obj
}

AccObjectFromWindow(hWnd, idObject = 0)
{
   static IID_IDispatch   := "{00020400-0000-0000-C000-000000000046}"
        , IID_IAccessible := "{618736e0-3c3d-11cf-810c-00aa00389b71}"
        , OBJID_NATIVEOM  := 0xFFFFFFF0, VT_DISPATCH := 9, h := DllCall("LoadLibrary", Str, "oleacc", Ptr)
        
   VarSetCapacity(IID, 16), idObject &= 0xFFFFFFFF
   DllCall("ole32\CLSIDFromString", Str, idObject = OBJID_NATIVEOM ? IID_IDispatch : IID_IAccessible, Ptr, &IID)
   if DllCall("oleacc\AccessibleObjectFromWindow", Ptr, hWnd, UInt, idObject, Ptr, &IID, PtrP, pAcc) = 0
      Return ComObjEnwrap(VT_DISPATCH, pAcc, 1)
}

Acc_Children(Acc) {
   if ComObjType(Acc,"Name") != "IAccessible"
      ErrorLevel := "Invalid IAccessible Object"
   else {
      cChildren:=Acc.accChildCount, Children:=[]
      if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren
         , "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
         Loop %cChildren%
            i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
               , Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
         return Children.MaxIndex()?Children:
      } else
         ErrorLevel := "AccessibleChildren DllCall Failed"
   }
}

Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
   try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}


Exit(ie)  {
   try ie.Quit()
}
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

13 Oct 2017, 01:58

No MsgBox is appearing and the target button looks like he is selected in some way.
Maybe this is the first glimmer of hope?
"Declare variables, not war."
Sonic1305
Posts: 12
Joined: 09 Oct 2017, 07:58
Contact:

Re: HTML5 Click / getElementByID not working on SAP

13 Oct 2017, 03:12

Not pressed.
"Declare variables, not war."
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HTML5 Click / getElementByID not working on SAP  Topic is solved

13 Oct 2017, 16:55

Let's try to find out button's coordinates and then to use ControlClick once again.

Code: Select all

#Persistent
SetBatchLines, -1
wb := ComObjCreate("InternetExplorer.Application")
OnExit( Func("Exit").Bind(wb) )
wb.Visible := True
wb.Navigate("http://URL.com")  ; specify the correct url
while wb.busy
   sleep 100

Loop  {
   Sleep, 50
   button := wb.document.getElementById("__button0")
} until IsObject(button)

ControlGet, hwnd, hwnd,, Internet Explorer_Server1, % "ahk_id" . wb.hwnd
accWB := AccObjectFromWindow(hwnd)
accButton := SearchElement(accWB, ROLE_SYSTEM_PUSHBUTTON := 0x2B, "Work-Center-Navigation einblenden/ausblenden")
if !IsObject(accButton)  {
   MsgBox, Failed to get an accessible object!
   Return
}

coords := Acc_Location(accButton)
if !coords.y  {
   MsgBox, Failed to get object coords!
   Return
}
ControlClick, % "x" coords.x - wb.left + 5 " y" coords.y - wb.top + 5, % "ahk_id" wb.hwnd

SearchElement(ParentElement, params*)
{
   found := 1
   for k, v in params  {
      try  {
         (k = 1 && ParentElement.accRole(0)  != v && found := "")
         (k = 2 && ParentElement.accName(0)  != v && found := "")
         (k = 3 && ParentElement.accValue(0) != v && found := "")
      }
   }
   if found
      Return ParentElement
   
   for k, v in Acc_Children(ParentElement)
      if obj := SearchElement(v, params*)
         Return obj
}

AccObjectFromWindow(hWnd, idObject = 0)
{
   static IID_IDispatch   := "{00020400-0000-0000-C000-000000000046}"
        , IID_IAccessible := "{618736e0-3c3d-11cf-810c-00aa00389b71}"
        , OBJID_NATIVEOM  := 0xFFFFFFF0, VT_DISPATCH := 9, h := DllCall("LoadLibrary", Str, "oleacc", Ptr)
        
   VarSetCapacity(IID, 16), idObject &= 0xFFFFFFFF
   DllCall("ole32\CLSIDFromString", Str, idObject = OBJID_NATIVEOM ? IID_IDispatch : IID_IAccessible, Ptr, &IID)
   if DllCall("oleacc\AccessibleObjectFromWindow", Ptr, hWnd, UInt, idObject, Ptr, &IID, PtrP, pAcc) = 0
      Return ComObjEnwrap(VT_DISPATCH, pAcc, 1)
}

Acc_Children(Acc) {
   if ComObjType(Acc,"Name") != "IAccessible"
      ErrorLevel := "Invalid IAccessible Object"
   else {
      cChildren:=Acc.accChildCount, Children:=[]
      if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren
         , "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
         Loop %cChildren%
            i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
               , Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
         return Children.MaxIndex()?Children:
      } else
         ErrorLevel := "AccessibleChildren DllCall Failed"
   }
}

Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
   try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
   try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
   catch
      return
   Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
   return   {x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
}

Exit(ie)  {
   try ie.Quit()
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Mannaia666, skeerrt and 155 guests