ToASCIIEx

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

ToASCIIEx

07 Dec 2017, 16:54

I'm sorry to ask here, probably it's the wrong place.... I'd like help to convert this DllCall("ToUnicodeEx") to DllCall("ToASCIIEx") api from the following code. ... ToUnicodeEx gets the name (character) of the virtual key pressed. It works fine. But, I understand from msdn.microsoft.com that toASCIIex can get the key name based on Shift or AltGr state. This what I need for my script (key press OSD).

The code.....

Code: Select all


hkl := DllCall("GetKeyboardLayout", "uint", thread, "ptr")
    vk := GetKeyVK(Key), sc := GetKeySC(Key)
    VarSetCapacity(state, 256, 0)
    VarSetCapacity(char, 4, 0)
    n := DllCall("ToUnicodeEx", "uint", vk, "uint", sc
        , "ptr", &state, "ptr", &char, "int", 2, "uint", 0, "ptr", hkl)
    return StrGet(&char, n, "utf-16")
    
    ‎
Thank you very much. Apologies if I am asking it in the wrong place.

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: list of dll functions with parameter types for DllCall

07 Dec 2017, 18:37

Yes it is the wrong place, maybe someone moves it.
I had these functions, with example,

Code: Select all

toascii(uVirtKey,uScanCode,uFlags:=0) {
	; Url:
	;		- https://msdn.microsoft.com/en-us/library/windows/desktop/ms646316(v=vs.85).aspx
	; params:
	; 		- uVirtKey,	The virtual-key code to be translated.
	; 		- uScanCode, The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed).
	;		- uFlags, This parameter must be 1 if a menu is active, or 0 otherwise.
	; return
	;		- corresponding character yielded by the combination of uVirtKey and whatever modifiers are down.
	static lpKeyState
	if !lpKeyState
		VarSetCapacity(lpKeyState,256,0)
	for modifier, vk in {Shift:0x10, Control:0x11, Alt:0x12}
		NumPut(128*(GetKeyState("L" modifier) || GetKeyState("R" modifier)) , lpKeyState, vk, "Uchar")
	NumPut(GetKeyState("CapsLock", "T") , lpKeyState, 0x14, "Uchar")
	DllCall("User32.dll\ToAscii", "Uint", uVirtKey, "Uint", uScanCode, "UPtr", &lpKeyState, "Uptr*", lpChar, "Uint", uFlags)
	return lpChar ? chr(lpChar) : ""
}

toUnicode(uVirtKey,uScanCode,wFlags:=0) {
	; Url:
	;		- https://msdn.microsoft.com/en-us/library/windows/desktop/ms646320(v=vs.85).aspx
	; params:
	; 		- uVirtKey,	The virtual-key code to be translated.
	; 		- uScanCode, The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed).
	;		- wFlags, The behavior of the function. If bit 0 is set, a menu is active. Bits 1 through 31 are reserved.
	; return
	;		- corresponding character yielded by the combination of uVirtKey and whatever modifiers are down.
	VarSetCapacity(lpKeyState,256,0)
	for modifier, vk in {Shift:0x10, Control:0x11, Alt:0x12}
		NumPut(128*(GetKeyState("L" modifier) || GetKeyState("R" modifier)) , lpKeyState, vk, "Uchar")
	NumPut(GetKeyState("CapsLock", "T") , &lpKeyState+0, 0x14, "Uchar")
	VarSetCapacity(pwszBuff,cchBuff:=3,0)
	DllCall("User32.dll\ToUnicode", "Uint", uVirtKey, "Uint", uScanCode, "UPtr", &lpKeyState, "Uptr*", pwszBuff, "Int", cchBuff, "Uint", wFlags)
	return chr(pwszBuff)
}

keywait("RAlt", "d")
msgbox(toUnicode(getKeyVk("2"), getKeySc("2")))

keywait("shift", "d")
msgbox(toascii(getKeyVk("a"), getKeySc("a")))
Edit: Thanks for moving it.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: ToASCIIEx

08 Dec 2017, 04:40

Thank you very much!

By reading the MSDN documentation, I was unable to understand the difference between ToUnicode vs. ToAscii . Can you please tell me?

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: ToASCIIEx

08 Dec 2017, 05:42

After testing it... some AltGr chars are not returned... for example €, @, ^, ‘,’ and others. Any idea why?

I tried both ToAscii and ToUnicode and both do not want to return such characters.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: ToASCIIEx

08 Dec 2017, 06:49

Hello. I have no examples showing the difference between the functions. When I wrote these functions, I think I decided I would only use the unicode version, I'm not sure though. I used them to translate keypresse s(hotkeys) to text, in real time. As a consequence, the functions depend on the actual state of the modifiers. You can modify them to take the modifiers state as input instead, if you like. I made a minor modification,

Code: Select all

toUnicode(uVirtKey,uScanCode,wFlags:=0) {
	; Url:
	;		- https://msdn.microsoft.com/en-us/library/windows/desktop/ms646320(v=vs.85).aspx
	; params:
	; 		- uVirtKey,	The virtual-key code to be translated.
	; 		- uScanCode, The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed).
	;		- wFlags, The behavior of the function. If bit 0 is set, a menu is active. Bits 1 through 31 are reserved.
	; return
	;		- corresponding character yielded by the combination of uVirtKey and whatever modifiers are down.
	static cchBuff := 3
	local lpKeyState, modifier, vk, pwszBuff
	VarSetCapacity(lpKeyState,256,0)
	for modifier, vk in {Shift:0x10, Control:0x11, Alt:0x12}
		NumPut(128*(GetKeyState("L" modifier) || GetKeyState("R" modifier)) , lpKeyState, vk, "Uchar")
	NumPut(GetKeyState("CapsLock", "T") , &lpKeyState+0, 0x14, "Uchar")
	varsetcapacity(pwszBuff, 8, 0)
	DllCall("User32.dll\ToUnicode", "Uint", uVirtKey, "Uint", uScanCode, "UPtr", &lpKeyState, "ptr", &pwszBuff, "Int", cchBuff, "Uint", wFlags)
	return strget(&pwszBuff)
}
When I call

Code: Select all

toUnicode(getKeyVk("2"), getKeySc("2")))
and hold AltGr, I get @ in return. In the example above, I used KeyWait RAlt to highlight this. I guess Ralt+2 will return something different on other layouts. How do you produce @ on your keyboard?

Cheers.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: ToASCIIEx

08 Dec 2017, 12:07

Hello!

Thanks for your reply. I managed to fix that. I was not providing the correct VK/SCs.

Now, I am having another problem. If you add in Windows the Yoruba or Igbo keyboard layouts and use AltGr, those extended unicode chars do not get inserted .... I tried with both: toAscii and toUnicode.

Here's how I changed them to suit my needs:

Code: Select all

toascii(uVirtKey,uScanCode,uFlags:=0) {
  ; Url:
  ;    - https://msdn.microsoft.com/en-us/library/windows/desktop/ms646316(v=vs.85).aspx
  ; params:
  ;     - uVirtKey,  The virtual-key code to be translated.
  ;     - uScanCode, The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed).
  ;    - uFlags, This parameter must be 1 if a menu is active, or 0 otherwise.
  ; return
  ;    - corresponding character yielded by the combination of uVirtKey and whatever modifiers are down.

  static lpKeyState

  thread := DllCall("GetWindowThreadProcessId", "ptr", WinActive("A"), "ptr", 0)
  hkl := DllCall("GetKeyboardLayout", "uint", thread, "ptr")

  VarSetCapacity(lpChar, 4, 0)
  if !lpKeyState
     VarSetCapacity(lpKeyState,256,0)

  for modifier, vk in {Shift:0x10, Control:0x11, Alt:0x12}
      NumPut(128*(GetKeyState("L" modifier) || GetKeyState("R" modifier)) , lpKeyState, vk, "Uchar")

  NumPut(GetKeyState("CapsLock", "T") , lpKeyState, 0x14, "Uchar")
  n := DllCall("ToAsciiEx", "Uint", uVirtKey, "Uint", uScanCode, "UPtr", &lpKeyState, "ptr", &lpChar, "Uint", uFlags, "ptr", hkl)
  return StrGet(&lpChar, n, "utf-16")
}

toUnicode(uVirtKey,uScanCode,wFlags:=0) {
  ; Url:
  ;    - https://msdn.microsoft.com/en-us/library/windows/desktop/ms646320(v=vs.85).aspx
  ; params:
  ;    - uVirtKey,  The virtual-key code to be translated.
  ;    - uScanCode, The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed).
  ;    - wFlags, The behavior of the function. If bit 0 is set, a menu is active. Bits 1 through 31 are reserved.
  ; return
  ;    - corresponding character yielded by the combination of uVirtKey and whatever modifiers are down.

  thread := DllCall("GetWindowThreadProcessId", "ptr", WinActive("A"), "ptr", 0)
  hkl := % DllCall("GetKeyboardLayout", "uint", thread, "ptr")

  VarSetCapacity(lpKeyState,256,0)
  VarSetCapacity(pwszBuff,cchBuff:=3,0)

  for modifier, vk in {Shift:0x10, Control:0x11, Alt:0x12}
      NumPut(128*(GetKeyState("L" modifier) || GetKeyState("R" modifier)) , lpKeyState, vk, "Uchar")

  NumPut(GetKeyState("CapsLock", "T") , &lpKeyState+0, 0x14, "Uchar")

  DllCall("ToUnicodeEx", "Uint", uVirtKey, "Uint", uScanCode, "UPtr", &lpKeyState, "Uptr*", pwszBuff, "Int", cchBuff, "Uint", wFlags, "ptr", hkl)
  return chr(pwszBuff)
}
I understand it's something about choosing the right encoding.

They differ a bit, in that toAscii throws Chinese looking like characters and the other, nothing. I need to display chars like ọ́ọ̀....

Thank you very much.

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: ToASCIIEx

08 Dec 2017, 15:15

I also discovered that some keyboards '"emit"/generate two chars... and it does not accept this... any suggestions? please... Buffer should be bigger? I tried changing ....

VarSetCapacity(pwszBuff,cchBuff:=6,0).... but no luck....

Maybe it's not a problem of encoding, as I mentioned previously, but of length.

Thank you,....

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: ToASCIIEx

08 Dec 2017, 18:12

I don't know anything about that. Your toascii function above seems to work fine in simple test case, ` + a = à, ` + space = `. ~ + o = õ where I produce ~ with AltGr + ¨ (¨ = VK: 0xba SC: 0x1b).

Good luck, please get back if you find something useful.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: ToASCIIEx

09 Dec 2017, 03:45

Thanks for the reply.

It all works fine, indeed, both of them.

But on the mentioned layouts [Igbo, Vietnamese], there are AltGr chars made of two chars. These are not returned by the functions.

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: ToASCIIEx

09 Dec 2017, 04:38

I've got it working as follows:

Code: Select all


toUnicodeExtended(uVirtKey,uScanCode,wFlags:=0) {
; Many thanks to Helgef:
; https://autohotkey.com/boards/viewtopic.php?f=5&t=41065&p=187582#p187582

  thread := DllCall("GetWindowThreadProcessId", "ptr", WinActive("A"), "ptr", 0)
  hkl := % DllCall("GetKeyboardLayout", "uint", thread, "ptr")
  VarSetCapacity(lpKeyState,256,0)
  VarSetCapacity(pwszBuff,cchBuff:=3,0)
  VarSetCapacity(pwszBuff,4,0)

  for modifier, vk in {Shift:0x10, Control:0x11, Alt:0x12}
      NumPut(128*(GetKeyState("L" modifier) || GetKeyState("R" modifier)) , lpKeyState, vk, "Uchar")

  NumPut(GetKeyState("CapsLock", "T") , &lpKeyState+0, 0x14, "Uchar")

  n := DllCall("ToUnicodeEx", "Uint", uVirtKey, "Uint", uScanCode, "UPtr", &lpKeyState, "ptr", &pwszBuff, "Int", cchBuff, "Uint", wFlags, "ptr", hkl)
  return StrGet(&pwszBuff, n, "utf-16")
}
Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: ToASCIIEx

09 Dec 2017, 14:00

Great, thanks for sharing, I would (probably) have needed to investigate this further at some point. :thumbup:
Minor comments, I recommend you remove the % in,

Code: Select all

hkl := % DllCall("GetKeyboardLayout", "uint", thread, "ptr")
and regarding,

Code: Select all

VarSetCapacity(pwszBuff,cchBuff:=3,0)
VarSetCapacity(pwszBuff,4,0)
this is a bit superfluous, and it is only correct on unicode builds by luck, since varsetcapacity(var, x) (x>0) sets the capacity to a minimum of 8 on unicode, I think this would be more appropriate

Code: Select all

cchBuff:=3 ; number of characters the buffer can hold
VarSetCapacity(pwszBuff, (cchBuff+1) * (A_IsUnicode ? 2 : 1), 0)	; this will hold cchBuff (3) characters and the null terminator on both unicode and ansi builds.
I will need to make further investigations, because I do not remember why I multiplied the modifier state with 128 but not the capslock state. And I do not recall why the choise of cchBuff:=3.
But on the mentioned layouts [Igbo, Vietnamese], there are AltGr chars made of two chars.
Could you make an explicit example? it would be interesting to test.

Cheers.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: ToASCIIEx

09 Dec 2017, 15:41

Thank you very much for the corrections.

The example I can offer is: download my script and install Igbo kbd layout and press AltGr with various keys and see what comes out... ;-).

http://marius.sucan.ro/media/files/blog ... ss-osd.ahk

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: OrangeCat and 163 guests