Very confused about AccViewer.ahk

Get help with using AutoHotkey and its commands and hotkeys
drizzt
Posts: 31
Joined: 20 Apr 2018, 20:44

Very confused about AccViewer.ahk

10 May 2018, 20:08

I am using AccViewer.ahk as it seems to be the closest to what I am looking for to accomplish a certain task.
https://autohotkey.com/boards/viewtopic.php?t=26201
However I am confused as I am new to AHK.

when I move the cursor to a treeview Does this script recursively go through every item in the tree and store the Accessible info from that item somewhere? If not, then how can I modify this script to store all accessible info of every item in the tree into an array.

for example say I have a Class(NN) of type SysTreeView321 that has a bunch of child objects, grand child objects etc. Is there a way I can store the accessible info of all of these objects in an array,

ie I want to store the name and location of all objects from a treeview into an array.
AHKStudent
Posts: 877
Joined: 05 May 2018, 12:23

Re: Very confused about AccViewer.ahk

10 May 2018, 20:19

I would start by looking at Jeeswg's work here https://autohotkey.com/boards/viewtopic.php?t=40590

Yes, it can be done.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Very confused about AccViewer.ahk

10 May 2018, 20:37

- For treeview controls, I would try JEE_TVGetText, and possibly JEE_AccGetTextAll.
GUIs via DllCall: get/set internal/external control text - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=40514
- AccViewer can retrieve and display information, but it doesn't give you an easy way to export all of that data AFAICS.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
drizzt
Posts: 31
Joined: 20 Apr 2018, 20:44

Re: Very confused about AccViewer.ahk

11 May 2018, 19:42

jeeswg wrote:- For treeview controls, I would try JEE_TVGetText, and possibly JEE_AccGetTextAll.
GUIs via DllCall: get/set internal/external control text - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=40514
- AccViewer can retrieve and display information, but it doesn't give you an easy way to export all of that data AFAICS.

OK I tried the example on a tree

Code: Select all

q:: ;Notepad - get Acc info (window)
WinGet, hWnd, ID, A
MsgBox, % Clipboard := JEE_AccGetTextAll(hWnd, "`r`n")

and it does work (except it doesnt get the position info)

But when I click OK on the window, another window Pops up with This error
https://imgur.com/a/SRdR13H
drizzt
Posts: 31
Joined: 20 Apr 2018, 20:44

Re: Very confused about AccViewer.ahk

12 May 2018, 15:33

Also I modified JEE_AccGetTextAll function to add location info. but its not working The location is always empty

Code: Select all

if IsObject(oKey)
		{
			vRoleText := Acc_GetRoleText(oKey.accRole(0))
			try vName := oKey.accName(0)
			try vValue := oKey.accValue(0)
			try vPos :=Acc_Location(oKey)}
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Very confused about AccViewer.ahk

12 May 2018, 15:48

- Here's how I get the window position via Acc:
AccViewer Basic - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=32039

Code: Select all

oRect := Acc_Location(oAcc, vChildId)
vAccLocation := Format("X{} Y{} W{} H{}", oRect.x, oRect.y, oRect.w, oRect.h)
- For your error you could use:
try and catch
or
ComObjError(False) and ComObjError(True).
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
drizzt
Posts: 31
Joined: 20 Apr 2018, 20:44

Re: Very confused about AccViewer.ahk

12 May 2018, 23:14

Where in the JEE_AccGetTextAll function do I add this code? I have tried many different places and every time the location is always 48,48,48

I am using this to display location

Code: Select all

vOutput .= vAccPath "`t" JEE_StrRept(vIndent, vLevel-1) vRoleText " [" vName "][" vValue "]" "][" vAccLocation "]"vSep

Here is the full code. I have a tree and press q when I am in the tree. the result is 48,48,48 for location of all tree objects

Code: Select all

#Include Acc.ahk
q:: ;Notepad - get Acc info (window)
WinGet, hWnd, ID, A
MsgBox, % Clipboard := JEE_AccGetTextAll(hWnd, "`r`n")
return

