Delphi KeyDown and ASCII Codes

[ DelphiLand FAQ ]

Posted by webmaster Guido on September 15, 2004 at 18:59:32:

In Reply to: ASCII Codes :S posted by Joey p12386 on September 12, 2004 at 00:45:35:

: I'm using the application event component and the OnMessage event of it. The code i am using is:

: if (Msg.message = WM_KEYDOWN) then
: ShowMessage(Chr(Msg.wParam));

: But why does this give me all my chars in UPPERCASE letters? I don't have Caps Lock on but yet i still get passed the ASCII Codes for the captials :S Why does this happen??

: Thanks ;)

: Joey ^__^

Let's look at the complete code for an Application OnMessage event handler:

procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
  if (Msg.message = WM_KEYDOWN) then

Msg.wParam does not contain an ASCII code, it contains Windows' *virtual key code*. If you convert this to a character, using the Delphi Chr() function, you get an uppercase letter even if a lowercase key is pressed.

So how can you see the difference an uppercase/lowercase letter or maybe an ALT+Key combination? That info is in another part of the Msg parameter that you receive, in Msg.lParam.

According to the Windows API helpfile, in the case of a WM_KEYDOWN message, lParam is a 32 bit number with the following meaning:

Bits 0-15: specifies the repeat count.
Bits 16-23: specifies the scan code.
Bits 24 and higher: see the help files.

The info that you need, is in bits 16 to 23 of Msg.lParam.

This show clearly what a great job Delphi does, in hiding all this complicated stuff for you ;-)
Look at the code below, for the OnKeyDown event of a Delphi component (Edit1 in this case). Also here, parameter "Key" contains the virtual key code, not the ASCII code:

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
  ShowMessage(Chr(Key)); // shows uppercase letter

In this example, you can easily distinguish between upper- and lowercase by looking at variable "Shift" (see the Delphi Help).

webmaster Guido

[ Delphi Forum -- by DelphiLand ]