| 
 
 
{Typically you would get the scancode needed from the
 lparam of a WM_KEYDOWN message.
 If you are trying to work from an OnKeyDown handler
 here you don't have that either,
 so you have to fall back on MapVirtualKey.
 The keystate array is obtained from GetKeyboardstate.
 }
 
 
 {: Obtain the character that will result from the virtual key
 passed in.
 @param vkey is the virtual key code, e.g. Key parameter of an
 OnKeyDown handler.
 @returns the character or '' if the key does not result in a
 character. On rare occasions the function may return two
 characters, e.g. if an accent key is pressed followed by another
 character that does not have an accented version. }
 
 function GetCharFromVKey(vkey: Word): string;
 var
 keystate: TKeyboardState;
 retcode: Integer;
 begin
 Win32Check(GetKeyboardState(keystate));
 SetLength(Result, 2);
 retcode := ToAscii(vkey,
 MapVirtualKey(vkey, 0),
 keystate, @Result[1],
 0);
 case retcode of
 0: Result := ''; // no character
 1: SetLength(Result, 1);
 2:;
 else
 Result := ''; // retcode < 0 indicates a dead key
 end;
 end;
 
 procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
 begin
 label1.Caption := GetCharFromVKey(Key);
 end;
 
 
   |