Jump to content

JAVA object automation and simple spy


Recommended Posts

There was a java udf based on the jab dll and in other languages plenty of examples on how to use jab dll. In this thread you see with jab simplespy the proof of concept in native AutoIt. Its just a matter of making the right declaration for the dllcalls in a straightforward way. Unfortunately never had time and not working with java gui nowadays otherwise i would enhance above.

Link to post
Share on other sites
  • Replies 90
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

As a starter and far from perfect and real messy code a simple spy for Java Accessibility Bridge Based on the information in general help and support '?do=embed' frameborder='0' data-embedC

;~ ******* ;~ Every AccessibleContext IntPtr must be replaced by long, including but not limited to getAccessibleContextFromHWND, getAccessibleParentFromContext, getAccessibleChildFromConte

revalidated and still works with 1.8.0.66 and autoit 3.3.15.0 Mouse position is retrieved 1519-331 JAVA window found <> Java Window Title= Handle=0x0000000000040A88 res: 1

Posted Images

  • 6 months later...

Just checked and still works nicely in 64 bits windows. 

>"C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Users\x\Documents\UIA\JABSimpleSpy.au3" /UserParams    
+>19:58:07 Starting AutoIt3Wrapper v.14.801.2025.0 SciTE v.3.4.4.0   Keyboard:00020409  OS:WIN_81/  CPU:X64 OS:X64    Environment(Language:0413)
+>         SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE   UserDir => C:\Users\x\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\x\AppData\Local\AutoIt v3\SciTE 
>Running AU3Check (3.3.14.5)  from:C:\Program Files (x86)\AutoIt3  input:C:\Users\x\Documents\UIA\JABSimpleSpy.au3
+>19:58:08 AU3Check ended.rc:0
>Running:(3.3.14.5):C:\Program Files (x86)\AutoIt3\autoit3_x64.exe "C:\Users\x\Documents\UIA\JABSimpleSpy.au3"    
--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
C:\Program Files\Java\jre1.8.0_181
We are using X64 at cpu X64 Autoit 64 bit version @AutoItX64=1
Opening C:\Program Files\Java\jre1.8.0_181\bin\WindowsAccessBridge-64.dll  Windows accessbridge 32 opened 1
 0 initializeAccessBridge is finishedWindows_run passed :
0hello  name: <Settings...>
  description: <<html>Modify settings for temporary files</html>>
  role: <push button>
  role_en_US: <push button>
  states: <enabled,focusable,visible,showing,opaque>
  states_en_US: <enabled,focusable,visible,showing,opaque>
  indexInParent: <0>
  childrenCount: <0>
  x: <1028>
  y: <447>
  width: <83>
  height: <0>
+>19:58:30 AutoIt3.exe ended.rc:0
+>19:58:30 AutoIt3Wrapper Finished.

Initially I learned a lot from NVDA to use this stuff and found another nice access-bridge-explorer that can be used for porting things from JAB into AU3

 

Link to post
Share on other sites
  • 2 months later...

Jabhandler is not imported. The declarations of python are just in the au3 file for easier translating to au3 syntax which will be manual labor intensive work. Just read carefully comments and code and see if you can transform one of the py functions.

Link to post
Share on other sites
  • 3 weeks later...

Func _JAB_getAccessibleContextByFindAll($vmId, $ac, $sName, $sRole)

   Local $find_ac = 0
   Local $iCount = __getVisibleChildrenCount($vmId, $ac)
   If $iCount = 0 Then
      Return
   EndIf
   For $i = 0 To $iCount - 1
      Local $child_ac = __getAccessibleChildFromContext($vmId, $ac, $i)
      Local $acInfo = DllStructCreate($tagAccessibleContextInfo)
      __getAccessibleContextInfo($vmId, $child_ac, $acInfo)
      $s1 = DllStructGetData($acInfo, "name")
      $s3 = DllStructGetData($acInfo, "role")
;      consolewrite($child_ac & "|" & $s1 & "," & $s3 & @CRLF)
      If $s1 = $sName And $s3 = $sRole Then
         $find_ac = $child_ac
         ExitLoop
      Else
         If $find_ac = 0 Then
            $find_ac = _JAB_getAccessibleContextByFindAll($vmId, $child_ac, $sName, $sRole)
         EndIf
      EndIf
   Next
   Return $find_ac

EndFunc

Link to post
Share on other sites

;~     _fixBridgeFunc(BOOL,'getAccessibleContextInfo',c_long,JOBJECT64,POINTER(AccessibleContextInfo),errcheck=True)
; Retrieves an AccessibleContextInfo object of the AccessibleContext object ac.
; AccessibleContext $ac
; $tAccessBridgeVersionInfo $info
Func __getAccessibleContextInfo($vmId, $ac, byref $info)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextInfo", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $info)
    If @error Then Return SetError(1, 0, 0)
    $info = $result[3]
    Return $result[0]
EndFunc

;~     _fixBridgeFunc(JOBJECT64,'getAccessibleChildFromContext',c_long,JOBJECT64,jint,errcheck=True)
; Returns an AccessibleContext object that represents the nth child of the object ac, where n is specified by the value index.
; AccessibleContext $ac
Func __getAccessibleChildFromContext($vmId, $ac, $index)
;~ Seems not to be allowed to call with null so passing $acParent
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleChildFromContext", "long", $vmId, $c_JOBJECT64, $ac, "int", $index)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
 EndFunc

;~ int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext)
; Returns the number of visible children of a component. Returns -1 on error.
; AccessibleContext $ac
Func __getVisibleChildrenCount($vmId, $ac)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getVisibleChildrenCount", "long", $vmId, $c_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

Link to post
Share on other sites
  • 3 weeks later...
;~ *******
;~ Every AccessibleContext IntPtr must be replaced by long, including but not limited to getAccessibleContextFromHWND, getAccessibleParentFromContext, getAccessibleChildFromContext, getAccessibleTextInf
;~ JOBJECT64 is defined as jlong on 64-bit systems and jobject on legacy versions of Java Access Bridge. For definitions, see the section ACCESSBRIDGE_ARCH_LEGACY in the AccessBridgePackages.h header file.
;~ #ifdef ACCESSBRIDGE_ARCH_LEGACY
;~      typedef jobject JOBJECT64;
;~      typedef HWND ABHWND64;
;~ #else
;~      typedef jlong JOBJECT64;
;~      typedef long ABHWND64;
;~ #endif
;~ a jobject is a 32 bit pointer for 32 bit builds
;~ 'bool' is a built-in C++ type while 'BOOL' is a Microsoft specific type that is defined as an 'int'. You can find it in 'windef.h'
;~
;~ ** jni_md.h **
;~ typedef long jint;
;~ typedef __int64 jlong;
;~ typedef signed char jbyte;
;~ *******
;~ accessbridgecalls.h
;~     typedef JOBJECT64 AccessibleContext;
;~     typedef JOBJECT64 AccessibleText;
;~     typedef JOBJECT64 AccessibleValue;
;~     typedef JOBJECT64 AccessibleSelection;
;~     typedef JOBJECT64 Java_Object;
;~     typedef JOBJECT64 PropertyChangeEvent;
;~     typedef JOBJECT64 FocusEvent;
;~     typedef JOBJECT64 CaretEvent;
;~     typedef JOBJECT64 MouseEvent;
;~     typedef JOBJECT64 MenuEvent;
;~     typedef JOBJECT64 AccessibleTable;
;~     typedef JOBJECT64 AccessibleHyperlink;
;~     typedef JOBJECT64 AccessibleHypertext;

;~ Primitive Types and Native Equivalents
;~ Java Type    Native Type Description
;~ boolean      jboolean    unsigned 8 bits
;~ byte         jbyte       signed 8 bits
;~ char         jchar       unsigned 16 bits
;~ short        jshort      signed 16 bits
;~ int          jint        signed 32 bits
;~ long         jlong       signed 64 bits
;~ float        jfloat      32 bits
;~ double       jdouble     64 bits
;~ void         void        not applicable
;#AutoIt3Wrapper_UseX64 = y

Global Const $c_JOBJECT64 = "UINT64"        ;~ JOBJECT64
Global Const $cP_JOBJECT64 = "UINT64*"      ;~ POINTER(JOBJECT64)

;=====================================Accessibility information================================
Global Const $MAX_BUFFER_SIZE = 10240
Global Const $MAX_STRING_SIZE = 1024
Global Const $SHORT_STRING_SIZE = 256

Global Const $tagAccessBridgeVersionInfo = _
"WCHAR VMversion[256];" & _                 ; output of "java -version"
"WCHAR bridgeJavaClassVersion[256];" & _    ; version of the AccessBridge.class
"WCHAR bridgeJavaDLLVersion[256];" & _      ; version of JavaAccessBridge.dll
"WCHAR bridgeWinDLLVersion[256]"            ; version of WindowsAccessBridge.dll

Global Const $tagAccessibleContextInfo = _
"WCHAR name[1024];" & _             ; the AccessibleName of the object
"WCHAR description[1024];" & _      ; the AccessibleDescription of the object
"WCHAR role[256];" & _              ; localized AccesibleRole string
"WCHAR role_en_US[256];" & _        ; AccesibleRole string in the en_US locale
"WCHAR states[256];" & _            ; localized AccesibleStateSet string (comma separated)
"WCHAR states_en_US[256];" & _      ; AccesibleStateSet string in the en_US locale (comma separated)
"INT indexInParent;" & _            ; index of object in parent
"INT childrenCount;" & _            ; # of children, if any
"INT x;" & _                        ; screen x-axis co-ordinate in pixels
"INT y;" & _                        ; screen y-axis co-ordinate in pixels
"INT width;" & _                    ; pixel width of object
"INT height;" & _                   ; pixel height of object
"BOOL accessibleComponent;" & _     ; flags for various additional Java Accessibility interfaces
"BOOL accessibleAction;" & _
"BOOL accessibleSelection;" & _     ; FALSE if this object does not implement the additional interface in question
"BOOL accessibleText;" & _
"BOOL accessibleInterfaces"         ; new bitfield containing additional interface flags

Global Const $tagAccessibleTextInfo = _
"INT charCount;" & _                ; # of characters in this text object
"INT caretIndex;" & _               ; index of caret
"INT indexAtPoint"                  ; index at the passsed in point

