list keys and their shift equivalents Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

list keys and their shift equivalents

20 Sep 2018, 16:45

- On my particular keyboard, here are the digits, and the characters you get when you press the digit keys while holding down shift.
1234567890 -> !"£$%^&*()
- I was wondering if there was any way to obtain this information programmatically. I don't especially need this information, however, it can be useful when comparing keyboards.
- (Actually, the information could be useful when trying to identify what keys are available for hotkeys.)
- One possible idea would be to send key presses using ControlSend to a hidden Edit control, demonstrated below.
- For reference, I also provide a script that lists all of the keys that AutoHotkey's GetKeyName function identifies.

Code: Select all

q:: ;list keys and their shift equivalents
;1234567890 -> !"£$%^&*()
vDHW := A_DetectHiddenWindows
DetectHiddenWindows, On
hWnd := DllCall("user32\CreateWindowEx", UInt,0, Str,"Edit", Str,"`r`n", UInt,0, Int,0, Int,0, Int,0, Int,0, Ptr,0, Ptr,0, Ptr,0, Ptr,0, Ptr)
ControlSend,, {Shift Down}1234567890{Shift Up}, % "ahk_id " hWnd
ControlGetText, vText,, % "ahk_id " hWnd
DllCall("user32\DestroyWindow", Ptr,hWnd)
DetectHiddenWindows, % vDHW
Clipboard := vText
MsgBox, % vText
return

w:: ;get key names
vOutput .= "SC:`r`n"
Loop, 256
{
	vNum := A_Index-1
	vKey := GetKeyName(Format("sc{:x}", vNum))
	if !(vKey = "")
		vOutput .= vNum "`t" vKey "`r`n"
}
vOutput .= "`r`n" "VK:`r`n"
Loop, 256
{
	vNum := A_Index-1
	vKey := GetKeyName(Format("vk{:x}", vNum))
	if !(vKey = "")
		vOutput .= vNum "`t" vKey "`r`n"
}
Clipboard := vOutput
MsgBox, % "done"
return
- A related problem is to get the letters qwertyuiopasdfghjklzxcvbnm without typing them in manually, or copying them from the Internet, (both of which are so barbaric,) but to instead obtain them via a pure method. A solution is offered here:
GET LETTERS IN KEYBOARD ORDER (E.G. 'QWERTY' ORDER)
jeeswg's characters tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=26486
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: list keys and their shift equivalents  Topic is solved

21 Sep 2018, 02:30

:arrow: Related topic.
Example, very limited testing,

Code: Select all

toUnicode(key, kbd := '', capslock := false) {
	; Url:
	;		- https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-tounicode
	local
	static cchBuff := 3
	
	varsetcapacity lpKeyState, 256, 0
	if isobject(kbd)
		for k, key in kbd
			numput 128, lpKeyState, getkeyvk(key), 'uchar'
	if capslock
		numput 1, lpKeyState, 0x14, 'uchar'
	varsetcapacity pwszBuff, 8, 0	
	
	r := DllCall('User32.dll\ToUnicode', 	'uint', getkeyvk(key),
											'uint', getkeysc(key), 
											'uptr', &lpKeyState, 
											'ptr', 	&pwszBuff, 
											'int', 	cchBuff, 
											'uint', wFlags,
											'int')
	if r >= 1
		return strget(&pwszBuff)
	/*
	The function returns one of the following values.

	Return value	Description
	-1				The specified virtual key is a dead-key character (accent or diacritic). 
					This value is returned regardless of the keyboard layout, even if several
					characters have been typed and are stored in the keyboard state. 
					If possible, even with Unicode keyboard layouts, the function has written 
					a spacing version of the dead-key character to the buffer specified by pwszBuff.
					For example, the function writes the character SPACING ACUTE (0x00B4),
					rather than the character NON_SPACING ACUTE (0x0301).
					
	0				The specified virtual key has no translation for the current state of the keyboard.
					Nothing was written to the buffer specified by pwszBuff.
					
	1				One character was written to the buffer specified by pwszBuff.
	
	2 ≤ value		Two or more characters were written to the buffer specified by pwszBuff.
					The most common cause for this is that a dead-key character (accent or diacritic)
					stored in the keyboard layout could not be combined with the specified virtual
					key to form a single character. However, the buffer may contain more characters
					than the return value specifies. When this happens, any extra characters are
					invalid and should be ignored.
	*/
	return r ; returns a number if
	
}
; example
msgbox tounicode('a', ['shift'])		; +a
msgbox tounicode('a', ['shift'], 1)		; +a with  capslock
msgbox tounicode('1', ['shift'])		; +1
msgbox tounicode('2', ['ctrl', 'alt'])	; ^!2
Cheers.

edit: url
Last edited by Helgef on 21 Sep 2018, 04:21, edited 1 time in total.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: list keys and their shift equivalents

21 Sep 2018, 03:41

- Well that took less time than I was expecting. Thanks a lot Helgef.
- Note: Helgef's code is AHK v2, although my code here is AHK v1.1.

Code: Select all

q:: ;list keys and their shift equivalents
;1234567890 -> !"£$%^&*()
vText := "1234567890"
vOutput := ""
Loop, Parse, vText
{
	vKey := A_LoopField
	vChars := 3, vFlags := 0
	VarSetCapacity(vKeyOut, vChars*2+2, 0)
	VarSetCapacity(vKeyState, 256, 0)
	NumPut(0x80, &vKeyState, GetKeyVK("Shift"), "UChar")
	vRet := DllCall("user32\ToUnicode", UInt,GetKeyVK(vKey), UInt,GetKeySC(vKey), Ptr,&vKeyState, Ptr,&vKeyOut, Int,vChars, UInt,vFlags)
	vKeyOut := (vRet >= 1) ? StrGet(&vKeyOut) : ""
	vOutput .= vKeyOut
}
Clipboard := vOutput
MsgBox, % vOutput
return
- I've been wondering about the hotkey 'does not exist in the current keyboard layout' error, and what checks it does. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: mikeyww and 308 guests