Тема: AHK: ControlSend YouTube Floating Window
Подскажите, пожалуйста, как отправить нажатие в попап окно, открытого с помощью Floating Video. У меня не получилось.
5::
ControlSend, , {Space}, ahk_class Chrome_WidgetWin_1
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Подскажите, пожалуйста, как отправить нажатие в попап окно, открытого с помощью Floating Video. У меня не получилось.
5::
ControlSend, , {Space}, ahk_class Chrome_WidgetWin_1
Либо активируйте окно перед этим либо через iaccessible.
Кстати, что window spy, что AccViewer имеют баги с определением пути.
Лучше использовать AccExplorer от MSDN:
https://github.com/blackrosezy/gui-insp … orer32.exe
либо через iaccessible
А что им делать?
баги с определением пути
Какого пути?
Пути кнопки воспроизведения или паузы.
Запускать хром надо с флагом --force-renderer-accessibility.
А где в window spy такой путь? И что с ним дальше делать?
Название перепутал.
Я имел в виду твой AhkSpy.
Я знаю, но в топике старая версия, там и этого нет.
Так что даёт путь, и флаг хрома?
Ты говоришь А не говоря Б, есть мнение что если бы собеседник знал о чём ты, то у него и вопроса бы не было.
Флаг хрома дает нам возможность управлять хромом через iaccessible интерфейс, то есть нажимать на элементы страницы, используя accDoDefaultAction.
Если мы знаем точный путь кнопки относительно дочернего окна и он не меняется, то мы можем не искать каждый раз кнопку по названию, а выполнять accDoDefaultAction исходя из её пути.
Я не знаю меняется у кнопок этого приложения путь или нет, но AhkSpy его просто не показывает.
Поэтому я и написал про баг.
У меня этого приложения нет, но в окне "Картинка в картинке" у меня показывает путь. В AhkSpy код из AccViewer, я иногда сталкивался с неправильными путями, но разбираться с этим не охота, тем более что я редко встречал элементы с постоянными путями.
но в окне "Картинка в картинке" у меня показывает путь
Ну и как его использовать, если он неверный?
Сравни с результатом у AccViewer.ahk.
https://github.com/Drugoy/Autohotkey-sc … Viewer.ahk
В общем по моей ссылке на гитхабе была ошибка в функции Acc_ObjectFromWindow.
Написал в issue.
Что касаемо неверного пути, то по-моему алгоритм, который выбрал автор по его нахождению не совсем верен.
Он получает список родительских объектов и сравнивает в цикле позицию каждого с позицией дочернего объекта и если они идентичны, то обрывает цикл и считает, что дочерний объект принадлежит именно этому родительскому объекту.
Но существуют ситуации, когда у нескольких родительских объектов может быть такая же позиция, как и у дочернего и тогда уже определить, какому из них принадлежит дочерний можно, наверное, только дойдя до "главного объекта в иерархии" и сравнив свойства объекта полученного из пути со свойствами объекта полученного через Acc_ObjectFromPoint.
Либо можно попробовать получать путь перебирая все объекты в окне и сравнивая их свойства с полученным, через Acc_ObjectFromPoint.
У меня сейчас так выглядит, сможешь поправить?
DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
CoordMode, Mouse, Screen
1::
MouseGetPos, mx, my
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", mx&0xFFFFFFFF|my<<32, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Acc := ComObjEnwrap(9,pacc,1), child := NumGet(varChild,8,"UInt")
If !IsObject(Acc)
Return
ToolTip % GetAccPath(Acc, child)
Return
GetAccPath(Acc, child) {
path := Acc_GetPath(Acc)
if path !=
Return child ? path "," child : path
Else
Return "object not found"
}
Acc_GetPath(Acc) {
hwnd := Acc_WindowFromObject(Acc)
WinObj := Acc_ObjectFromWindow(hwnd)
WinObjPos := Acc_Location(WinObj)
While Acc_WindowFromObject(Parent := Acc_Parent(Acc)) = hwnd {
t2 := GetEnumIndex(Acc) "," t2
if Acc_Location(Parent) = WinObjPos
return SubStr(t2, 1, -1)
Acc := Parent
}
While Acc_WindowFromObject(Parent := Acc_Parent(WinObj)) = hwnd
t1 .= "P.", WinObj := Parent
return t1 SubStr(t2, 1, -1)
}
GetEnumIndex(Acc, ChildId=0) {
if Not ChildId {
ChildPos := Acc_Location(Acc)
For Each, child in Acc_Children(Acc_Parent(Acc))
if IsObject(child) and Acc_Location(child) = ChildPos
return A_Index
}
else {
ChildPos := Acc_Location(Acc,ChildId)
For Each, child in Acc_Children(Acc)
if Not IsObject(child) and Acc_Location(Acc,child) = ChildPos
return A_Index
}
}
Acc_ObjectFromWindow(hWnd, idObject = 0) {
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_Location(Acc, ChildId=0) {
try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
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"))
}
Acc_Parent(Acc) {
try parent:=Acc.accParent
return parent?Acc_Query(parent):
}
Acc_Children(Acc) {
if ComObjType(Acc,"Name")!="IAccessible"
return
else {
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)=3?child:Acc_Query(child)), ObjRelease(child)
return Children
}
}
}
Acc_Query(Acc) {
try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Ну у тебя сейчас вообще непонятно для чего показывется путь, так как не показано к какому окну он относится.
А в целом мне пока непонятно как правильней делать - получать путь от ребенка к родителю, как сейчас, но учитывая возможность присутствия нескольких родительских объектов с нужной позицией, либо через перебирание всех объектов.
В общем посмотрел я какая может быть иерархия iaccessible в разных окнах и понял, что от ребенка к родителю путь будет находиться не всегда - например в хроме, если объект расположен в контроле Chrome_RenderWidgetHostHWND, то на первые 5 уровней можно выйти только добавляя их к полученному пути (они постоянны).
А с некоторых дочерних элементов по данному алгоритму вообще не выйти на родительский (может быть из-за каких-то хитросплетений отображения DOM в броузере), хотя через Acc_ObjectFromWindow можно.
Пример - справка автохотки через фаерфокс 69, win10.
Если по этой ссылке https://www.autohotkey.com/docs/AutoHotkey.htm попытаться получить родительский объект для объекта "1.1.30.03", то мы через через Acc_WindowFromObject(Parent:=Acc_Parent(Acc)) сразу получим хендл родительского окна равный пустоте.
Также в некоторых окнах на дочерний объект можно выйти только с дочерних окон, а в некоторых и с дочерних нельзя.
К тому же есть ситуации, что относительно дочернего окна путь будет постоянен, а относительно главного нет.
Исходя из этого можно сделать вывод, что для того, чтобы получить реальную пользу от пути, нужно получать путь до нужного объекта и от дочернего окна и от главного через Acc_ObjectFromWindow и отображать эти пути вместе с выводом хендлов этих окон.
Так что мои предположения о том, что от AccViewer.ahk пользы никакой, а только путанница - верны.
Если хочешь, то можешь модернизировать этот скрипт и вставить его в AhkSpy:
https://www.autohotkey.com/boards/viewt … mp;t=40615
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться