Solved

Scancode to ASCII with WinAPI ToASCIIEx().

Posted on 2000-04-25
7
1,684 Views
Last Modified: 2008-02-20
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?
0
Comment
Question by:Traal
  • 3
  • 3
7 Comments
 
LVL 3

Expert Comment

by:shenqw
ID: 2750093
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
 
LVL 10

Expert Comment

by:Lischke
ID: 2750470
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
 

Author Comment

by:Traal
ID: 2750879
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 10

Accepted Solution

by:
Lischke earned 50 total points
ID: 2750922
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
 

Author Comment

by:Traal
ID: 2751258
Adjusted points from 40 to 50
0
 

Author Comment

by:Traal
ID: 2751259
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
 
LVL 10

Expert Comment

by:Lischke
ID: 2751275
:-))
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi IDE crash without error message ... 7 76
Multiple image collision 13 69
creating threads in delphi 1 82
Multi-layered image in FireMonkey 9 18
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

867 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now