Page 1 of 1

AccViewer Basic

Posted: 20 May 2017, 18:24
by jeeswg
A no-frills AccViewer. Information is presented in a ToolTip. Note: currently it does not retrieve path/hierarchy information.

The purpose of this script is to make using and retrieving information via the Acc library easier to understand. Also it might be used by me as a basis for an AccViewer rewrite.

Acc library (MSAA) and AccViewer download links - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

It originated here:
Can I detect mouse over window title? - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=31119

Code: Select all

q:: ;get information from object under cursor, 'AccViewer Basic' (cf. AccViewer.ahk)
ComObjError(False)
oAcc := Acc_ObjectFromPoint(vChildId)
vAccRoleNum := oAcc.accRole(vChildId)
vAccRoleNumHex := Format("0x{:X}", vAccRoleNum)
vAccStateNum := oAcc.accState(vChildId)
vAccStateNumHex := Format("0x{:X}", vAccStateNum)
oRect := Acc_Location(oAcc, vChildId)

vAccName := oAcc.accName(vChildId)
vAccValue := oAcc.accValue(vChildId)
vAccRoleText := Acc_GetRoleText(oAcc.accRole(vChildId))
vAccStateText := Acc_GetStateText(oAcc.accState(vChildId))
vAccStateTextAll := JEE_AccGetStateTextAll(vAccStateNum)
vAccAction := oAcc.accDefaultAction(vChildId)
vAccFocus := oAcc.accFocus
vAccSelection := JEE_AccSelection(oAcc)
StrReplace(vAccSelection, ",",, vCount), vCount += 1
vAccSelectionCount := (vAccSelection = "") ? 0 : vCount
vAccChildCount := oAcc.accChildCount
vAccLocation := Format("X{} Y{} W{} H{}", oRect.x, oRect.y, oRect.w, oRect.h)
vAccDescription := oAcc.accDescription(vChildId)
vAccKeyboard := oAcc.accKeyboardShortCut(vChildId)
vAccHelp := oAcc.accHelp(vChildId)
vAccHelpTopic := oAcc.accHelpTopic(vChildId)
hWnd := Acc_WindowFromObject(oAcc)
vAccPath := "--" ;not implemented
oAcc := ""
ComObjError(True)

;get window/control details
if (hWndParent := DllCall("user32\GetParent", Ptr,hWnd, Ptr))
{
	WinGetTitle, vWinTitle, % "ahk_id " hWndParent
	ControlGetText, vWinText,, % "ahk_id " hWnd
	WinGetClass, vWinClass, % "ahk_id " hWnd

	;control hWnd to ClassNN
	WinGet, vCtlList, ControlList, % "ahk_id " hWndParent
	Loop, Parse, vCtlList, `n
	{
		ControlGet, hCtl, Hwnd,, % A_LoopField, % "ahk_id " hWndParent
		if (hCtl = hWnd)
		{
			vWinClass := A_LoopField
			break
		}
	}
	ControlGetPos, vPosX, vPosY, vPosW, vPosH,, % "ahk_id " hWnd
	WinGet, vPName, ProcessName, % "ahk_id " hWndParent
	WinGet, vPID, PID, % "ahk_id " hWndParent
}
else
{
	WinGetTitle, vWinTitle, % "ahk_id " hWnd
	WinGetText, vWinText, % "ahk_id " hWnd
	WinGetClass, vWinClass, % "ahk_id " hWnd
	WinGetPos, vPosX, vPosY, vPosW, vPosH, % "ahk_id " hWnd
	WinGet, vPName, ProcessName, % "ahk_id " hWnd
	WinGet, vPID, PID, % "ahk_id " hWnd
}
hWnd := Format("0x{:X}", hWnd)
vWinPos := Format("X{} Y{} W{} H{}", vPosX, vPosY, vPosW, vPosH)

;truncate variables with long text
vList := "vWinText,vAccName,vAccValue"
Loop, Parse, vList, % ","
{
	%A_LoopField% := StrReplace(%A_LoopField%, "`r", " ")
	%A_LoopField% := StrReplace(%A_LoopField%, "`n", " ")
	if (StrLen(%A_LoopField%) > 100)
		%A_LoopField% := SubStr(%A_LoopField%, 1, 100) "..."
}

vOutput = ;continuation section
(
Name: %vAccName%
Value: %vAccValue%
Role: %vAccRoleText% (%vAccRoleNumHex%) (%vAccRoleNum%)
State: %vAccStateText% (%vAccStateNumHex%)
State (All): %vAccStateTextAll%
Action: %vAccAction%
Focused Item: %vAccFocus%
Selected Items: %vAccSelection%
Selection Count: %vAccSelectionCount%
Child Count: %vAccChildCount%

Location: %vAccLocation%
Description: %vAccDescription%
Keyboard: %vAccKeyboard%
Help: %vAccHelp%
HelpTopic: %vAccHelpTopic%

Child ID: %vChildId%
Path: %vAccPath%

WinTitle: %vWinTitle%
Text: %vWinText%
HWnd: %hWnd%
Location: %vWinPos%
Class(NN): %vWinClass%
Process: %vPName%
Proc ID: %vPID%
)
ToolTip, % vOutput
return

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