Global Const $tagAccessibleTextItemsInfo = _
"WCHAR letter;" & _
"WCHAR word[256];" & _
"WCHAR sentence[1024]"

Global Const $tagAccessibleTextSelectionInfo = _
"INT selectionStartIndex;" & _
"INT selectionEndIndex;" & _
"WCHAR selectedText[1024]"

Global Const $tagAccessibleTextRectInfo = _
"INT x;" & _                        ; bounding recttangle of char at index, x-axis co-ordinate
"INT y;" & _                        ; y-axis co-ordinate
"INT width;" & _                    ; bounding rectangle width
"INT height"                        ; bounding rectangle height

Global Const $tagAccessibleTextAttributesInfo = _
"BOOL bold;" & _
"BOOL italic;" & _
"BOOL underline;" & _
"BOOL strikethrough;" & _
"BOOL superscript;" & _
"BOOL subscript;" & _
"WCHAR backgroundColor[256];" & _
"WCHAR foregroundColor[256];" & _
"WCHAR fontFamily[256];" & _
"INT fontSize;" & _
"INT alignment;" & _
"INT bidiLevel;" & _
"FLOAT firstLineIndent;" & _
"FLOAT LeftIndent;" & _
"FLOAT rightIndent;" & _
"FLOAT lineSpacing;" & _
"FLOAT spaceAbove;" & _
"FLOAT spaceBelow;" & _
"WCHAR fullAttributesString[1024]"

;=====================================AccessibleTable================================
Global Const $MAX_TABLE_SELECTIONS = 64

Global Const $tagAccessibleTableInfo = _
"UINT64 caption;" & _               ; AccessibleContext
"UINT64 summary;" & _               ; AccessibleContext
"INT rowCount;" & _
"INT columnCount;" & _
"UINT64 accessibleContext;" & _
"UINT64 accessibleTable"

Global Const $tagAccessibleTableCellInfo = _
"UINT64 accessibleContext;" & _
"INT index;" & _
"INT row;" & _
"INT column;" & _
"INT rowExtent;" & _
"INT columnExtent;" & _
"BOOL isSelected"

;=====================================AccessibleRelationSet================================
Global Const $MAX_RELATION_TARGETS = 25
Global Const $MAX_RELATIONS = 5

Global Const $tagAccessibleRelationInfo = _
"WCHAR key[256];" & _
"INT targetCount;" & _
"UINT64 targets[25]"                ; AccessibleContexts

Local $tag_Relations = ""
For $i = 1 To 5
   If $tag_Relations = "" Then
      $tag_Relations = $tagAccessibleRelationInfo
   Else
      $tag_Relations = $tag_Relations & ";" & $tagAccessibleRelationInfo
   EndIf
Next
Global Const $tagAccessibleRelationSetInfo = _
"INT relationCount;" & _
$tag_Relations                      ; $tAccessibleRelationInfo relations[5]

;=====================================AccessibleHypertext================================
Global Const $MAX_HYPERLINKS = 64   ;~ maximum number of hyperlinks returned

Global Const $tagAccessibleHyperlinkInfo = _
"WCHAR text[256];" & _              ; the hyperlink text
"INT startIndex;" & _               ; index in the hypertext document where the link begins
"INT endIndex;" & _                 ; index in the hypertext document where the link ends
"UINT64 accessibleHyperlink"        ; AccessibleHyperlink object

Local $tag_Links = ""
For $i = 1 To 64
   If $tag_Links = "" Then
      $tag_Links = $tagAccessibleHyperlinkInfo
   Else
      $tag_Links = $tag_Links & ";" & $tagAccessibleHyperlinkInfo
   EndIf
Next
Global Const $tagAccessibleHypertextInfo = _
"INT linkCount;" & _                ; number of hyperlinks
$tag_Links & ";" & _                ; the hyperlinks ,$tAccessibleHyperlinkInfo links[64]
"UINT64 accessibleHypertext"        ; AccessibleHypertext object

;=====================================Accessible Key Bindings================================
Global Const $MAX_KEY_BINDINGS = 8

Global Const $tagAccessibleKeyBindingInfo = _
"WCHAR character;" & _              ; the key character
"INT modifiers"                     ; the key modifiers

Local $tag_KeyBindingInfo = ""
For $i = 1 To 8
   If $tag_KeyBindingInfo  = "" Then
      $tag_KeyBindingInfo  = $tagAccessibleKeyBindingInfo
   Else
      $tag_KeyBindingInfo  = $tag_KeyBindingInfo  & ";" & $tagAccessibleKeyBindingInfo
   EndIf
Next
Global Const $tagAccessibleKeyBindings = _
"INT keyBindingsCount;" & _         ; number of key bindings
$tag_KeyBindingInfo                 ; $tAccessibleKeyBindingInfo keyBindingInfo[8]

;=====================================AccessibleIcon================================
Global Const $MAX_ICON_INFO = 8

Global Const $tagAccessibleIconInfo = _
"WCHAR description[256];" & _       ; icon description
"INT height;" & _                   ; icon height
"INT width"                         ; icon width

Local $tag_IconInfo = ""
For $i = 1 To 8
   If $tag_IconInfo  = "" Then
      $tag_IconInfo  = $tagAccessibleIconInfo
   Else
      $tag_IconInfo  = $tag_IconInfo  & ";" & $tagAccessibleIconInfo
   EndIf
Next
Global Const $tagAccessibleIcon = _
"INT iconsCount;" & _               ; number of icons
$tag_IconInfo                       ; the icons ,$tAccessibleIconInfo iconInfo[8]

;=====================================AccessibleAction================================
Global Const $MAX_ACTION_INFO = 256
Global Const $MAX_ACTIONS_TO_DO = 32

Global Const $tagAccessibleActionInfo = _
"WCHAR name[256]"

Local $tag_ActionInfo = ""
For $i = 1 To 256
   If $tag_ActionInfo = "" Then
      $tag_ActionInfo = $tagAccessibleActionInfo
   Else
      $tag_ActionInfo = $tag_ActionInfo & ";" & $tagAccessibleActionInfo
   EndIf
Next
Global Const $tagAccessibleActions = _
"INT actionsCount;" & _
$tag_ActionInfo                     ; $tAccessibleActionInfo actionInfo[256]

Local $tag_Actions = ""
For $i = 1 To 32
   If $tag_Actions = "" Then
      $tag_Actions = $tagAccessibleActionInfo
   Else
      $tag_Actions = $tag_Actions & ";" & $tagAccessibleActionInfo
   EndIf
Next
Global Const $tagAccessibleActionsToDo = _
"INT actionsCount;" & _
$tag_Actions                            ; $tAccessibleActions actions[32]

;=====================================VisibleChilden================================
Global Const $MAX_VISIBLE_CHILDREN = 256

Global Const $tagVisibleChildenInfo = _
"INT returnedChildrenCount;" & _    ; number of children returned
"UINT64 children[256]"              ; the visible children


Global $hAccessBridgeDll  ;~ reference to the accessbridge dll

_JAB_init()

