Virtual key to character translation (Windows API)

L

lolzy

Hello comp.lang.c!

I'am trying to convert a virtual key to a normal character (just a
human readable character). This is my code:

LPWORD r;
SHORT c = /* Some virtual key */
byte ba[256];

r = calloc(3, sizeof(char));

/* Init keybord status */
if (GetKeyboardState(ba) == 0)
{
printf("ERROR: Could not get keybord status.");
exit(1);
}


ToAscii(c, MapVirtualKey(c, 0), ba, r, 0);

putc(r[0]);


This code works. BUT not 100% hehe, when holding the shift key the
ToAscii function still returns the 'normal' characters, for example
lower case characters instead of uppercase, [ instead of {, etc.

Thanks in advance!
Jori.
 
K

Kenny McCormack

Hello comp.lang.c!

I'am trying to convert a virtual key to a normal character (just a
human readable character). This is my code:

LPWORD r;
SHORT c = /* Some virtual key */
byte ba[256];

r = calloc(3, sizeof(char));

/* Init keybord status */
if (GetKeyboardState(ba) == 0)
{
printf("ERROR: Could not get keybord status.");
exit(1);
}


ToAscii(c, MapVirtualKey(c, 0), ba, r, 0);

putc(r[0]);


This code works. BUT not 100% hehe, when holding the shift key the
ToAscii function still returns the 'normal' characters, for example
lower case characters instead of uppercase, [ instead of {, etc.

Thanks in advance!
Jori.

Off topic. Not portable. Cant discuss it here. Blah, blah, blah.

--
Useful clc-related links:

http://en.wikipedia.org/wiki/Aspergers
http://en.wikipedia.org/wiki/Clique
http://en.wikipedia.org/wiki/C_programming_language
 
M

Malcolm McLean

Hello comp.lang.c!

I'am trying to convert a virtual key to a normal character (just a
human readable character). This is my code:

LPWORD r;
SHORT c = /* Some virtual key */
byte ba[256];

r = calloc(3, sizeof(char));

/* Init keybord status */
if (GetKeyboardState(ba) == 0)
{
        printf("ERROR: Could not get keybord status.");
        exit(1);

}

ToAscii(c, MapVirtualKey(c, 0), ba, r, 0);

putc(r[0]);

This code works. BUT not 100% hehe, when holding the shift key the
ToAscii function still returns the 'normal' characters, for example
lower case characters instead of uppercase, [ instead of {, etc.
The function is too low-level.

<OT>
Windows sends a WM_CHAR message to a window that receives a
character from a keyboard or similar device attached to it. Normally
this is the message you want to trap for everyday text input.
</OT>
 
D

DDD

Hello comp.lang.c!

I'am trying to convert a virtual key to a normal character (just a
human readable character). This is my code:

LPWORD r;
SHORT c = /* Some virtual key */
byte ba[256];

r = calloc(3, sizeof(char));

/* Init keybord status */
if (GetKeyboardState(ba) == 0)
{
        printf("ERROR: Could not get keybord status.");
        exit(1);

}

ToAscii(c, MapVirtualKey(c, 0), ba, r, 0);

putc(r[0]);

This code works. BUT not 100% hehe, when holding the shift key the
ToAscii function still returns the 'normal' characters, for example
lower case characters instead of uppercase, [ instead of {, etc.

Thanks in advance!
Jori.

According to http://msdn.microsoft.com/en-us/library/dd375731(VS.85).aspx,

Maybe you can add a judge statement like

If Shift pressed
{
....
}
else
{
....
}
 
L

lolzy

Hello comp.lang.c!
I'am trying to convert a virtual key to a normal character (just a
human readable character). This is my code:
LPWORD r;
SHORT c = /* Some virtual key */
byte ba[256];
r = calloc(3, sizeof(char));
/* Init keybord status */
if (GetKeyboardState(ba) == 0)
{
        printf("ERROR: Could not get keybord status.");
        exit(1);

ToAscii(c, MapVirtualKey(c, 0), ba, r, 0);
putc(r[0]);

This code works. BUT not 100% hehe, when holding the shift key the
ToAscii function still returns the 'normal' characters, for example
lower case characters instead of uppercase, [ instead of {, etc.
Thanks in advance!
Jori.

According tohttp://msdn.microsoft.com/en-us/library/dd375731%28VS.85%29.aspx,

Maybe you can add a judge statement like

If Shift pressed
{
...}

else
{
...







}

DDD, I tried that but it does not work properly. Also if you have a
character returned, for example ']', how to convert it to '}'. You
could make a convert table, but thats not very clean.
 
J

Jens Thoms Toerring

DDD, I tried that but it does not work properly. Also if you have a
character returned, for example ']', how to convert it to '}'. You
could make a convert table, but thats not very clean.

I'd strongly recommend to ask in a Windows newsgroup since
this isn't a problem related to C (that's just the language
you're using) but a question concerning the inner working
of the Windows operating system (and for example for UNIX
the answer would be completely different). Thus here just
a few comments regarding the C part of it:
LPWORD r;
SHORT c = /* Some virtual key */
byte ba[256];

r = calloc(3, sizeof(char));

I have no idea what the type 'LPWORD' is (that's something
Windows specific) but I would be raher astonished if it
had a size of 3 bytes (my guess is that it's a pointerto a
long integer value). Thus I would make that call

r = calloc( 1, sizeof *r );

That will give you exactly as much space (initialized to
all 0 bits which perhaps isn't necessary) as you need for
what an LPWORD is pointing to. Allocation less may result
in functions called with this pointer to result in writes
past the end of the buffer which, in turn, could lead to
all kinds of nasty things to happen.
/* Init keybord status */
if (GetKeyboardState(ba) == 0)
{
printf("ERROR: Could not get keybord status.");

You also should output a '\n' at the end (or use e.g. puts()),
otherwise the error message may never be appear on your
screen. Also directing error messages to stderr instead of
stdout is an often followed convention.
exit(1);
}

ToAscii(c, MapVirtualKey(c, 0), ba, r, 0);

putc(r[0]);

This looks strange - putc() expects an int and a FILE pointer,
but you pass it only a single argument.

Regards, Jens
 
K

Keith Thompson

Hello comp.lang.c!

I'am trying to convert a virtual key to a normal character (just a
human readable character). This is my code:

LPWORD r;
SHORT c = /* Some virtual key */
byte ba[256];
[snip]

I'm sure the folks in comp.os.ms-windows.programmer.win32 could give you
a better answer to this.
 
L

lolzy

DDD, I tried that but it does not work properly. Also if you have a
character returned, for example ']', how to convert it to '}'. You
could make a convert table, but thats not very clean.

I'd strongly recommend to ask in a Windows newsgroup since
this isn't a problem related to C (that's just the language
you're using) but a question concerning the inner working
of the Windows operating system (and for example for UNIX
the answer would be completely different). Thus here just
a few comments regarding the C part of it:
LPWORD r;
SHORT c = /* Some virtual key */
byte ba[256];
r = calloc(3, sizeof(char));

I have no idea what the type 'LPWORD' is (that's something
Windows specific) but I would be raher astonished if it
had a size of 3 bytes (my guess is that it's a pointerto a
long integer value). Thus I would make that call

r = calloc( 1, sizeof *r );

That will give you exactly as much space (initialized to
all 0 bits which perhaps isn't necessary) as you need for
what an LPWORD is pointing to. Allocation less may result
in functions called with this pointer to result in writes
past the end of the buffer which, in turn, could lead to
all kinds of nasty things to happen.
/* Init keybord status */
if (GetKeyboardState(ba) == 0)
{
        printf("ERROR: Could not get keybord status.");

You also should output a '\n' at the end (or use e.g. puts()),
otherwise the error message may never be appear on your
screen. Also directing error messages to stderr instead of
stdout is an often followed convention.
        exit(1);
}
ToAscii(c, MapVirtualKey(c, 0), ba, r, 0);
putc(r[0]);

This looks strange - putc() expects an int and a FILE pointer,
but you pass it only a single argument.

                               Regards, Jens

Thanks for your response Jens.

I will ask this in a windows group, you are totaly right.

LPWORD is a pointer to void thats contains a string, in this case with
a maximum size of 3 characters (2 chars + \0). Also putc() expect just
1 argument, its a macro:

#define putc(x) fputc(x, stdout)
 
J

Jens Thoms Toerring

LPWORD is a pointer to void thats contains a string, in this case with
a maximum size of 3 characters (2 chars + \0).

Fine, if that's what the ToAscii() function expects then this
is one poin less to worry about;-)

But in that case your line
putc(r[0]);

(independent of the question of how many arguments putc()
takes) is fishy - a void pointer can't be dereferenced,
and that's what you're attempting by using 'r[0]' (which
is equivalent to '*(r+0)'). If the compiler doesn't flag
this as an error you're relying on some interpretation of
what dereferencing a void pointer might mean that may be
unique to the compiler you're using at the moment. I would
recommend that you use e.g.

putc( * ( unsigned char * ) r );

or

putc( ( ( unsigned char * ) r )[ 0 ] );

to avoid that (assuming you want to get at the first
character in the string).
Also putc() expect just 1 argument, its a macro:
#define putc(x) fputc(x, stdout)

My C standard claims that the putc() macro is to be used
as

int putc(int c, FILE *stream)

and it could be at least astonishing to others if you
redefine a standard C macro. Are you perhaps getting
this mixed up with the putchar() macro? That's the
one that automatically writes to stdout and thus does
not need a second argument.
Regards, Jens
 
K

Keith Thompson

I will ask this in a windows group, you are totaly right.

Probably comp.os.ms-windows.programmer.win32.
LPWORD is a pointer to void thats contains a string, in this case with
a maximum size of 3 characters (2 chars + \0).

Actually it's a pointer to a WORD, where a WORD is a typedef for
unsigned short (which is 16 bits under Windows). Windows makes heavy
use of UTF-16 for character data. If you're setting an LPWORD to point
to a 3-byte object, you're probably doing something wrong. (C experts
can tell you why it's wrong; Windows experts can tell you how to do it
right.)
Also putc() expect just
1 argument, its a macro:

#define putc(x) fputc(x, stdout)

Incorrect, putc() takes two arguments. putchar() takes one. (I *hope*
nobody has redefined putc() as a macro taking 1 argument.)
 
L

lolzy

(e-mail address removed) writes:

[...]
I will ask this in a windows group, you are totaly right.

Probably comp.os.ms-windows.programmer.win32.
LPWORD is a pointer to void thats contains a string, in this case with
a maximum size of 3 characters (2 chars + \0).

Actually it's a pointer to a WORD, where a WORD is a typedef for
unsigned short (which is 16 bits under Windows).  Windows makes heavy
use of UTF-16 for character data.  If you're setting an LPWORD to point
to a 3-byte object, you're probably doing something wrong.  (C experts
can tell you why it's wrong; Windows experts can tell you how to do it
right.)
                                              Also putc() expect just
1 argument, its a macro:
#define putc(x) fputc(x, stdout)

Incorrect, putc() takes two arguments.  putchar() takes one.  (I *hope*
nobody has redefined putc() as a macro taking 1 argument.)

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

I am sorry, mixed up with putchar() haha. Thank you very much for your
anwsers!
 

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

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top