JEE_AccGetStateTextAll(vState)
{
	;sources: WinUser.h, oleacc.h
	;e.g. STATE_SYSTEM_SELECTED := 0x2
	static oArray := {0x1:"UNAVAILABLE"
	, 0x2:"SELECTED"
	, 0x4:"FOCUSED"
	, 0x8:"PRESSED"
	, 0x10:"CHECKED"
	, 0x20:"MIXED"
	, 0x40:"READONLY"
	, 0x80:"HOTTRACKED"
	, 0x100:"DEFAULT"
	, 0x200:"EXPANDED"
	, 0x400:"COLLAPSED"
	, 0x800:"BUSY"
	, 0x1000:"FLOATING"
	, 0x2000:"MARQUEED"
	, 0x4000:"ANIMATED"
	, 0x8000:"INVISIBLE"
	, 0x10000:"OFFSCREEN"
	, 0x20000:"SIZEABLE"
	, 0x40000:"MOVEABLE"
	, 0x80000:"SELFVOICING"
	, 0x100000:"FOCUSABLE"
	, 0x200000:"SELECTABLE"
	, 0x400000:"LINKED"
	, 0x800000:"TRAVERSED"
	, 0x1000000:"MULTISELECTABLE"
	, 0x2000000:"EXTSELECTABLE"
	, 0x4000000:"ALERT_LOW"
	, 0x8000000:"ALERT_MEDIUM"
	, 0x10000000:"ALERT_HIGH"
	, 0x20000000:"PROTECTED"
	, 0x40000000:"HASPOPUP"}
	vNum := 1
	Loop, 30
	{
		if vState & vNum
			vOutput .= oArray[vNum] " "
		vNum <<= 1 ;multiply by 2
	}
	vOutput := RTrim(vOutput)
	return Format("{:L}", vOutput)
}

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

JEE_AccSelection(oAcc)
{
	vSel := oAcc.accSelection ;if one item selected, gets index, if multiple items selected, gets indexes as object
	if IsObject(vSel)
	{
		oSel := vSel, vSel := ""
		while oSel.Next(vValue, vType)
			vSel .= (A_Index=1?"":",") vValue
		oSel := ""
	}
	return vSel
}

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

Re: AccViewer Basic

Posted: 27 Aug 2017, 16:21
by jeeswg
ACC: ROLE NUMBERS AND ROLE TEXT

Using the role number instead of the role text in scripts, makes them more compatible internationally.

Code: Select all

role numbers and role text (English):
0	unknown object
1	title bar
2	menu bar
3	scroll bar
4	grip
5	sound
6	cursor
7	caret
8	alert
9	window
10	client
11	popup menu
12	menu item
13	tool tip
14	application
15	document
16	pane
17	chart
18	dialog
19	border
20	grouping
21	separator
22	tool bar
23	status bar
24	table
25	column header
26	row header
27	column
28	row
29	cell
30	link
31	help balloon
32	character
33	list
34	list item
35	outline
36	outline item
37	page tab
38	property page
39	indicator
40	graphic
41	text
42	editable text
43	push button
44	check box
45	radio button
46	combo box
47	drop down
48	progress bar
49	dial
50	hot key field
51	slider
52	spin box
53	diagram
54	animation
55	equation
56	drop down button
57	menu button
58	grid drop down button
59	white space
60	page tab list
61	clock
62	split button
63	IP address
64	outline button

Code: Select all

;From oleacc.h:
;ROLE_SYSTEM_TITLEBAR := 0x1
;ROLE_SYSTEM_MENUBAR := 0x2
;ROLE_SYSTEM_SCROLLBAR := 0x3
;ROLE_SYSTEM_GRIP := 0x4
;ROLE_SYSTEM_SOUND := 0x5
;ROLE_SYSTEM_CURSOR := 0x6
;ROLE_SYSTEM_CARET := 0x7
;ROLE_SYSTEM_ALERT := 0x8
;ROLE_SYSTEM_WINDOW := 0x9
;ROLE_SYSTEM_CLIENT := 0xA
;ROLE_SYSTEM_MENUPOPUP := 0xB
;ROLE_SYSTEM_MENUITEM := 0xC
;ROLE_SYSTEM_TOOLTIP := 0xD
;ROLE_SYSTEM_APPLICATION := 0xE
;ROLE_SYSTEM_DOCUMENT := 0xF
;ROLE_SYSTEM_PANE := 0x10
;ROLE_SYSTEM_CHART := 0x11
;ROLE_SYSTEM_DIALOG := 0x12
;ROLE_SYSTEM_BORDER := 0x13
;ROLE_SYSTEM_GROUPING := 0x14
;ROLE_SYSTEM_SEPARATOR := 0x15
;ROLE_SYSTEM_TOOLBAR := 0x16
;ROLE_SYSTEM_STATUSBAR := 0x17
;ROLE_SYSTEM_TABLE := 0x18
;ROLE_SYSTEM_COLUMNHEADER := 0x19
;ROLE_SYSTEM_ROWHEADER := 0x1A
;ROLE_SYSTEM_COLUMN := 0x1B
;ROLE_SYSTEM_ROW := 0x1C
;ROLE_SYSTEM_CELL := 0x1D
;ROLE_SYSTEM_LINK := 0x1E
;ROLE_SYSTEM_HELPBALLOON := 0x1F
;ROLE_SYSTEM_CHARACTER := 0x20
;ROLE_SYSTEM_LIST := 0x21
;ROLE_SYSTEM_LISTITEM := 0x22
;ROLE_SYSTEM_OUTLINE := 0x23
;ROLE_SYSTEM_OUTLINEITEM := 0x24
;ROLE_SYSTEM_PAGETAB := 0x25
;ROLE_SYSTEM_PROPERTYPAGE := 0x26
;ROLE_SYSTEM_INDICATOR := 0x27
;ROLE_SYSTEM_GRAPHIC := 0x28
;ROLE_SYSTEM_STATICTEXT := 0x29
;ROLE_SYSTEM_TEXT := 0x2A
;ROLE_SYSTEM_PUSHBUTTON := 0x2B
;ROLE_SYSTEM_CHECKBUTTON := 0x2C
;ROLE_SYSTEM_RADIOBUTTON := 0x2D
;ROLE_SYSTEM_COMBOBOX := 0x2E
;ROLE_SYSTEM_DROPLIST := 0x2F
;ROLE_SYSTEM_PROGRESSBAR := 0x30
;ROLE_SYSTEM_DIAL := 0x31
;ROLE_SYSTEM_HOTKEYFIELD := 0x32
;ROLE_SYSTEM_SLIDER := 0x33
;ROLE_SYSTEM_SPINBUTTON := 0x34
;ROLE_SYSTEM_DIAGRAM := 0x35
;ROLE_SYSTEM_ANIMATION := 0x36
;ROLE_SYSTEM_EQUATION := 0x37
;ROLE_SYSTEM_BUTTONDROPDOWN := 0x38
;ROLE_SYSTEM_BUTTONMENU := 0x39
;ROLE_SYSTEM_BUTTONDROPDOWNGRID := 0x3A
;ROLE_SYSTEM_WHITESPACE := 0x3B
;ROLE_SYSTEM_PAGETABLIST := 0x3C
;ROLE_SYSTEM_CLOCK := 0x3D
;ROLE_SYSTEM_SPLITBUTTON := 0x3E
;ROLE_SYSTEM_IPADDRESS := 0x3F
;ROLE_SYSTEM_OUTLINEBUTTON := 0x40
A script to retrieve a list of role text for specific role numbers.

Code: Select all

q:: ;acc - role numbers get text (text varies depending on locale)
;based on Acc_GetRoleText function:
vOutput := ""
VarSetCapacity(vOutput, 10000*2)
Loop, 80
{
	nRole := A_Index-4
	nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
	vOutput .= nRole "`t" sRole "`r`n"
}
Clipboard := vOutput
MsgBox, % vOutput
return

Re: AccViewer Basic

Posted: 22 Oct 2017, 15:02
by jeeswg
ACC: STATE

Constants for accState:

Code: Select all

;From oleacc.h:
;STATE_SYSTEM_NORMAL := 0x0
;STATE_SYSTEM_HASPOPUP := 0x40000000