Func _JAB_init()

   ;~ Determine java location
   Local $sJavaVersion
   Local $sJavaHome
   Local $sAccessBridgeDLL
   If @OSArch = "X86" Then
      Local $sJavaReg = "HKLM\SOFTWARE\JavaSoft\Java Runtime Environment"
      $sJavaVersion = RegRead($sJavaReg, "CurrentVersion")
      $sJavaHome = RegRead($sJavaReg & "\" & $sJavaVersion, "JavaHome")
   ElseIf @OSArch = "X64" Then
      Local $sJavaReg64 = "HKLM64\SOFTWARE\JavaSoft\Java Runtime Environment"
      Local $sJavaReg32 = "HKLM64\SOFTWARE\Wow6432Node\JavaSoft\Java Runtime Environment"
      $sJavaVersion = RegRead($sJavaReg32, "CurrentVersion")
      $sJavaHome = RegRead($sJavaReg32 & "\" & $sJavaVersion, "JavaHome")
      If $sJavaVersion = "" Then
         $sJavaVersion = RegRead($sJavaReg64, "CurrentVersion")
         $sJavaHome = RegRead($sJavaReg64 & "\" & $sJavaVersion, "JavaHome")
      EndIf
   EndIf
   If $sJavaHome = "" Then
      consolewrite("  Unable to find Java Registry " & @CRLF)
      Return
   EndIf
   consolewrite("  Java Home: " & $sJavaHome & @CRLF)

   ;~ TODO: Check which dll that Autoit can work with, still can't find eazy way to work with both dlls
   consolewrite("  We are using OS " & @OSArch & " at cpu " & @CPUArch & "; Autoit 64 bit version @AutoItX64="& @AutoItX64 & @CRLF)
   ;~ Only Autoit 64 bit version can open WindowsAccessBridge-64.dll, so use @AutoItX64 to decide which WindowsAccessBridge can be opened
   $sAccessBridgeDLL = (@AutoItX64) ? "WindowsAccessBridge-64.dll" : "WindowsAccessBridge-32.dll"

   ;~ Open the Dll for accessibility
   $hAccessBridgeDll = DllOpen($sJavaHome & "\bin\" & $sAccessBridgeDLL)
   If $hAccessBridgeDll <> -1 Then
      ConsoleWrite("  PASS: Windows accessbridge " & $sAccessBridgeDLL & " opened returns: " & $hAccessBridgeDll & @CRLF)
   Else
      ConsoleWrite("  ERROR: Windows accessbridge " & $sAccessBridgeDLL & " open failed returns: " & $hAccessBridgeDll & @CRLF)
      Return
   EndIf

   ;~ Make sure Java Access Bridge is turned on
   Runwait($sJavaHome & "\bin\jabswitch /enable","",@SW_MAXIMIZE)
   ;~ TODO: Handle messages received from initialize
   $result = __Windows_run()
   consolewrite(@error & " Windows_run returns: " & $result & @CRLF)
   ;$result = __initializeAccessBridge()
   ;consolewrite($result & " " & @error & " initializeAccessBridge is finished" & @CRLF)

EndFunc

Func _JAB_shutDown()
    __shutdownAccessBridge()
EndFunc


Func _JAB_getName($vmId, $ac)
   Local $acInfo = DllStructCreate($tagAccessibleContextInfo)
   __getAccessibleContextInfo($vmId, $ac, $acInfo)
   Return DllStructGetData($acInfo, "name")
EndFunc

Func _JAB_getRole($vmId, $ac)
   Local $acInfo = DllStructCreate($tagAccessibleContextInfo)
   __getAccessibleContextInfo($vmId, $ac, $acInfo)
   Return DllStructGetData($acInfo, "role")
EndFunc

Func _JAB_getIndexInParent($vmId, $ac)
   Local $acInfo = DllStructCreate($tagAccessibleContextInfo)
   __getAccessibleContextInfo($vmId, $ac, $acInfo)
   Return DllStructGetData($acInfo, "indexInParent")
EndFunc

Func _JAB_getChildrenCount($vmId, $ac)
   Local $acInfo = DllStructCreate($tagAccessibleContextInfo)
   __getAccessibleContextInfo($vmId, $ac, $acInfo)
   Return DllStructGetData($acInfo, "childrenCount")
EndFunc


;~ Must use the AccessibleContext got from the win handle which include the target element
Func _JAB_getAccessibleContextByFindAll($vmId, $ac, $sName, $sRole)
   Local $find_ac = 0
   Local $iCount =_JAB_getChildrenCount($vmId, $ac)
   If $iCount = 0 Then
      Return
   EndIf
   For $i = 0 To $iCount - 1
      Local $child_ac = __getAccessibleChildFromContext($vmId, $ac, $i)
      Local $s1 = _JAB_getName($vmId, $child_ac)
      Local $s3 = _JAB_getRole($vmId, $child_ac)
;     consolewrite($child_ac & "|" & $s1 & "," & $s3 & @CRLF)
      If $s1 = $sName And $s3 = $sRole Then
         $find_ac = $child_ac
         ExitLoop
      Else
         If $find_ac = 0 Then
            $find_ac = _JAB_getAccessibleContextByFindAll($vmId, $child_ac, $sName, $sRole)
         EndIf
      EndIf
   Next
   Return $find_ac
EndFunc

;~ $next can be negative
Func _JAB_getNextSibling($vmId, $ac, $next = 1)
   If Not IsInt($next) Then
      consolewrite("_JAB_findNextSibling: $next must be int" & @CRLF)
      Return
   EndIf
   Local $s7 = _JAB_getIndexInParent($vmId, $ac)
   Local $parent_ac = __getAccessibleParentFromContext($vmId, $ac)
   Local $parent_s8 = _JAB_getChildrenCount($vmId, $parent_ac)
   If $s7 + $next >= 0 and $s7 + $next <= $parent_s8 - 1 Then
      Local $sibling_ac = __getAccessibleChildFromContext($vmId, $parent_ac, $s7 + $next)
      Return $sibling_ac
   EndIf
EndFunc

Func _JAB_getFirstChildByRole($vmId, $ac, $sRole)
   Local $iCount = _JAB_getChildrenCount($vmId, $ac)
   If $iCount = 0 Then
      Return
   EndIf
   Local $re1 = -1
   For $i = 0 To $iCount - 1
      Local $child_ac = __getAccessibleChildFromContext($vmId, $ac, $i)
      Local $child_ac_s3 = _JAB_getRole($vmId, $child_ac)
      If $child_ac_s3 = $sRole Then
         $re1 = $child_ac
         Return $child_ac
         ExitLoop
      EndIf
   Next
   If $re1 = -1 Then
      consolewrite("_JAB_getFirstChildByRole: " & $sRole & " is not found" & @CRLF)
      Return
   EndIf
EndFunc

;~ list element's actions
Func _JAB_getAllActions($vmId, $ac)
   Local $actions = DllStructCreate($tagAccessibleActions)
   __getAccessibleActions($vmId, $ac, $actions)
   Local $s1 = DllStructGetData($actions, "actionsCount")
   If $s1 = 0 Then
      consolewrite("_JAB_findAllActions: this element has no action" & @CRLF)
      Return
   EndIf
   Local $re = ""
   For $i = 2 To $s1 + 1
      Local $s = $i&"|"&DllStructGetData($actions, $i)&@CRLF
      If $re = "" Then
         $re = $s
      Else
         $re = $re & $s
      EndIf
   Next
   Return $re
EndFunc

;~ Only applicable for single action element like button or check box, menu, menu item
Func _JAB_singleAction($vmId, $ac)
   Local $actions = DllStructCreate($tagAccessibleActions)
   Local $actionsToDo = DllStructCreate($tagAccessibleActionsToDo)
   __getAccessibleActions($vmId, $ac, $actions)
   Local $s1 = DllStructGetData($actions, "actionsCount")
   Local $s2 = DllStructGetData($actions, 2)
   If $s1 <> 1 Then
      consolewrite("_JAB_singleAction: Only applicable for single action element like button or check box, menu, menu item" & @CRLF)
      Return
   EndIf
   Local $failure
   DllStructSetData($actionsToDo, "actionsCount", 1)
   DllStructSetData($actionsToDo, 2, $s2)
   __doAccessibleActions($vmId, $ac, $actionsToDo, $failure)
EndFunc

Func _JAB_setValue($vmId, $ac, $sValue)
   Local $actions = DllStructCreate($tagAccessibleActions)
   __getAccessibleActions($vmId, $ac, $actions)
   Local $s1 = DllStructGetData($actions, "actionsCount")
   If $s1 = 0 Then
      consolewrite("_JAB_setValue: this element has no action" & @CRLF)
      Return
   EndIf
   Local $re1 = 0
   Local $re2 = 0
   For $i = 2 To $s1 + 1
      Local $s = DllStructGetData($actions, $i)
      If $s = "select-all" Then
         $re1 = 1
         ExitLoop
      EndIf
   Next
   If $re1 = 0 Then
      consolewrite("_JAB_setValue: this element doesn't support select-all action" & @CRLF)
      Return
   EndIf
   For $i = 2 To $s1 + 1
      Local $s = DllStructGetData($actions, $i)
      If $s = "paste-from-clipboard" Then
         $re2 = 1
         ExitLoop
      EndIf
   Next
   If $re2 = 0 Then
      consolewrite("_JAB_setValue: this element doesn't support paste-from-clipboard action" & @CRLF)
      Return
   EndIf
   Local $actionsToDo = DllStructCreate($tagAccessibleActionsToDo)
   Local $failure
   ClipPut($sValue)
   DllStructSetData($actionsToDo, "actionsCount", 2)
   DllStructSetData($actionsToDo, 2, "select-all")
   DllStructSetData($actionsToDo, 3, "paste-from-clipboard")
   __doAccessibleActions($vmId, $ac, $actionsToDo, $failure)
EndFunc

Func _JAB_getValue($vmId, $ac)
   Local $actions = DllStructCreate($tagAccessibleActions)
   __getAccessibleActions($vmId, $ac, $actions)
   Local $s1 = DllStructGetData($actions, "actionsCount")
   If $s1 = 0 Then
      consolewrite("_JAB_getValue: this element has no action" & @CRLF)
      Return
   EndIf
   Local $re1 = 0
   For $i = 2 To $s1 + 1
      Local $s = DllStructGetData($actions, $i)
      If $s = "copy-to-clipboard" Then
         $re1 = 1
         ExitLoop
      EndIf
   Next
   If $re1 = 0 Then
      consolewrite("_JAB_getValue: this element doesn't support copy-to-clipboard action" & @CRLF)
      Return
   EndIf
   ;~ empty the clipboard
   ClipPut("")
   Local $actionsToDo = DllStructCreate($tagAccessibleActionsToDo)
   Local $failure
   DllStructSetData($actionsToDo, "actionsCount", 1)
   DllStructSetData($actionsToDo, 2, "copy-to-clipboard")
   __doAccessibleActions($vmId, $ac, $actionsToDo, $failure)
   Return ClipGet()
EndFunc

Func _JAB_selectCheckBox($vmId, $ac)
   Local $acInfo = DllStructCreate($tagAccessibleContextInfo)
   __getAccessibleContextInfo($vmId, $ac, $acInfo)
   Local $s3 = DllStructGetData($acInfo, "role")
   If $s3 <> "check box" Then
      consolewrite("_JAB_selectCheckBox: this element isn't check box" & @CRLF)
      Return
   EndIf
   Local $s6 = DllStructGetData($acInfo, "states_en_US")
   If StringInStr($s6, "checked") Then
      Return
   Else
      _JAB_singleAction($vmId, $ac)
   EndIf
EndFunc

Func _JAB_unselectCheckBox($vmId, $ac)
   Local $acInfo = DllStructCreate($tagAccessibleContextInfo)
   __getAccessibleContextInfo($vmId, $ac, $acInfo)
   Local $s3 = DllStructGetData($acInfo, "role")
   If $s3 <> "check box" Then
      consolewrite("_JAB_unselectCheckBox: this element isn't check box" & @CRLF)
      Return
   EndIf
   Local $s6 = DllStructGetData($acInfo, "states_en_US")
   If StringInStr($s6, "checked") Then
      _JAB_singleAction($vmId, $ac)
   EndIf
EndFunc

;~ scroll pane-->viewport-->table
;~           |-->scroll bar
;~           |-->scroll bar
;~           |-->viewport-->panel-->panel:column1
;~                              |-->panel:column2
;~ Must use unique name to find column ac
Func _JAB_getTableFromColumn($vmId, $ac)
   Local $p1_ac = __getAccessibleParentFromContext($vmId, $ac)
   Local $p2_ac = __getAccessibleParentFromContext($vmId, $p1_ac)
   Local $s3 = _JAB_getRole($vmId, $p2_ac)
   If $s3 <> "viewport" Then
      consolewrite("_JAB_getTableFromColumn: find wrong column viewport" & @CRLF)
      Return
   EndIf
   Local $p3_ac = __getAccessibleParentFromContext($vmId, $p2_ac)
   Local $iCount = _JAB_getChildrenCount($vmId, $p3_ac)
   For $i = 0 To $iCount - 1
      Local $child_ac = __getAccessibleChildFromContext($vmId, $p3_ac, $i)
      Local $child_s3 = _JAB_getRole($vmId, $child_ac)
      If $child_s3 = "viewport" Then
         ;~ first child is table, begin from 0
         Local $grandson_ac = __getAccessibleChildFromContext($vmId, $child_ac, 0)
         Local $grandson_s3 = _JAB_getRole($vmId, $grandson_ac)
         If $grandson_s3 = "table" Then
            Return $grandson_ac
            ExitLoop
         EndIf
      EndIf
   Next
EndFunc

;~ row and column begin from 0
Func _JAB_getTableCellText($vmId, $ac, $iRow = 0, $iColumn = 0)
   If Not IsInt($iRow) Or Not IsInt($iColumn) Then
      consolewrite("_JAB_getTableCellText: $iRow and $iColumn must be int" & @CRLF)
      Return
   EndIf
   Local $s3 = _JAB_getRole($vmId, $ac)
   If $s3 <> "table" Then
      consolewrite("_JAB_getTableCellText: this element isn't table" & @CRLF)
      Return
   EndIf
   Local $tableInfo = DllStructCreate($tagAccessibleTableInfo)
   __getAccessibleTableInfo($vmId, $ac, $tableInfo)
   Local $table_s3 = DllStructGetData($tableInfo, "rowCount")
   Local $table_s4 = DllStructGetData($tableInfo, "columnCount")
   Local $table_s6 = DllStructGetData($tableInfo, "accessibleTable")
   If $iRow < 0 Or $iRow > $table_s3 - 1 Then
      consolewrite("_JAB_getTableCellText: $iRow out of range" & @CRLF)
      Return
   EndIf
   If $iColumn < 0 Or $iColumn > $table_s4 - 1 Then
      consolewrite("_JAB_getTableCellText: $iColumn out of range" & @CRLF)
      Return
   EndIf
   Local $tableCellInfo = DllStructCreate($tagAccessibleTableCellInfo)
   __getAccessibleTableCellInfo($vmId, $table_s6, $iRow, $iColumn, $tableCellInfo)
   Local $cell_s1 = DllStructGetData($tableCellInfo, "accessibleContext")
   Return _JAB_getName($vmId, $cell_s1)
EndFunc

Func _JAB_selectAFromTableWhereB($vmId, $ac, $iColumnA, $iColumnB, $sB)
   If Not IsInt($iColumnA) Or Not IsInt($iColumnB) Then
      consolewrite("_JAB_selectAFromTableWhereB: $iColumnA and $iColumnB must be int" & @CRLF)
      Return
   EndIf
   Local $s3 = _JAB_getRole($vmId, $ac)
   If $s3 <> "table" Then
      consolewrite("_JAB_selectAFromTableWhereB: this element isn't table" & @CRLF)
      Return
   EndIf
   Local $tableInfo = DllStructCreate($tagAccessibleTableInfo)
   __getAccessibleTableInfo($vmId, $ac, $tableInfo)
   Local $table_s3 = DllStructGetData($tableInfo, "rowCount")
   Local $table_s4 = DllStructGetData($tableInfo, "columnCount")
   Local $table_s6 = DllStructGetData($tableInfo, "accessibleTable")
   If $iColumnA < 0 Or $iColumnA > $table_s4 - 1 Then
      consolewrite("_JAB_selectAFromTableWhereB: $iColumnA out of range" & @CRLF)
      Return
   EndIf
   If $iColumnB < 0 Or $iColumnB > $table_s4 - 1 Then
      consolewrite("_JAB_selectAFromTableWhereB: $iColumnB out of range" & @CRLF)
      Return
   EndIf
   Local $re = -1
   For $i = 0 To $table_s3 - 1
      Local $tableCellInfo = DllStructCreate($tagAccessibleTableCellInfo)
      __getAccessibleTableCellInfo($vmId, $table_s6, $i, $iColumnB, $tableCellInfo)
      Local $cell_s1 = DllStructGetData($tableCellInfo, "accessibleContext")
      Local $s1 = _JAB_getName($vmId, $cell_s1)
      If StringInStr($s1, $sB) Then
         $re = 1
         __getAccessibleTableCellInfo($vmId, $table_s6, $i, $iColumnA, $tableCellInfo)
         Local $cell_s2 = DllStructGetData($tableCellInfo, "accessibleContext")
         Return _JAB_getName($vmId, $cell_s2)
         ExitLoop
      EndIf
   Next
   If $re = -1 Then
      consolewrite("_JAB_selectAFromTableWhereB: " & $sB & " is not found" & @CRLF)
      Return
   EndIf
EndFunc

Func _JAB_menuSelectItem($vmId, $ac, $item1 = "", $item2 = "", $item3 = "", $item4 = "", $item5 = "", $item6 = "")
   Local $s3 =  _JAB_getRole($vmId, $ac)
   If $s3 <> "menu" Then
      consolewrite("_JAB_menuSelectItem: this element isn't menu" & @CRLF)
      Return
   EndIf
   _JAB_singleAction($vmId, $ac)
   Sleep(250)
   If $item1 <> "" Then
      Local $re1 = -1
      Local $iCount = _JAB_getChildrenCount($vmId, $ac)
      For $i = 0 To $iCount - 1
         Local $ac1 = __getAccessibleChildFromContext($vmId, $ac, $i)
         Local $ac1_s1 = _JAB_getName($vmId, $ac1)
         If StringInStr($ac1_s1, $item1) Then
            _JAB_singleAction($vmId, $ac1)
            Sleep(250)
            $re1 = $ac1
            ExitLoop
         EndIf
      Next
      If $re1 = -1 Then
         consolewrite("_JAB_menuSelectItem: " & $item1 & " is not found" & @CRLF)
         Return
      EndIf
      If $item2 <> "" Then
         Local $re2 = -1
         Local $iCount = _JAB_getChildrenCount($vmId, $re1)
         For $i = 0 To $iCount - 1
            Local $ac2 = __getAccessibleChildFromContext($vmId, $re1, $i)
            Local $ac2_s1 = _JAB_getName($vmId, $ac2)
            If StringInStr($ac2_s1, $item2) Then
               _JAB_singleAction($vmId, $ac2)
               Sleep(250)
               $re2 = $ac2
               ExitLoop
            EndIf
         Next
         If $re2 = -1 Then
            consolewrite("_JAB_menuSelectItem: " & $item2 & " is not found" & @CRLF)
            Return
         EndIf
         If $item3 <> "" Then
            Local $re3 = -1
            Local $iCount = _JAB_getChildrenCount($vmId, $re2)
            For $i = 0 To $iCount - 1
               Local $ac3 = __getAccessibleChildFromContext($vmId, $re2, $i)
               Local $ac3_s1 = _JAB_getName($vmId, $ac3)
               If StringInStr($ac3_s1, $item3) Then
                  _JAB_singleAction($vmId, $ac3)
                  Sleep(250)
                  $re3 = $ac3
                  ExitLoop
               EndIf
            Next
            If $re3 = -1 Then
               consolewrite("_JAB_menuSelectItem: " & $item3 & " is not found" & @CRLF)
               Return
            EndIf
            If $item4 <> "" Then
               Local $re4 = -1
               Local $iCount = _JAB_getChildrenCount($vmId, $re3)
               For $i = 0 To $iCount - 1
                  Local $ac4 = __getAccessibleChildFromContext($vmId, $re3, $i)
                  Local $ac4_s1 = _JAB_getName($vmId, $ac4)
                  If StringInStr($ac4_s1, $item4) Then
                     _JAB_singleAction($vmId, $ac4)
                     Sleep(250)
                     $re4 = $ac4
                     ExitLoop
                  EndIf
               Next
               If $re4 = -1 Then
                  consolewrite("_JAB_menuSelectItem: " & $item4 & " is not found" & @CRLF)
                  Return
               EndIf
               If $item5 <> "" Then
                  Local $re5 = -1
                  Local $iCount = _JAB_getChildrenCount($vmId, $re4)
                  For $i = 0 To $iCount - 1
                     Local $ac5 = __getAccessibleChildFromContext($vmId, $re4, $i)
                     Local $ac5_s1 = _JAB_getName($vmId, $ac5)
                     If StringInStr($ac5_s1, $item5) Then
                        _JAB_singleAction($vmId, $ac5)
                        Sleep(250)
                        $re5 = $ac5
                        ExitLoop
                     EndIf
                  Next
                  If $re5 = -1 Then
                     consolewrite("_JAB_menuSelectItem: " & $item5 & " is not found" & @CRLF)
                     Return
                  EndIf
                  If $item6 <> "" Then
                     Local $re6 = -1
                     Local $iCount = _JAB_getChildrenCount($vmId, $re5)
                     For $i = 0 To $iCount - 1
                        Local $ac6 = __getAccessibleChildFromContext($vmId, $re5, $i)
                        Local $ac6_s1 = _JAB_getName($vmId, $ac6)
                        If StringInStr($ac6_s1, $item6) Then
                           _JAB_singleAction($vmId, $ac6)
                           Sleep(250)
                           $re6 = $ac6
                           ExitLoop
                        EndIf
                     Next
                     If $re6 = -1 Then
                        consolewrite("_JAB_menuSelectItem: " & $item6 & " is not found" & @CRLF)
                        Return
                     EndIf
                  EndIf
               EndIf
            EndIf
         EndIf
      EndIf
   EndIf
EndFunc

;~ combo box-->popup menu-->scroll pane-->viewport-->list-
;~                                      |                 |-->label 0
;~                                      |                 |-->label 1
;~                                      |                 |-->label 2
;~                                      |                 |-->label 3
;~                                      -->scroll bar
Func _JAB_comboBoxSelectItem($vmId, $ac, $listItem)
   Local $s3 = _JAB_getRole($vmId, $ac)
   If $s3 <> "combo box" Then
      consolewrite("_JAB_comboBoxSelectItem: this element isn't combo box" & @CRLF)
      Return
   EndIf
   Local $popup_ac = _JAB_getFirstChildByRole($vmId, $ac, "popup menu")
   If $popup_ac = "" Then
      consolewrite("_JAB_comboBoxSelectItem: popup menu is not found" & @CRLF)
      Return
   EndIf
   Local $scroll_ac = _JAB_getFirstChildByRole($vmId, $popup_ac, "scroll pane")
    If $scroll_ac = "" Then
      consolewrite("_JAB_comboBoxSelectItem: scroll pane is not found" & @CRLF)
      Return
   EndIf
   Local $viewport_ac = _JAB_getFirstChildByRole($vmId, $scroll_ac, "viewport")
   If $viewport_ac = "" Then
      consolewrite("_JAB_comboBoxSelectItem: viewport is not found" & @CRLF)
      Return
   EndIf
   Local $list_ac = _JAB_getFirstChildByRole($vmId, $viewport_ac, "list")
   If $list_ac = "" Then
      consolewrite("_JAB_comboBoxSelectItem: list is not found" & @CRLF)
      Return
   EndIf
   Local $re2 = -1
   Local $iCount = _JAB_getChildrenCount($vmId, $list_ac)
   For $i = 0 To $iCount - 1
      Local $child_ac = __getAccessibleChildFromContext($vmId, $list_ac, $i)
      Local $child_ac_s1 = _JAB_getName($vmId, $child_ac)
      If StringInStr($child_ac_s1 ,$listItem) Then
         $re2 = $i
         ExitLoop
      EndIf
   Next
   If $re2 = -1 Then
      consolewrite("_JAB_comboBoxSelectItem: " & $listItem & " is not found" & @CRLF)
      Return
   EndIf
   __addAccessibleSelectionFromContext($vmId, $ac, $re2)
EndFunc



;~  _fixBridgeFunc(None,'Windows_run')
Func __Windows_run()
    $result = DllCall($hAccessBridgeDll, "NONE", "Windows_run")
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~  _fixBridgeFunc(None,'setFocusGainedFP',c_void_p)
;~  _fixBridgeFunc(None,'setPropertyNameChangeFP',c_void_p)
;~  _fixBridgeFunc(None,'setPropertyDescriptionChangeFP',c_void_p)
;~  _fixBridgeFunc(None,'setPropertyValueChangeFP',c_void_p)
;~  _fixBridgeFunc(None,'setPropertyStateChangeFP',c_void_p)
;~  _fixBridgeFunc(None,'setPropertyCaretChangeFP',c_void_p)
;~  _fixBridgeFunc(None,'setPropertyActiveDescendentChangeFP',c_void_p)

;========================================Initialization/Shutdown Functions==========================================
; Starts Java Access Bridge. You can't use any part of the Java Access Bridge API until you call this function.
Func __initializeAccessBridge()
    $result = DllCall($hAccessBridgeDll, "NONE", "initializeAccessBridge")
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; Shuts down Java Access Bridge.
Func __shutdownAccessBridge()
    $result = DllCall($hAccessBridgeDll, "NONE", "shutdownAccessBridge")
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc


;========================================Gateway Functions=========================================================
;~ BOOL IsJavaWindow(HWND window)
; Checks to see if the given window implements the Java Accessibility API.
Func __isJavaWindow($hwnd)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isJavaWindow", "hwnd", $hwnd)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac)
; Returns the virtual machine ID and AccessibleContext for a top-level window.
Func __getAccessibleContextFromHWND($hwnd, byref $vmID, byref $ac)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextFromHWND", "hwnd", $hwnd, "long*", $vmId, $cP_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    $vmID = $result[2]
    $ac = $result[3]
    Return $result[0]
EndFunc


;========================================General Functions=========================================================
;~ void ReleaseJavaObject(long vmID, Java_Object object)
; Release the memory used by the Java object object, where object is an object returned to you by Java Access Bridge.
Func __releaseJavaObject($vmId, $object)
    $result = DllCall($hAccessBridgeDll, "NONE", "releaseJavaObject", "long", $vmId, $c_JOBJECT64, $object)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info)
; Gets the version information of the instance of Java Access Bridge instance your application is using.
; $tAccessBridgeVersionInfo $info
Func __getVersionInfo($vmId, byref $info)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getVersionInfo", "long", $vmId, "struct*", $info)
    If @error Then Return SetError(1, 0, 0)
    $info = $result[2]
    Return $result[0]
EndFunc


;========================================Accessible Context Functions=========================================================
;~ BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, jint x, jint y, AccessibleContext *ac)
; Retrieves an AccessibleContext object of the window or object that is under the mouse pointer.
Func __getAccessibleContextAt($vmId, $acParent, $x, $y, byref $ac)
;~ Seems not to be allowed to call with null so passing $acParent
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextAt", "long", $vmId, $c_JOBJECT64, $acParent, "int", $x, "int", $y, $cP_JOBJECT64, $ac)
    consolewrite(@error)
    If @error Then Return SetError(1, 0, 0)
    $ac = $result[5]
    Return $result[0]
EndFunc

;~ BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac)
; Retrieves an AccessibleContext object of the window or object that has the focus.
Func __getAccessibleContextWithFocus($hwnd, byref $vmID, byref $ac)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextWithFocus", "hwnd", $hwnd, "long*", $vmId, $cP_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    $vmID = $result[2]
    $ac = $result[3]
    Return $result[0]
EndFunc

;~ BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info)
; Retrieves an AccessibleContextInfo object of the AccessibleContext object ac.
; $tAccessibleContextInfo $info
Func __getAccessibleContextInfo($vmId, $ac, byref $info)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleContextInfo", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $info)
    If @error Then Return SetError(1, 0, 0)
    $info = $result[3]
    Return $result[0]
