1

Тема: AHK: Получение значения адресной строки в фаерфоксе через UIA

setbatchlines -1
IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")

f11::
DllCall(NumGet(NumGet(IUIAutomation+0)+6*A_PtrSize), "ptr", IUIAutomation, "ptr", WinExist("A"), "ptr*", ElementFromHandle)   ; IUIAutomation::ElementFromHandle
AddressBarName := DllCall("oleaut32\SysAllocString", "str", "Search with Google or enter address", "ptr")
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(VT_BSTR := 8, variant, 0, "ushort")
NumPut(AddressBarName, variant, 8, "ptr")
if (A_PtrSize = 4)
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_NamePropertyId := 30005, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition1)   ; IUIAutomation::CreatePropertyCondition
else
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_NamePropertyId := 30005, "ptr", &variant, "ptr*", condition1)   ; IUIAutomation::CreatePropertyCondition
DllCall("oleaut32\SysFreeString", "ptr", AddressBarName)
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(VT_I4 := 3, variant, 0, "ushort")
NumPut(UIA_EditControlTypeId := 50004, variant, 8, "int")
if (A_PtrSize = 4)
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_ControlTypePropertyId := 30003, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition2)   ; IUIAutomation::CreatePropertyCondition
else
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_ControlTypePropertyId := 30003, "ptr", &variant, "ptr*", condition2)   ; IUIAutomation::CreatePropertyCondition
DllCall(NumGet(NumGet(IUIAutomation+0)+25*A_PtrSize), "ptr", IUIAutomation, "ptr", condition1, "ptr", condition2, "ptr*", conditions)   ; IUIAutomation::CreateAndCondition
DllCall(NumGet(NumGet(ElementFromHandle+0)+5*A_PtrSize), "ptr", ElementFromHandle, "int", TreeScope_Descendants := 0x4, "ptr", conditions, "ptr*", element) ; IUIAutomationElement::FindFirst
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
DllCall(NumGet(NumGet(element+0)+10*A_PtrSize), "ptr", element, "int", UIA_ValueValuePropertyId := 30045, "ptr", &variant)   ; IUIAutomationElement::GetCurrentPropertyValue
ObjRelease(element)
ObjRelease(conditions)
ObjRelease(condition1)
ObjRelease(condition2)
ObjRelease(ElementFromHandle)
msgbox % StrGet(NumGet(variant, 8, "ptr"), "utf-16")
return

2

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Спасибо, будем изучать!

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Но у меня не срабатывает, сейчас на десятке проверяю.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

4

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Возможно дело в названии адресной строки.
У меня называется "Search with Google or enter address".

5

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

А независимого от языка нет варианта?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Можно так попробовать.

setbatchlines -1
IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
oStates := [collapsed_focusable_haspopup := 0x40100400, expanded_focusable_haspopup := 0x40100200, focused_collapsed_focusable_haspopup := 0x40100404, focused_expanded_focusable_haspopup := 0x40100204]
SafeArray := ComObjArray(VT_UNKNOWN := 13, oStates.Count())
if (A_PtrSize = 4)
   SafeArrayConditions := ComObject(0x2000|3, ComObjValue(SafeArray), 1)
else
   SafeArrayConditions := ComObject(0x2000|0x14, ComObjValue(SafeArray), 1)
loop % oStates.Count()
{
   VarSetCapacity(variant, 8+A_PtrSize*2, 0)
   NumPut(VT_I4 := 3, variant, 0, "ushort")
   NumPut(oStates[A_Index], variant, 8, "int")
   if (A_PtrSize = 4)
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_LegacyIAccessibleStatePropertyId := 30096, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   else
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_LegacyIAccessibleStatePropertyId := 30096, "ptr", &variant, "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   SafeArrayConditions[A_Index-1] := condition
}
DllCall(NumGet(NumGet(IUIAutomation+0)+29*A_PtrSize), "ptr", IUIAutomation, "ptr", ComObjValue(SafeArrayConditions), "ptr*", condition1)   ; IUIAutomation::CreateOrConditionFromArray
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(VT_I4 := 3, variant, 0, "ushort")
NumPut(UIA_EditControlTypeId := 50004, variant, 8, "int")
if (A_PtrSize = 4)
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_ControlTypePropertyId := 30003, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition2)   ; IUIAutomation::CreatePropertyCondition
else
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_ControlTypePropertyId := 30003, "ptr", &variant, "ptr*", condition2)   ; IUIAutomation::CreatePropertyCondition
DllCall(NumGet(NumGet(IUIAutomation+0)+25*A_PtrSize), "ptr", IUIAutomation, "ptr", condition1, "ptr", condition2, "ptr*", conditions)   ; IUIAutomation::CreateAndCondition
ObjRelease(condition1)
ObjRelease(condition2)
loop % oStates.Count()
   ObjRelease(SafeArrayConditions[A_Index-1])
return

