Что нового

Скрытие курсора мыши на всем экране

GreyWerewolf

То тут, то там...
Сообщения
23
Репутация
0
Была необходимость скрыть курсор мыши, а с файлами курсоров возиться не хотелось. Кроме того - если наша программа изменит курсор Windows, то при каком либо непредвиденном вылете нашей программы курсор обратно не восстановится сам.

Появилась идея перекрыть окном весь рабочий стол. В целом для моих целей такой вариант вполне подошел. К сожалению, в таком варианте перетаскивание мышью работать не будет, а если его включить, то на время перетаскивания курсор вылезет наверх.

Мне данный вариант пригодился для того, чтобы видеть, какую область у меня запишет getpixel в текстовый файл. Области были небольшие - курсор перекрывал квадраты-обозначения. Скрыть курсор за квадратами было нельзя - мне через них нужно было кликать.

Внимание! Пример требует наличия MouseOnEvent!
Собственно сам код:

Код:
#include "MouseOnEvent.au3"
#include <WinAPI.au3>

Global $WidthX=(WinGetPos('Program Manager'))[2];разрешение экрана в сумме
Global $hParenttt = GUICreate('', $WidthX, @DesktopHeight, 0, 0);родитель чтобы не было иконки снизу

$hSquare_GUI = GUICreate("", 10, 10,0,0,$WS_POPUPWINDOW, BitOR($WS_EX_LAYERED,$ws_ex_transparent,$WS_EX_TOPMOST),$hParenttt);прорисовка замены курсора
GUISetBkColor(0x0000FF,$hSquare_GUI)
WinSetTrans($hSquare_GUI, '', 100)
GUISetState(@SW_SHOWNA, $hSquare_GUI)

global $hCross_GUI = GUICreate("", $WidthX, @DesktopHeight - 20, 0, 0, 2147483648, 8,$hParenttt);перекрывающее окно
WinSetTrans($hCross_GUI, "", 1)
GUISetState(@SW_SHOWNA, $hCross_GUI)
GUISetCursor(16, 1, $hCross_GUI)

_mousesetonevent($MOUSE_PRIMARYDOWN_EVENT,"_mouseclickdown",$hCross_GUI,1);хоткей на поднятие левой кнопки
HotKeySet("{Esc}","_Exit");выход по Esc

Example()

func Example()
while 1
	sleep(30)
	WinMove($hSquare_GUI, "", MouseGetPos(0), MouseGetPos(1));двигаем замену курсора
WEnd
EndFunc

func _mouseclickdown()
	GUIDelete($hCross_GUI);удаляем прозрачное окно, скрывающее курсор
 if (WinGetState($hCross_GUI)=0) then
	        MouseClick("left");кликаем мышей
			$hCross_GUI = GUICreate("", $WidthX, @DesktopHeight - 20, 0, 0,  2147483648, 8,$hParenttt);снова создаем окно для перекрытия курсора
			GUISetCursor(16, 1, $hCross_GUI)
			GUISetState(@SW_SHOWNA, $hCross_GUI)
			WinSetTrans($hCross_GUI, "", 1)
			_mousesetonevent($MOUSE_PRIMARYDOWN_EVENT,"_mouseclickdown",$hCross_GUI);назначаем новому окну горячую клавишу
 EndIf
EndFunc

Func _Exit()
exit
EndFunc


Бывает ошибка программы при нажатии Esc на выходе. Проблема в библиотеке MouseOnEvent.au3.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Мой вариант:

Код:
#include <WindowsConstants.au3>

$hShow = _CursorShow()
ToolTip('Cursor hidden for 3 seconds...')
Sleep(3000)
_CursorHide($hShow)

Func _CursorShow()
	Local $aRet[2] = [WinGetHandle('[ACTIVE]'), GUICreate('test', @DesktopWidth, @DesktopHeight + 50, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))]
	
	GUIRegisterMsg($WM_ACTIVATE, 'WM_ACTIVATE')
	GUISetCursor(16, 1, $aRet[1])
	WinSetTrans($aRet[1], '', 1)
	GUISetState(@SW_SHOWNOACTIVATE, $aRet[1])
	
	Return $aRet
EndFunc

Func _CursorHide($hShow)
	GUIRegisterMsg($WM_ACTIVATE, '')
	Return GUIDelete($hShow[1])
EndFunc

Func WM_ACTIVATE($hWnd, $iMsg, $wParam, $lParam)
	If BitAND($wParam, 0xFFFF) > 0 And $lParam <> $hShow[1] Then
		WinActivate($hShow[0])
	EndIf
EndFunc
 
Автор
GreyWerewolf

GreyWerewolf

То тут, то там...
Сообщения
23
Репутация
0
CreatoR сказал(а):

Дело не в том, чтобы просто скрыть указатель, это делается еще проще - выносом мыши за экран) Или еще есть функция
Код:
_WinAPI_ShowCursor(True)

В Вашем примере нельзя осуществить щелчок или ввод текста, когда указателя не видно. (ну ввод можно Alt+tab-ом)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Или так:

Код:
#include <WinAPIRes.au3>

_SysCursor_Show(False)

Sleep(3000)

_SysCursor_Show(True)

