Огромное спасибо! Оставил пока в таком виде:
1::
MouseGetPos, X, Y
Global HW := WinExist("A")
HC := ControlIdFromPoint( X, Y)
ToolTip % GetClassNN(HC)
Return
ControlIdFromPoint(X, Y)
{
static EnumChildFindPointProc=0
if !EnumChildFindPointProc
EnumChildFindPointProc := RegisterCallback("EnumChildFindPoint","Fast")
VarSetCapacity(rect, 16)
DllCall("GetWindowRect","uint",HW,"uint",&rect)
VarSetCapacity(pah, 36, 0)
NumPut(X + NumGet(rect,0,"int"), pah,0,"int")
NumPut(Y + NumGet(rect,4,"int"), pah,4,"int")
DllCall("EnumChildWindows","uint",HW,"uint",EnumChildFindPointProc,"uint",&pah)
return NumGet(pah,24)
}
EnumChildFindPoint(aWnd, lParam)
{
if !DllCall("IsWindowVisible","uint",aWnd)
return true
VarSetCapacity(rect, 16)
if !DllCall("GetWindowRect","uint",aWnd,"uint",&rect)
return true
pt_x:=NumGet(lParam+0,0,"int"), pt_y:=NumGet(lParam+0,4,"int")
rect_left:=NumGet(rect,0,"int"), rect_right:=NumGet(rect,8,"int")
rect_top:=NumGet(rect,4,"int"), rect_bottom:=NumGet(rect,12,"int")
if (pt_x >= rect_left && pt_x <= rect_right && pt_y >= rect_top && pt_y <= rect_bottom)
{
center_x := rect_left + (rect_right - rect_left) / 2
center_y := rect_top + (rect_bottom - rect_top) / 2
distance := Sqrt((pt_x-center_x)**2 + (pt_y-center_y)**2)
update_it := !NumGet(lParam+24)
if (!update_it)
{
rect_found_left:=NumGet(lParam+8,0,"int"), rect_found_right:=NumGet(lParam+8,8,"int")
rect_found_top:=NumGet(lParam+8,4,"int"), rect_found_bottom:=NumGet(lParam+8,12,"int")
if (rect_left >= rect_found_left && rect_right <= rect_found_right
&& rect_top >= rect_found_top && rect_bottom <= rect_found_bottom)
update_it := true
else if (distance < NumGet(lParam+28,0,"double")
&& (rect_found_left < rect_left || rect_found_right > rect_right
|| rect_found_top < rect_top || rect_found_bottom > rect_bottom))
update_it := true
}
if (update_it)
{
NumPut(aWnd, lParam+24)
DllCall("RtlMoveMemory","uint",lParam+8,"uint",&rect,"uint",16)
NumPut(distance, lParam+28, 0, "double")
}
}
return true
}
GetClassNN(HC) {
WinGetClass, CL, ahk_id %HC%
WinGet, List, ControlList, ahk_id %HW%
Loop, parse, List, `n
{
If InStr(A_LoopField, CL)
{
ControlGet, id, Hwnd, , %A_LoopField%, ahk_id %HW%
If (id = HC)
Return A_LoopField
}
}
Return False
}
Что интересно, оказалось что FindWindowEx "не знает" про многие контролы, например ListView:
GetClassNN(HC) {
WinGetClass, CL, ahk_id %HC%
While HA := DllCall("FindWindowEx", UInt,HW, UInt,HA, UInt,&CL, UInt,0)
If (HA = HC)
Return CL . A_Index
Return False
}
Заменил на WinGet, List, ControlList
Совсем немного сократил ControlNNFromPoint, но не смог EnumChildFindPoint, если вы знаете что ненужного можно вычеркнуть, подскажите.
---
Что ж, всё пока супер, координаты задаются относительно окна и контрол определяется даже в свёрнутом окне!
---
С порядком контролов вообще не всё понятно. Вот пример ниже. Когда окно создаётся, сверху вроде бы Edit5. Но если щёлкнуть в нём мышью, там оказывается Edit1. Или просто вывести поверх другое окно — тот же эффект.
Угу, но продолжает определяться MouseGetPos и этой функцией как Edit5. Но при запуске скрипта ControlFocus сразу определяет Edit1.
Если сделать так:
Gui, Add, Edit, x5 y5 w111 h111, Edit 1
Gui, Add, Edit, wp hp xp yp, Edit 2
Gui, Add, Edit, wp hp xp yp, Edit 3
Gui, Add, Edit, wp hp xp yp, Edit 4
Gui, Add, Edit, wp vEdit hp xp yp, Edit 5
GuiControl, Focus, Edit
Gui, Show
ControlFocus определяет Edit5, но при клике всё тоже самое.
По вопросам возмездной помощи пишите на
E-Mail: serzh82saratov@mail.ru Telegram:
https://t.me/sergiol982Win10x64
AhkSpy,
Hotkey,
ClockGui