WindowList - Viewer and manipulation of window data
Posted: 15 Sep 2020, 17:05
Here is the code for a viewer for used windows information, with functionalities to several autohotkey commands for windows.
Functionalities:
- Filters with radio buttons only visible windows and windows with titles
- Allows to filter on strings with Edit fields above the list
- Doubleclick on the window info in the list to be able to retrieve the coordinates and exicute several commands regarding that window
- The move button can move the window to the entered coordinates (changing the width and Height currently does not work yet)
- Rightclick the windowlist to show a menu to Activate, Hide, copy the title, get Acc data,...
- Doubleclick on controls to draw a rectangle arround the control
- Transparency of window can be changed with the slider
- Also includes a button to Kill the selected window
Here is ACC.ahk
Functionalities:
- Filters with radio buttons only visible windows and windows with titles
- Allows to filter on strings with Edit fields above the list
- Doubleclick on the window info in the list to be able to retrieve the coordinates and exicute several commands regarding that window
- The move button can move the window to the entered coordinates (changing the width and Height currently does not work yet)
- Rightclick the windowlist to show a menu to Activate, Hide, copy the title, get Acc data,...
- Doubleclick on controls to draw a rectangle arround the control
- Transparency of window can be changed with the slider
- Also includes a button to Kill the selected window
Code: Select all
#NoEnv
SendMode Input
#SingleInstance force
#InstallKeybdHook
SetWorkingDir %A_ScriptDir%
SetTitleMatchMode, 2
SetTitleMatchMode, RegEx
SetBatchLines, -1
global vVisible
vVisible := 1
Gui, Add, Text, ,WinSearch:
Gui, Add, Edit, yp x70 w200 vSearchTerm glVisible
Gui, Add, Checkbox, xp+210 yp+4 vvVisible glVisible checked, Visible
Gui, Add, Checkbox, xp+75 yp vvTitle glVisible checked, Title
Gui, Add, Text, yp x620,ControlSearch:
Gui, Add, Edit, yp x+10 w200 vcSearchTerm glUpdateControlList
Gui, Add, Checkbox, xp+210 yp+4 vvcTextVisible glUpdateControlList checked, Text visible
Gui, Add, ListView, xm r15 w600 vMyWinList gMyWinList section AltSubmit, Title|Process|ID|Style
LV_ModifyCol()
LV_ModifyCol(1, 300)
LV_ModifyCol(3, "Integer")
LV_ModifyCol(4, "SortDesc")
Gui, Add, ListView, x+m r15 w600 vMyControlList gMyControlList AltSubmit, Control|Hwnd|Text|X|Y|With|Height
Gui, Add, Button, gKill xm w50, Kill
Gui, Add, Text,xm, X:
Gui, Add, Edit, vXPos xp+20 w40,
Gui, Add, Text, xp+50 , Y:
Gui, Add, Edit, vYPos xp+20 w40,
Gui, Add, Text, xp+50 , Width:
Gui, Add, Edit, vwWidth xp+40 w40,
Gui, Add, Text, xp+50 , Height:
Gui, Add, Edit, vwHeight xp+40 w40,
Gui, Add, Button, gMove xp+50 w50, Move
Gui, Add, Text,xm, Transparent:
Gui, Add, Slider, xp+60 vvTransparent glTransparent Range0-255 ToolTip, 255
LV_Update()
Gui, Add, StatusBar,
Gui, Show
return
GuiClose:
Gui, Destroy
ExitApp
return
MyWinList:
{
Gui, ListView, MyWinList
if (A_GuiEvent = "DoubleClick"){
ControlGet, Selected, List, Selected, SysListView321,
Selected := StrSplit(Selected, A_Tab)
wid := Selected[3]
WinGetPos, wX, wY,wWidth ,wHeight , ahk_id %wid%
WinGet, wTransparent, Transparent, ahk_id %wid%
if(wTransparent=""){
wTransparent:=255
}
DebugWindow(wTransparent "`n")
GuiControl, Text, XPos , %wX%
GuiControl, Text, YPos , %wY%
GuiControl, Text, wWidth , %wWidth%
GuiControl, Text, wHeight , %wHeight%
GuiControl, Text, vTransparent , %wTransparent%
Gosub, lUpdateControlList
}
if (A_GuiEvent = "RightClick"){
Menu, Menu_Win, add
Menu, Menu_Win, DeleteAll
ControlGet, Selected, List, Selected, SysListView321,
Selected := StrSplit(Selected, A_Tab)
wTitle := Selected[1]
wProcess := Selected[2]
wId := Selected[3]
wStyle := Selected[4]
BoundGivePar := Func("WinActivate").Bind("ahk_id " wId)
Menu, Menu_Win, Add, Activate, % BoundGivePar
WinGet, wStyle, Style, ahk_id %wId%
If (wStyle & 0x10000000){ ; 0x10000000 is WS_VISIBLE
BoundGivePar := Func("WinHide").Bind("ahk_id " wId)
Menu, Menu_Win, Add, Visible, % BoundGivePar
Menu, Menu_Win, Check, Visible,
BoundGivePar := Func("WinSet").Bind("AlwaysOnTop", "ahk_id " wId)
Menu, Menu_Win, Add, AlwaysOnTop, % BoundGivePar
WinGet, ExStyle, ExStyle, ahk_id %wId%
If (ExStyle & 0x8){
Menu, Menu_Win, Check, AlwaysOnTop
}
}
Else{
BoundGivePar := Func("WinShow").Bind("ahk_id " Selected[3])
Menu, Menu_Win, Add, Visible, % BoundGivePar
}
Menu, Menu_Win, Add,
BoundGivePar := Func("ClipboardSet").Bind(wTitle)
Menu, Menu_Win, Add, Copy Title, % BoundGivePar
Menu, Menu_Win, Icon, Copy Title, C:\Windows\syswow64\SHELL32.dll , 261
BoundGivePar := Func("ClipboardSet").Bind(wProcess)
Menu, Menu_Win, Add, Copy Process, % BoundGivePar
Menu, Menu_Win, Icon, Copy Process, C:\Windows\syswow64\SHELL32.dll , 261
Menu, Menu_Win, Add
BoundGivePar := Func("Gui_Acc").Bind(wId)
Menu, Menu_Win, Add, Get Acc, % BoundGivePar
Menu, Menu_Win, Show
}
return
}
lUpdateControlList:
{
Gui, Submit, Nohide
WinGet, cList, ControlList, ahk_id %wid%
Gui, ListView, MyControlList
LV_Delete()
loop,{
cSearchTermOld := cSearchTerm
vcTextVisibleOld := vcTextVisible
Loop, Parse, cList, `n, `r
{
Control := A_LoopField
ControlGetText, cText, %Control%, ahk_id %wid%
ControlGetPos, cX, cY, cW, cH, %Control%, ahk_id %wid%
Controlget,cHwnd, Hwnd , , %Control%, ahk_id %wid%
if (vcTextVisible=0 or cText !=""){
If (InStr(Control " " cText, cSearchTerm) or (cSearchTerm = "")){
LV_Add("", A_LoopField, cHwnd, cText, cX, cY, cW, cH)
}
}
GuiControlGet, cSearchTerm
GuiControlGet, vcTextVisible
if(cSearchTermOld != cSearchTerm or vcTextVisible != vcTextVisibleOld){
Break
}
}
if(cSearchTermOld = cSearchTerm and vcTextVisible = vcTextVisibleOld){
Break
}
}
LV_ModifyCol()
Return
}
MyControlList:
{
Gui, ListView, MyWinList
ControlGet, wSelected, List, Selected, SysListView321,
wSelected := StrSplit(wSelected, A_Tab)
wId := wSelected[3]
wStyle := wSelected[4]
Gui, ListView, MyControlList
if (A_GuiEvent = "DoubleClick"){
ControlGet, cSelected, List, Selected, SysListView322,
cSelected := StrSplit(cSelected, A_Tab)
cControl := cSelected[1]
cId := cSelected[2]
cX := cSelected[4]
cY := cSelected[5]
cW := cSelected[6]
cH := cSelected[7]
WinGetPos, wX, wY,,, ahk_id %wId%
DebugWindow(cControl cX "-" cY "-" cW "-" cH "`n")
Box_Init(C="FF0000")
Box_Draw(cX+wX, cY+wY, cW, cH, 2, "in")
}
if (A_GuiEvent = "RightClick"){
Menu, Menu_Contr, add
Menu, Menu_Contr, DeleteAll
ControlGet, cSelected, List, Selected, SysListView322,
cSelected := StrSplit(cSelected, A_Tab)
cControl := cSelected[1]
cId := cSelected[2]
BoundGivePar := Func("ControlFocus").Bind(cId)
Menu, Menu_Contr, Add, Focus, % BoundGivePar
Menu, Menu_Contr, Add
BoundGivePar := Func("ClipboardSet").Bind(cControl)
Menu, Menu_Contr, Add, Copy Control, % BoundGivePar
Menu, Menu_Contr, Icon, Copy Control, C:\Windows\syswow64\SHELL32.dll , 261
Menu, Menu_Contr, Add
BoundGivePar := Func("Gui_Acc").Bind(cId)
Menu, Menu_Contr, Add, Get Acc, % BoundGivePar
Menu, Menu_Contr, Show
}
return
}
Kill:
ControlGet, Selected, List, Selected, SysListView321,
Selected := StrSplit(Selected, A_Tab)
id := Selected[3]
WinClose, ahk_id %id%
return
lTransparent:
Gui, Submit, Nohide
ControlGet, Selected, List, Selected, SysListView321,
Selected := StrSplit(Selected, A_Tab)
id := Selected[3]
WinSet, Transparent, %vTransparent%, ahk_id %id%
return
Move:
{
ControlGet, Selected, List, Selected, SysListView321,
Selected := StrSplit(Selected, A_Tab)
id := Selected[3]
WinGetPos, wX, wY, , , ahk_id %id%
GuiControlGet, xPos
GuiControlGet, yPos
GuiControlGet, wWidth
GuiControlGet, wHeight
WinActivate, ahk_id %id%
WinWaitActive, ahk_id %id%
WinMove, xPos, yPos
return
}
lVisible:
Gui,Submit, NoHide
GuiControl, -Redraw, LV
LV_Update()
GuiControl, +Redraw, LV
return
LV_Update() {
Gui, ListView, MyWinList
WinGet, windowList, List,,, Program Manager
GuiControlGet, SearchTerm
GuiControlGet, vTitle
GuiControlGet, vVisible
SearchTermOld := SearchTerm
loop,{
SearchTermOld := SearchTerm
vTitleOld := vTitle
vVisibleOld := vVisible
TotalItems := 0
LV_Delete()
Loop %windowList%
{
id := windowList%A_Index%
WinGetTitle wTitle, ahk_id %id%
WinGet, wProcessName, ProcessName, ahk_id %id%
DetectHiddenWindows, Off
WinGetPos, x,,,,ahk_id %id%
if !x{
wStyle := "Hidden"
}
else{
wStyle := "Visible"
}
DetectHiddenWindows, On
if (vVisible=0 or wStyle = "Visible"){
If (InStr(wTitle " " wProcessName, SearchTerm) or (SearchTerm = "")){
DebugWindow(vTitle "`n")
if(!vTitle or wTitle !=""){
LV_Add("", wTitle, wProcessName, id, wStyle)
}
}
TotalItems++
}
GuiControlGet, SearchTerm
GuiControlGet, vTitle
GuiControlGet, vVisible
if(SearchTermOld != SearchTerm){
Break
}
}
GuiControlGet, SearchTerm
GuiControlGet, vTitle
GuiControlGet, vVisible
if(SearchTermOld = SearchTerm and vTitleOld = vTitle and vVisibleOld = vVisible){
Break
}
}
LV_ModifyCol()
LV_ModifyCol(1, 300)
LV_ModifyCol(3, "Integer")
LV_ModifyCol(4, "SortDesc")
Items := LV_GetCount()
SB_SetText(" " . Items . " of " . TotalItems . " Items")
return
}
WinActivate(WinTitle:=""){
WinActivate, %WinTitle%
return
}
WinHide(WinTitle:=""){
WinHide, %WinTitle%
return
}
WinShow(WinTitle:=""){
WinShow, %WinTitle%
return
}
WinSet(SubCommand, Wintitle){
WinSet, %SubCommand%, , %WinTitle%
return ErrorLevel
}
ControlFocus(Control){
ControlFocus, %Control%
return
}
ClipboardSet(strClipboard){
Clipboard := strClipboard
return
}
DebugWindow(Text,Clear:=0,LineBreak:=0,Sleep:=0,AutoHide:=0,MsgBox:=0){
if WinExist("AHK Studio"){
x:=ComObjActive("{DBD5A90A-A85C-11E4-B0C7-43449580656B}"),x.DebugWindow(Text,Clear,LineBreak,Sleep,AutoHide,MsgBox)
}
}
/*
Box_Init - Creates the necessary GUIs.
Author: berban and Wicked
https://autohotkey.com/board/topic/54443-box-ie-draw-simple-gui-based-boxes-on-screen/
C - The color of the box.
*/
Box_Init(C="FF0000") {
Gui, 96: +ToolWindow -Caption +AlwaysOnTop +LastFound
Gui, 96: Color, % C
Gui, 97: +ToolWindow -Caption +AlwaysOnTop +LastFound
Gui, 97: Color, % C
Gui, 98: +ToolWindow -Caption +AlwaysOnTop +LastFound
Gui, 98: Color, % C
Gui, 99: +ToolWindow -Caption +AlwaysOnTop +LastFound
Gui, 99: Color, % C
}
/*
Box_Draw - Draws a box on the screen using 4 GUIs.
X - The X coord.
Y - The Y coord.
W - The width of the box.
H - The height of the box.
T - The thickness of the borders.
O - The offset. O - Outside. C - Centered. I - Inside.
*/
Box_Draw(X, Y, W, H, T="1", O="I") {
If(W < 0)
X += W, W *= -1
If(H < 0)
Y += H, H *= -1
If(T >= 2)
{
If(O == "O")
X -= T, Y -= T, W += T, H += T
If(O == "C")
X -= T / 2, Y -= T / 2
If(O == "I")
W -= T, H -= T
}
Gui, 96: Show, % "x" X " y" Y " w" W " h" T " NA", Horizontal 1
Gui, 98: Show, % "x" X " y" Y + H " w" W " h" T " NA", Horizontal 2
Gui, 97: Show, % "x" X " y" Y " w" T " h" H " NA", Vertical 1
Gui, 99: Show, % "x" X + W " y" Y " w" T " h" H " NA", Vertical 2
}
/*
Box_Destroy - Destoyes the 4 GUIs.
*/
Box_Destroy() {
Loop, 4
Gui, % A_Index + 95 ": Destroy"
}
/*
Box_Hide - Hides the 4 GUIs.
*/
Box_Hide() {
Loop, 4
Gui, % A_Index + 95 ": Hide"
}
Gui_Acc(hWnd){
global
TrayTip, Acc, Get objects %hWnd%
Menu, Tray, Tip, Loading data...
AccData := JEE_AccGetTextAll2(hWnd, "`r`n")
Menu, Tray, Tip, %A_ScriptName%
Gui, 2:default
Gui, Add, Text, ,Search:
Gui, Add, Edit, x+10 w400 vvSearchAcc glSearchAcc
; Create the ListView with two columns, Name and Size:
Gui, Add, ListView, xm r20 w700 vMyAccList glMyAccList AltSubmit, Path|ChildId|Name|Value|Role
TotalItems :=0
loop,{
vSearchAccOld := vSearchAcc
; Gather a list of file names from a folder and put them into the ListView:
Loop, Parse, AccData, `n
{
Line := StrSplit(A_LoopField, "|`t")
LV_Add("", Line*)
TotalItems ++
GuiControlGet, vSearchAcc
if(vSearchAcc!=vSearchAccOld){
break
}
}
if(vSearchAcc=vSearchAccOld){
break
}
}
Gui, Add, StatusBar, , % " " . TotalItems . " of " . TotalItems . " Items"
LV_ModifyCol() ; Auto-size each column to fit its contents.
LV_ModifyCol(2,50)
; Display the window and return. The script will be notified whenever the user double clicks a row.
Gui, Show, , Acc Data - %hWnd%
return
2GuiClose: ; Indicate that the script should exit automatically when the window is closed.
Gui, Destroy
return
lSearchAcc:
Gui, 2:default
Gui, Submit, NoHide
;~ GuiControlGet, vSearchAcc
GuiControl, -Redraw, MyAccList
LV_Delete()
Loop, Parse, AccData, `n
{
If (InStr(A_LoopField, vSearchAcc) or (vSearchAcc = "")){
Line := StrSplit(A_LoopField, "|`t")
LV_Add("", Line*)
}
}
LV_ModifyCol() ; Auto-size each column to fit its contents.
LV_ModifyCol(2,50)
Items := LV_GetCount()
SB_SetText(" " . Items . " of " . TotalItems . " Items")
GuiControl, +Redraw, MyAccList
Return
lMyAccList:
ControlGet, accSelected, List, Selected, SysListView321,
accSelected := StrSplit(accSelected, A_Tab)
accPath := accSelected[1]
accChildId := accSelected[2]
accValue := accSelected[3]
accRole := accSelected[4]
if (A_GuiEvent = "DoubleClick"){
oAcc := Acc_Get("Object", accPath, accChildId, "Ahk_id " hWnd)
GetAccLocation(oAcc, accChildId, accX, accY, accW, accH)
WinGetPos, wX, wY,,, ahk_id %wId%
DebugWindow(cControl accX "-" accY "-" accW "-" accH "`n")
Box_Init(C="FF0000")
Box_Draw(accX+wX, accY+wY, accW, accH, 2, "in")
}
if (A_GuiEvent = "RightClick"){
try Menu, Menu_Acc, DeleteAll
ControlGet, accSelected, List, Selected, SysListView321,
accSelected := StrSplit(accSelected, A_Tab)
accControl := accSelected[1]
BoundGivePar := Func("AccDefaultAction").Bind(accPath, accChildId, "ahk_id " hWnd)
Menu, Menu_Acc, Add, AccDefaultAction, % BoundGivePar
Menu, Menu_Acc, Add
BoundGivePar := Func("ClipboardSet").Bind(accPath "." accChildId)
Menu, Menu_Acc, Add, Copy Path, % BoundGivePar
Menu, Menu_Acc, Icon, Copy Path, C:\Windows\syswow64\SHELL32.dll , 261
Menu, Menu_Acc, Show
}
return
}
AccDefaultAction(ChildPath="", ChildID=0, WinTitle=""){
oAcc := Acc_Get("Object", ChildPath, ChildID, WinTitle)
oAcc.accDoDefaultAction(ChildID)
}
; Borrowed From ACC Viewer
GetAccLocation(AccObj, Child=0, byref x="", byref y="", byref w="", byref h="") {
AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), Child)
return "x" (x:=NumGet(x,0,"int")) " "
. "y" (y:=NumGet(y,0,"int")) " "
. "w" (w:=NumGet(w,0,"int")) " "
. "h" (h:=NumGet(h,0,"int"))
}
;==================================================
; Borrowed jeeswg from https://www.autohotkey.com/boards/viewtopic.php?f=6&t=40615
JEE_StrRept(vText, vNum)
{
if (vNum <= 0)
return
return StrReplace(Format("{:" vNum "}", ""), " ", vText)
;return StrReplace(Format("{:0" vNum "}", 0), 0, vText)
}
;==================================================
;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_AccGetTextAll2(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)
}
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]", " ")
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()]
}
; Quick Modify by AHK_User
vChildCount := Acc_Get("ChildCount", vAccPath, 0, "ahk_id " hWnd)
if (vChildCount=""){
vParent_Path := RegExReplace(vAccPath, "(.*)\.(\d*)", "$1")
vChild_Id := RegExReplace(vAccPath, "(.*)\.(\d*)", "$2")
vName := Acc_Get("Name", vParent_Path, vChild_Id, "ahk_id " hWnd)
vRoleText := Acc_Get("Role", vParent_Path, vChild_Id, "ahk_id " hWnd)
vOutput .= vParent_Path "|`t" vChild_Id "|`t" vName "|`t" vValue "|`t" vRoleText vSep
}
else{
vOutput .= vAccPath "|`t0|`t" vName "|`t" vValue "|`t" vRoleText vSep
}
;~ vOutput .= vAccPath "`t" JEE_StrRept(vIndent, vLevel-1) vRoleText " [" vName "][" vValue "]" 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))
}
Code: Select all
; http://www.autohotkey.com/board/topic/77303-acc-library-ahk-l-updated-09272012/
; https://dl.dropbox.com/u/47573473/Web%20Server/AHK_L/Acc.ahk
;------------------------------------------------------------------------------
; Acc.ahk Standard Library
; by Sean
; Updated by jethrow:
; Modified ComObjEnwrap params from (9,pacc) --> (9,pacc,1)
; Changed ComObjUnwrap to ComObjValue in order to avoid AddRef (thanks fincs)
; Added Acc_GetRoleText & Acc_GetStateText
; Added additional functions - commented below
; Removed original Acc_Children function
; last updated 2/25/2010
;------------------------------------------------------------------------------
Acc_Init()
{
Static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild)
{
Acc_Init()
If DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
Acc_Init()
If DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_ObjectFromWindow(hWnd, idObject = -4)
{
Acc_Init()
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
Return ComObjEnwrap(9,pacc,1)
}
Acc_WindowFromObject(pacc)
{
If DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
Return hWnd
}
Acc_GetRoleText(nRole)
{
nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
Return sRole
}
Acc_GetStateText(nState)
{
nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0)
VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1)
Return sState
}
Acc_SetWinEventHook(eventMin, eventMax, pCallback)
{
Return DllCall("SetWinEventHook", "Uint", eventMin, "Uint", eventMax, "Uint", 0, "Ptr", pCallback, "Uint", 0, "Uint", 0, "Uint", 0)
}
Acc_UnhookWinEvent(hHook)
{
Return DllCall("UnhookWinEvent", "Ptr", hHook)
}
/* Win Events:
pCallback := RegisterCallback("WinEventProc")
WinEventProc(hHook, event, hWnd, idObject, idChild, eventThread, eventTime)
{
Critical
Acc := Acc_ObjectFromEvent(_idChild_, hWnd, idObject, idChild)
; Code Here:
}
*/
; Written by jethrow
Acc_Role(Acc, ChildId=0) {
try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
}
Acc_State(Acc, ChildId=0) {
try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object"
}
Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
catch
return
Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
return {x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
}
Acc_Parent(Acc) {
try parent:=Acc.accParent
return parent?Acc_Query(parent):
}
Acc_Child(Acc, ChildId=0) {
try child:=Acc.accChild(ChildId)
return child?Acc_Query(child):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Error(p="") {
static setting:=0
return p=""?setting:setting:=p
}
Acc_Children(Acc) {
if ComObjType(Acc,"Name") != "IAccessible"
ErrorLevel := "Invalid IAccessible Object"
else {
Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
Loop %cChildren%
i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
return Children.MaxIndex()?Children:
} else
ErrorLevel := "AccessibleChildren DllCall Failed"
}
if Acc_Error()
throw Exception(ErrorLevel,-1)
}
Acc_ChildrenByRole(Acc, Role) {
if ComObjType(Acc,"Name")!="IAccessible"
ErrorLevel := "Invalid IAccessible Object"
else {
Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
Loop %cChildren% {
i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
if NumGet(varChildren,i-8)=9
AccChild:=Acc_Query(child), ObjRelease(child), Acc_Role(AccChild)=Role?Children.Insert(AccChild):
else
Acc_Role(Acc, child)=Role?Children.Insert(child):
}
return Children.MaxIndex()?Children:, ErrorLevel:=0
} else
ErrorLevel := "AccessibleChildren DllCall Failed"
}
if Acc_Error()
throw Exception(ErrorLevel,-1)
}
Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") {
static properties := {Action:"DefaultAction", DoAction:"DoDefaultAction", Keyboard:"KeyboardShortcut"}
AccObj := IsObject(WinTitle)? WinTitle
: Acc_ObjectFromWindow( WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText), 0 )
if ComObjType(AccObj, "Name") != "IAccessible"
ErrorLevel := "Could not access an IAccessible Object"
else {
StringReplace, ChildPath, ChildPath, _, %A_Space%, All
AccError:=Acc_Error(), Acc_Error(true)
Loop Parse, ChildPath, ., %A_Space%
try {
if A_LoopField is digit
Children:=Acc_Children(AccObj), m2:=A_LoopField ; mimic "m2" output in else-statement
else
RegExMatch(A_LoopField, "(\D*)(\d*)", m), Children:=Acc_ChildrenByRole(AccObj, m1), m2:=(m2?m2:1)
if Not Children.HasKey(m2)
throw
AccObj := Children[m2]
} catch {
ErrorLevel:="Cannot access ChildPath Item #" A_Index " -> " A_LoopField, Acc_Error(AccError)
if Acc_Error()
throw Exception("Cannot access ChildPath Item", -1, "Item #" A_Index " -> " A_LoopField)
return
}
Acc_Error(AccError)
StringReplace, Cmd, Cmd, %A_Space%, , All
properties.HasKey(Cmd)? Cmd:=properties[Cmd]:
try {
if (Cmd = "Location")
AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
, ret_val := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
else if (Cmd = "Object")
ret_val := AccObj
else if Cmd in Role,State
ret_val := Acc_%Cmd%(AccObj, ChildID+0)
else if Cmd in ChildCount,Selection,Focus
ret_val := AccObj["acc" Cmd]
else
ret_val := AccObj["acc" Cmd](ChildID+0)
} catch {
ErrorLevel := """" Cmd """ Cmd Not Implemented"
if Acc_Error()
throw Exception("Cmd Not Implemented", -1, Cmd)
return
}
return ret_val, ErrorLevel:=0
}
if Acc_Error()
throw Exception(ErrorLevel,-1)
}