;From WinUser.h:
;STATE_SYSTEM_UNAVAILABLE := 0x1 ;Disabled
;STATE_SYSTEM_SELECTED := 0x2
;STATE_SYSTEM_FOCUSED := 0x4
;STATE_SYSTEM_PRESSED := 0x8
;STATE_SYSTEM_CHECKED := 0x10
;STATE_SYSTEM_MIXED := 0x20 ;3-state checkbox or toolbar button
;STATE_SYSTEM_INDETERMINATE := STATE_SYSTEM_MIXED
;STATE_SYSTEM_READONLY := 0x40
;STATE_SYSTEM_HOTTRACKED := 0x80
;STATE_SYSTEM_DEFAULT := 0x100
;STATE_SYSTEM_EXPANDED := 0x200
;STATE_SYSTEM_COLLAPSED := 0x400
;STATE_SYSTEM_BUSY := 0x800
;STATE_SYSTEM_FLOATING := 0x1000 ;Children "owned" not "contained" by parent
;STATE_SYSTEM_MARQUEED := 0x2000
;STATE_SYSTEM_ANIMATED := 0x4000
;STATE_SYSTEM_INVISIBLE := 0x8000
;STATE_SYSTEM_OFFSCREEN := 0x10000
;STATE_SYSTEM_SIZEABLE := 0x20000
;STATE_SYSTEM_MOVEABLE := 0x40000
;STATE_SYSTEM_SELFVOICING := 0x80000
;STATE_SYSTEM_FOCUSABLE := 0x100000
;STATE_SYSTEM_SELECTABLE := 0x200000
;STATE_SYSTEM_LINKED := 0x400000
;STATE_SYSTEM_TRAVERSED := 0x800000
;STATE_SYSTEM_MULTISELECTABLE := 0x1000000 ;Supports multiple selection
;STATE_SYSTEM_EXTSELECTABLE := 0x2000000 ;Supports extended selection
;STATE_SYSTEM_ALERT_LOW := 0x4000000 ;This information is of low priority
;STATE_SYSTEM_ALERT_MEDIUM := 0x8000000 ;This information is of medium priority
;STATE_SYSTEM_ALERT_HIGH := 0x10000000 ;This information is of high priority
;STATE_SYSTEM_PROTECTED := 0x20000000 ;access to this is restricted
;STATE_SYSTEM_VALID := 0x3FFFFFFF
Links:
Object State Constants (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Check Box (MSAA UI Element Reference) (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
[these are different from the accState numbers]
List-View Item States (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

Further links:
Constants (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
SELFLAG Constants (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Object Roles (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

Re: AccViewer Basic

Posted: 17 Feb 2019, 18:27
by jeeswg
ACC: OBJECT FROM WINDOW

Constants for Acc_ObjectFromWindow:

Code: Select all

;source: WinUser.h
;OBJID_WINDOW := 0
;OBJID_SYSMENU := -1 ;(LONG)0xFFFFFFFF
;OBJID_TITLEBAR := -2 ;(LONG)0xFFFFFFFE
;OBJID_MENU := -3 ;(LONG)0xFFFFFFFD
;OBJID_CLIENT := -4 ;(LONG)0xFFFFFFFC
;OBJID_VSCROLL := -5 ;(LONG)0xFFFFFFFB
;OBJID_HSCROLL := -6 ;(LONG)0xFFFFFFFA
;OBJID_SIZEGRIP := -7 ;(LONG)0xFFFFFFF9
;OBJID_CARET := -8 ;(LONG)0xFFFFFFF8
;OBJID_CURSOR := -9 ;(LONG)0xFFFFFFF7
;OBJID_ALERT := -10 ;(LONG)0xFFFFFFF6
;OBJID_SOUND := -11 ;(LONG)0xFFFFFFF5
;OBJID_QUERYCLASSNAMEIDX := -12 ;(LONG)0xFFFFFFF4
;OBJID_NATIVEOM := -16 ;(LONG)0xFFFFFFF0
A_AhkUser requested these constants be listed:

Code: Select all

;source: WinUser.h
;CONSOLE_APPLICATION_16BIT := 0x0 ;64-bit applications
;CONSOLE_APPLICATION_16BIT := 0x1 ;32-bit applications

;CONSOLE_CARET_SELECTION := 0x1
;CONSOLE_CARET_VISIBLE := 0x2
For the 'AccessibleObjectFromWindow' Winapi function.
And for the 'Acc_ObjectFromWindow' custom AHK function.
Object Identifiers - Windows applications | Microsoft Docs
https://docs.microsoft.com/en-gb/windows/desktop/WinAuto/object-identifiers

Re: AccViewer Basic

Posted: 20 Feb 2020, 03:23
by Bluscream
Can someone please add a little extra window that shows a log of all recent events with a basic filter by event?

Re: AccViewer Basic

Posted: 21 Jun 2022, 15:46
by Skrell
Is there any way to get the basic "AccViewer" example to work upon a mouse click (or possibly ignore the mouse click)? It seems that the code ONLY works if it executes while hovering, but by left clicking it changes what values you get in vOutput.

Re: AccViewer Basic

Posted: 22 Jun 2022, 08:07
by Skrell
My apologies, the issue isn't left clicking messing up the vAcc___- values, the problem is some windows simply return wrong values. So for insqance, Windows Explorer doesn't seem to ever return the correct values for Min/Max/Close buttons if you trigger vOutput with LButton. However, the hover and trigger vOutput with q:: seems to ALWAYS work with these buttons.
So basically I'm really confused as to what is going on in trying to use this library with certain windows + Lbutton trigger. Task Manager is another incorrect one btw.