Search code examples
delphicharactersendinput

Repetitious characters using send input in delphi


My Problem is following procedure that shows this string 'a-bb-ccc-dddd' in outpot like this 'a-b-c-d'. How can I fix it?

procedure SendText(const Value: WideString);
var
  i: Integer;
  S: WideString;
  TI, TYY222: TInput;
  ki: TKeybdInput;
  MyWND: HWND;
const
  KEYEVENTF_UNICODE = $0004;
begin
  S := (Value);
  TI.Itype := INPUT_KEYBOARD;
  for i := 1 to Length(S) do
  begin
    ki.wVk := 0;
    ki.dwFlags := KEYEVENTF_UNICODE;
    ki.wScan := Ord(S[i]);
    TI.ki := ki;
    SendInput(1, TI, SizeOf(TI));
  end;
end;

Solution

  • It is invariably a mistake to call SendInput multiple times in a loop in that way. The whole point of SendInput is that it batches up a series of related input events, and sends them as an atomic group. This is stated quite explicitly in the documentation for SendInput and I recommend that you re-read that.

    The first thing to change therefore is to use your loop to build an array of input events, and send that array in its entirety with a single call to SendInput, made after your loop completes.

    Another problem is that your code currently fakes the key down events, but omits to fake the key up events. Each character that you type involves the key going down, and then coming back up. So, your array needs to be sized to contain twice as many items as characters in the string. And for each character you need to include both key down and key up. Include KEYEVENTF_KEYUP in dwFlags to indicate a key up event.

    Yet another problem that I can see is that you are working with uninitialised variables. You set some but not all fields of ki. You need to make sure that the entire record is initialized.

    There seems little reason for you to make a copy of the input string. You can work with the input string directly. There is nothing to be gained from making a copy of it.

    Finally, did you consider using UI Automation instead of faking input?