[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Virtual key to character translation (Windows API

lolzy

8/21/2011 9:07:00 AM

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.
10 Answers

gazelle

8/21/2011 12:53:00 PM

0

In article <061bf8d5-fef2-478d-9fd2-96fdfbcbd88f@n35g2000yqf.googlegroups.com>,
<lolzy@live.nl> wrote:
>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...
http://en.wikipedia.org/w...
http://en.wikipedia.org/wiki/C_programmin...

Malcolm McLean

8/21/2011 1:45:00 PM

0

On Aug 21, 12:06 pm, lo...@live.nl wrote:
> 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>

DDD

8/21/2011 2:35:00 PM

0

On Aug 21, 5:06 pm, lo...@live.nl wrote:
> 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%28VS....,

Maybe you can add a judge statement like

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

lolzy

8/21/2011 3:53:00 PM

0

On 21 aug, 16:34, DDD <1983...@gmail.com> wrote:
> On Aug 21, 5:06 pm, lo...@live.nl wrote:
>
>
>
>
>
>
>
>
>
> > 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....,
>
> 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.

jt

8/21/2011 5:37:00 PM

0

lolzy@live.nl wrote:
> 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
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://t...

Keith Thompson

8/21/2011 5:57:00 PM

0

lolzy@live.nl writes:
> 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.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

lolzy

8/21/2011 6:03:00 PM

0

On 21 aug, 19:36, j...@toerring.de (Jens Thoms Toerring) wrote:
> lo...@live.nl wrote:
> > 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
> --
>   \   Jens Thoms Toerring  ___      j...@toerring.de
>    \__________________________      http://t...

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)

jt

8/21/2011 6:52:00 PM

0

lolzy@live.nl wrote:
> 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
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://t...

Keith Thompson

8/21/2011 7:01:00 PM

0

lolzy@live.nl 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) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

lolzy

8/21/2011 7:09:00 PM

0

On 21 aug, 21:00, Keith Thompson <ks...@mib.org> wrote:
> lo...@live.nl 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) ks...@mib.org  <http://www.ghoti.ne...
> 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!