Что нового

[Баг] GUICtrlSetCursor блокирует WM_SETCURSOR

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Обнаружил, что в версиях AutoIt 3.3.10.2 и 3.3.12.0, при установки курсора для элемента при помощи функции GUICtrlSetCursor(), блокируется обработка сообщения WM_SETCURSOR, wParam не возвращает Handle элемента на котором находится курсор. В версиях (не бета - на бетах не проверял) ниже все отрабатывает на ура. Проверял на Windows 7x32. Пример:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

Global $hGui, $iLbl, $hLbl, $iBtn, $hBtn, $iCountBtn, $iCountLbl, $iCursor = 0

$hGui = GUICreate('Test ' & @AutoItVersion, 200, 150)
$iLbl = GUICtrlCreateLabel('', 20, 40, 160, 20, BitOR($GUI_SS_DEFAULT_LABEL, $SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetBkColor($iLbl, 0xFFFFFF)
$hLbl = GUICtrlGetHandle($iLbl)
GUICtrlSetData($iLbl, 'Test GUICtrlSetCursor')
$iBtn = GUICtrlCreateButton('SetCursor', 20, 80, 160, 40)
$hBtn = GUICtrlGetHandle($iBtn)
GUISetState()
GUIRegisterMsg($WM_SETCURSOR, '_WM_SETCURSOR')

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $iBtn
			GUICtrlSetData($iBtn, 'SetCursor, Now = ' & $iCursor)
			GUICtrlSetCursor($iLbl, $iCursor)
			GUICtrlSetCursor($iBtn, $iCursor)
			$iCursor += 1
			If $iCursor = 16 Then $iCursor = 0
	EndSwitch
WEnd

Func _WM_SETCURSOR($h_Wnd, $i_Msg, $i_wParam, $i_lParam)
	Switch $h_Wnd
		Case $hGui
			Switch $i_wParam
				Case $hLbl
					$iCountLbl += 1
					ConsoleWrite($iCountLbl & ' Cursor on Label' & @LF)
				Case $hBtn
					$iCountBtn += 1
					ConsoleWrite($iCountBtn & ' Cursor on Button' & @LF)
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_SETCURSOR
 
Автор
madmasles

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
Спасибо!


Вариант, как можно обойти этот баг.
Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

Global $hGui, $iLbl, $hLbl, $iBtn, $hBtn, $iCountBtn, $iCountLbl, $iCursor = 0, $aInfo

$hGui = GUICreate('Test ' & @AutoItVersion, 200, 150)
$iLbl = GUICtrlCreateLabel('', 20, 40, 160, 20, BitOR($GUI_SS_DEFAULT_LABEL, $SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetBkColor($iLbl, 0xFFFFFF)
$hLbl = GUICtrlGetHandle($iLbl)
GUICtrlSetData($iLbl, 'Test GUICtrlSetCursor')
$iBtn = GUICtrlCreateButton('SetCursor', 20, 80, 160, 40)
$hBtn = GUICtrlGetHandle($iBtn)
GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $iBtn
			GUICtrlSetData($iBtn, 'SetCursor, Now = ' & $iCursor)
			GUICtrlSetCursor($iLbl, $iCursor)
			GUICtrlSetCursor($iBtn, $iCursor)
			$iCursor += 1
			If $iCursor = 16 Then $iCursor = 0
		Case $GUI_EVENT_MOUSEMOVE
			$aInfo = GUIGetCursorInfo()
			If @error Then ContinueLoop
			Switch $aInfo[4]
				Case $iLbl
					$iCountLbl += 1
					ConsoleWrite($iCountLbl & ' Cursor on Label' & @LF)
				Case $iBtn
					$iCountBtn += 1
					ConsoleWrite($iCountBtn & ' Cursor on Button' & @LF)
			EndSwitch
	EndSwitch
WEnd
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,484

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,484
Тикет закрыли, объяснив что на MSDN написано что это нормально, wParam возвращает дескриптор окна а не элемента.
Хотя это неправда, раньше же оно возвращало дескриптор элемента, или сейчас возвращает также, но если не использовать GUICtrlSetCursor()...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,484
Ещё вариант обхода проблемы:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

$hGui = GUICreate('Test ' & @AutoItVersion, 200, 150)
$iLbl = GUICtrlCreateLabel('Test GUICtrlSetCursor', 20, 40, 160, 20)
$hLbl = GUICtrlGetHandle($iLbl)

GUISetState()
GUIRegisterMsg($WM_SETCURSOR, 'WM_SETCURSOR')
GUICtrlSetCursor($iLbl, 0)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func WM_SETCURSOR($hWnd, $iMsg, $wParam, $lParam)
	AdlibRegister('_CheckCtrl', 1)
    Return $GUI_RUNDEFMSG
EndFunc

Func _CheckCtrl()
	AdlibUnRegister('_CheckCtrl')
	
	Local $tPoint = _WinAPI_GetMousePos()
	Local $hCtrl = _WinAPI_WindowFromPoint($tPoint)
	
	If $hCtrl = $hLbl Then
		ConsoleWrite('$hCtrl = $hLbl ? True' & @LF)
	EndIf
EndFunc
 
Верх