TAdvSysKeyboardHook - Why it always returns uppercase letter?

I am registered customer for > 10 years.
The AdvSysKeyboardHook, KeyDown event, always returns the Key representing UpperCase letter.
For example, if user types "a" (lowercase) the Key is 65, i.e., uppercase "A".
It should be: 97 (lowercase "a")
How can I get the proper upper-case/lower-case letters?
Thank you
Shirley

At this level, keys are reported as the hardware key codes and thus, it reports the key pressed and the shift key state needs to be checked to see whether it is uppercase or lowercase. The physical key is the same for uppercase and lowercase.

Create a new VCL application, place a label on it, set the font size of the label to 64, set KeyPreview of the form to TRUE and double-click the OnKeyDown event for the form. Then paste in this code:

FUNCTION KeyPressed(VirtualKey : WORD) : BOOLEAN;
  BEGIN
    Result:=(GetKeyState(VirtualKey) AND $80000000<>0)
  END;

FUNCTION Shift : BOOLEAN;
  BEGIN
    Result:=KeyPressed(VK_SHIFT)
  END;

FUNCTION Alt : BOOLEAN;
  BEGIN
    Result:=KeyPressed(VK_MENU)
  END;

FUNCTION Ctrl : BOOLEAN;
  BEGIN
    Result:=KeyPressed(VK_CONTROL)
  END;

FUNCTION CapsLock : BOOLEAN;
  BEGIN
    Result:=(GetKeyState(VK_CAPITAL) AND $0001<>0)
  END;

PROCEDURE TForm151.FormKeyDown(Sender : TObject ; VAR Key : Word ; Shifts : TShiftState);
  VAR
    C   : CHAR;

  BEGIN
    IF Key IN [ORD('A')..ORD('Z')] THEN BEGIN
      IF Ctrl THEN
        C:=CHAR(SUCC(KEY-ORD('A')))
      ELSE IF Shift XOR CapsLock THEN
        C:=CHAR(KEY)
      ELSE
        C:=CHAR(KEY+32);
      IF C<'A' THEN
        Label1.Caption:='^'+CHAR(ORD(C)+64)
      ELSE
        Label1.Caption:=C
    END
  END;

Change the TForm151 part of the FormKeyDown to your form's class name. Then run the program.

It will now (for keys A-Z) show the "proper" case of the pressed key, taking into account shift, ctrl and Caps Lock.