f11::
DllCall(NumGet(NumGet(IUIAutomation+0)+6*A_PtrSize), "ptr", IUIAutomation, "ptr", WinExist("A"), "ptr*", ElementFromHandle)   ; IUIAutomation::ElementFromHandle
DllCall(NumGet(NumGet(ElementFromHandle+0)+5*A_PtrSize), "ptr", ElementFromHandle, "int", TreeScope_Descendants := 0x4, "ptr", conditions, "ptr*", element) ; IUIAutomationElement::FindFirst
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
DllCall(NumGet(NumGet(element+0)+10*A_PtrSize), "ptr", element, "int", UIA_ValueValuePropertyId := 30045, "ptr", &variant)   ; IUIAutomationElement::GetCurrentPropertyValue
ObjRelease(element)
ObjRelease(ElementFromHandle)
msgbox % StrGet(NumGet(variant, 8, "ptr"), "utf-16")
return

7

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Так работает. А какое здесь преимущество перед IAccessible?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

В скорости поиска.
У IAccessible нет встроенных методов, а тут есть.
Например IUIAutomationElement::FindFirst.

9

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Да, это должно ускорить, надо поизучать.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Последний код завершается с ошибкой.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Спасибо.
Изменил создание SafeArray.

setbatchlines -1
IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
oStates := [focusable_haspopup := 0x40100000, collapsed_focusable_haspopup := 0x40100400, expanded_focusable_haspopup := 0x40100200, focused_focusable_haspopup := 0x40100004, focused_collapsed_focusable_haspopup := 0x40100404, focused_expanded_focusable_haspopup := 0x40100204]
SafeArray := DllCall("oleaut32\SafeArrayCreateVector", "uint", VT_UNKNOWN := 13, "uint", 0, "uint", oStates.Count())
if (A_PtrSize = 4)
   SafeArrayConditions := ComObject(0x2000|3, SafeArray, 1)
else
   SafeArrayConditions := ComObject(0x2000|0x14, SafeArray, 1)
loop % oStates.Count()
{
   VarSetCapacity(variant, 8+A_PtrSize*2, 0)
   NumPut(VT_I4 := 3, variant, 0, "ushort")
   NumPut(oStates[A_Index], variant, 8, "int")
   if (A_PtrSize = 4)
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_LegacyIAccessibleStatePropertyId := 30096, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   else
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_LegacyIAccessibleStatePropertyId := 30096, "ptr", &variant, "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   SafeArrayConditions[A_Index-1] := condition
}
DllCall(NumGet(NumGet(IUIAutomation+0)+29*A_PtrSize), "ptr", IUIAutomation, "ptr", ComObjValue(SafeArrayConditions), "ptr*", condition1)   ; IUIAutomation::CreateOrConditionFromArray
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(VT_I4 := 3, variant, 0, "ushort")
NumPut(UIA_EditControlTypeId := 50004, variant, 8, "int")
if (A_PtrSize = 4)
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_ControlTypePropertyId := 30003, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition2)   ; IUIAutomation::CreatePropertyCondition
else
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_ControlTypePropertyId := 30003, "ptr", &variant, "ptr*", condition2)   ; IUIAutomation::CreatePropertyCondition
DllCall(NumGet(NumGet(IUIAutomation+0)+25*A_PtrSize), "ptr", IUIAutomation, "ptr", condition1, "ptr", condition2, "ptr*", conditions)   ; IUIAutomation::CreateAndCondition
ObjRelease(condition1)
ObjRelease(condition2)
DllCall("oleaut32\SafeArrayDestroy", "ptr", SafeArray)
return

f11::
DllCall(NumGet(NumGet(IUIAutomation+0)+6*A_PtrSize), "ptr", IUIAutomation, "ptr", WinExist("A"), "ptr*", ElementFromHandle)   ; IUIAutomation::ElementFromHandle
DllCall(NumGet(NumGet(ElementFromHandle+0)+5*A_PtrSize), "ptr", ElementFromHandle, "int", TreeScope_Descendants := 0x4, "ptr", conditions, "ptr*", element) ; IUIAutomationElement::FindFirst
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
DllCall(NumGet(NumGet(element+0)+10*A_PtrSize), "ptr", element, "int", UIA_ValueValuePropertyId := 30045, "ptr", &variant)   ; IUIAutomationElement::GetCurrentPropertyValue
ObjRelease(element)
ObjRelease(ElementFromHandle)
msgbox % StrGet(NumGet(variant, 8, "ptr"), "utf-16")
return

12

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Угу, работает. ComObjValue(SafeArrayConditions) — это сам SafeArray и есть.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Вначале я его создавал так

SafeArray := ComObjArray(VT_UNKNOWN := 13, oStates.Count())

Сейчас так:

SafeArray := DllCall("oleaut32\SafeArrayCreateVector", "uint", VT_UNKNOWN := 13, "uint", 0, "uint", oStates.Count())

Я думал это одно и тоже, а похоже, что нет.

14

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

teadrinker пишет:

ComObjValue(SafeArrayConditions) — это сам SafeArray и есть.

Я имею в виду, что можно так:

