0

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.

codeGood
  • 175
  • 1
  • 8
  • 2
    Mandatory reading: [Is it a bug to pass a single-element array to SendInput?](https://stackoverflow.com/q/46744894/1889329) – IInspectable Feb 22 '22 at 22:57
  • 1
    It would be much better to [use the `KEYEVENTF_UNICODE` flag](https://stackoverflow.com/a/19696146/65863) instead, then you don't need to mess with the keyboard state at all. You can send the actual characters you want - uppercase, lowercase, ascii, non-ascii, etc. – Remy Lebeau Feb 22 '22 at 23:08

1 Answers1

2

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;
Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
  • My procedure is the exact code I sent above with just Begin-End Statement and Declaring Variables... And of course, I set an editBox in focus (not in code) before calling this procedure (I don't call it from a button that takes away the focus, so instead I call it from a rectangle MouseDown event which keeps the focus on the EditBox) – codeGood Feb 23 '22 at 17:09
  • So, ... ? I'm not sure I get what you are saying with your comment? Don't you think it is worth it to try what I suggested to do, and that worked in my test? – Tom Brunberg Feb 23 '22 at 17:42
  • Yes it is working, I had difficulties in last parameter setting to `sizeOf(Input)` instead of `sizeOf(TInput)` – codeGood Feb 23 '22 at 19:18