Scancode to ASCII with WinAPI ToASCIIEx().

Okay, the subject says it all.  Given a scancode, I want to get the ASCII code of the key pressed.  The following function should do it, but I think I'm having a problem with a pointer.

function ScanToASCII(scancode: DWORD; PResult: PChar): Integer;
var
  KBLayout: HKL;
  KBState: TKeyboardState;
  vk: UINT;
begin
  KBLayout := GetKeyboardLayout(0);

  if (GetKeyboardState(KBState) = False) then
  begin
    Result := 0;
    exit;
  end;

  vk := MapVirtualKeyEx(scancode, 1, KBLayout);

  Result := ToAsciiEx(vk, scancode, KBState, PResult, 0, KBLayout);
end;

The above function is my conversion of the C function found at http://www.gamedev.net/reference/programming/directx/article842.asp.  I'm thinking that there's a problem with my usage of "PResult PChar" in place of the C function's "ushort* result" in the calling parameter list, but I can't seem to get it right.  Any thoughts?
TraalAsked:
Who is Participating?
 
LischkeCommented:
Mmh, MSDN states the parameter is a PWord while Delphi's translation is a PChar. From this I conclude the C definition is (how seldom!) really a pointer to a Word instead an array of Words (because there are at most two characters to return).

In this case your code should work fine. I have no idea why it doesn't. What is actually wrong?

Passing the parameter by reference is basically not necessary because you will not change the pointer but to what it points to. The code looks then (very much like your original):

function ScanToASCII(scancode: DWORD; ASCIICodes: PChar): Integer;
var
  KBLayout: HKL;
  KBState: TKeyboardState;
  vk: UINT;
begin
  KBLayout := GetKeyboardLayout(0);

  if (GetKeyboardState(KBState) = False) then
  begin
    Result := 0;
    exit;
  end;

  vk := MapVirtualKeyEx(scancode, 1, KBLayout);

  Result := ToAsciiEx(vk, scancode, KBState, ASCIICodes, 0, KBLayout);
end;

var
  Codes: array[0..1] of Char;

begin
  ScanToASCII(..., @Codes);
end;


If this does still not work then please tell us more detailed what happens.

Ciao, Mike
0
 
shenqwCommented:
function ScanToASCII(scancode: DWORD; var PResult: PChar): Integer;
var
  KBLayout: HKL;
  KBState: TKeyboardState;
  vk: UINT;
begin
  KBLayout := GetKeyboardLayout(0);

  if (GetKeyboardState(KBState) = False) then
  begin
    Result := 0;
    exit;
  end;

  vk := MapVirtualKeyEx(scancode, 1, KBLayout);

  Result := ToAsciiEx(vk, scancode, KBState, PResult, 0, KBLayout);
end;


Call the function:

var
  P:PChar;
begin
  GetMem(P,256);
  //ScanToASCII(...,P);
  FreeMem(P,256);
end;
0
 
LischkeCommented:
Traal,

you have overseen a small point which is important. The PResult parameter must be PWideChar (in C it is a pointer to an unsigned short, which is Word in Delphi).

Additionally, the previous allocation of memory is not necessary. There can only be at most two characters in the result buffer, so recommend to write the code so:

function ScanToASCII(scancode: DWORD; var ASCIICodes: PWideChar): Integer;
var
  KBLayout: HKL;
  KBState: TKeyboardState;
  vk: UINT;
begin
  KBLayout := GetKeyboardLayout(0);

  if (GetKeyboardState(KBState) = False) then
  begin
    Result := 0;
    exit;
  end;

  vk := MapVirtualKeyEx(scancode, 1, KBLayout);

  Result := ToAsciiEx(vk, scancode, KBState, ASCIICodes, 0, KBLayout);
end;

and to call it:

var
  Codes: array[0..1] of WideChar;

begin
  ScanToASCII(..., @Codes);
end;

Ciao, Mike
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
TraalAuthor Commented:
Okay, Lischke, I made the change to PWIdeChar, and now I get the following error message when compiling:

"Incompatible types:  WideChar and Char".

The error occurs here...

"Result := ToAsciiEx(vk, scancode, KBState, ASCIICodes, 0, KBLayout);"

....with the cursor right after ASCIICodes.  So, it seems to be asking for a Char instead of a WideChar.

Brian
0
 
TraalAuthor Commented:
Adjusted points from 40 to 50
0
 
TraalAuthor Commented:
Success!  I didn't have the Codes buffer set up properly, and also wasn't calling ScanToASCII with the address (@) of the buffer.  Simple errors!  Sheesh!  Thanks for your excellent help.

Brian
0
 
LischkeCommented:
:-))
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.