'SendInput in FMX Windows not releasing Shift state

I'm trying to type an uppercase letter in an EditBox using the sendInput function to press down Shift then sending a character then KeyUp for the character and for shift.

The Char comes in in the EditBox correctly, however, when I start typing in the EditBox it types everything in CAPS.

It seems that it does not release the Shift Key correctly. Below is my code:

input.Itype  := INPUT_KEYBOARD;
input.ki.wVk := VK_LSHIFT;
SendInput(1, input, SizeOf(input));

input.Itype  := INPUT_KEYBOARD;
input.ki.wVk := Word('T');
SendInput(1, input, SizeOf(input));

input.Itype      := INPUT_KEYBOARD;
input.ki.dwFlags := KEYEVENTF_KEYUP;
input.ki.wVk     := Word('T');
SendInput(1, input, SizeOf(input));

input.Itype      := INPUT_KEYBOARD;
input.ki.dwFlags := KEYEVENTF_KEYUP;
input.ki.wVk     := VK_LSHIFT;
SendInput(1, input, SizeOf(input));

Any help would be greatly appreciated.



Solution 1:[1]

I can not reproduce the problem, in my test the "Shift" key doesn't "stick", but as you did not show the complete procedure, I can't investigate/explain why you experience what you do.

A note though: TInput is a record and records are not automatically zero filled. Thus, fields that you do not assign values to, can have whatever values. Don't know if this might be the reason for the unexpected behaviour.

Anyway, it is better to send all keyboard event at the same time, in an array:

procedure TForm47.Button1Click(Sender: TObject);
var
  Inputs: array of TInput;
begin
  Edit1.SetFocus;

  SetLength(Inputs, 4); // ref. comment above, mem automatically zeroed

  Inputs[0].iType := INPUT_KEYBOARD;
  Inputs[0].ki.wvk := VK_SHIFT;
  Inputs[0].ki.dwFlags := 0;

  Inputs[1].itype := INPUT_KEYBOARD;
  Inputs[1].ki.wvk := $54;
  Inputs[1].ki.dwFlags := 0;

  Inputs[2].iType := INPUT_KEYBOARD;
  Inputs[2].ki.wVk := $54;
  Inputs[2].ki.dwFlags := KEYEVENTF_KEYUP;

  Inputs[3].iType := INPUT_KEYBOARD;
  Inputs[3].ki.wVk := VK_SHIFT;
  Inputs[3].ki.dwFlags := KEYEVENTF_KEYUP;

  SendInput(4, Inputs[0], SizeOf(TInput));

end;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tom Brunberg