junkew Posted September 18, 2016 Share Posted September 18, 2016 I need some help in fixing this on W10 / 64 bits system either compiled with #AutoIt3Wrapper_UseX64=Y or #AutoIt3Wrapper_UseX64=N @Larsj : Did you ever migrate this to W10 /64 bits system. Post #154 I tried in different ways on $tagVARIANT lengths but application stops. I did partly get it running for spied object when useX64=N but then quickly after that fails on child objects when using iAccessible FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Danyfirex Posted September 19, 2016 Share Posted September 19, 2016 (edited) Hello. I did just a little adjutments. Working for me in Windows 7x86 and Windows 10 x64 (compiled x64 and x86 Version) expandcollapse popup#AutoIt3Wrapper_UseX64=Y #RequireAdmin #include "CUIAutomation2.au3" #include "MSAccessibility.au3" #include "ISimpleDOM.au3" #include <Array.au3> Opt("MustDeclareVars", 1) Global $aInfo[10000], $iInfo = 0 MainFunc() Func MainFunc() HotKeySet("^w", "GetWindowInfo") HotKeySet("{ESC}", "Close") While Sleep(100) WEnd EndFunc ;==>MainFunc Func GetWindowInfo() Local $aMousePos = MouseGetPos(), $pObject, $tVarChild, $vt, $err = 0 If AccessibleObjectFromPoint($aMousePos[0], $aMousePos[1], $pObject, $tVarChild) = $S_OK Then $vt = BitAND(DllStructGetData($tVarChild, 1, 1), 0xFFFF) If $vt = $VT_I4 Then Local $oObject, $hWnd, $sName = "" If WindowFromAccessibleObject($pObject, $hWnd) = $S_OK Then AccessibleObjectFromWindow($hWnd, $OBJID_CLIENT, $tIID_IAccessible, $pObject) $oObject = ObjCreateInterface($pObject, $sIID_IAccessible, $dtagIAccessible) ; Get parent objects to top window Local $pParent, $pPrev, $oPrev, $iRole Do $pPrev = $pParent $oPrev = $oObject If IsObj($oObject) Then $oObject.get_accParent($pParent) $oObject = ObjCreateInterface($pParent, $sIID_IAccessible, $dtagIAccessible) EndIf If IsObj($oObject) Then $oObject.get_accName($CHILDID_SELF, $sName) EndIf Until String($sName) = "Escritorio";"Desktop" ; Info for top window (previous to desktop) PrintElementInfoToArray($pPrev, $oPrev, $CHILDID_SELF, "") ; Info for child objects of the top window If $oPrev.get_accRole($CHILDID_SELF, $iRole) = $S_OK And $iRole = $ROLE_SYSTEM_WINDOW Then WindowFromAccessibleObject($pPrev, $hWnd) PrintWindowObjects($hWnd) Else $err = 1 EndIf Else $err = 1 EndIf Else $err = 1 EndIf Else $err = 1 EndIf If $err Then _ MsgBox(0, "ISimpleDOM interfaces", _ "AccessibleObjectFromPoint failed." & @CRLF & _ "Try another point e.g. the window title bar.") EndFunc ;==>GetWindowInfo Func PrintWindowObjects($hWindow) ; Object from window Local $pWindow, $oWindow AccessibleObjectFromWindow($hWindow, $OBJID_CLIENT, $tIID_IAccessible, $pWindow) $oWindow = ObjCreateInterface($pWindow, $sIID_IAccessible, $dtagIAccessible) If Not IsObj($oWindow) Then Return ; Get window objects WalkTreeWithAccessibleChildren($pWindow, 0, 8) ; Print window objects ReDim $aInfo[$iInfo] _ArrayDisplay($aInfo, "ISimpleDOM interfaces") ReDim $aInfo[10000] $iInfo = 0 EndFunc ;==>PrintWindowObjects Func WalkTreeWithAccessibleChildren($pAcc, $iLevel, $iLevels = 0) If $iLevels And $iLevel = $iLevels Then Return ; Create object Local $oAcc = ObjCreateInterface($pAcc, $sIID_IAccessible, $dtagIAccessible) If Not IsObj($oAcc) Then Return $oAcc.AddRef() ; Indentation Local $sIndent = "" For $i = 0 To $iLevel - 1 $sIndent &= " " Next Local $iChildCount, $iReturnCount, $tVarChildren ; Get children If $oAcc.get_accChildCount($iChildCount) Or Not $iChildCount Then Return If AccessibleChildren($pAcc, 0, $iChildCount, $tVarChildren, $iReturnCount) Then Return Local $vt, $pChildObj, $oChildObj Local $pService, $oService, $pISimpleDOMNode, $oISimpleDOMNode, $pISimpleDOM, $oISimpleDOM ; $oISimpleDOMNode.nodeInfo Local $sNodeName, $iNameSpaceID, $sNodeValue, $iNumChildren, $iUniqueID, $iNodeType, $sInnerHTML ; $oISimpleDOMNode.attributes Local $iMaxAttribs = 100, $iNumAttribs Local $tAttribNames = DllStructCreate("ptr[" & $iMaxAttribs & "]"), $sAttribName Local $tNameSpaceIDs = DllStructCreate("short[" & $iMaxAttribs & "]"), $iNameSpaceID Local $tAttribValues = DllStructCreate("ptr[" & $iMaxAttribs & "]"), $sAttribValue ; $oISimpleDOMNode.computedStyle Local $iMaxStyleProperties = 100, $iNumStyleProperties Local $tStyleProperties = DllStructCreate("ptr[" & $iMaxStyleProperties & "]"), $sStyleProperty Local $tStyleValues = DllStructCreate("ptr[" & $iMaxStyleProperties & "]"), $sStyleValue ; For each child For $i = 1 To $iReturnCount ; $tVarChildren is an array of VARIANTs with information about the children $vt = BitAND(DllStructGetData($tVarChildren, $i, 1), 0xFFFF) If $vt = $VT_DISPATCH Then ; Child object; get correct ptr x64 or x86 version Local $tVariant = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr;", DllStructGetPtr($tVarChildren, $i)) $pChildObj = DllStructGetData($tVariant, 5) ;this is wrong. You will never get the x64 ptr ;~ ; Child object ;~ $pChildObj = DllStructGetData($tVarChildren, $i, 3) ;~ $oChildObj = ObjCreateInterface($pChildObj, $sIID_IAccessible, $dtagIAccessible) $oChildObj = ObjCreateInterface(($pChildObj), $sIID_IAccessible, $dtagIAccessible) If IsObj($oChildObj) Then ; Try to get an ISimpleDOMNode interface pointer for the child object If $oChildObj.QueryInterface(DllStructGetPtr($tIID_IServiceProvider), $pService) = $S_OK Then $oService = ObjCreateInterface($pService, $sIID_IServiceProvider, $dtagIServiceProvider) If $oService.QueryService($tIID_ISimpleDOMNode, $tIID_ISimpleDOMNode, $pISimpleDOMNode) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$pISimpleDOMNode = " & Ptr($pISimpleDOMNode) $iInfo += 1 $oISimpleDOMNode = ObjCreateInterface($pISimpleDOMNode, $sIID_ISimpleDOMNode, $dtagISimpleDOMNode) If IsObj($oISimpleDOMNode) Then $oISimpleDOMNode.nodeInfo($sNodeName, $iNameSpaceID, $sNodeValue, $iNumChildren, $iUniqueID, $iNodeType) $aInfo[$iInfo + 0] = $sIndent & "$sNodeName = " & $sNodeName $aInfo[$iInfo + 1] = $sIndent & "$iNameSpaceID = " & $iNameSpaceID $aInfo[$iInfo + 2] = $sIndent & "$sNodeValue = " & $sNodeValue $aInfo[$iInfo + 3] = $sIndent & "$iNumChildren = " & $iNumChildren $aInfo[$iInfo + 4] = $sIndent & "$iUniqueID = " & $iUniqueID $aInfo[$iInfo + 5] = $sIndent & "$iNodeType = " & $iNodeType & " (" & GetNodeType($iNodeType) & ")" $iInfo += 6 ; $oISimpleDOMNode.attributes $oISimpleDOMNode.attributes($iMaxAttribs, $tAttribNames, $tNameSpaceIDs, $tAttribValues, $iNumAttribs) $aInfo[$iInfo] = $sIndent & "$iNumAttribs = " & $iNumAttribs $iInfo += 1 For $j = 1 To $iNumAttribs $sAttribName = SysReadString(DllStructGetData($tAttribNames, 1, $j)) $sAttribValue = SysReadString(DllStructGetData($tAttribValues, 1, $j)) $iNameSpaceID = DllStructGetData($tNameSpaceIDs, 1, $j) $aInfo[$iInfo + 0] = " " & $sIndent & "$iAttrib = " & $j $aInfo[$iInfo + 1] = " " & $sIndent & "$sAttribName = " & $sAttribName $aInfo[$iInfo + 2] = " " & $sIndent & "$sAttribValue = " & $sAttribValue $aInfo[$iInfo + 3] = " " & $sIndent & "$iNameSpaceID = " & $iNameSpaceID $iInfo += 4 ; Free memory allocated by BSTRs SysFreeString(DllStructGetData($tAttribNames, 1, $j)) SysFreeString(DllStructGetData($tAttribValues, 1, $j)) Next ; $oISimpleDOMNode.computedStyle $oISimpleDOMNode.computedStyle($iMaxStyleProperties, 0, $tStyleProperties, $tStyleValues, $iNumStyleProperties) $aInfo[$iInfo] = $sIndent & "$iNumStyleProps = " & $iNumStyleProperties $iInfo += 1 For $j = 1 To $iNumStyleProperties $sStyleProperty = SysReadString(DllStructGetData($tStyleProperties, 1, $j)) $sStyleValue = SysReadString(DllStructGetData($tStyleValues, 1, $j)) $aInfo[$iInfo + 0] = " " & $sIndent & "$iStyle = " & $j $aInfo[$iInfo + 1] = " " & $sIndent & "$sStyleProp = " & $sStyleProperty $aInfo[$iInfo + 2] = " " & $sIndent & "$sStyleValue = " & $sStyleValue $iInfo += 3 ; Free memory allocated by BSTRs SysFreeString(DllStructGetData($tStyleProperties, 1, $j)) SysFreeString(DllStructGetData($tStyleValues, 1, $j)) Next ;$oISimpleDOMNode.innerHTML( $sInnerHTML ) ;If String( $sInnerHTML ) <> "0" Then ; $aInfo[$iInfo] = $sIndent & "$sInnerHTML = " & $sInnerHTML ; $iInfo += 1 ;EndIf If $iNodeType = 3 Then ; $NODETYPE_TEXT ; Try to get an ISimpleDOMText interface pointer with $oISimpleDOMNode.QueryInterface If $oISimpleDOMNode.QueryInterface(DllStructGetPtr($tIID_ISimpleDOMText), $pISimpleDOM) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$pISimpleDOMText = " & Ptr($pISimpleDOM) $iInfo += 1 $oISimpleDOM = ObjCreateInterface($pISimpleDOM, $sIID_ISimpleDOMText, $dtagISimpleDOMText) If IsObj($oISimpleDOM) Then Local $sDomText $oISimpleDOM.domText($sDomText) $aInfo[$iInfo] = $sIndent & "$sDomText = " & $sDomText $iInfo += 1 EndIf EndIf ElseIf $iNodeType = 9 Then ; $NODETYPE_DOCUMENT ; Try to get an ISimpleDOMDocument interface pointer with $oISimpleDOMNode.QueryInterface If $oISimpleDOMNode.QueryInterface(DllStructGetPtr($tIID_ISimpleDOMDocument), $pISimpleDOM) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$pISimpleDOMDocument = " & Ptr($pISimpleDOM) $iInfo += 1 $oISimpleDOM = ObjCreateInterface($pISimpleDOM, $sIID_ISimpleDOMDocument, $dtagISimpleDOMDocument) If IsObj($oISimpleDOM) Then Local $sURL, $sTitle, $sMimeType, $sDocType $oISimpleDOM.URL($sURL) $oISimpleDOM.title($sTitle) $oISimpleDOM.mimeType($sMimeType) $oISimpleDOM.docType($sDocType) $aInfo[$iInfo + 0] = $sIndent & "$sURL = " & $sURL $aInfo[$iInfo + 1] = $sIndent & "$sTitle = " & $sTitle $aInfo[$iInfo + 2] = $sIndent & "$sMimeType = " & $sMimeType $aInfo[$iInfo + 3] = $sIndent & "$sDocType = " & $sDocType $iInfo += 4 EndIf EndIf EndIf EndIf EndIf EndIf PrintElementInfoToArray($pChildObj, $oChildObj, $CHILDID_SELF, $sIndent) WalkTreeWithAccessibleChildren($pChildObj, $iLevel + 1, $iLevels) EndIf EndIf Next EndFunc ;==>WalkTreeWithAccessibleChildren Func PrintElementInfoToArray($pElement, $oElement, $iChild, $sIndent) Local $hWnd, $sName, $iRole, $sRole, $iRoleLen Local $iState, $sState, $iStateLen Local $sValue, $x, $y, $w, $h If $iChild <> $CHILDID_SELF Then $aInfo[$iInfo] = $sIndent & "$iChildElem = " & $iChild $iInfo += 1 EndIf If $iChild = $CHILDID_SELF And $oElement.get_accRole($CHILDID_SELF, $iRole) = $S_OK And $iRole = $ROLE_SYSTEM_WINDOW Then WindowFromAccessibleObject($pElement, $hWnd) $aInfo[$iInfo] = $sIndent & "$hWnd = " & $hWnd $iInfo += 1 EndIf $oElement.get_accName($iChild, $sName) $aInfo[$iInfo] = $sIndent & "$sName = " & $sName $iInfo += 1 If $oElement.get_accRole($iChild, $iRole) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$iRole = 0x" & Hex($iRole) $iInfo += 1 $iRoleLen = GetRoleText($iRole, 0, 0) + 1 $sRole = DllStructCreate("wchar[" & $iRoleLen & "]") GetRoleText($iRole, DllStructGetPtr($sRole), $iRoleLen) $aInfo[$iInfo] = $sIndent & "$sRole = " & DllStructGetData($sRole, 1) $iInfo += 1 EndIf If $oElement.get_accState($iChild, $iState) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$iState = 0x" & Hex($iState) $iInfo += 1 $iStateLen = GetStateText($iState, 0, 0) + 1 $sState = DllStructCreate("wchar[" & $iStateLen & "]") GetStateText($iState, DllStructGetPtr($sState), $iStateLen) $aInfo[$iInfo] = $sIndent & "$sState = " & DllStructGetData($sState, 1) $iInfo += 1 EndIf If $oElement.get_accValue($iChild, $sValue) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$sValue = " & $sValue $iInfo += 1 EndIf If $oElement.accLocation($x, $y, $w, $h, $iChild) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$x, $y, $w, $h = " & $x & ", " & $y & ", " & $w & ", " & $h $iInfo += 1 EndIf $aInfo[$iInfo] = "" $iInfo += 1 EndFunc ;==>PrintElementInfoToArray Func Close() Exit EndFunc ;==>Close Saludos Edited September 19, 2016 by Danyfirex Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
LarsJ Posted September 19, 2016 Share Posted September 19, 2016 I've not tested these interfaces (IAccessible, IAccessible2, IAccessibleEx, ISimpleDOM) or the examples on 64 bit or Windows 10. A few minor issues cannot be excluded. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
junkew Posted September 19, 2016 Author Share Posted September 19, 2016 (edited) Weird doing nothing on my system when trying as X64 I changed some constants to come from include in MSACCESSIBILITY.AU3 #include "CUIAutomation2.au3" #include <autoitconstants.au3> #include <winapiconstants.au3> #include <menuconstants.au3> to prevent some compile errors removed const If @AutoItX64 Then global $tagVARIANT = "dword[6];" ; Use this form to be able to build an Else ; array in function AccessibleChildren. global $tagVARIANT = "dword[4];" EndIf using above source from @Danyfirex I get with some translation in the name of top level object in my case dutch Bureaublad #AutoIt3Wrapper_UseX64=N ;~ #RequireAdmin ... consolewrite("GetWindowInfo name " & String($sName) & @CRLF) Until stringinstr("Desktop Bureaublad Escritorio",String($sName))>0 The hotkey is calling the GetWindowInfo function when pressing ctrl+w above htmlDocument of google browser and then it works for above nice dump of elements The problem starts when working with X64 #AutoIt3Wrapper_UseX64=Y #RequireAdmin Func GetWindowInfo() consolewrite("GetWindowInfo before first if" & @CRLF) ;~ MsgBox(0, "GetWindowInfo", "GetWindowInfo'before first if" & @CRLF) Local $aMousePos = MouseGetPos(), $pObject, $tVarChild, $vt, $err = 0 Consolewrite statements seems not to work at all (probably as I now am elevated running as admin? happens also in X86) but msgbox goes fine. Testing further gives me the feeling it goes wrong in AccessibleObjectFromWindow AccessibleObjectFromPoint gives a correct value when making an iaccessible object from it maybe after googling hitting this feature https://bugs.webkit.org/show_bug.cgi?id=141391 Before comparing this value against the OBJID_ values, the server must cast it to DWORD; otherwise, on 64-bit Windows, the sign extension of the lParam can interfere with the comparison. But it does not say anything on the clientside https://groups.google.com/a/chromium.org/forum/#!topic/chromium-reviews/TY6rBImbySQ So most likely I need to fix this function to call differently in X64 compared to X86 for the $OBJID_CLIENT value which is defined as Global Const $OBJID_CLIENT = 0xFFFFFFFC Func AccessibleObjectFromWindow( $hWnd, $iObjectID, $tRIID, ByRef $pObject ) If @AutoItX64 Then ;~ Local $aRet = DllCall( $hdllOleacc, "int", "AccessibleObjectFromWindow", "hwnd", $hWnd, "uint64", 0xfffffffffffffffc, "struct*", $tRIID, "int*", 0 ) Local $aRet = DllCall( $hdllOleacc, "int", "AccessibleObjectFromWindow", "hwnd", $hWnd, "uint64", 0x00000000fffffffc, "struct*", $tRIID, "int*", 0 ) else Local $aRet = DllCall( $hdllOleacc, "int", "AccessibleObjectFromWindow", "hwnd", $hWnd, "dword", $iObjectID, "struct*", $tRIID, "int*", 0 ) endif If @error Then msgbox(0,"Error",$aRet) Return SetError(1, 0, $S_FALSE) EndIf If $aRet[0] Then Return SetError(2, 0, $aRet[0]) $pObject = $aRet[4] Return $S_OK EndFunc source for testing includes messageboxes expandcollapse popup#AutoIt3Wrapper_UseX64=Y #RequireAdmin #include "CUIAutomation2.au3" #include "MSAccessibility.au3" #include "ISimpleDOM.au3" #include <Array.au3> Opt("MustDeclareVars", 1) Global $aInfo[10000], $iInfo = 0 MainFunc() Func MainFunc() HotKeySet("^w", "GetWindowInfo") HotKeySet("{ESC}", "Close") While Sleep(100) WEnd EndFunc ;==>MainFunc Func GetWindowInfo() ;~ consolewrite("GetWindowInfo before first if" & @CRLF) ;~ MsgBox(0, "GetWindowInfo", "GetWindowInfo before first if" & @CRLF) Local $aMousePos = MouseGetPos(), $pObject, $tVarChild, $vt, $err = 0 Local $oObject, $hWnd, $sName = "" If AccessibleObjectFromPoint($aMousePos[0], $aMousePos[1], $pObject, $tVarChild) = $S_OK Then ;~ MsgBox(0, "GetWindowInfo", "GetWindowInfo after first if" & @CRLF) ;~ consolewrite("GetWindowInfo after first if" & @CRLF) $oObject = ObjCreateInterface($pObject, $sIID_IAccessible, $dtagIAccessible) $oObject.get_accName($CHILDID_SELF, $sName) ;~ consolewrite("GetWindowInfo name " & String($sName) & @CRLF) MsgBox(0, "GetWindowInfo", "GetWindowInfo name " & String($sName) & @CRLF) $vt = BitAND(DllStructGetData($tVarChild, 1, 1), 0xFFFF) If $vt = $VT_I4 Then ;~ consolewrite("GetWindowInfo after 2nd if VT_I4" & @CRLF) ;~ MsgBox(0, "GetWindowInfo", "GetWindowInfo after 2nd if VT_I4" & @CRLF) If WindowFromAccessibleObject($pObject, $hWnd) = $S_OK Then MsgBox(0, "GetWindowInfo", "GetWindowInfo after 3rd if" & @CRLF) ;~ consolewrite("GetWindowInfo after 3rd if " & @CRLF) AccessibleObjectFromWindow($hWnd, $OBJID_CLIENT, $tIID_IAccessible, $pObject) MsgBox(0, "GetWindowInfo", "Yeah we did not break" & @CRLF) $oObject = ObjCreateInterface($pObject, $sIID_IAccessible, $dtagIAccessible) MsgBox(0, "GetWindowInfo", "But unfortunately did not come here" & @CRLF) $oObject.get_accName($CHILDID_SELF, $sName) ;~ consolewrite("GetWindowInfo name " & String($sName) & @CRLF) MsgBox(0, "GetWindowInfo", "GetWindowInfo name after 3rd if " & String($sName) & @CRLF) ; Get parent objects to top window Local $pParent, $pPrev, $oPrev, $iRole Do $pPrev = $pParent $oPrev = $oObject If IsObj($oObject) Then $oObject.get_accParent($pParent) $oObject = ObjCreateInterface($pParent, $sIID_IAccessible, $dtagIAccessible) EndIf If IsObj($oObject) Then $oObject.get_accName($CHILDID_SELF, $sName) EndIf ;~ consolewrite("GetWindowInfo name " & String($sName) & @CRLF) MsgBox(0, "GetWindowInfo", "GetWindowInfo name " & String($sName) & @CRLF) Until stringinstr("Desktop Bureaublad Escritorio",String($sName))>0 ;~ String($sName) = "Desktop" or "Bureaublad" ;"Escritorio";"Desktop" ; Info for top window (previous to desktop) PrintElementInfoToArray($pPrev, $oPrev, $CHILDID_SELF, "") ; Info for child objects of the top window If $oPrev.get_accRole($CHILDID_SELF, $iRole) = $S_OK And $iRole = $ROLE_SYSTEM_WINDOW Then WindowFromAccessibleObject($pPrev, $hWnd) PrintWindowObjects($hWnd) Else $err = 1 EndIf Else $err = 1 EndIf Else $err = 1 EndIf Else $err = 1 EndIf If $err Then _ MsgBox(0, "ISimpleDOM interfaces", _ "Accessible function xxxxx failed." & @CRLF & _ "Try another point e.g. the window title bar.") EndFunc ;==>GetWindowInfo Func PrintWindowObjects($hWindow) ; Object from window Local $pWindow, $oWindow AccessibleObjectFromWindow($hWindow, $OBJID_CLIENT, $tIID_IAccessible, $pWindow) $oWindow = ObjCreateInterface($pWindow, $sIID_IAccessible, $dtagIAccessible) If Not IsObj($oWindow) Then Return ; Get window objects WalkTreeWithAccessibleChildren($pWindow, 0, 8) ; Print window objects ReDim $aInfo[$iInfo] _ArrayDisplay($aInfo, "ISimpleDOM interfaces") ReDim $aInfo[10000] $iInfo = 0 EndFunc ;==>PrintWindowObjects Func WalkTreeWithAccessibleChildren($pAcc, $iLevel, $iLevels = 0) If $iLevels And $iLevel = $iLevels Then Return ; Create object Local $oAcc = ObjCreateInterface($pAcc, $sIID_IAccessible, $dtagIAccessible) If Not IsObj($oAcc) Then Return $oAcc.AddRef() ; Indentation Local $sIndent = "" For $i = 0 To $iLevel - 1 $sIndent &= " " Next Local $iChildCount, $iReturnCount, $tVarChildren ; Get children If $oAcc.get_accChildCount($iChildCount) Or Not $iChildCount Then Return If AccessibleChildren($pAcc, 0, $iChildCount, $tVarChildren, $iReturnCount) Then Return Local $vt, $pChildObj, $oChildObj Local $pService, $oService, $pISimpleDOMNode, $oISimpleDOMNode, $pISimpleDOM, $oISimpleDOM ; $oISimpleDOMNode.nodeInfo Local $sNodeName, $iNameSpaceID, $sNodeValue, $iNumChildren, $iUniqueID, $iNodeType, $sInnerHTML ; $oISimpleDOMNode.attributes Local $iMaxAttribs = 100, $iNumAttribs Local $tAttribNames = DllStructCreate("ptr[" & $iMaxAttribs & "]"), $sAttribName Local $tNameSpaceIDs = DllStructCreate("short[" & $iMaxAttribs & "]"), $iNameSpaceID Local $tAttribValues = DllStructCreate("ptr[" & $iMaxAttribs & "]"), $sAttribValue ; $oISimpleDOMNode.computedStyle Local $iMaxStyleProperties = 100, $iNumStyleProperties Local $tStyleProperties = DllStructCreate("ptr[" & $iMaxStyleProperties & "]"), $sStyleProperty Local $tStyleValues = DllStructCreate("ptr[" & $iMaxStyleProperties & "]"), $sStyleValue ; For each child For $i = 1 To $iReturnCount ; $tVarChildren is an array of VARIANTs with information about the children $vt = BitAND(DllStructGetData($tVarChildren, $i, 1), 0xFFFF) If $vt = $VT_DISPATCH Then ; Child object; get correct ptr x64 or x86 version Local $tVariant = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr;", DllStructGetPtr($tVarChildren, $i)) $pChildObj = DllStructGetData($tVariant, 5) ;this is wrong. You will never get the x64 ptr ;~ ; Child object ;~ $pChildObj = DllStructGetData($tVarChildren, $i, 3) ;~ $oChildObj = ObjCreateInterface($pChildObj, $sIID_IAccessible, $dtagIAccessible) $oChildObj = ObjCreateInterface(($pChildObj), $sIID_IAccessible, $dtagIAccessible) If IsObj($oChildObj) Then ; Try to get an ISimpleDOMNode interface pointer for the child object If $oChildObj.QueryInterface(DllStructGetPtr($tIID_IServiceProvider), $pService) = $S_OK Then $oService = ObjCreateInterface($pService, $sIID_IServiceProvider, $dtagIServiceProvider) If $oService.QueryService($tIID_ISimpleDOMNode, $tIID_ISimpleDOMNode, $pISimpleDOMNode) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$pISimpleDOMNode = " & Ptr($pISimpleDOMNode) $iInfo += 1 $oISimpleDOMNode = ObjCreateInterface($pISimpleDOMNode, $sIID_ISimpleDOMNode, $dtagISimpleDOMNode) If IsObj($oISimpleDOMNode) Then $oISimpleDOMNode.nodeInfo($sNodeName, $iNameSpaceID, $sNodeValue, $iNumChildren, $iUniqueID, $iNodeType) $aInfo[$iInfo + 0] = $sIndent & "$sNodeName = " & $sNodeName $aInfo[$iInfo + 1] = $sIndent & "$iNameSpaceID = " & $iNameSpaceID $aInfo[$iInfo + 2] = $sIndent & "$sNodeValue = " & $sNodeValue $aInfo[$iInfo + 3] = $sIndent & "$iNumChildren = " & $iNumChildren $aInfo[$iInfo + 4] = $sIndent & "$iUniqueID = " & $iUniqueID $aInfo[$iInfo + 5] = $sIndent & "$iNodeType = " & $iNodeType & " (" & GetNodeType($iNodeType) & ")" $iInfo += 6 ; $oISimpleDOMNode.attributes $oISimpleDOMNode.attributes($iMaxAttribs, $tAttribNames, $tNameSpaceIDs, $tAttribValues, $iNumAttribs) $aInfo[$iInfo] = $sIndent & "$iNumAttribs = " & $iNumAttribs $iInfo += 1 For $j = 1 To $iNumAttribs $sAttribName = SysReadString(DllStructGetData($tAttribNames, 1, $j)) $sAttribValue = SysReadString(DllStructGetData($tAttribValues, 1, $j)) $iNameSpaceID = DllStructGetData($tNameSpaceIDs, 1, $j) $aInfo[$iInfo + 0] = " " & $sIndent & "$iAttrib = " & $j $aInfo[$iInfo + 1] = " " & $sIndent & "$sAttribName = " & $sAttribName $aInfo[$iInfo + 2] = " " & $sIndent & "$sAttribValue = " & $sAttribValue $aInfo[$iInfo + 3] = " " & $sIndent & "$iNameSpaceID = " & $iNameSpaceID $iInfo += 4 ; Free memory allocated by BSTRs SysFreeString(DllStructGetData($tAttribNames, 1, $j)) SysFreeString(DllStructGetData($tAttribValues, 1, $j)) Next ; $oISimpleDOMNode.computedStyle $oISimpleDOMNode.computedStyle($iMaxStyleProperties, 0, $tStyleProperties, $tStyleValues, $iNumStyleProperties) $aInfo[$iInfo] = $sIndent & "$iNumStyleProps = " & $iNumStyleProperties $iInfo += 1 For $j = 1 To $iNumStyleProperties $sStyleProperty = SysReadString(DllStructGetData($tStyleProperties, 1, $j)) $sStyleValue = SysReadString(DllStructGetData($tStyleValues, 1, $j)) $aInfo[$iInfo + 0] = " " & $sIndent & "$iStyle = " & $j $aInfo[$iInfo + 1] = " " & $sIndent & "$sStyleProp = " & $sStyleProperty $aInfo[$iInfo + 2] = " " & $sIndent & "$sStyleValue = " & $sStyleValue $iInfo += 3 ; Free memory allocated by BSTRs SysFreeString(DllStructGetData($tStyleProperties, 1, $j)) SysFreeString(DllStructGetData($tStyleValues, 1, $j)) Next ;$oISimpleDOMNode.innerHTML( $sInnerHTML ) ;If String( $sInnerHTML ) <> "0" Then ; $aInfo[$iInfo] = $sIndent & "$sInnerHTML = " & $sInnerHTML ; $iInfo += 1 ;EndIf If $iNodeType = 3 Then ; $NODETYPE_TEXT ; Try to get an ISimpleDOMText interface pointer with $oISimpleDOMNode.QueryInterface If $oISimpleDOMNode.QueryInterface(DllStructGetPtr($tIID_ISimpleDOMText), $pISimpleDOM) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$pISimpleDOMText = " & Ptr($pISimpleDOM) $iInfo += 1 $oISimpleDOM = ObjCreateInterface($pISimpleDOM, $sIID_ISimpleDOMText, $dtagISimpleDOMText) If IsObj($oISimpleDOM) Then Local $sDomText $oISimpleDOM.domText($sDomText) $aInfo[$iInfo] = $sIndent & "$sDomText = " & $sDomText $iInfo += 1 EndIf EndIf ElseIf $iNodeType = 9 Then ; $NODETYPE_DOCUMENT ; Try to get an ISimpleDOMDocument interface pointer with $oISimpleDOMNode.QueryInterface If $oISimpleDOMNode.QueryInterface(DllStructGetPtr($tIID_ISimpleDOMDocument), $pISimpleDOM) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$pISimpleDOMDocument = " & Ptr($pISimpleDOM) $iInfo += 1 $oISimpleDOM = ObjCreateInterface($pISimpleDOM, $sIID_ISimpleDOMDocument, $dtagISimpleDOMDocument) If IsObj($oISimpleDOM) Then Local $sURL, $sTitle, $sMimeType, $sDocType $oISimpleDOM.URL($sURL) $oISimpleDOM.title($sTitle) $oISimpleDOM.mimeType($sMimeType) $oISimpleDOM.docType($sDocType) $aInfo[$iInfo + 0] = $sIndent & "$sURL = " & $sURL $aInfo[$iInfo + 1] = $sIndent & "$sTitle = " & $sTitle $aInfo[$iInfo + 2] = $sIndent & "$sMimeType = " & $sMimeType $aInfo[$iInfo + 3] = $sIndent & "$sDocType = " & $sDocType $iInfo += 4 EndIf EndIf EndIf EndIf EndIf EndIf PrintElementInfoToArray($pChildObj, $oChildObj, $CHILDID_SELF, $sIndent) WalkTreeWithAccessibleChildren($pChildObj, $iLevel + 1, $iLevels) EndIf EndIf Next EndFunc ;==>WalkTreeWithAccessibleChildren Func PrintElementInfoToArray($pElement, $oElement, $iChild, $sIndent) Local $hWnd, $sName, $iRole, $sRole, $iRoleLen Local $iState, $sState, $iStateLen Local $sValue, $x, $y, $w, $h If $iChild <> $CHILDID_SELF Then $aInfo[$iInfo] = $sIndent & "$iChildElem = " & $iChild $iInfo += 1 EndIf If $iChild = $CHILDID_SELF And $oElement.get_accRole($CHILDID_SELF, $iRole) = $S_OK And $iRole = $ROLE_SYSTEM_WINDOW Then WindowFromAccessibleObject($pElement, $hWnd) $aInfo[$iInfo] = $sIndent & "$hWnd = " & $hWnd $iInfo += 1 EndIf $oElement.get_accName($iChild, $sName) $aInfo[$iInfo] = $sIndent & "$sName = " & $sName $iInfo += 1 If $oElement.get_accRole($iChild, $iRole) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$iRole = 0x" & Hex($iRole) $iInfo += 1 $iRoleLen = GetRoleText($iRole, 0, 0) + 1 $sRole = DllStructCreate("wchar[" & $iRoleLen & "]") GetRoleText($iRole, DllStructGetPtr($sRole), $iRoleLen) $aInfo[$iInfo] = $sIndent & "$sRole = " & DllStructGetData($sRole, 1) $iInfo += 1 EndIf If $oElement.get_accState($iChild, $iState) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$iState = 0x" & Hex($iState) $iInfo += 1 $iStateLen = GetStateText($iState, 0, 0) + 1 $sState = DllStructCreate("wchar[" & $iStateLen & "]") GetStateText($iState, DllStructGetPtr($sState), $iStateLen) $aInfo[$iInfo] = $sIndent & "$sState = " & DllStructGetData($sState, 1) $iInfo += 1 EndIf If $oElement.get_accValue($iChild, $sValue) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$sValue = " & $sValue $iInfo += 1 EndIf If $oElement.accLocation($x, $y, $w, $h, $iChild) = $S_OK Then $aInfo[$iInfo] = $sIndent & "$x, $y, $w, $h = " & $x & ", " & $y & ", " & $w & ", " & $h $iInfo += 1 EndIf $aInfo[$iInfo] = "" $iInfo += 1 EndFunc ;==>PrintElementInfoToArray Func Close() Exit EndFunc ;==>Close MSAccessibility.au3 Edited September 19, 2016 by junkew FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
junkew Posted September 19, 2016 Author Share Posted September 19, 2016 (edited) above my hat https://bugzilla.mozilla.org/show_bug.cgi?id=649236 It seems to be AccessibleObjectFromWindow with the actual problem, though AccessibleObjectFromEvent calls it internally. A work around has been implemented in NVDA changeset:main,4474 which replaces a call to AccessibleObjectFromEvent with custom code that sends WM_GETOBJECT, calls ObjectFromLresult, and tries accChild. All the things that I'd think AccessibleObjectFromEvent/AccessibleObjectFromWindow would do normally. http://hg.mozilla.org/mozilla-central/rev/62cb7ce43f42 has an actual workaround but no clue for me on how to do this in AutoIT AccessibleObjectFromWindow API sends WM_GETOBJECT message to the Window so that could be used as a workaround. Edited September 19, 2016 by junkew FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
junkew Posted September 19, 2016 Author Share Posted September 19, 2016 probably change this from @trancexx Should then try something like this ;~ Func _IEControlGetObjFromHWND($hWin) Func _AccessibleObjectFromWindow( $hWnd, $iObjectID, $tRIID, ByRef $pObject ) Local $aCall = DllCall("user32.dll", "dword", "RegisterWindowMessageW", "wstr", "WM_GETOBJECT") If @error Or Not $aCall[0] Then Return SetError(1, 0, "") EndIf Local Const $WM_GETOBJECT = $aCall[0] $aCall = DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hWnd, "dword", $WM_GETOBJECT, "wparam", 0, "lparam", $iObjectID0) Local $lResult = $aCall[0] ;~ Global Const $sIID_IAccessible="{618736E0-3C3D-11CF-810C-00AA00389B71}" Local $tUUID = _WinAPI_GUIDFromString("{618736E0-3C3D-11CF-810C-00AA00389B71}") ;~ Local $tUUID = _WinAPI_GUIDFromString("{626FC520-A41E-11CF-A731-00A0C9082637}") ; IID_IHTMLDocument DllCall("ole32.dll", "int", "CoInitializeEx", "ptr", 0, "dword", 2) ;COINIT_APARTMENTTHREADED $aCall = DllCall("oleacc.dll", "dword", "ObjectFromLresult", _ "lresult", $lResult, _ "ptr", DllStructGetPtr($tUUID), _ "wparam", 0, _ "idispatch*", 0) If IsObj($aCall[4]) Then return $aCall[4] Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_AccessibleObjectFromWindow FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Danyfirex Posted September 19, 2016 Share Posted September 19, 2016 Hello. try the call this way Local $aRet = DllCall( $hdllOleacc, "int", "AccessibleObjectFromWindow", "hwnd", $hWnd, "dword", $iObjectID, "struct*", $tRIID, "ptr*", 0 ) Saludos junkew 1 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
junkew Posted September 19, 2016 Author Share Posted September 19, 2016 that works I learned a lot by reading all stuff above Func AccessibleObjectFromWindow( $hWnd, $iObjectID, $tRIID, ByRef $pObject ) ;~ Local $aRet = DllCall( $hdllOleacc, "int", "AccessibleObjectFromWindow", "hwnd", $hWnd, "dword", $iObjectID, "struct*", $tRIID, "int*", 0 ) Local $aRet = DllCall( $hdllOleacc, "int", "AccessibleObjectFromWindow", "hwnd", $hWnd, "dword", $iObjectID, "struct*", $tRIID, "ptr*", 0 ) FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Danyfirex Posted September 19, 2016 Share Posted September 19, 2016 I forgot to tell you that in the first post. I did that change when I tried code lastnight then I forgot that I did lol. Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now