e::
;Edit control info is: 4.1.4
;the acc path will be 4.1.4
;and we will use 0 with accValue()
oAcc := Acc_Get("Object", "4.1.4", 0, "ahk_id " hWnd)
MsgBox, % oAcc.accValue(0)
oAcc := ""
return

;status bar info is: 4.2.4 c2
;the acc path will be 4.2.4
;and we will use 2 with accName()
oAcc := Acc_Get("Object", "4.2.4", 0, "ahk_id " hWnd)
MsgBox, % oAcc.accName(2)
oAcc := ""
return

w:: ;Notepad - get Acc info (controls)
ControlGet, hCtl1, Hwnd,, Edit1, A
ControlGet, hCtl2, Hwnd,, msctls_statusbar321, A
MsgBox, % Clipboard := JEE_AccGetTextAll(hCtl1, "`r`n")
MsgBox, % Clipboard := JEE_AccGetTextAll(hCtl2, "`r`n")

return

;Edit control info is: 4
;the acc path will be 4
;and we will use 0 with accValue()
oAcc := Acc_Get("Object", "4", 0, "ahk_id " hCtl1)
MsgBox, % oAcc.accValue(0)
oAcc := ""

;status bar info is: 4 c2
;the acc path will be 4
;and we will use 2 with accName()
oAcc := Acc_Get("Object", "4", 0, "ahk_id " hCtl2)
MsgBox, % oAcc.accName(2)
oAcc := ""
return

;==================================================

JEE_StrRept(vText, vNum)
{
	if (vNum <= 0)
		return
	return StrReplace(Format("{:" vNum "}", ""), " ", vText)
	;return StrReplace(Format("{:0" vNum "}", 0), 0, vText)
}

;==================================================

; ;e.g.
; q::
; WinGet, hWnd, ID, A
; MsgBox, % Clipboard := JEE_AccGetTextAll(hWnd, "`r`n")
; return

; ;e.g.
; q::
; ControlGet, hCtl, Hwnd,, Edit1, A
; MsgBox, % Clipboard := JEE_AccGetTextAll(hCtl, "`r`n")
; return

; ;e.g.
; q::
; ControlGetFocus, vCtlClassNN, A
; ControlGet, hCtl, Hwnd,, % vCtlClassNN, A
; MsgBox, % Clipboard := JEE_AccGetTextAll(hCtl, "`r`n")
; return

;vOpt: space-separated list
;vOpt: n#: e.g. n20 ;limit retrieve name to first 20 characters
;vOpt: v#: e.g. v20 ;limit retrieve value to first 20 characters

