Что нового

GUICtrlOnHover - Обработка событии при наведении мышки

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Версия AutoIt
3.3.0.0
Версия
2.1
Категория: Элементы GUI
Описание: Позволяет установить обработчик на событие вызываемое при наведении курсора мышки над элементами GUI (OnHover)
Пример:
Код:
#include "GUICtrlOnHover.au3"

Opt("GUIOnEventMode", 1)

$Btn_Color = 0x7A9DD8
$Hover_Color = 0xFF0000 ;0x7AC5D8

$GUIMain = GUICreate("Letters Hovering Example", 570, 200)
GUISetOnEvent(-3, "Quit")

_CreateLetters_Proc(10, 60, 18, 20)

GUICtrlCreateButton("Close", 30, 120, 100, 30)
GUICtrlSetOnEvent(-1, "Quit")

GUICtrlSetFont(GUICtrlCreateLabel("Letter: ", 35, 170, 200, 20), 9, 800)
$Status_Label = GUICtrlCreateLabel("", 80, 171, 200, 20)
GUICtrlSetColor(-1, 0xFF0000)
GUICtrlSetFont(-1, 8.5, 800)

GUISetState()

While 1
    Sleep(100)
WEnd

Func _CreateLetters_Proc($iLeft, $Top, $Width=15, $Height=15)
    Local $iLeft_Begin = $iLeft
    Local $iAsc_Char = 64
   
    For $i = 0 To 25
        $iLeft_Begin += 20
        $iAsc_Char += 1
        GUICtrlCreateButton(Chr($iAsc_Char), $iLeft_Begin, $Top, $Width, $Height)
       
        _GUICtrl_OnHoverRegister(-1, "_Hover_Func", "_Leave_Hover_Func")
        GUICtrlSetOnEvent(-1, "_Letter_Events")
        GUICtrlSetBkColor(-1, $Btn_Color)
        GUICtrlSetFont(-1, 6)
    Next
EndFunc

Func _Letter_Events()
    MsgBox(64, "Pressed", "Letter = " & GUICtrlRead(@GUI_CtrlId))
EndFunc

Func _Hover_Func($iCtrlID)
    GUICtrlSetBkColor($iCtrlID, $Hover_Color)
    GUICtrlSetData($Status_Label, GUICtrlRead($iCtrlID))
    Beep(1000, 20)
EndFunc

Func _Leave_Hover_Func($iCtrlID)
    GUICtrlSetBkColor($iCtrlID, $Btn_Color)
    GUICtrlSetData($Status_Label, "")
EndFunc

Func Quit()
    Exit
EndFunc
 
Автор
G.Sandler
Источник
Ссылка на источник

Вложения

  • GUICtrlOnHover_v2.1.zip
    158.7 КБ · Просмотры: 15
Последнее редактирование:

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при навидении

Отлично, CreatoR. Спасибо. Я давно ждал этот UDF здесь.

+1

:smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при навидении

Обнаружил одну проблему. Если нажать кнопку мыши вне элемента и затем, не отпуская кнопки, подвести к любому элементу, то срабатывает вызов функции для нажатия. Мог бы ты это пофиксить?

:-\
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Re: GUICtrlSetOnHover - Обработка событии при навидении

Yashied [?]
Если нажать кнопку мыши вне элемента и затем, не отпуская кнопки, подвести к любому элементу, то срабатывает вызов функции для нажатия
Это действительно проблема, и простого решения я пока не вижу. Есть идеи как различить нажатие на кнопке и в другом месте (я уже молчу про нажатие на другом элементе, на который тоже задан OnHover)?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Re: GUICtrlSetOnHover - Обработка событии при навидении

Нашёл решение! :whistle: Правда тут нужно будет задействовать WM_COMMAND и WM_LBUTTONUP...
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Re: GUICtrlSetOnHover - Обработка событии при навидении

Мда, оказалось сложнее чем я думал. Придётся ставить Mouse Hook... Нет не придётся (тем более с ним свои проблемы), всё же обошлось дело одними WM_... сообщениями.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

Как тебе такой вариант?

Код:
#Include <Constants.au3>
#Include <WinAPIEx.au3>
#Include <WindowsConstants.au3>

Global Const $WM_MOUSELEAVE = 0x02A3
;Global Const $WM_MOUSEMOVE = 0x0200

Global $Hover = False

$hForm = GUICreate('MyGUI', 400, 400)
$Button = GUICtrlCreateButton('Exit', 165, 366, 70, 23)

$hButton = GUICtrlGetHandle($Button)
$hDll = DllCallbackRegister('_WinProc', 'ptr', 'hwnd;uint;wparam;lparam')
$pDll = DllCallbackGetPtr($hDll)
$hProc = _WinAPI_SetWindowLong($hButton, $GWL_WNDPROC, $pDll)

GUISetState()

Do
Until GUIGetMsg() = -3

