Converting key value in OnKeyDown from Word to Char

Posted on 2012-09-14
Last Modified: 2012-09-17
For a Delphi form, I'm using OnKeyDown to trap the key that's pressed, and then doing various actions. However, if (key >= 32) and (key <=126) then I need to append the key to a string. Since OnKeyDown returns a Word rather than a char, I need to convert the Word to the ASCII char equivalent (e.g., 65 -> A, etc.) Not wanting to manually write something that manually addresses each possible value (which would work buy which would be kludgey), and not knowing how to do this, I looked online and "borrowed" something like this:
function KeyToStr(Key: Word): string;
    keyboardState: TKeyboardState;
    asciiResult: Integer;
    SetLength(Result, 2);
    asciiResult := ToAscii(key, MapVirtualKey(key, 0), keyboardState, @Result[1], 0);
    case asciiResult of
      1: SetLength(Result, 1);
      else Result := '';

Open in new window

This mostly works (though I confess to not understanding all of what it's doing), but when I press certain keys (e.g. Backspace consistently does it), when I append to the value to something I can display it in (using a DevExpress TcxEdit... though don't see why that would have a bearing), the characters turn to some seeming random foreign character set (often Chinese but not always).
Is there a better way to determine the character value of the key and/or can someone tell me how to keep this  from picking some other set of characters?
Question by:EricTaylor
    LVL 22

    Expert Comment

    by:Ferruccio Accalai
    You could use the OnkeyPress and the OnkeyDOwn combined togeter

    OnKeyDown is trapped before of OnKeyPress, so you could just check in the OnKeyPress event any char key and let the other job for OnKeyDown

    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
      Showmessage(Format('KeyValue = %d', [Key]));

    procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
      // check if the key is a valid keyboard char
      if (ord(Key) >= 32) and (ord(Key) <=126) then

    Author Comment

    In this case, since OnKeyDown has information about the TshiftState and OnKeyPress doesn't, Whether I want to take action for example, if the A key is pressed, depends on whether ssCtrl or ssAlt are combined with it, so I think I need OnKeyDown rather than OnKeyPress.
    LVL 22

    Accepted Solution

    So if you don't need to check the case just use CHAR(KEy) in OnKeyDown to get the char value of the key
    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
      s, k: String;
      if ssShift in Shift then
        s := 'SHIFT pressed - ';
      if ssCTRL in Shift then
        s := s+ 'CTRL pressed - ';
      if ssALT in Shift then
        if ssShift in Shift then
          s := s+'ALT pressed - ';
      if (Key >= 32) and (Key <=126) then
        k := char(Key);
        s := s+(Format('Char = %s - ', [k]));
      s := s+Format('KeyValue = %d', [Key]);

    Author Closing Comment

    Thanks... didn't know one could cast the key as Char. That did the trick. I knew about handling the shift state, but appreciate the completeness of covering that in your example just in case.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
    Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
    Hi everyone! This is Experts Exchange customer support.  This quick video will show you how to change your primary email address.  If you have any questions, then please Write a Comment below!
    Internet Business Fax to Email Made Easy - With eFax Corporate (, you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

    737 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

    22 Experts available now in Live!

    Get 1:1 Help Now