Func _SysCursor_Show($bShow)
	Local Static $bRet = -1
	
	If $bShow == $bRet Then
		Return SetError(1, 0, 0)
	EndIf
	
	$bRet = $bShow
	
	Local Static $aOCR_Curs[] = _
		[ _
			$OCR_NORMAL, $OCR_IBEAM, $OCR_WAIT, $OCR_CROSS, $OCR_UP, $OCR_SIZE, $OCR_ICON, $OCR_SIZENWSE, _
			$OCR_SIZENESW, $OCR_SIZEWE, $OCR_SIZENS, $OCR_SIZEALL, $OCR_ICOCUR, $OCR_NO, $OCR_HAND, $OCR_APPSTARTING, $OCR_HELP _
		]
	
	Local Static $ahOld_Curs[UBound($aOCR_Curs)]
	Local Static $ahEmpty_Curs[UBound($aOCR_Curs)]
	
	Local $hBitmap[2] = [_WinAPI_CreateBitmap(1, 1, 1, 16), _WinAPI_InvertANDBitmap(_WinAPI_CreateBitmap(1, 1, 1, 1), 1)]
	Local $hEmpty_Cursor = _WinAPI_CreateIconIndirect($hBitmap[0], $hBitmap[1], 0, 0, 0)
	
	_WinAPI_DeleteObject($hBitmap[0])
	_WinAPI_DeleteObject($hBitmap[1])
	
	For $i = 0 To UBound($aOCR_Curs) - 1
		If $bShow Then
			If $ahOld_Curs[$i] And $ahEmpty_Curs[$i] Then
				_WinAPI_SetSystemCursor($ahOld_Curs[$i], $aOCR_Curs[$i])
				_WinAPI_DestroyCursor($ahOld_Curs[$i])
				_WinAPI_DestroyCursor($ahEmpty_Curs[$i])
				
				$ahOld_Curs[$i] = 0
				$ahEmpty_Curs[$i] = 0
			EndIf
		Else
			If $ahOld_Curs[$i] = 0 And $ahEmpty_Curs[$i] = 0 Then
				$ahOld_Curs[$i] = _WinAPI_CopyCursor(_WinAPI_LoadCursor(0, $aOCR_Curs[$i]))
				$ahEmpty_Curs[$i] = _WinAPI_CopyCursor($hEmpty_Cursor)
				_WinAPI_SetSystemCursor($ahEmpty_Curs[$i], $aOCR_Curs[$i])
			EndIf
		EndIf
	Next
	
	_WinAPI_DestroyCursor($hEmpty_Cursor)
EndFunc


но это чревато тем, что при падений скрипта, все ваши системные курсоры будут невидимыми :laugh:.
 
Автор
GreyWerewolf

GreyWerewolf

То тут, то там...
Сообщения
23
Репутация
0
CreatoR сказал(а):
но это чревато тем, что при падений скрипта, все ваши системные курсоры будут невидимыми :laugh:.

О чем я и упоминал в первом сообщении. :rofl:

Странно что нет легкого способа убрать курсор отовсюду. Даже на иностранных форумах все решения - замена файла курсора на время работы скрипта. :scratch:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
См. функцию _WinAPI_SetSystemCursor(). А сам "пустой" курсор можно либо приложить в виде файла, либо нарисовать с помощью GDI.

P.S

CreatoR, похоже, именно так и сделал.
 
Автор
GreyWerewolf

GreyWerewolf

То тут, то там...
Сообщения
23
Репутация
0
Yashied сказал(а):
См. функцию _WinAPI_SetSystemCursor(). А сам "пустой" курсор можно либо приложить в виде файла, либо нарисовать с помощью GDI.
CreatoR, похоже, именно так и сделал.

Данный подход вполне возможен, и в основном, только он и описан на иностранных форумах. Но он опасен по причине сбоя скрипта. Если скрипт не выполнится до конца по какой-либо причине, то пользователь будет иметь проблемы с курсором. О чем CreatoR в своём и я в первом посте и написали. :-X

И, к слову, у CreatoR'а очень элегантное решение, т.к. курсор отдельно заливать с программой не требуется.
 

VadimKHL

Новичок
Сообщения
155
Репутация
0
Добрый день! Проблема в том, что имею устройство на основе Win7 и тачскрин монитора.
Отображение курсора там совсем не нужно.
Очень хорошо подходит данный пример.
CreatoR, если скрыть курсор данным способом, не возвращая его после,
что произойдет при перезагрузки Windows?

Возможно ли сделать так, что бы после срытия курсоров,
они сохранялись, и в любой момент их можно было восстановить,
т.е. решить эту проблему:

CreatoR сказал(а):
но это чревато тем, что при падений скрипта, все ваши системные курсоры будут невидимыми :laugh:.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
VadimKHL

Предупреждение За нарушение общих правил (пункт В.2):
Старайтесь избегать “Over quoting” (преувеличенное цитирование) - цитируйте только необходимую часть сообщения, которая наилучшим образом подчеркнёт суть цитируемого.


С уважением, ваш Глобальный модератор.
 

VadimKHL

Новичок
Сообщения
155
Репутация
0
Проверил. Убил системные курсоры.
После перезагрузки WIN курсоры снова отображаются корректно. :smile:

Вопрос, а как убрать курсоры, которые не системные, в разных приложения (типа paint) ?
 

Hikari

Новичок
Сообщения
22
Репутация
0
А нельзя сделать, чтобы при падении скрипта файл курсора устанавливался на место?.. Думаю это не так уж сложно осуществить
 
Верх