DllCall(NumGet(NumGet(IUIAutomation+0)+29*A_PtrSize), "ptr", IUIAutomation, "ptr", SafeArray, "ptr*", condition1)
Malcev пишет:

Вначале я его создавал так

Да, я стал смотреть и тоже подумал, что так должно работать, но почему-то не выходит.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Ещё так можно:

SafeArray := DllCall("oleaut32\SafeArrayCreateVector", "uint", VT_UNKNOWN := 13, "uint", 0, "uint", oStates.Count())
loop % oStates.Count()
{
   VarSetCapacity(variant, 8+A_PtrSize*2, 0)
   NumPut(VT_I4 := 3, variant, 0, "ushort")
   NumPut(oStates[A_Index], variant, 8, "int")
   if (A_PtrSize = 4)
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_LegacyIAccessibleStatePropertyId := 30096, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   else
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_LegacyIAccessibleStatePropertyId := 30096, "ptr", &variant, "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   NumPut(condition, NumGet(SafeArray + 8 + A_PtrSize) + A_PtrSize*(A_Index - 1))
}
DllCall(NumGet(NumGet(IUIAutomation+0)+29*A_PtrSize), "ptr", IUIAutomation, "ptr", SafeArray, "ptr*", condition1)   ; IUIAutomation::CreateOrConditionFromArray
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16 (изменено: teadrinker, 2021-04-13 14:56:19)

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Понял, что было с SafeArray не так, нужно было флаг F_OWNVALUE удалить:

setbatchlines -1
IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
oStates := [focusable_haspopup := 0x40100000, collapsed_focusable_haspopup := 0x40100400, expanded_focusable_haspopup := 0x40100200, focused_focusable_haspopup := 0x40100004, focused_collapsed_focusable_haspopup := 0x40100404, focused_expanded_focusable_haspopup := 0x40100204]

SafeArray := ComObjArray(VT_UNKNOWN := 13, oStates.Count())
ComObjFlags(SafeArray, -1)               ; Remove F_OWNVALUE
pSafeArray := ComObjValue(SafeArray)

loop % oStates.Count()
{
   VarSetCapacity(variant, 8+A_PtrSize*2, 0)
   NumPut(VT_I4 := 3, variant, 0, "ushort")
   NumPut(oStates[A_Index], variant, 8, "int")
   if (A_PtrSize = 4)
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_LegacyIAccessibleStatePropertyId := 30096, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   else
      DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_LegacyIAccessibleStatePropertyId := 30096, "ptr", &variant, "ptr*", condition)   ; IUIAutomation::CreatePropertyCondition
   NumPut(condition, NumGet(pSafeArray + 8 + A_PtrSize) + A_PtrSize*(A_Index - 1))
}
DllCall(NumGet(NumGet(IUIAutomation+0)+29*A_PtrSize), "ptr", IUIAutomation, "ptr", pSafeArray, "ptr*", condition1)   ; IUIAutomation::CreateOrConditionFromArray
NumPut(VT_I4 := 3, variant, 0, "ushort")
NumPut(UIA_EditControlTypeId := 50004, variant, 8, "int")
if (A_PtrSize = 4)
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_ControlTypePropertyId := 30003, "int64", NumGet(variant, 0, "int64"), "int64", NumGet(variant, 8, "int64"), "ptr*", condition2)   ; IUIAutomation::CreatePropertyCondition
else
   DllCall(NumGet(NumGet(IUIAutomation+0)+23*A_PtrSize), "ptr", IUIAutomation, "int", UIA_ControlTypePropertyId := 30003, "ptr", &variant, "ptr*", condition2)   ; IUIAutomation::CreatePropertyCondition
DllCall(NumGet(NumGet(IUIAutomation+0)+25*A_PtrSize), "ptr", IUIAutomation, "ptr", condition1, "ptr", condition2, "ptr*", conditions)   ; IUIAutomation::CreateAndCondition
ObjRelease(condition1)
ObjRelease(condition2)
DllCall("oleaut32\SafeArrayDestroy", "ptr", pSafeArray)
return

f11::
DllCall(NumGet(NumGet(IUIAutomation+0)+6*A_PtrSize), "ptr", IUIAutomation, "ptr", WinExist("A"), "ptr*", ElementFromHandle)   ; IUIAutomation::ElementFromHandle
DllCall(NumGet(NumGet(ElementFromHandle+0)+5*A_PtrSize), "ptr", ElementFromHandle, "int", TreeScope_Descendants := 0x4, "ptr", conditions, "ptr*", element) ; IUIAutomationElement::FindFirst
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
DllCall(NumGet(NumGet(element+0)+10*A_PtrSize), "ptr", element, "int", UIA_ValueValuePropertyId := 30045, "ptr", &variant)   ; IUIAutomationElement::GetCurrentPropertyValue
ObjRelease(element)
ObjRelease(ElementFromHandle)
msgbox % StrGet(NumGet(variant, 8, "ptr"), "utf-16")
return
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: Получение значения адресной строки в фаерфоксе через UIA

Точно.