Что нового

Коды и символы клавиш

RaZum

Знающий
Сообщения
78
Репутация
14
Как проще получать символы кодов клавиатуры?
Цель: автоподстановкой устанавливать горячие клавиши.
Пока решений нашёл три:
1) регистрировать функцию на $WM_KEYDOWN и через GetKeyNameText получать символ, предварительно проверив модификаторы. Но ни все нужные клавиши возвращает.
2) получать скан всех клавиш через GetKeyboardState и просеивать массив через цикл, затем определение символов по порядковым номерам.
3) пример под спойлером (прогон через GetAsyncKeyState) но вот с символами напутал :smile:
Код:
Opt("GUIOnEventMode", 1)

Local $sHotKey
Local $user32 = DllOpen ('user32.dll')

	GUICreate ("test", 400,300)
	GUISetOnEvent (-3, 'Close')
Local $Input = GUICtrlCreateInput ("" ,10,50, 200,30, 0x0800)
Local $Label = GUICtrlCreateLabel ("" ,10,100, 200,30, 0x1100)
	GUICtrlSetOnEvent (-1, "SetLabel")
	GUISetState ()

While 1
	Sleep (100)
	$sHotKey = _KeyPressCheck (1, 256)
	If $sHotKey Then GUICtrlSetData ($Input, $sHotKey)
WEnd


Func _WinAPI_GetKeyNameText ($lParam)
	Local $aCall = DllCall ($user32, 'int', 'GetKeyNameTextW', 'long', $lParam, 'wstr', '', 'int', 128)
	If @error Or Not $aCall[0] Then Return SetError (@error, @extended, '')

	Return $aCall[2]
EndFunc

Func _WinAPI_MapVirtualKey ($iCode, $iType, $hLocale = 0)
	Local $aCall = DllCall ($user32, 'INT', 'MapVirtualKeyExW', 'uint', $iCode, 'uint', $iType, 'uint_ptr', $hLocale)
	If @error Then Return SetError (@error, @extended, 0)

	Return $aCall[0]
EndFunc

Func _KeyPressCheck ($iStart, $iFinish)
	Local $ikey, $skey, $ia_R, $Alt, $Ctrl, $Shift, $Win
	
	For $ikey = $iStart To $iFinish
		$ia_R = DllCall ($user32, 'int', 'GetAsyncKeyState', 'int', '0x' & Hex ($ikey, 2))
		If Not @error And BitAND ($ia_R[0], 0x8000) = 0x8000 Then
			
			Switch $ikey
				Case 16 ; назначение Shift
					$Shift = '+'
					ContinueLoop
				Case 17 ; назначение Ctrl
					$Ctrl = '^'
					ContinueLoop
				Case 18 ; назначение Alt
					$Alt = '!'
					ContinueLoop
				Case 91 ; назначение Win
					$Win = '#'
					ContinueLoop
				Case 1 To 6, 92, 160 To 165 ; отсев модификаторов R/L Shift, Ctrl, Alt, R Win ?, MouseClick
					; тут же отсев всего прочего
					ContinueLoop
			EndSwitch
			
			If $skey Then ContinueLoop
			
			$skey = _WinAPI_MapVirtualKey ($ikey, 0)
			$skey = _WinAPI_GetKeyNameText ('0x' & Hex ($skey, 2) & "0000")
			$skey = "{" & $skey & " (" & $ikey & ")" & "}"
		Else
			ContinueLoop
		EndIf
	Next
	
	Return ($skey)?($Shift & $Ctrl & $Alt & $Win & $skey):("")
EndFunc

Func _HotKey ()
	MsgBox (48, "HotKey Test" , @HotKeyPressed)
EndFunc

Func SetLabel ()	
	HotKeySet (GUICtrlRead ($Label))
	HotKeySet (GUICtrlRead ($Input), "_HotKey")
	GUICtrlSetData ($Label, GUICtrlRead ($Input))
EndFunc

Func Close ()
	DllClose ($user32)
	Exit
EndFunc
 
Верх