Func _WinProc($hWnd, $iMsg, $wParam, $lParam)
    Switch $iMsg
        Case $WM_MOUSEMOVE
            If Not $Hover Then
                ConsoleWrite('Hover' & @CR)
                $Hover = 1
            EndIf
        Case $WM_MOUSELEAVE
            ConsoleWrite('Leave' & @CR)
            $Hover = 0
    EndSwitch
    Return _WinAPI_CallWindowProc($hProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>_WinProc

Func OnAutoItExit()
    _WinAPI_SetWindowLong($hButton, $GWL_WNDPROC, $hProc)
    DllCallbackFree($hDll)
EndFunc   ;==>OnAutoItExit
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

:(

Здесь тоже есть много проблем.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

Можно еще попробывать использовать _IsPressed() внутри функции таймера и ввести глобальный флаг, который будет однозначно (10 мс - ?) показывать состояние клавиши мыши. Получиться своего рода замена Mouse Hook. Останется только проверить этот флаг перед вызовом пользовательской функции.

Код:
$LeftButtonDown = _IsPressed('01')
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Re: GUICtrlSetOnHover - Обработка событии при наведении

Yashied [?]
Можно еще попробывать использовать _IsPressed() внутри функции таймера
Мне не хотелось бы нагружать скрипт постоянным (и лишним) вызовом Dll'ок... Решение у меня уже есть, вопрос насколько UDF после этого будет конфликтовать с другими скриптами, в силу использования WM сообщении?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

Мне не терпится посмотреть на твое решение.

:laugh:
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Re: GUICtrlSetOnHover - Обработка событии при наведении

Yashied [?]
Мне не терпится посмотреть на твое решение
Примерно так:

В переменные (в начало) добавляем:
Код:
Global $iLAST_PRIMARYDOWN_CTRLID				= 0

Global Const $__GUICtrl_SetOnHover_WM_COMMAND		= 0x0111
Global Const $__GUICtrl_SetOnHover_WM_LBUTTONDOWN	= 0x0201


В функцию _GUICtrl_SetOnHover под условие «If $pTimerProc = 0 Then» добавляем:
Код:
GUIRegisterMsg($__GUICtrl_SetOnHover_WM_COMMAND, "__GUICtrl_SetOnHover_WM_COMMAND")
		GUIRegisterMsg($__GUICtrl_SetOnHover_WM_LBUTTONDOWN, "__GUICtrl_SetOnHover_WM_LBUTTONDOWN")


далее в функции __MAIN_CALLBACK_ONHOVER_PROC находим условие начинающиеся с «If $aCursorInfo[2] = 1 And $aHOVER_CONTROLS_ARRAY[$i][3]» и перед этим условием (в том же «If») добавляем ещё одно:
Код:
$iLAST_PRIMARYDOWN_CTRLID = $iControl_Hovered And


Всё, теперь только осталось добавить сами WM-функции:
Код:
Func __GUICtrl_SetOnHover_WM_COMMAND($hWndGUI, $MsgID, $WParam, $LParam)
	$iLAST_PRIMARYDOWN_CTRLID = $LParam
EndFunc

Func __GUICtrl_SetOnHover_WM_LBUTTONDOWN($hWndGUI, $MsgID, $WParam, $LParam)
	$iLAST_PRIMARYDOWN_CTRLID = 0
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

Да, но WM_LBUTTONDOWN будет работать только с окном, а если я нажму кнопку вне окна, или на другом элементе, или на заголовке окна? Здесь "малой кровью" не обойтись.

А почему ты не хочешь использовать _IsPressed()? Одним DllCall() больше, одним меньше, в данном случае это не имеет никакого значения, т.к. ты все равно используешь таймер. Дополнительная нагрузка будет практически незаметна.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Re: GUICtrlSetOnHover - Обработка событии при наведении

Yashied [?]
почему ты не хочешь использовать _IsPressed()?
Попытался, не получилось приспособить, есть идеи? Кстати свой пост поправил немного, забыл там добавить переменную в начало.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Re: GUICtrlSetOnHover - Обработка событии при наведении

Yashied [?]
WM_LBUTTONDOWN будет работать только с окном, а если я нажму кнопку вне окна, или на другом элементе, или на заголовке окна? Здесь "малой кровью" не обойтись.
Ты пробовал то что я написал? Мне пока не удалось найти ситуацию где бы это решение провалилось ;D. Ок, нашёл где это может не сработать - если при удерживании кнопки увести курсор за пределы окна и отпустить, то потом при удерживании вне окна и наведении над элементом, функция нажатия снова вызывается, но только для последнего нажатого элемента. Решение простое - добавить ещё одно условие: «And WinActive($hParent_Wnd[0])»...
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

CreatoR сказал(а):
Ты пробовал то что я написал?

Выложи пожалуйста правленный UDF, я протестирую.

Кстати, я приспособил свой Icons.au3 для совместной работы с твойм GUICtrlSetOnHover_UDF.au3. Пока только на оф. форуме, но там я выложил прикольный пример, обязательно посмотри.

http://www.autoitscript.com/forum/index.php?showtopic=92675
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

CreatoR сказал(а):
Ок, нашёл где это может не сработать - если при удерживании кнопки увести курсор за пределы окна и отпустить...

Не только за пределы окна, но и на любой другой элемент или заголовок.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
Re: GUICtrlSetOnHover - Обработка событии при наведении

Yashied [?]
Выложи пожалуйста правленный UDF
Ок, обновил.

там я выложил прикольный пример, обязательно посмотри
Клас, мне понравилось. Только вот ширина GUI большая, лучше ориентироваться по @DesktopWidth-10.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

CreatoR сказал(а):
Клас, мне понравилось. Только вот ширина GUI большая, лучше ориентироваться по @DesktopWidth-10.

Да, об этом как-то не подумал.

OffTopic:
Когда на столе стоит 30", то сам понимаешь, о таких мелочах начинаешь забывать. :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Re: GUICtrlSetOnHover - Обработка событии при наведении

CreatoR сказал(а):

Да, сейчас работает как нужно, спасибо. Более детально буду разбираться позже.

+1
 
Верх