EndFunc

;~ AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index))
; Returns an AccessibleContext object that represents the nth child of the object ac, where n is specified by the value index.
Func __getAccessibleChildFromContext($vmId, $ac, $index)
;~ Seems not to be allowed to call with null so passing $acParent
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleChildFromContext", "long", $vmId, $c_JOBJECT64, $ac, "int", $index)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac)
; Returns an AccessibleContext object that represents the parent of object ac.
Func __getAccessibleParentFromContext($vmId, $ac)
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleParentFromContext", "long", $vmId, $c_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ HWND getHWNDFromAccessibleContext(long vmID, AccessibleContext ac)
; Returns the HWND from the AccessibleContextof a top-level window.
Func __getHWNDFromAccessibleContext($vmId, $ac)
    $result = DllCall($hAccessBridgeDll, "hwnd", "getHWNDFromAccessibleContext", "long", $vmId, $c_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc


;========================================Accessible Text Functions=========================================================
;~ BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y)
; $tAccessibleTextInfo $textInfo
Func __getAccessibleTextInfo($vmId, $at, byref $textInfo, $x, $y)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextInfo", "long", $vmId, $c_JOBJECT64, $at, "struct*", $textInfo, "int", $x, "int", $y)
    If @error Then Return SetError(1, 0, 0)
    $textInfo = $result[3]
    Return $result[0]
