Тема: AHK: Определить контрол по координатам
Собсно вопрос в заголовке. Мышь не использовать.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Собсно вопрос в заголовке. Мышь не использовать.
loop
ToolTip % Acc_WindowFromObject2(Acc_ObjectFromPoint2( "", x = "", y = ""))
Acc_ObjectFromPoint2(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_WindowFromObject2(pacc)
{
If DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
Return hWnd
}
Acc_ObjectFromPoint2 - кормить нужными x и y относительно экрана.
IsObject(pacc)?ComObjValue(pacc):pacc
Это скопипастено так, без пробелов?
Acc_Init() - этой функции нет в коде...
К сожалению не смог запустить, а проще метода нету?
К сожалению не смог запустить
Правильно, так должно работать:
SetFormat, IntegerFast, h
loop
ToolTip % Acc_WindowFromObject2(Acc_ObjectFromPoint2())
Acc_ObjectFromPoint2()
{
Acc_Init2()
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_WindowFromObject2(pacc)
{
If DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
Return hWnd
}
Acc_Init2()
{
Static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Это скопипастено так, без пробелов?
Да из библиотеки Acc.
а проще метода нету?
Пока в голову не пришло.
Можно немного упростить запись:
SetFormat, IntegerFast, h
loop
ToolTip % hWndFromPoint( 100, 100)
hWndFromPoint( x, y)
{
Static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
If DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x&0xFFFFFFFF|y<<32, "Ptr*", pacc)=0
pacc := ComObjEnwrap(9,pacc,1)
If DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
Return hWnd
}
АП:
Исправил код в 4 посте.
А что за 7-значные цифры эта функция возвращает? Использую на Gui, Add, Picture. Window Spy ничего похожего не показывает.
Возвращает хэндл контрола, а что нужно то? И Window Spy что может показать?
А почему нельзя получить список всех контролов и потом узнать к какому из них принадлежат ваши x и y.
Malcev
Можно, кто сказал нельзя. Применить для каждого ControlGetPos, просто может занять много времени для большого списка, зато можно узнавать и в свёрнутом окне какой контрол находится в заданных координатах.
В принципе если по hWnd требуется узнавать classnn контрола и порядковый номер, то ControlList всё таки тоже придётся получать.
Malcev
1::
tX := 23, tY := 349
hActWin := WinExist("A")
WinGet, ListControl, ControlList, ahk_id %hActWin%
Loop, parse, ListControl, `n
{
ControlGetPos, cX, cY, cW, cH, %A_LoopField%, ahk_id %hActWin%
If (cX <= tX && cY <= tY && cX + cW >= tX && cY + cH >= tY)
{
ControlGet, Visible, Visible,, %A_LoopField%, ahk_id %hActWin%
If Visible
MsgBox,, %tX% - %tY%, %A_LoopField% `n x%cX% w%cW% y%cY% h%cH%
}
}
Вот только много совпадений. Посмотрите на калькуляторе например кнопку 7.
ап:
Так вместо 5, 3 совпадения:
1::
tX := 23, tY := 349
hActWin := WinExist("A")
WinGet, ListControl, ControlList, ahk_id %hActWin%
Loop, parse, ListControl, `n
{
ControlGetPos, cX, cY, cW, cH, %A_LoopField%, ahk_id %hActWin%
If (cX > tX || cY > tY)
Continue
If (cX + cW >= tX && cY + cH >= tY)
{
ControlGet, Visible, Visible,, %A_LoopField%, ahk_id %hActWin%
If Visible
MsgBox,, %tX% - %tY%, %A_LoopField% `n x%cX% w%cW% y%cY% h%cH% `n Vis %Vis%
}
}
Слизал с оф.форума.
F3::
ActiveHwnd := WinExist("A")
Control := CoordGetControl("33","186", ActiveHwnd)
msgbox % Control
Return
CoordGetControl(xCoord, yCoord, _hWin) ; _hWin should be the ID of the active window
{
CtrlArray := Object()
WinGet, ControlList, ControlList, ahk_id %_hWin%
Loop, Parse, ControlList, `n
{
Control := A_LoopField
ControlGetPos, left, top, right, bottom, %Control%, ahk_id %_hWin%
right += left, bottom += top
if (xCoord >= left && xCoord <= right && yCoord >= top && yCoord <= bottom)
MatchList .= Control "|"
}
StringTrimRight, MatchList, MatchList, 1
Loop, Parse, MatchList, |
{
ControlGetPos,,, w, h, %A_LoopField%, ahk_id %_hWin%
Area := w * h
CtrlArray[Area] := A_LoopField
}
for Area, Ctrl in CtrlArray
{
Control := Ctrl
if A_Index = 1
break
}
return Control
}Malcev
Это можно и попроще записать:
1:: MsgBox % CoordGetControl(23, 349, WinExist("A"))
CoordGetControl(tX, tY, hActWin) {
WinGet, ListControl, ControlList, ahk_id %hActWin%
Loop, parse, ListControl, `n
{
ControlGetPos, cX, cY, cW, cH, %A_LoopField%, ahk_id %hActWin%
If (cX <= tX && cY <= tY && cX + cW >= tX && cY + cH >= tY)
(LastMinArea >= cW * cH || LastMinArea = "")
? (LastMinArea := cW * cH, Control := A_LoopField) : ""
}
Return Control
}
Принцип тот же.
Но почему вы думаете что нужный нам контрол (естественно подходящий под координаты), это обязательно тот, который ниже по списку, и меньшей площадью?
Я не знаю. Но ведь работает же.
Может потому, что контролы располагаются от большего к меньшему "матрешкой"?
Да, что то размытые критерии.
Malcev
Это можно и попроще записать:
Похоже это то что нужно!
От WinGet, ListControl, ControlList ранее отказался, т.к. он возвращал отсортированный список (Static1, Static2...), а у меня Picture передвигаемые.
Решил накодить на AHK "Три в ряд")), задача с определением контрола решена, спасибо, будем думать дальше.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться