Getting a character name

K

kurotsuke

Hi,

I'm trying to use the GetKeyName API to get the name of certain keys
(in the system language). For example the names of SHIFT and RETURN
keys as well as the names of same special characters.

I tried to call the API GetKeyName passing the KeyCode of the KeyUP
event but got no result


scancode = (uint) e.KeyCode;
StringBuilder sb= new StringBuilder(260);
int ret=GetKeyNameText(scancode,sb,20);


[DllImport("user32.dll")]
static extern int GetKeyNameText(uint lParam, [Out] StringBuilder
lpString, int nSize);

Sometimes the APi return 0 and sometimes it returns the name of
another character.

Can somebody post an example on how to use it? I could not find
anything worthwhile around.

Thanks.
 
C

Chris Taylor

Hi,

Please do not cross post, I answered this post on the interop group.

I took a quick look at the MSDN docs regarding this function and put
together the following code that should help you get started.

[DllImport("user32", SetLastError=true, CharSet=CharSet.Unicode)]
static extern int GetKeyNameTextW(uint lParam, StringBuilder lpString,
int nSize);

[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern uint MapVirtualKeyW(uint uCode, uint uMapType);

private void Form1_KeyDown(object sender,
System.Windows.Forms.KeyEventArgs e)
{
StringBuilder sb= new StringBuilder(260);

uint key = MapVirtualKeyW((uint)e.KeyCode, 0) << 16;
int ret=GetKeyNameTextW(key, sb, 260);

label2.Text = sb.ToString();
}

You will notice that I had to use MapVirtualKey to map the key code and then
when passing the code to the GetKeyNameText function I performed a shift, in
the docs you will see that the scan code needs to be in bits 16..23
therefore I needed to shift the returned code to the correct position.

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/weblog/chris.taylor
kurotsuke said:
Hi,

I'm trying to use the GetKeyName API to get the name of certain keys
(in the system language). For example the names of SHIFT and RETURN
keys as well as the names of same special characters.

I tried to call the API GetKeyName passing the KeyCode of the KeyUP
event but got no result


scancode = (uint) e.KeyCode;
StringBuilder sb= new StringBuilder(260);
int ret=GetKeyNameText(scancode,sb,20);


[DllImport("user32.dll")]
static extern int GetKeyNameText(uint lParam, [Out] StringBuilder
lpString, int nSize);

Sometimes the APi return 0 and sometimes it returns the name of
another character.

Can somebody post an example on how to use it? I could not find
anything worthwhile around.

Thanks.



--
Chris Taylor
http://dotnetjunkies.com/weblog/chris.taylor
kurotsuke said:
Hi,

I'm trying to use the GetKeyName API to get the name of certain keys
(in the system language). For example the names of SHIFT and RETURN
keys as well as the names of same special characters.

I tried to call the API GetKeyName passing the KeyCode of the KeyUP
event but got no result


scancode = (uint) e.KeyCode;
StringBuilder sb= new StringBuilder(260);
int ret=GetKeyNameText(scancode,sb,20);


[DllImport("user32.dll")]
static extern int GetKeyNameText(uint lParam, [Out] StringBuilder
lpString, int nSize);

Sometimes the APi return 0 and sometimes it returns the name of
another character.

Can somebody post an example on how to use it? I could not find
anything worthwhile around.

Thanks.
 
A

Amit

Note that converting e.KeyCode into an int will give its .NET value in the
Keys enumeration which may or may not be equal to what the windows API
expects (I don't know). But here's a purely .NET way of doing it using
reflection, try it out and see if it gives you what you're looking for:

//in the KeyDown event handler:
string name = Enum.Parse(typeof(Keys),
Convert.ToString((int)e.KeyData)).ToString();


-Amit
 
A

Amit

I just realized - it doesn't really use Reflection



Amit said:
Note that converting e.KeyCode into an int will give its .NET value in the
Keys enumeration which may or may not be equal to what the windows API
expects (I don't know). But here's a purely .NET way of doing it using
reflection, try it out and see if it gives you what you're looking for:

//in the KeyDown event handler:
string name = Enum.Parse(typeof(Keys),
Convert.ToString((int)e.KeyData)).ToString();


-Amit


kurotsuke said:
Hi,

I'm trying to use the GetKeyName API to get the name of certain keys
(in the system language). For example the names of SHIFT and RETURN
keys as well as the names of same special characters.

I tried to call the API GetKeyName passing the KeyCode of the KeyUP
event but got no result


scancode = (uint) e.KeyCode;
StringBuilder sb= new StringBuilder(260);
int ret=GetKeyNameText(scancode,sb,20);


[DllImport("user32.dll")]
static extern int GetKeyNameText(uint lParam, [Out] StringBuilder
lpString, int nSize);

Sometimes the APi return 0 and sometimes it returns the name of
another character.

Can somebody post an example on how to use it? I could not find
anything worthwhile around.

Thanks.
 
M

Mattias Sjögren

But here's a purely .NET way of doing it

That gives the English names used in the enum, not the localized names
returned by GetKeyNameText.



Mattias
 
K

kurotsuke

Hi,

Please do not cross post, I answered this post on the interop group.

I took a quick look at the MSDN docs regarding this function and put
together the following code that should help you get started.

[DllImport("user32", SetLastError=true, CharSet=CharSet.Unicode)]
static extern int GetKeyNameTextW(uint lParam, StringBuilder lpString,
int nSize);

[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern uint MapVirtualKeyW(uint uCode, uint uMapType);

private void Form1_KeyDown(object sender,
System.Windows.Forms.KeyEventArgs e)
{
StringBuilder sb= new StringBuilder(260);

uint key = MapVirtualKeyW((uint)e.KeyCode, 0) << 16;
int ret=GetKeyNameTextW(key, sb, 260);

label2.Text = sb.ToString();
}

You will notice that I had to use MapVirtualKey to map the key code and then
when passing the code to the GetKeyNameText function I performed a shift, in
the docs you will see that the scan code needs to be in bits 16..23
therefore I needed to shift the returned code to the correct position.

Hope this helps

--

Sorry for crossposting. After posting here I realized that maybe the
interop newsgroup was better.
I tried your solution and it worked. Will it work on Win98, too?

I'm having a minor problem. When a key on the numpad is pressed, the
description shown is always the numpad one (so I get 9 (tn) and never
get the pageup, pagedown, left, right... codes).
Have you got any idea on how to fix this? The Keycodes are different
for pageUp and (numpad 9)
Thanks again.
 
C

Chris Taylor

Hi,

To get the information for the extended keys I think your best bet is to go
slightly lower level and handle the windows keyboard messages as they are in
the windows message queue. Add the following code to a form and you will get
what you are looking for.

[DllImport("user32", SetLastError=true, CharSet=CharSet.Unicode)]
static extern int GetKeyNameTextW(uint lParam, StringBuilder lpString,
int nSize);

protected override void WndProc(ref Message m)
{
if (m.Msg == 0x100) // WM_KEYDOWN
{
StringBuilder sb= new StringBuilder(260);

int ret=GetKeyNameTextW((uint)m.LParam.ToInt64(), sb, 260);
label2.Text = sb.ToString();
}

base.WndProc (ref m);
}

With regards to Win98, to use the GetKeyNameTextW you need the Microsoft
Layer for Unicode on Windows 95/98/Me Systems you can get this from the
following link
http://tinyurl.com/6wf9s
The original link is
http://www.microsoft.com/downloads/...d7-ed06-4f0d-80a4-2a7eeaee17e2&displaylang=en

I *think* for 98 you can import GetKeyNameText, but this does not exist on
Windows 2003 so your code would have to check what version of the OS it is
executing on and call the relevant DllImport alias.

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/weblog/chris.taylor
kurotsuke said:
Hi,

Please do not cross post, I answered this post on the interop group.

I took a quick look at the MSDN docs regarding this function and put
together the following code that should help you get started.

[DllImport("user32", SetLastError=true, CharSet=CharSet.Unicode)]
static extern int GetKeyNameTextW(uint lParam, StringBuilder lpString,
int nSize);

[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern uint MapVirtualKeyW(uint uCode, uint uMapType);

private void Form1_KeyDown(object sender,
System.Windows.Forms.KeyEventArgs e)
{
StringBuilder sb= new StringBuilder(260);

uint key = MapVirtualKeyW((uint)e.KeyCode, 0) << 16;
int ret=GetKeyNameTextW(key, sb, 260);

label2.Text = sb.ToString();
}

You will notice that I had to use MapVirtualKey to map the key code and then
when passing the code to the GetKeyNameText function I performed a shift, in
the docs you will see that the scan code needs to be in bits 16..23
therefore I needed to shift the returned code to the correct position.

Hope this helps

--

Sorry for crossposting. After posting here I realized that maybe the
interop newsgroup was better.
I tried your solution and it worked. Will it work on Win98, too?

I'm having a minor problem. When a key on the numpad is pressed, the
description shown is always the numpad one (so I get 9 (tn) and never
get the pageup, pagedown, left, right... codes).
Have you got any idea on how to fix this? The Keycodes are different
for pageUp and (numpad 9)
Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top