Virtual key to character translation (Windows API)

Discussion in 'C Programming' started by lolzy@live.nl, Aug 21, 2011.

  1. Guest

    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.
     
    , Aug 21, 2011
    #1
    1. Advertising

  2. In article <>,
    <> 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/Aspergers
    http://en.wikipedia.org/wiki/Clique
    http://en.wikipedia.org/wiki/C_programming_language
     
    Kenny McCormack, Aug 21, 2011
    #2
    1. Advertising

  3. On Aug 21, 12:06 pm, 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>
     
    Malcolm McLean, Aug 21, 2011
    #3
  4. DDD Guest

    On Aug 21, 5:06 pm, 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(VS.85).aspx,

    Maybe you can add a judge statement like

    If Shift pressed
    {
    ....
    }
    else
    {
    ....
    }
     
    DDD, Aug 21, 2011
    #4
  5. Guest

    On 21 aug, 16:34, DDD <> wrote:
    > On Aug 21, 5:06 pm, 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.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.
     
    , Aug 21, 2011
    #5
  6. 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Aug 21, 2011
    #6
  7. 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) <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"
     
    Keith Thompson, Aug 21, 2011
    #7
  8. Guest

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


    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)
     
    , Aug 21, 2011
    #8
  9. 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Aug 21, 2011
    #9
  10. 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) <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"
     
    Keith Thompson, Aug 21, 2011
    #10
  11. Guest

    On 21 aug, 21:00, Keith Thompson <> wrote:
    > 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)  <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!
     
    , Aug 21, 2011
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    1,912
    Phlip
    Jun 9, 2006
  2. Ikke
    Replies:
    4
    Views:
    2,015
    Alexander Bartolich
    Aug 19, 2009
  3. M P
    Replies:
    1
    Views:
    494
  4. Replies:
    2
    Views:
    149
    bbiker
    Oct 25, 2007
  5. Jeff
    Replies:
    4
    Views:
    138
Loading...

Share This Page