JEE_AccGetTextAll(hWnd:=0, vSep:="`n", vIndent:="`t", vOpt:="")
{
	vLimN := 20, vLimV := 20
	Loop, Parse, vOpt, % " "
	{
		vTemp := A_LoopField
		if (SubStr(vTemp, 1, 1) = "n")
			vLimN := SubStr(vTemp, 2)
		else if (SubStr(vTemp, 1, 1) = "v")
			vLimV := SubStr(vTemp, 2)
	}
	
	oMem := {}, oPos := {}
	;OBJID_WINDOW := 0x0
	oMem[1, 1] := Acc_ObjectFromWindow(hWnd, 0x0)
	oPos[1] := 1, vLevel := 1
	VarSetCapacity(vOutput, 1000000*2)
	
	Loop
	{
		if !vLevel
			break
		if !oMem[vLevel].HasKey(oPos[vLevel])
		{
			oMem.Delete(vLevel)
			oPos.Delete(vLevel)
			vLevelLast := vLevel, vLevel -= 1
			oPos[vLevel]++
			continue
		}
		oKey := oMem[vLevel, oPos[vLevel]]
		
		vName := "", vValue := ""
		
		
		
		if IsObject(oKey)
		{
			vRoleText := Acc_GetRoleText(oKey.accRole(0))
			try vName := oKey.accName(0)
			try vValue := oKey.accValue(0)
			try vPos :=Acc_Location(oKey)
			
			
			
			
			
		}
		else
		{
			oParent := oMem[vLevel-1,oPos[vLevel-1]]
			vChildId := IsObject(oKey) ? 0 : oPos[vLevel]
			vRoleText := Acc_GetRoleText(oParent.accRole(vChildID))
			try vName := oParent.accName(vChildID)
			try vValue := oParent.accValue(vChildID)
			
			
			
			
			
			
		}
		
		
		
		
		if (StrLen(vName) > vLimN)
			vName := SubStr(vName, 1, vLimN) "..."
		if (StrLen(vValue) > vLimV)
			vValue := SubStr(vValue, 1, vLimV) "..."
		vName := RegExReplace(vName, "[`r`n]", " ")
		vValue := RegExReplace(vValue, "[`r`n]", " ")
		
		
		
		
		
				;;;;;;;;
		oRect := Acc_Location(oAcc, vChildId)
		vAccLocation := Format("X{} Y{} W{} H{}", oRect.x, oRect.y, oRect.w, oRect.h)
		
		FileAppend,
			(
			Date:%vAccLocation%
			), File.txt
			;;;;;;;;
		
		
		
		
		vAccPath := ""
		if IsObject(oKey)
		{
			Loop, % oPos.Length() - 1
				vAccPath .= (A_Index=1?"":".") oPos[A_Index+1]
		}
		else
		{
			Loop, % oPos.Length() - 2
				vAccPath .= (A_Index=1?"":".") oPos[A_Index+1]
			vAccPath .= " c" oPos[oPos.Length()]
		}
		vOutput .= vAccPath "`t" JEE_StrRept(vIndent, vLevel-1) vRoleText " [" vName "][" vValue "]" "][" vAccLocation "]"vSep
		
		oChildren := Acc_Children(oKey)
		if !oChildren.Length()
			oPos[vLevel]++
		else
		{
			vLevelLast := vLevel, vLevel += 1
			oMem[vLevel] := oChildren
			oPos[vLevel] := 1
		}
	}
	return SubStr(vOutput, 1, -StrLen(vSep))
}
drizzt
Posts: 31
Joined: 20 Apr 2018, 20:44

Re: Very confused about AccViewer.ahk

13 May 2018, 22:16

OK I think I figured it out

Code: Select all

oRect := Acc_Location(oParent, vChildId)
DRocks
Posts: 559
Joined: 08 May 2018, 10:20

Re: Very confused about AccViewer.ahk

20 Sep 2019, 20:24

Code: Select all

;jeeSwg wrote:
oRect := Acc_Location(oAcc, vChildId)
vAccLocation := Format("X{} Y{} W{} H{}", oRect.x, oRect.y, oRect.w, oRect.h)
Acc_Location returns positions on SCREEN by default but,
is there a way to return the location of a control relative to its parent window or do we have to manually calculate those relative values ?
Its not that hard to calculate but I am just curious if there's a more elegant built-in Acc.ahk way of doing this calculation

For reference here's my hacky solution right now:

Code: Select all

	;Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="")
	oAcc:= Acc_Get("Object", "4.1", 0 , "ahk_id "hSageTable) ; En-tetes colonnes Sage Table
	colCount:=oAcc.accChildCount
	Loop, %colCount% 
	{
		oSageTableHeader:= Acc_Get("Object", "4.1."A_Index, 0, "ahk_id "hSageTable)
		;MsgBox % "accName: "oSageTableHeader.accName(0) "`naccValue: "oSageTableHeader.accValue(0)
		oColName:=RegExReplace(oSageTableHeader.accName(0), "\W") ; remove non-word chars
		%oColName%:= Acc_Location(oSageTableHeader, %A_Index%)
		;MsgBox % "oColName: "oColName "`nColScreenRelativePos: x"%oColName%.x
		
		; convert to WindowRelative
		%oColName%.x -= winX
		%oColName%.y -= winY
	}
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Very confused about AccViewer.ahk

22 Oct 2019, 06:43

The Acc_Location function uses the accLocation method, and that returns screen coordinates:
IAccessible::accLocation (oleacc.h) | Microsoft Docs
https://docs.microsoft.com/en-us/windows/win32/api/oleacc/nf-oleacc-iaccessible-acclocation

You'd have to convert any coordinates yourself. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: AHKStudent, Bing [Bot], boiler, hisrRB57, Raymond888, Smile_, teadrinker, ziwzih and 53 guests