EndFunc

;~ BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index)
; $tAccessibleTextItemsInfo $textItems
Func __getAccessibleTextItems($vmId, $at, byref $textItems, $index)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextItems", "long", $vmId, $c_JOBJECT64, $at, "struct*", $textItems, "int", $index)
    If @error Then Return SetError(1, 0, 0)
    $textItems = $result[3]
    Return $result[0]
EndFunc

;~ BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection)
; $tAccessibleTextSelectionInfo $textSelection
Func __getAccessibleTextSelectionInfo($vmId, $at, byref $textSelection)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextSelectionInfo", "long", $vmId, $c_JOBJECT64, $at, "struct*", $textSelection)
    If @error Then Return SetError(1, 0, 0)
    $textSelection = $result[3]
    Return $result[0]
 EndFunc

;~ BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes)
; $tAccessibleTextAttributesInfo $attributes
Func __getAccessibleTextAttributes($vmId, $at, $index, byref $attributes)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextAttributes", "long", $vmId, $c_JOBJECT64, $at, "int", $index, "struct*", $attributes)
    If @error Then Return SetError(1, 0, 0)
    $attributes = $result[4]
    Return $result[0]
EndFunc

; BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index);
; $tAccessibleTextRectInfo $rectInfo
Func __getAccessibleTextRect($vmId, $at, byref $rectInfo, $index)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextRect", "long", $vmId, $c_JOBJECT64, $at, "struct*", $rectInfo, "int", $index)
    If @error Then Return SetError(1, 0, 0)
    $attributes = $result[3]
    Return $result[0]
EndFunc

;~ BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len)
Func __getAccessibleTextRange($vmId, $at, $start, $end, $text, $len)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextRange", "long", $vmId, $c_JOBJECT64, $at, "int", $start, "int", $end, "wstr", $text, "short", $len)
    If @error Then Return SetError(1, 0, 0)
    $text = $result[5]
    Return $result[0]
EndFunc

;~ BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex)
Func __getAccessibleTextLineBounds($vmId, $at, $index, byref $startIndex, byref $endIndex)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTextLineBounds", "long", $vmId, $c_JOBJECT64, $at, "int", $index, "int*", $startIndex, "int*", $endIndex)
    If @error Then Return SetError(1, 0, 0)
    $startIndex = $result[4]
    $endIndex = $result[5]
    Return $result[0]
EndFunc


;========================================Additional Text Functions=========================================================
;~  _fixBridgeFunc(BOOL,'selectTextRange',c_long,JOBJECT64,c_int,c_int,errcheck=True)
; Selects text between two indices. Selection includes the text at the start index and the text at the end index.
; AccessibleContext $ac
Func __selectTextRange($vmId, $ac, $startIndex, $endIndex)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "selectTextRange", "long", $vmId, $c_JOBJECT64, $ac, "int", $startIndex, "int", $endIndex)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~  _fixBridgeFunc(BOOL,'getTextAttributesInRange',c_long,JOBJECT64,c_int,c_int,POINTER(AccessibleTextAttributesInfo),POINTER(c_short),errcheck=True)
; Get text attributes between two indices. The attribute list includes the text at the start index and the text at the end index.
; AccessibleContext $ac
; $tAccessibleTextAttributesInfo $attributes
Func __getTextAttributesInRange($vmId, $ac, $startIndex, $endIndex, byref $attributes, byref $len)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getTextAttributesInRange", "long", $vmId, $c_JOBJECT64, $ac, "int", $startIndex, "int", $endIndex, "struct*", $attributes, "short*", $len)
    If @error Then Return SetError(1, 0, 0)
    $attributes = $result[5]
    $len = $result[6]
    Return $result[0]
EndFunc

