Sorry, shortint / short is of course a signed word of 2 bytes

On a form drop a TEdit and a TButton, create an OnClick handler for the button and try this code:
uses ..., LCLType, LCLIntf;
Function GetKeyMask(Key: Integer): String;
Var K, I: Smallint; //Changed from Shortint to Smallint
Begin
K:= LCLIntf.GetKeyState(Key);
Result:= '';
For I:= 15 DownTo 0 Do
If (K And (1 Shl I)) <> 0 Then Result:= Result + '1'
Else Result:= Result + '0';
End;
procedure Button1Click(Sender: TObject);
begin
Edit1.Text:= GetKeyMask(VK_SHIFT);
end;
I'm not 100% sure, but GetKeyState may be declared both in Windows and LCLIntf and this may be what's causing variation. Stick with the one in LCLIntf

On Linux Mint 64bit the output is "1111111110000001" when shift is down, and "0000000000000001" when it is up. The low order bit toggles for each key press registred and this seems to be the case for all keys, not only the ones who actually can toggle (like CAPS, NUMLOCK etc.). If this is a bug or a workaround, I do not know.