Что нового

GUICtrlRegisterMsg будет ли.

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Нужно было зарегистрировать оконное сообщение WM_MOUSEMOVE для определенного контрола. Сделал так:
Код:
GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE")

но как оказалось, сообщения только приходят, когда движение мышки происходит в окне, а как только курсор попадает на контрол, то сообщения уже не отсылается.
интересно, почему есть функция GUIRegisterMsg но нет такой же для контролов, скажем GUICtrlRegisterMsg

Хорошо что есть библиотека <a href="http://www.autoitscript.com/forum/topic/144041-guiregistermsgex-udf-like-native-but-for-controls/">_GUIRegisterMsgEx от JScript</a>, за что ему огромное спасибо :smile:
 

asdf8

Скриптер
Сообщения
564
Репутация
152
inververs [?]
когда движение мышки происходит в окне, а как только курсор попадает на контрол, то сообщения уже не отсылается
Почему-то мне кажется, что это не так. Хотя бы пример приведите.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
asdf8
Вот пример:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$Form1 = GUICreate("Form1", 615, 438, 192, 124)
$Graphic1 = GUICtrlCreateGraphic(24, 16, 200, 200)
GUICtrlSetBkColor(-1, 0x99B4D1)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_MOUSEMOVE, "_WM_MOUSEMOVE")
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
Func _WM_MOUSEMOVE($hWnd, $uiMsg, $wParam, $lParam)
	$X = BitAND($lParam, 0xFFFF)
	$Y = BitShift($lParam, 16) ; координаты мыши
	ConsoleWrite($X & ":"& $Y& @LF)
EndFunc

Сообщения не приходят, когда передвигаешь курсор над графиком


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

CreatoR
Интересно. Есть отличные примеры. Но меня удивляет другое, почему что бы регистрировать сообщения от контролов, нужно что то изобретать свое, почему этого нет как стандартной функции.


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

CreatoR
не подходит ваше UDF, мне было нужно что бы функция вызывалась все время, когда происходит движение, что бы знать, где сейчас находится курсор. А у вас, функция вызывается один раз когда курсор над элементом.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
AZJIO
Вызывается постоянно, даже если не двигать курсор.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
inververs
Странно, на WinXP у меня не вызывается постоянно. Когда курсор не двигается, то счётчик вызова в заголовке останавливается (из примера к функции).


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

Можете WM_SETCURSOR ещё попробовать.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
AZJIO
У меня win 7. Вызывается постоянно. Тема не о том, какие костыли можно придумать, а о том, почему их надо выдумавать. Хочу что бы была функция GUICtrlRegisterMsg :whistle:
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
inververs
WM_NCHITTEST это не костыль, эта как бы нативный функционал от MS. Знать бы что вы выдумываете, или вы пока сами не знаете что? А это к флуду.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Почему не знаю, знаю, я рисую график, и мне понадобилось знать, где сейчас находится курсор, над какой точкой. Что бы не опрашивать все время позицию курсора, я подумал, что можно использовать сообщение WM_MOUSEMOVE, но как оказалось не работает.
Тогда я нашел сторонню UDF, которая делает то что нужно. И очень удачно, ведь в таком случае координаты курсора передаются относительно контрола, а не относительно всего окна.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
inververs
Как вы определили, что затрачиваемость ресурсов процессора этой функции меньше, чем производительность нативных функций?

Вы так не сообщили про WM_SETCURSOR, выше ссылка.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
AZJIO [?]
Вы так не сообщили про WM_SETCURSOR, выше ссылка.
Сообщаю, вызывается только при движении.

Как вы определили, что затрачиваемость ресурсов процессора этой функции меньше, чем производительность нативных функций?
Я это и не определял.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
inververs [?]

Действительно странно. Как вариант, если не будет мешать общему алгоритму программы, в пример можно добавить
Код:
GUICtrlSetState($Graphic1, $GUI_DISABLE)

тогда WM_MOUSEMOVE будет работать.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
inververs сказал(а):
Тема не о том, какие костыли можно придумать, а о том, почему их надо выдумавать. Хочу что бы была функция GUICtrlRegisterMsg.

Если сделать функцию GUICtrlRegisterMsg(), то придется делать сабклассинг абсолютно всех создаваемых контролов. В результате это неизбежно приведет к неработоспособности скрипта. Не забывайте, что AutoIt, это интерпритатор, и вмешиваться в оконные процедуры контролов нужно очень осторожно. Например, попробуйте применить вышеупомянутую UDF для ListView...
 

CreatoR

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

На вопрос будет ли функция GUICtrlRegisterMsg (нативно), ответ отрицательный.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Не спорю, что нужно понимать как оно работает. Но autoit, когда создает окно итак берет на себя всю работу по обработке всех сообщений. Мне кажется можно было бы сделать так, что принимая очередное сообщение для контрола,то сперва проверялось, зарегистрированна ли в скрипте какая нибудь пользовательская функция, и если да, то сперва вызывать ее, и есть последняя возвращаяет, что то типа $GUI_RUNDEFMSG, то выполнять обработку "поумолчанию".
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
inververs сказал(а):
Мне кажется можно было бы сделать так, что принимая очередное сообщение для контрола,то сперва проверялось, зарегистрированна ли в скрипте какая нибудь пользовательская функция, и если да, то сперва вызывать ее, и есть последняя возвращаяет, что то типа $GUI_RUNDEFMSG, то выполнять обработку "поумолчанию".

Я выше написал почему это не реализовано.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
inververs
Посмотрите пример содержащийся в справке с событием $GUI_EVENT_MOUSEMOVE
Код:
_GUICtrlHeader_CreateDragImage
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Как замена WM_MOUSEMOVE можно тогда так сделать:
Код:
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)
$Form1 = GUICreate("Form1", 615, 438, 192, 124)
$Graphic1 = GUICtrlCreateGraphic(56, 80, 200, 200)
GUICtrlSetBkColor(-1, 0x99B4D1)
GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SpecialEvents")
GUISetState(@SW_SHOW)
While 1
	Sleep(100)
WEnd
Func SpecialEvents()
	Switch @GUI_CTRLID
		Case $GUI_EVENT_CLOSE
			Exit
		Case $GUI_EVENT_MOUSEMOVE
			$aInfo = GUIGetCursorInfo()
			If $aInfo[4] = $Graphic1 Then
				ConsoleWrite('X:'&$aInfo[0]&' Y:'&$aInfo[1] & @LF)
			EndIf
	EndSwitch
EndFunc
 
Верх