kunkel321 wrote: ↑My sRole variable is simply empty.
Code: Select all
ROLE_SYSTEM_TEXT := 0x2A
MsgBox, % Acc_GetRoleText(ROLE_SYSTEM_TEXT)
Acc_GetRoleText(nRole)
{
len := DllCall("oleacc\GetRoleText", "UInt", nRole, "Ptr", 0, "UInt", 0)
VarSetCapacity(sRole, size := (len + 1) << !!A_IsUnicode, 0)
DllCall("oleacc\GetRoleText", "UInt", nRole, "Str", sRole, "UInt", size)
Return sRole
}
kunkel321 wrote: ↑I can't figure out how to assess it in my one script though.
You need to implement recursive element search, for example:
Code: Select all
SetBatchLines, -1
ROLE_SYSTEM_TEXT := 0x0000002A
ROLE_SYSTEM_COMBOBOX := 0x0000002E
STATE_SYSTEM_FOCUSED := 0x00000004
text := { Role: ROLE_SYSTEM_TEXT
, State: STATE_SYSTEM_FOCUSED }
combo := { Role: ROLE_SYSTEM_COMBOBOX
, State: STATE_SYSTEM_FOCUSED }
Return
$F11::
WinGet, processName, ProcessName, A
hwnd := WinExist("A")
if (processName ~= "i)^(chrome|msedge)\.exe")
SendMessage, WM_GETOBJECT := 0x3D, 0, 1, Chrome_RenderWidgetHostHWND1, ahk_id %hWnd%
AccObj := AccObjectFromWindow(hWnd)
if !IsObject(AccObj)
throw "Failed to get acc object from window"
if SearchElement(AccObj, text) || SearchElement(AccObj, combo)
MsgBox, There is a focused input field
else
MsgBox, Focused input field not found
Return
SearchElement(parentElement, params)
{
found := true
for k, v in params {
try {
if (k = "State")
(!(parentElement.accState(0) & v) && found := false)
else if (k ~= "^(Name|Value)$")
(!(parentElement["acc" . k](0) ~= v) && found := false)
else if (k = "ChildCount")
(parentElement["acc" . k] != v && found := false)
else
(parentElement["acc" . k](0) != v && found := false)
}
catch
found := false
} until !found
if found
Return parentElement
try Children := AccChildren(parentElement)
catch
Return
for k, v in Children
if obj := SearchElement(v, params)
Return obj
}
AccObjectFromWindow(hWnd, idObject = 0) {
static IID_IDispatch := "{00020400-0000-0000-C000-000000000046}"
, IID_IAccessible := "{618736E0-3C3D-11CF-810C-00AA00389B71}"
, OBJID_NATIVEOM := 0xFFFFFFF0, VT_DISPATCH := 9, F_OWNVALUE := 1
, h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
VarSetCapacity(IID, 16), idObject &= 0xFFFFFFFF
DllCall("ole32\CLSIDFromString", "Str", idObject = OBJID_NATIVEOM ? IID_IDispatch : IID_IAccessible, "Ptr", &IID)
if DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject, "Ptr", &IID, "PtrP", pAcc) = 0
Return ComObject(VT_DISPATCH, pAcc, F_OWNVALUE)
}
AccChildren(Acc) {
static VT_DISPATCH := 9
Loop 1 {
if ComObjType(Acc, "Name") != "IAccessible" {
error := "Invalid IAccessible Object"
break
}
try cChildren := Acc.accChildCount
catch
Return ""
Children := []
VarSetCapacity(varChildren, cChildren*(8 + A_PtrSize*2), 0)
res := DllCall("oleacc\AccessibleChildren", "Ptr", ComObjValue(Acc), "Int", 0
, "Int", cChildren, "Ptr", &varChildren, "IntP", cChildren)
if (res != 0) {
error := "AccessibleChildren DllCall Failed"
break
}
Loop % cChildren {
i := (A_Index - 1)*(A_PtrSize*2 + 8)
child := NumGet(varChildren, i + 8)
Children.Push( (b := NumGet(varChildren, i) = VT_DISPATCH) ? AccQuery(child) : child )
( b && ObjRelease(child) )
}
}
if error
ErrorLevel := error
else
Return Children.MaxIndex() ? Children : ""
}
AccQuery(Acc) {
static IAccessible := "{618736e0-3c3d-11cf-810c-00aa00389b71}", VT_DISPATCH := 9, F_OWNVALUE := 1
try Return ComObject(VT_DISPATCH, ComObjQuery(Acc, IAccessible), F_OWNVALUE)
}
Perhaps, the search can be optimized.