Что нового

[Мышь, клавиатура] Можно ли получить хэндл контрола при наведении на него мышкой?

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>

AutoItSetOption("MustDeclareVars", 1)
AutoItSetOption("MouseCoordMode", 1)
AdlibRegister("_Mouse_Control_GetInfoAdlib", 10)
HotKeySet("{ESC}", "_Exit")

Global $pos1 = MouseGetPos()
Global $pos2 = MouseGetPos()
Global $appHandle = 0

While 1
    Sleep(10)
WEnd

Func _Mouse_Control_GetInfoAdlib()
    $pos1 = MouseGetPos()
    If $pos1[0] <> $pos2[0] Or $pos1[1] <> $pos2[1] Then
        Local $a_info = _Mouse_Control_GetInfo()
        Local $aDLL = DllCall('User32.dll', 'int', 'GetDlgCtrlID', 'hwnd', $a_info[0])
        If @error Then Return
        ToolTip("Handle = " & $a_info[0] & @CRLF & _
                "Class = " & $a_info[1] & @CRLF & _
                "ID = " & $aDLL[0] & @CRLF & _
                "Mouse X Pos = " & $a_info[2] & @CRLF & _
                "Mouse Y Pos = " & $a_info[3] & @CRLF & _
                "ClassNN = " & $a_info[4] & @CRLF & _
                "Parent Hwd = " & _WinAPI_GetAncestor($appHandle, $GA_ROOT))
        $pos2 = MouseGetPos()
    EndIf
EndFunc

Func _Mouse_Control_GetInfo()
    Local $client_mpos = $pos1
    Local $a_mpos

    $a_mpos = $client_mpos
    $appHandle = GetHoveredHwnd($client_mpos[0], $client_mpos[1])

    If @error Then Return SetError(1, 0, 0)
    Local $a_wfp = DllCall("user32.dll", "hwnd", "WindowFromPoint", "long", $a_mpos[0], "long", $a_mpos[1])
    If @error Then Return SetError(2, 0, 0)

    Local $t_class = DllStructCreate("char[260]")
    DllCall("User32.dll", "int", "GetClassName", "hwnd", $a_wfp[0], "ptr", DllStructGetPtr($t_class), "int", 260)
    Local $a_ret[5] = [$a_wfp[0], DllStructGetData($t_class, 1), $a_mpos[0], $a_mpos[1], "none"]
    Local $sClassNN = _ControlGetClassnameNN($a_ret[0])
    $a_ret[4] = $sClassNN

    Return $a_ret
EndFunc

Func GetHoveredHwnd($i_xpos, $i_ypos)
    Local $iRet = DllCall("user32.dll", "int", "WindowFromPoint", "long", $i_xpos, "long", $i_ypos)
    If IsArray($iRet) Then
        $appHandle = $iRet[0]
        Return HWnd($iRet[0])
    Else
        Return SetError(1, 0, 0)
    EndIf
EndFunc

Func _ControlGetClassnameNN($hControl)
    If Not IsHWnd($hControl) Then Return SetError(1, 0, "")
    Local Const $hParent = _WinAPI_GetAncestor($appHandle, $GA_ROOT)
    If Not $hParent Then Return SetError(2, 0, "")

    Local Const $sList = WinGetClassList($hParent)
    Local $aList = StringSplit(StringTrimRight($sList, 1), @LF, 2)
    _ArraySort($aList)
    Local $nInstance, $sLastClass, $sComposite

    For $i = 0 To UBound($aList) - 1
        If $sLastClass <> $aList[$i] Then
            $sLastClass = $aList[$i]
            $nInstance = 1
        EndIf
        $sComposite = $sLastClass & $nInstance
        If ControlGetHandle($hParent, "", $sComposite) = $hControl Then
            Return $sComposite
        EndIf
        $nInstance += 1
    Next
    Return SetError(3, 0, "")
EndFunc

Func _Exit()
    Exit
EndFunc
 
Автор
M

Medved

Новичок
Сообщения
27
Репутация
0
Спасибо, пошел разбираться.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Medved,
Еще вариант.
Код:
#include <WinAPIEx.au3>
#include <APIConstants.au3>

$sMessageOld = ''
HotKeySet('{ESC}', '_Quit')

While 1
	$t_Point = _WinAPI_GetMousePos()
	$hHandle = _WinAPI_WindowFromPoint($t_Point)
	$hWin = _WinAPI_GetAncestor($hHandle, $GA_ROOT)
	$sClassW = _WinAPI_GetClassName($hWin)
	If $hHandle = $hWin Then
		$sMessage = 'Window:' & @LF & 'Class Window: ' & $sClassW & @LF & 'Title Window: ' & WinGetTitle($hWin)
	Else
		$sClassC = _WinAPI_GetClassName($hHandle)
		$sID = _WinAPI_GetDlgCtrlID($hHandle)
		$sMessage = 'Control:' & @LF & 'ID Control: ' & $sID & @LF & 'Class Control: ' & $sClassC & @LF & _
				'Class Window: ' & $sClassW & @LF & 'Title Window: ' & WinGetTitle($hWin)
	EndIf
	If $sMessageOld <> $sMessage Then
		$sMessageOld = $sMessage
		ToolTip($sMessageOld, 0, 0)
	EndIf
	Sleep(100)
WEnd

Func _Quit()
	Exit
EndFunc   ;==>_Quit
 
Автор
M

Medved

Новичок
Сообщения
27
Репутация
0
Спасибо, будем посмотреть :beer:


Добавлено:
Сообщение автоматически объединено:

madmasles
Большое спасибо, Ваш вариант очень простой и понятный. Заработало сразу!


Добавлено:
Сообщение автоматически объединено:

madmasles
Я правильно понимаю, что расширенная версия библиотеки винапи тут не используется и можно оставить стандартную?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Medved [?]
Я правильно понимаю, что расширенная версия библиотеки винапи тут не используется и можно оставить стандартную?
Да, это у меня кусок выдран.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
тема очищена от флуда.
Medved, running-frag, пользуйтесь лс
 
Верх