;~  _fixBridgeFunc(BOOL,'setCaretPosition',c_long,JOBJECT64,c_int,errcheck=True)
; Set the caret to a text position.
; AccessibleContext $ac
Func __setCaretPosition($vmId, $ac, $position)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "setCaretPosition", "long", $vmId, $c_JOBJECT64, $ac, "int", $position)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~  _fixBridgeFunc(BOOL,'getCaretLocation',c_long,JOBJECT64,POINTER(AccessibleTextRectInfo),jint,errcheck=True)
; Gets the text caret location.
; AccessibleContext $ac
; $tAccessibleTextRectInfo $rectInfo
Func __getCaretLocation($vmId, $ac, byref $rectInfo, $position)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getCaretLocation", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $position, "int", $position)
    If @error Then Return SetError(1, 0, 0)
    $rectInfo = $result[3]
    Return $result[0]
EndFunc

; BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text)
; Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and be editable. The maximum text length that can be set is MAX_STRING_SIZE - 1. Returns whether successful.
; AccessibleContext $ac
Func __setTextContents($vmId, $ac, $text)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "setTextContents", "long", $vmId, $c_JOBJECT64, $ac, "wstr", $text)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc


;========================================Accessible Table Functions=========================================================
;~ BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo)
; Returns information about the table, for example, caption, summary, row and column count, and the AccessibleTable.
; $tAccessibleTableInfo $tableInfo
Func __getAccessibleTableInfo($vmId, $acParent, byref $tableInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableInfo", "long", $vmId, $c_JOBJECT64, $acParent, "struct*", $tableInfo)
    If @error Then Return SetError(1, 0, 0)
    $tableInfo = $result[3]
    Return $result[0]
EndFunc

;~ BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, jint row, jint column, AccessibleTableCellInfo *tableCellInfo)
; Returns information about the specified table cell. The row and column specifiers are zero-based.
; $tAccessibleTableCellInfo $tableCellInfo
Func __getAccessibleTableCellInfo($vmId, $table, $row, $column, byref $tableCellInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableCellInfo", "long", $vmId, $c_JOBJECT64, $table, "int", $row, "int", $column, "struct*", $tableCellInfo)
    If @error Then Return SetError(1, 0, 0)
    $tableCellInfo = $result[5]
    Return $result[0]
EndFunc

;~ BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo)
; Returns the table row headers of the specified table as a table.
; $tAccessibleTableInfo $tableInfo
Func __getAccessibleTableRowHeader($vmId, $acParent, byref $tableInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableRowHeader", "long", $vmId, $c_JOBJECT64, $acParent, "struct*", $tableInfo)
    If @error Then Return SetError(1, 0, 0)
    $tableInfo = $result[3]
    Return $result[0]
EndFunc

;~ BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo)
; Returns the table column headers of the specified table as a table.
; $tAccessibleTableInfo $tableInfo
Func __getAccessibleTableColumnHeader($vmId, $acParent, byref $tableInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableColumnHeader", "long", $vmId, $c_JOBJECT64, $acParent, "struct*", $tableInfo)
    If @error Then Return SetError(1, 0, 0)
    $tableInfo = $result[3]
    Return $result[0]
EndFunc

;~ AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row)
; Returns the description of the specified row in the specified table. The row specifier is zero-based.
Func __getAccessibleTableRowDescription($vmId, $acParent, $row)
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleTableRowDescription", "long", $vmId, $c_JOBJECT64, $acParent, "int", $row)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column)
; Returns the description of the specified column in the specified table. The column specifier is zero-based.
Func __getAccessibleTableColumnDescription($vmId, $acParent, $column)
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleTableColumnDescription", "long", $vmId, $c_JOBJECT64, $acParent, "int", $column)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table)
; Returns how many rows in the table are selected.
Func __getAccessibleTableRowSelectionCount($vmId, $table)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableRowSelectionCount", "long", $vmId, $c_JOBJECT64, $table)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row)
; Returns true if the specified zero based row is selected.
Func __isAccessibleTableRowSelected($vmId, $table, $row)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isAccessibleTableRowSelected", "long", $vmId, $c_JOBJECT64, $table, "int", $row)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections)
; Returns an array of zero based indices of the selected rows.
Func __getAccessibleTableRowSelections($vmId, $table, $count, byref $selections)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableRowSelections", "long", $vmId, $c_JOBJECT64, $table, "int", $count, "int*", $selections)
    If @error Then Return SetError(1, 0, 0)
    $selections =  $result[4]
    Return $result[0]
EndFunc

; jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table)
; Returns how many columns in the table are selected.
Func __getAccessibleTableColumnSelectionCount($vmId, $table)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableColumnSelectionCount", "long", $vmId, $c_JOBJECT64, $table)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column)
; Returns true if the specified zero based column is selected.
Func __isAccessibleTableColumnSelected($vmId, $table, $column)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isAccessibleTableColumnSelected", "long", $vmId, $c_JOBJECT64, $table, "int", $column)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections)
; Returns an array of zero based indices of the selected columns.
Func __getAccessibleTableColumnSelections($vmId, $table, $count, byref $selections)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleTableColumnSelections", "long", $vmId, $c_JOBJECT64, $table, "int", $count, "int*", $selections)
    If @error Then Return SetError(1, 0, 0)
    $selections =  $result[4]
    Return $result[0]
EndFunc

;~ jint getAccessibleTableRow(long vmID, AccessibleTable table, jint index)
; Returns the row number of the cell at the specified cell index. The values are zero based.
Func __getAccessibleTableRow($vmId, $table, $index)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableRow", "long", $vmId, $c_JOBJECT64, $table, "int", $index)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ jint getAccessibleTableColumn(long vmID, AccessibleTable table, jint index)
; Returns the column number of the cell at the specified cell index. The values are zero based.
Func __getAccessibleTableColumn($vmId, $table, $index)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableColumn", "long", $vmId, $c_JOBJECT64, $table, "int", $index)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ jint getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column)
; Returns the index in the table of the specified row and column offset. The values are zero based.
Func __getAccessibleTableIndex($vmId, $table, $row, $column)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleTableIndex", "long", $vmId, $c_JOBJECT64, $table, "int", $row, "int", $column)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc


;========================================Accessible Relation Set Function=========================================================
;~ BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, AccessibleRelationSetInfo *relationSetInfo)
; Returns information about an object's related objects.
; $tAccessibleRelationInfo $relationSetInfo
Func __getAccessibleRelationSet($vmId, $ac, byref $relationSetInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleRelationSet", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $relationSetInfo)
    If @error Then Return SetError(1, 0, 0)
    $relationSetInfo = $result[3]
    Return $result[0]
EndFunc


;========================================Accessible Hypertext Functions=========================================================
; BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, AccessibleHypertextInfo *hypertextInfo)
; Returns hypertext information associated with a component.
; $tAccessibleHyperlinkInfo $hypertextInfo
Func __getAccessibleHypertext($vmId, $ac, byref $hypertextInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleHypertext", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $hypertextInfo)
    If @error Then Return SetError(1, 0, 0)
    $hypertextInfo = $result[3]
    Return $result[0]
EndFunc

; BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, AccessibleHyperlink accessibleHyperlink)
; Requests that a hyperlink be activated.
Func __activateAccessibleHyperlink($vmId, $ac, $accessibleHyperlink)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "activateAccessibleHyperlink", "long", $vmId, $c_JOBJECT64, $ac, $c_JOBJECT64, $accessibleHyperlink)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; jint getAccessibleHyperlinkCount(const long vmID, const AccessibleHypertext hypertext)
; Returns the number of hyperlinks in a component. Maps to AccessibleHypertext.getLinkCount. Returns -1 on error.
Func __getAccessibleHyperlinkCount($vmId, $hypertext)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleHyperlinkCount", "long", $vmId, $c_JOBJECT64, $hypertext)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; BOOL getAccessibleHypertextExt(const long vmID, const AccessibleContext accessibleContext, const jint nStartIndex, AccessibleHypertextInfo *hypertextInfo)
; Iterates through the hyperlinks in a component. Returns hypertext information for a component starting at hyperlink index nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will be returned for each call to this method. Returns FALSE on error.
; $tAccessibleHyperlinkInfo $hypertextInfo
Func __getAccessibleHypertextExt($vmId, $ac, $nStartIndex, byref $hypertextInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleHypertextExt", "long", $vmId, $c_JOBJECT64, $ac, "int", $nStartIndex, "struct*", $hypertextInfo)
    If @error Then Return SetError(1, 0, 0)
    $hypertextInfo = $result[4]
    Return $result[0]
EndFunc

; jint getAccessibleHypertextLinkIndex(const long vmID, const AccessibleHypertext hypertext, const jint nIndex)
; Returns the index into an array of hyperlinks that is associated with a character index in document. Maps to AccessibleHypertext.getLinkIndex. Returns -1 on error.
Func __getAccessibleHypertextLinkIndex($vmId, $hypertext, $nIndex)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleHypertextLinkIndex", "long", $vmId, $c_JOBJECT64, $hypertext, "int", $nIndex)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; BOOL getAccessibleHyperlink(const long vmID, const AccessibleHypertext hypertext, const jint nIndex, AccessibleHypertextInfo *hyperlinkInfo)
; Returns the nth hyperlink in a document. Maps to AccessibleHypertext.getLink. Returns FALSE on error.
; $tAccessibleHyperlinkInfo $hypertextInfo
Func __getAccessibleHyperlink($vmId, $hypertext, $nIndex, byref $hypertextInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleHyperlink", "long", $vmId, $c_JOBJECT64, $hypertext, "int", $nIndex, "struct*", $hypertextInfo)
    If @error Then Return SetError(1, 0, 0)
    $hypertextInfo = $result[4]
    Return $result[0]
EndFunc


;========================================Accessible Key Binding Function=========================================================
;~ BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, AccessibleKeyBindings *keyBindings)
; Returns a list of key bindings associated with a component.
; $tAccessibleKeyBindings $keyBindings
Func __getAccessibleKeyBindings($vmId, $ac, byref $keyBindings)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleKeyBindings", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $keyBindings)
    If @error Then Return SetError(1, 0, 0)
    $keyBindings = $result[3]
    Return $result[0]
EndFunc


;========================================Accessible Icon Function=========================================================
; BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, AccessibleIcons *icons)
; Returns a list of icons associate with a component.
; $tAccessibleIconInfo $icons
Func __getAccessibleIcons($vmId, $ac, byref $icons)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleIcons", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $icons)
    If @error Then Return SetError(1, 0, 0)
    $icons = $result[3]
    Return $result[0]
EndFunc


;========================================Accessible Action Functions=========================================================
;~ BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, AccessibleActions *actions)
; Returns a list of actions that a component can perform.
; $tAccessibleActions $actions
Func __getAccessibleActions($vmId, $ac, byref $actions)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getAccessibleActions", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $actions)
    If @error Then Return SetError(1, 0, 0)
    $actions = $result[3]
    Return $result[0]
EndFunc

;~ BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, AccessibleActionsToDo *actionsToDo, jint *failure)
; Request that a list of AccessibleActions be performed by a component.
; $tAccessibleActionsToDo $actionsToDo
Func __doAccessibleActions($vmId, $ac, byref $actionsToDo, byref $failure)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "doAccessibleActions", "long", $vmId, $c_JOBJECT64, $ac, "struct*", $actionsToDo,  "int*", $failure)
    If @error Then Return SetError(1, 0, 0)
    $actionsToDo = $result[3]
    $failure = $result[4]
    Return $result[0]
EndFunc


;========================================Utility Functions=========================================================
;~ BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2)
; Returns whether two object references refer to the same object.
Func __isSameObject($vmId, $obj1, $obj2)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isSameObject", "long", $vmId, $c_JOBJECT64, $obj1, $c_JOBJECT64, $obj2)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role)
;Returns the AccessibleContext with the specified role that is the ancestor of a given object. The role is one of the role strings defined in Java Access Bridge API Data Stuctures.
Func __getParentWithRole($vmId, $ac, $role)
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getParentWithRole", "long", $vmId, $c_JOBJECT64, $ac, "wstr", $role)
    If @error Then Return SetError(1, 0, 0)
    $role = $result[3]
    Return $result[0]
EndFunc

; AccessibleContext getParentWithRoleElseRoot(const long vmID, const AccessibleContext accessibleContext, const wchar_t *role);
; Returns the AccessibleContext with the specified role that is the ancestor of a given object. If an object with the specified role does not exist, returns the top level object for the Java Window.
Func __getParentWithRoleElseRoot($vmId, $ac, $role)
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getParentWithRoleElseRoot", "long", $vmId, $c_JOBJECT64, $ac, "wstr", $role)
    If @error Then Return SetError(1, 0, 0)
    $role = $result[3]
    Return $result[0]
EndFunc

;~ AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext)
; Returns the AccessibleContext for the top level object in a Java window.
Func __getTopLevelObject($vmId, $ac)
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getTopLevelObject", "long", $vmId, $c_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ int getObjectDepth (const long vmID, const AccessibleContext accessibleContext)
; Returns how deep in the object hierarchy a given object is. The top most object in the object hierarchy has an object depth of 0. Returns -1 on error.
Func __getObjectDepth($vmId, $ac)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getObjectDepth", "long", $vmId, $c_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext)
; Returns the AccessibleContext of the current ActiveDescendent of an object. This method assumes the ActiveDescendent is the component that is currently selected in a container object.
Func __getActiveDescendent($vmId, $ac)
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getActiveDescendent", "long", $vmId, $c_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext)
; Request focus for a component. Returns whether successful.
Func __requestFocus($vmId, $ac)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "requestFocus", "long", $vmId, $c_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

;~ int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext)
; Returns the number of visible children of a component. Returns -1 on error.
Func __getVisibleChildrenCount($vmId, $ac)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getVisibleChildrenCount", "long", $vmId, $c_JOBJECT64, $ac)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, const int startIndex, VisibleChildrenInfo *visibleChildrenInfo);
; Gets the visible children of an AccessibleContext. Returns whether successful.
; $tVisibleChildenInfo $visibleChildrenInfo
Func __getVisibleChildren($vmId, $ac, $startIndex, byref $visibleChildrenInfo)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getVisibleChildren", "long", $vmId, $c_JOBJECT64, $ac, "int", $startIndex, "struct*", $visibleChildrenInfo)
    If @error Then Return SetError(1, 0, 0)
    $visibleChildrenInfo = $result[4]
    Return $result[0]
EndFunc

; int getEventsWaiting()
; Gets the number of events waiting to fire.
Func __getEventsWaiting()
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getEventsWaiting")
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
 EndFunc


;========================================Accessible Value Functions=========================================================
;~ BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len)
Func __getCurrentAccessibleValueFromContext($vmId, $av, $value, $len)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getCurrentAccessibleValueFromContext", "long", $vmId, $c_JOBJECT64, $av, "wstr", $value, "short", $len)
    If @error Then Return SetError(1, 0, 0)
    $value = $result[3]
    Return $result[0]
EndFunc

; BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_ *value, short len)
Func __getMaximumAccessibleValueFromContext($vmId, $av, $value, $len)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getMaximumAccessibleValueFromContext", "long", $vmId, $c_JOBJECT64, $av, "wstr", $value, "short", $len)
    If @error Then Return SetError(1, 0, 0)
    $value = $result[3]
    Return $result[0]
EndFunc

; BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_ *value, short len)
Func __getMinimumAccessibleValueFromContext($vmId, $av, $value, $len)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "getMinimumAccessibleValueFromContext", "long", $vmId, $c_JOBJECT64, $av, "wstr", $value, "short", $len)
    If @error Then Return SetError(1, 0, 0)
    $value = $result[3]
    Return $result[0]
EndFunc


;========================================Accessible Selection Functions=========================================================
; void AddAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i)
Func __addAccessibleSelectionFromContext($vmId, $as, $i)
    $result = DllCall($hAccessBridgeDll, "NONE", "addAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as, "int", $i)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; void ClearAccessibleSelectionFromContext(long vmID, AccessibleSelection as)
Func __clearAccessibleSelectionFromContext($vmId, $as)
    $result = DllCall($hAccessBridgeDll, "NONE", "clearAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; jobject GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i)
Func __getAccessibleSelectionFromContext($vmId, $as, $i)
    $result = DllCall($hAccessBridgeDll, "ptr:cdecl", "getAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as, "int", $i)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as)
Func __getAccessibleSelectionCountFromContext($vmId, $as)
    $result = DllCall($hAccessBridgeDll, "int:cdecl", "getAccessibleSelectionCountFromContext", "long", $vmId, $c_JOBJECT64, $as)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i)
Func __isAccessibleChildSelectedFromContext($vmId, $as, $i)
    $result = DllCall($hAccessBridgeDll, "bool:cdecl", "isAccessibleChildSelectedFromContext", "long", $vmId, $c_JOBJECT64, $as, "int", $i)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i)
Func __removeAccessibleSelectionFromContext($vmId, $as, $i)
    $result = DllCall($hAccessBridgeDll, "NONE", "removeAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as, "int", $i)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

; void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as)
Func __selectAllAccessibleSelectionFromContext($vmId, $as)
    $result = DllCall($hAccessBridgeDll, "NONE", "selectAllAccessibleSelectionFromContext", "long", $vmId, $c_JOBJECT64, $as)
    If @error Then Return SetError(1, 0, 0)
    Return $result[0]
EndFunc

 

Edited by fablecao
grammar check
Link to post
Share on other sites

fablecao, Most active members currently seem to be much more chit-chatting guys than coding guys. For you, it seems to be the reverse. I like that. But will you please explain in a few words what you are doing? However, it looks interesting.

Link to post
Share on other sites
28 minutes ago, LarsJ said:

fablecao, Most active members currently seem to be much more chit-chatting guys than coding guys. For you, it seems to be the reverse. I like that. But will you please explain in a few words what you are doing? However, it looks interesting.

My English is not so good.

My code is written according to the Java Access Bridge Interface strictly. The Oracle official Document is not detailed enough. So the struct definition is written according to AccessBridgePackages.h, the data definition and function definition is written according to AccessBridgeCalls.h. If you installed accessbridge2_0_2, you will find these two files in src/include directory.

During these two parts of coding , the data type conversion is the most confusing work.

Firstly, according to AccessBridgeCalls.h, all these data type are same. In Autoit, it is "UINT64".

    typedef JOBJECT64 AccessibleContext;
    typedef JOBJECT64 AccessibleText;
    typedef JOBJECT64 AccessibleValue;
    typedef JOBJECT64 AccessibleSelection;
    typedef JOBJECT64 Java_Object;
    typedef JOBJECT64 PropertyChangeEvent;
    typedef JOBJECT64 FocusEvent;
    typedef JOBJECT64 CaretEvent;
    typedef JOBJECT64 MouseEvent;
    typedef JOBJECT64 MenuEvent;
    typedef JOBJECT64 AccessibleTable;
    typedef JOBJECT64 AccessibleHyperlink;
    typedef JOBJECT64 AccessibleHypertext;

Secondly, how to definite a struct in struct.  The C interface code:

******************************************************
*  AccessibleAction packages
******************************************************
*/
#define MAX_ACTION_INFO 256
#define MAX_ACTIONS_TO_DO 32

    // an action assocated with a component
    typedef struct AccessibleActionInfoTag {
    wchar_t name[SHORT_STRING_SIZE];    // action name
    } AccessibleActionInfo;

    // all of the actions associated with a component
    typedef struct AccessibleActionsTag {
    jint actionsCount;        // number of actions
    AccessibleActionInfo actionInfo[MAX_ACTION_INFO];    // the action information
    } AccessibleActions;

    // struct for requesting the actions associated with a component
    typedef struct GetAccessibleActionsPackageTag {
    long vmID;
    JOBJECT64 accessibleContext;                    // the component
    AccessibleActions rAccessibleActions;        // the actions
    } GetAccessibleActionsPackage;

    // list of AccessibleActions to do
    typedef struct AccessibleActionsToDoTag {
    jint actionsCount;                // number of actions to do
    AccessibleActionInfo actions[MAX_ACTIONS_TO_DO];// the accessible actions to do
    } AccessibleActionsToDo;

    // struct for sending an message to do one or more actions
    typedef struct DoAccessibleActionsPackageTag {
    long vmID;                        // the virtual machine ID
    JOBJECT64 accessibleContext;        // component to do the action
    AccessibleActionsToDo actionsToDo;// the accessible actions to do
    BOOL rResult;                   // action return value
    jint failure;                    // index of action that failed if rResult is FALSE
    } DoAccessibleActionsPackage;

We just need to implement three of them in Autoit:

;=====================================AccessibleAction================================
Global Const $MAX_ACTION_INFO = 256
Global Const $MAX_ACTIONS_TO_DO = 32

Global Const $tagAccessibleActionInfo = _
"WCHAR name[256]"

Local $tag_ActionInfo = ""
For $i = 1 To 256
   If $tag_ActionInfo = "" Then
      $tag_ActionInfo = $tagAccessibleActionInfo
   Else
      $tag_ActionInfo = $tag_ActionInfo & ";" & $tagAccessibleActionInfo
   EndIf
Next
Global Const $tagAccessibleActions = _
"INT actionsCount;" & _
$tag_ActionInfo                        ; $tAccessibleActionInfo actionInfo[256]

Local $tag_Actions = ""
For $i = 1 To 32
   If $tag_Actions = "" Then
      $tag_Actions = $tagAccessibleActionInfo
   Else
      $tag_Actions = $tag_Actions & ";" & $tagAccessibleActionInfo
   EndIf
Next
Global Const $tagAccessibleActionsToDo = _
"INT actionsCount;" & _
$tag_Actions                            ; $tAccessibleActions actions[32]

Thirdly, how to set the data type in DllCall function. If  it returns an object, you should use "ptr:cdecl". If the variable is kind of struct such as 'AccessibleContextInfo *info', you should use '"struct*", $info'. If the variable is string such as 'wchar_t *text', you should use '"wstr", $text'. Because in C, a string is an array of char, you must use it's pointer to access it.

In the middle of the code, I write some _JAB function to implement some frequently used functions. The most important function is:

Func _JAB_getAccessibleContextByFindAll($vmId, $ac, $sName, $sRole)
   Local $find_ac = 0
   Local $iCount =_JAB_getChildrenCount($vmId, $ac)
   If $iCount = 0 Then
      Return
   EndIf
   For $i = 0 To $iCount - 1
      Local $child_ac = __getAccessibleChildFromContext($vmId, $ac, $i)
      Local $s1 = _JAB_getName($vmId, $child_ac)
      Local $s3 = _JAB_getRole($vmId, $child_ac)
;      consolewrite($child_ac & "|" & $s1 & "," & $s3 & @CRLF)
      If $s1 = $sName And $s3 = $sRole Then
         $find_ac = $child_ac
         ExitLoop
      Else
         If $find_ac = 0 Then
            $find_ac = _JAB_getAccessibleContextByFindAll($vmId, $child_ac, $sName, $sRole)
         EndIf
      EndIf
   Next
   Return $find_ac
EndFunc

Due to the lacking of element searching tools in java element tree, I write this recursive function.

Link to post
Share on other sites
  • 1 month later...
On 4/7/2019 at 1:08 PM, fablecao said:

My English is not so good.

My code is written according to the Java Access Bridge Interface strictly. The Oracle official Document is not detailed enough. So the struct definition is written according to AccessBridgePackages.h, the data definition and function definition is written according to AccessBridgeCalls.h. If you installed accessbridge2_0_2, you will find these two files in src/include directory.

During these two parts of coding , the data type conversion is the most confusing work.

Firstly, according to AccessBridgeCalls.h, all these data type are same. In Autoit, it is "UINT64".

Secondly, how to definite a struct in struct.  The C interface code:

Thirdly, how to set the data type in DllCall function. If  it returns an object, you should use "ptr:cdecl". If the variable is kind of struct such as 'AccessibleContextInfo *info', you should use '"struct*", $info'. If the variable is string such as 'wchar_t *text', you should use '"wstr", $text'. Because in C, a string is an array of char, you must use it's pointer to access it.


Thank you for contributing to this, also for posting the .au3 template.

Would it be too much to ask if you could post an example of a .au3 that runs few example commands (Clicks, get/set values) on some app? like the javacpl.exe app for example, can you simulate some actions like clicking the security tab and adding an exception URL or something? Thanks alot!

Link to post
Share on other sites
On 6/4/2019 at 7:44 AM, sn1kzZ said:


Thank you for contributing to this, also for posting the .au3 template.

Would it be too much to ask if you could post an example of a .au3 that runs few example commands (Clicks, get/set values) on some app? like the javacpl.exe app for example, can you simulate some actions like clicking the security tab and adding an exception URL or something? Thanks alot!

Access Bridge Explorer is a Windows application that allows exploring, as well as interacting with, the Accessibility tree of any Java applications that uses the Java Access Bridge to expose their accessibility features

Access Bridge Explorer provides features similar to the Java Ferret and Java Monkey sample applications that were distributed as part of the Java Access Bridge SDK when it was still distributed as a stand alone download.

The Access Bridge Explorer application requires

  • Windows 7 or later
  • .NET 4.0 or later
  • A version of the Java JRE/JDK that contains the Java Access Bridge, e.g. Java SE Runtime Environment (JRE) Release 7 Update 6 (7u6) and later. It also works with earlier versions if the standalone Java Access Bridge SDK has been installed.

https://github.com/google/access-bridge-explorer

 

In my .au3, the _JAB functions are examples in themselves. 

Function _JAB_setValue demonstrates how to use actions: create structure actions, get actionsCount, find two useful actions, create structure actionsToDo, put actionsCount and two actions into this structure, execute the actions.

If an ac has only one action such as button click, you can use _JAB_singleAction.

Link to post
Share on other sites
On 6/10/2019 at 9:13 AM, fablecao said:

Access Bridge Explorer is a Windows application that allows exploring, as well as interacting with, the Accessibility tree of any Java applications that uses the Java Access Bridge to expose their accessibility features

Access Bridge Explorer provides features similar to the Java Ferret and Java Monkey sample applications that were distributed as part of the Java Access Bridge SDK when it was still distributed as a stand alone download.

The Access Bridge Explorer application requires

  • Windows 7 or later
  • .NET 4.0 or later
  • A version of the Java JRE/JDK that contains the Java Access Bridge, e.g. Java SE Runtime Environment (JRE) Release 7 Update 6 (7u6) and later. It also works with earlier versions if the standalone Java Access Bridge SDK has been installed.

https://github.com/google/access-bridge-explorer

 

In my .au3, the _JAB functions are examples in themselves. 

Function _JAB_setValue demonstrates how to use actions: create structure actions, get actionsCount, find two useful actions, create structure actionsToDo, put actionsCount and two actions into this structure, execute the actions.

If an ac has only one action such as button click, you can use _JAB_singleAction.

Ok but i don't understand what syntax to use...

Here's what I do:
1. Launch javacpl.exe and use JavaAccessBridge to spy on this button
image.png.79d7a19a4e341743a2a347bbc443f2d2.png

 

I get this in JAB window:
image.thumb.png.a6bdbb47e9bd09f75b64bb85a650d85c.png

So then I just write this simple script (Obviously wrong, hopefully you can correct me)

#include "JavaUI.au3"


WinActivate("Java Control Panel")
sleep(500)
_JAB_singleAction("push button: Edit Site List...", "click")

(JavaUI.au3 = Your _Jab script) I'm sure I'm not the only one not able to understand the full picture, appreciate any help in advance.

Edited by sn1kzZ
Link to post
Share on other sites
  • 3 weeks later...
On 6/17/2019 at 10:16 PM, sn1kzZ said:

Ok but i don't understand what syntax to use...

Here's what I do:
1. Launch javacpl.exe and use JavaAccessBridge to spy on this button
image.png.79d7a19a4e341743a2a347bbc443f2d2.png

 

I get this in JAB window:
image.thumb.png.a6bdbb47e9bd09f75b64bb85a650d85c.png

So then I just write this simple script (Obviously wrong, hopefully you can correct me)

#include "JavaUI.au3"


WinActivate("Java Control Panel")
sleep(500)
_JAB_singleAction("push button: Edit Site List...", "click")

(JavaUI.au3 = Your _Jab script) I'm sure I'm not the only one not able to understand the full picture, appreciate any help in advance.

global $wintitle = "Java Control Panel"

$winHandle = WinActivate($wintitle)

$result = __isJavaWindow($winHandle)

Global $vmId
Global $ac

global $sName = "Edit Site List..."
global $sRole = "push button"

__getAccessibleContextFromHWND($winHandle, $vmID, $ac)

$re_ac = _JAB_getAccessibleContextByFindAll($vmId, $ac, $sName, $sRole)

_JAB_singleAction($vmId, $re_ac)

Link to post
Share on other sites

One JAVA program has one vmID, every element in this program has its own ac (accessible context).

You can manipulate an element by vmID and its unique ac.

Function __getAccessibleContextFromHWND can acquire vmID and ac from a window’s handle.

Before use this handle, you must use function __isJavaWindow to check whether it is or not a java window.

And then, you can use its unique combination of name and role to find an element's ac by functon _JAB_getAccessibleContextByFindAll.

Link to post
Share on other sites
  • 1 month later...
global $wintitle = "Java Control Panel"

$winHandle = WinActivate($wintitle)

$result = __isJavaWindow($winHandle)

Global $vmId
Global $ac

global $sName = "Edit Site List..."
global $sRole = "push button"

__getAccessibleContextFromHWND($winHandle, $vmID, $ac)

$re_ac = _JAB_getAccessibleContextByFindAll($vmId, $ac, $sName, $sRole)

_JAB_singleAction($vmId, $re_ac)

Very good code above worked very well, but when you click a button and open a window with that click, the click is locked until you finish this window would you avoid it?

Could you click and fill in the id field? What would that look like?

Link to post
Share on other sites
Thanks for the answer, but it’s not serious in terms of coordinates: the window size and resolution may change.
There are some code snippets in recent posts: FindAll, singleAction
and etc.
I would like an example if this method has a chance to be used.
 
Link to post
Share on other sites

Whats wrong with the click on sitelist example?

If you do not want blocking actions you can only bypass with mousemove mouseclick commands and doiing some math with desktop height width etc. And yes this can be more work but changing xy is just as terrible to manage then changing labelnames. Before you run on xy you can set desktop, window size and dpi to a known value or recalculate you xy based on percentage of scaling.

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...