Что нового

GUICtrlEvent - обработка событий мыши

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
На форуме достаточно примеров по обработке событий мыши но решил показать ещё один
пример, более простой :smile:

Функции обработки событий я включил в отдельный Include файл для удобства, так как их
всего 2, то и UDF собирать ни к чему.

GUICtrlEvent.au3
Код:
#cs
    $__aMouseEvent[0][0]  = Count controls
    $__aMouseEvent[id][0] = Id control
	$__aMouseEvent[id][1] = Window handle
	$__aMouseEvent[id][2] = Hover event
	$__aMouseEvent[id][3] = Pressed event
	$__aMouseEvent[id][4] = Control over the cycle
	$__aMouseEvent[id][5] = Blocking of the remaining events
#ce

Global Const $GUI_EVENT_NORMAL  = 0x100
Global Const $GUI_EVENT_HOVER   = 0x200
Global Const $GUI_EVENT_PRESSED = 0x300

Global $__aMouseEvent[1][6] = [[0, 0, 0, 0, 0, 0]]

Func GUICtrlSetEvent($hWnd, $iCtrl)
	$__aMouseEvent[0][0] += 1
	ReDim $__aMouseEvent[$__aMouseEvent[0][0] + 1][Ubound($__aMouseEvent, 2)]
	$__aMouseEvent[$__aMouseEvent[0][0]][0] = $iCtrl
	$__aMouseEvent[$__aMouseEvent[0][0]][1] = $hWnd
	$__aMouseEvent[$__aMouseEvent[0][0]][2] = False
	$__aMouseEvent[$__aMouseEvent[0][0]][3] = False
	$__aMouseEvent[$__aMouseEvent[0][0]][4] = False
	$__aMouseEvent[$__aMouseEvent[0][0]][5] = False
	Return $__aMouseEvent[0][0]
EndFunc

Func GUICtrlGetEvent($id)
	Local $__aInfo = GUIGetCursorInfo($__aMouseEvent[$id][1])
	If ((Not @error) And IsArray($__aInfo)) Then
        If ($__aInfo[4] = $__aMouseEvent[$id][0]) Then
			If ($__aInfo[2] And ($__aMouseEvent[$id][5] <> $__aMouseEvent[$id][0])) Then
			    Return 0
		    EndIf
			$__aMouseEvent[$id][5] = $__aMouseEvent[$id][0]
			If ((Not $__aMouseEvent[$id][2]) And (Not $__aInfo[2])) Then
				$__aMouseEvent[$id][2] = True
				$__aMouseEvent[$id][4] = True
				Return $GUI_EVENT_HOVER
			EndIf
			If $__aInfo[2] Then
				If (Not $__aMouseEvent[$id][3]) Then
					$__aMouseEvent[$id][3] = True
					$__aMouseEvent[$id][4] = True
					Return $GUI_EVENT_PRESSED
				EndIf
			Else
                If $__aMouseEvent[$id][3] Then
					$__aMouseEvent[$id][3] = False
					$__aMouseEvent[$id][4] = True
					ControlClick($__aMouseEvent[$id][1], '', $__aMouseEvent[$id][0])
					Return $GUI_EVENT_HOVER
                EndIf
			EndIf
		Else
			If $__aMouseEvent[$id][3] Then
				$__aMouseEvent[$id][3] = False
				Return $GUI_EVENT_HOVER
			EndIf
			If ($__aMouseEvent[$id][4] And (Not $__aInfo[2])) Then
				$__aMouseEvent[$id][2] = False
				$__aMouseEvent[$id][3] = False
				$__aMouseEvent[$id][4] = False
				$__aMouseEvent[$id][5] = False
				Return $GUI_EVENT_NORMAL
			EndIf
		EndIf
	EndIf
EndFunc

И пример с картинками в архиве.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Неплохо.
Но оно не будет работать если в одном из Case будет задержка (например MsgBox).
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Да кстати, в данном варианте было бы неплохо сделать что то типа этого:

Код:
While 1
	Switch _GUIGetMsgEx()
		Case $GUI_EVENT_CLOSE
			...
		Case $GUI_EVENT_NORMAL
			...
		Case $GUI_EVENT_HOVER
			...
        Case $GUI_EVENT_PRESSED
			...
	EndSwitch
Wend

Func _GUIGetMsgEx($iFlag = 0)
	Local $vMsg = GUIGetMsg($iFlag)
	Local $iID = $vMsg
	If $iFlag <> 0 Then $iID = $vMsg[0]
	
	Local $iCtrlEvent = GUICtrlGetEvent($iID)
	If $iCtrlEvent <> 0 Then Return $iCtrlEvent
    Return $vMsg
EndFunc
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Но оно не будет работать если в одном из Case будет задержка (например MsgBox).

Конечно не очень хорошо будет, но для простых вариантов кода наверное вполне сойдёт, на счёт примера, собирал на быструю руку, тут уже кто как хочет может написать, но я с Вами согласен, с _GUIGetMsgEx было бы лучше :smile:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Viktor1703 [?]
на счёт примера, собирал на быструю руку
Ну тут видимо одним изменением примера не обойтись, возможно нужно будет немного переписать функции обработки.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Тоесть сделать их через DllCallbackRegister ?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
В идеале, это должно было быть так (если бы это встроили нативно):

Код:
#include <GUIConstantsEx.au3>

$hGUI = GUICreate("")
$iButton = GUICtrlCreateButton("Button", 20, 20)
GUISetState(@SW_SHOW, $hGUI)

While 1
	$aMsg = GUIGetMsg(1) ;0 - Default, 1 - Advanced (!!! including hovering info)
	
	Switch $aMsg[0]
		Case $GUI_EVENT_CLOSE
			Exit
		Case $GUI_EVENT_HOVER
			ConsoleWrite('Hovered control: ' & $aMsg[5] & @LF) ;$aMsg[5] - Added element (Hovered CtrlID)
		Case $GUI_EVENT_UNHOVER
			ConsoleWrite('UnHovered control: ' & $aMsg[6] & @LF) ;$aMsg[6] - Added element (UnHovered CtrlID)
		Case $GUI_EVENT_PRESSED
			ConsoleWrite('Pressed/PrimaryDown control: ' & $aMsg[7] & @LF) ;$aMsg[7] - Added element (Pressed/PrimaryDown CtrlID)
		Case $GUI_EVENT_UNPRESSED
			ConsoleWrite('UnPressed/PrimaryUp control: ' & $aMsg[8] & @LF) ;$aMsg[8] - Added element (UnPressed/PrimaryUp CtrlID)
		Case $iButton ;Button event
			
	EndSwitch
WEnd
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Немного подправил “абстракцию”, т.с объект мечтаний :muttley:
 
Верх