Solved

Syntax problem

Posted on 2000-03-08
16
667 Views
Last Modified: 2012-05-04
Hello!
I want to use the ToAscii function and GetKeyboardState function and I have the following C++ code:

int iScan, vKey; //key scan code and virtual key code
BYTE kbuf[256];
ULONG ch;
ULONG *pCh = NULL;
int chcount;
char ch1,ch2;

GetKeyboardState(&(kbuf[256]));
pCh = &ch;
chcount = ToAscii(vKey,iScan,&(kbuf[256]),(USHORT*)pCh,0);
pCh = NULL;
if (chcount==2)
{
    ch1 = (CHAR) LOWORD(ch);
    ch2 = (CHAR) HIWORD(ch);
}

But when I ran this code, computer falled down. The problem was in the GetKeyboardState function, so I've fixed it by this:
GetKeyboardState((PBYTE)(kbuf[256]));

After that, the C++ code "worked". But on native keyboard layouts there are OEM keys. If the OEM key is pressed, the output is some
character, but if it's pressed with the Shift key, the character is completely different. The ToAscii function doesn't translate them right.
It always translates the unshifted character, even if the Shift is pressed. I have had code in a C compiler. It looked like this:

int iScan, vKey; //key scan code and virtual key code
BYTE kbuf[256];
ULONG ch;
int chcount;
char ch1,ch2;

GetKeyboardState(kbuf);
if (bShiftKey) //the bShiftKey detects when the Shift key is pressed
    chcount = ToAscii(vKey,iScan,&(kbuf[256]),&((SHORT)ch),0);
else
    chcount = ToAscii(vKey,iScan,kbuf,&((SHORT)ch),0);
if (chcount==2)
{
    ch1 = (CHAR) LOWORD(ch);
    ch2 = (CHAR) HIWORD(ch);
}

This C code worked with OEM keys. But I don't know how this C code convert to working C++ code. I think problem is in bad getting (GetKeyboardState) or bad giving (ToAscii) of the kbuf buffer.
Thanks in advance.
0
Comment
Question by:myson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 2
  • +1
16 Comments
 
LVL 1

Expert Comment

by:prozak
ID: 2597015
You need to look in kbuf[VK_LSHIFT] or kbuf[VK_RSHIFT] to see if the shift key is pressed.
0
 

Author Comment

by:myson
ID: 2597068
Yes, I´m doing it, but how could I detect the OEM character when with shift is completely different than without it?
0
 
LVL 1

Expert Comment

by:prozak
ID: 2597179
Check out the OemKeyScan function, it doesn't allow you to get the whole keyboard in one swoop like GetKeyboardState but it may do what you're looking for.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:myson
ID: 2597211
Ye, but this function gives scancode and shift state for a OEM character, but I want reverse process. I want from Virtual key/scancode and shift state to a character.
0
 
LVL 1

Expert Comment

by:prozak
ID: 2597306
GetKeyboardState(kbuf);

if (kbuf[VK_SHIFT] & 0x80) //the bShiftKey detects when the Shift key is pressed
  chcount = ToAscii(vKey,iScan,&(kbuf[256]),&((SHORT)ch),0);
else
  chcount = ToAscii(vKey,iScan,kbuf,&((SHORT)ch),0);

if (chcount==2)
{
    ch1 = (CHAR) LOWORD(ch);
    ch2 = (CHAR) HIWORD(ch);
}



0
 

Author Comment

by:myson
ID: 2597338
Yes, this is a way I've detected shift key in bShiftKey variable. But there's a problem in giving the kbuf parameter in that 2 functions, not when is the Shift key pressed. Sorry if the question was asked badly.
0
 
LVL 1

Expert Comment

by:prozak
ID: 2597372
What exactly are you trying to do? Detect an OEM key being pressed? If ToAscii returns the same character regardless of whether the shift key is pressed then whats the problem? You can tell if its the OEM char your looking for by calling ToAscii and then look at kbuf[VK_SHIFT] to see if the shift is pressed.

I guess I'm not really following your problem. Could you give a brief description of what it is you are trying to do?
0
 
LVL 22

Expert Comment

by:nietod
ID: 2597443
I'm having trouble following all this too.  But

>> I want from Virtual key/scancode and
>> shift state to a character.

Does MapVirtualKey() work for what you want?
0
 

Author Comment

by:myson
ID: 2597590
Sorry, I can explain. I'm getting informations from WM_HOTKEY message, whitch informs me what key is pressed (Virtual key code) and if any key-modifier (like Shift, if it was registered with it by RegisterHotkey) is pressed. I'm trying to get from these informations a character. For example if the vKey is VK_A, the ToAscii function returns a character 'A'. Note, that ToAscii returns always shifted keys (for example always A, B, not a, b). I'm getting them to right state with CharUpper / CharLower functions. That works. But if the character is an OEM character, ToAscii always returns unshifted character. I have no idea how to get it to shift state. If I set a bit in kbuf[VK_SHIFT] that the key is down, it doesn't work. I think the problem is in passing argument kbuf to ToAscii function. I hope I've at least little explained the problem.
0
 

Author Comment

by:myson
ID: 2597638
The MapVirtualKey functions good-for-me syntax is only this: ch1 = (UINT) LOWORD(MapVirtualKey(vKey, 2)). But it does the same problem as ToAscii. The return value is always unshifted. Unfortunately OEM keys have different characters output when they are shifted and unshifted.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2597790
MapVirtualKey() should be returning lowercase characters, not uppercase ones.  Are you sure it is returning uppercase ones?
0
 

Author Comment

by:myson
ID: 2597969
The return value of MapVirtualKey() is lowercase character, not mentioned when the pressed key is OEM or not. The ToAscii() returns uppercase chars.
The problem is not with normal characters, only with OEM characters.
It doesn't mind if they are lowercase or uppercase, that can I handle with CharUpper and ChatLower functions. Normal keys with Shift key produce the same character (except the char is uppercase). But OEM keys with Shift key down produce different characters than when they are pressed without Shift.

The problem is how to get the character that is being produced by OEM key when it is pressed with Shift key down.
The character being produced by OEM key with Shift key up I can get by calling ToAscii/MapVirtualKey functions.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2598549
>GetKeyboardState(&(kbuf[256]));
>pCh = &ch;
>chcount = ToAscii(vKey,iScan,&(kbuf[256]),(USHORT*)pCh,0);

you are passing the address of an elemnent past the end of the array.

You probably want:
GetKeyboardState(&kbuf);
pCh = &ch;
chcount = ToAscii(vKey,iScan,&kbuf,(USHORT*)pCh,0);

that is probably why your pc is crashing

0
 
LVL 1

Accepted Solution

by:
prozak earned 25 total points
ID: 2600501
Actually if you pass it like this:

ToAscii(vKey,iScan,&kbuf,(USHORT*)pCh,0);

You are passing a char** which will crash it as well, it should probably be just:

ToAscii(vKey,iScan,kbuf,(USHORT*)pCh,0);
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2602486
&kbuf will be the same as kbuf because it is an array (an array name gives the address of the array as does the address-of-array-name).  No problem (as long as it compiles).


0
 

Author Comment

by:myson
ID: 2603886
ROZLOWs code doesn't compile in VC++ because of error: cannot convert parameter &kbuf from 'unsigned char (*)[256]' to 'unsigned char *'.
Prozaks code is right, it compiles. Now with this right code the ToAscii function returns lowercase chars.
But it doesn't solve that problem with OEM chars. If an OEM key is pressed, ToAscii always returns the character
that would be produced by pressing that key without Shift, even if Shift is pressed! The problem is that the OEM key with Shift
has got the same virtual key code and scan code as OEM key without Shift. ToAscii can recognize if the Shift Key is down only
by detecting the high-order bit of Shift key in kBuf. I have manualy set the Shift high-order bit:
kbuf[VK_SHIFT] = (kbuf[VK_SHIFT] | (1 << 7)). And it WORKED!! So the problem is in GetKeyboardState function.
But the Shift state indicates the LOWORD(lParam) of message WM_HOTKEY. So now the code is:

GetKeyboardState(kbuf);
if (bShiftKey)
      kbuf[VK_SHIFT] = (kbuf[VK_SHIFT] | (1 << 7));
else
      kbuf[VK_SHIFT] = (kbuf[VK_SHIFT] & ~(1 << 7));
pCh = &ch;
chcount = ToAscii(vKey,iScan,kbuf,(USHORT*)pCh,0);
pCh = NULL;

Can anybody explain me where is the error in GetKeyboardState function? The error can be in
that GetKeyboardState function returns not the current state of keyboard or the parameter is passed badly or anything else. But I don't know,
because the GetKeyboard function returns the keystate of the message that is currently being processed, so it should be current state.
However, if the error is in not returning the current state, how can I get the CURRENT state of a key? I know the GetAsyncKeyState() function but it returns
error if the keyboard focus has another thread. Is another function like this, but system-wide? Thanks a lot.
0

Featured Post

[Webinar] Code, Load, and Grow

Managing multiple websites, servers, applications, and security on a daily basis? Join us for a webinar on May 25th to learn how to simplify administration and management of virtual hosts for IT admins, create a secure environment, and deploy code more effectively and frequently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
C++ to C# code conversion issue 4 128
Dynamically allocate memory 9 74
How to split this in C++ 4 127
Gaming Software 1 38
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question