What's a simple way of programmatically simulating user input?
Asked Answered
B

3

4

I have a dialog that pops up as result of an error condition. I want the dialog to remain open for at least 30 seconds, and close 30 seconds after the last user input (mouse or keyboard) is received.

I can implement this by checking the value returned by GetLastInputInfo and closing the dialog when this is more than 30 seconds ago, but if the dialog pops up when the user hasn't been at the mouse or keyboard for 30 seconds, the GetLastInputInfo test passes immediately, and the dialog closes again immediately. I could do this with another timer, but I figure it would be much simpler to simulate the mouse being moved a bit, or issuing a (harmless) keypress, just before the dialog opens. It would also have the advantage presumably of kicking the system out of screensaver.

What's the simplest 1-line Delphi code fragment to achieve this?

Blodget answered 11/10, 2011 at 8:14 Comment(1)
I would suggest that you should stick with simple. Use a timer, show a countdown, close the dialog. Don't mess with the mouse - I have a system that shows a display from 9am to 5pm, and the screen is auto-turned off out of hours. If you "jiggle" the mouse, you defeat my tool. Why are you interfering with other systems for such a simple task? (Just my thoughts - feel free to reject!)Knockwurst
S
7

the most simple is using the keybd_event function (one line of code)

keybd_event(Ord('A'), 0, 0, 0);

Also you can use the SendInput function but requires more than one line :)

Var
  pInputs : TInput;
begin
    pInputs.Itype := INPUT_KEYBOARD;
    pInputs.ki.wVk := Ord('A');
    pInputs.ki.dwFlags := KEYEVENTF_KEYUP;
    SendInput(1, pInputs, SizeOf(pInputs));
end;
Septempartite answered 12/10, 2011 at 9:58 Comment(0)
R
0

Input multiple byte characters with keybd_event:

procedure InsertText(text:string);
var i:integer;
    j:integer;
    ch:byte;
    str:string;
begin
  i:=1;
  while i<=Length(text) do
  begin
    ch:=byte(text[i]);
    if Windows.IsDBCSLeadByte(ch) then
       begin
         Inc(i);
         str:=inttostr(MakeWord(byte(text[i]), ch));
         keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), 0, 0);
         j:=1;
         while j<=Length(str) do
         begin
               keybd_event(96+strtoint(str[j]), MapVirtualKey(96+strtoint(str[j]), 0), 0, 0);
               keybd_event(96+strtoint(str[j]), MapVirtualKey(96+strtoint(str[j]), 0), 2, 0);
               j:=j+1;
         end;
         keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), KEYEVENTF_KEYUP, 0);
       end
    else begin
           keybd_event(VkKeyScan(text[i]),0,0,0);
           keybd_event(VkKeyScan(text[i]),0,2,0);
         end;
    Inc(i);
  end;
end;
Roanne answered 25/3, 2012 at 13:0 Comment(0)
M
0

https://github.com/WladiD/SendInputHelper by Mr. Waldemar Derr.

Simple and versatile, choose 2.

Example:

uses
  ..., SendInputHelper;

procedure TForm1.Button1Click(Sender: TObject);
var
  SIH: TSendInputHelper;
begin
  SIH := TSendInputHelper.Create;
  try
    // Start command shell
    SIH.AddShortCut([ssWin], 'r'); // Win+R
    SIH.AddDelay(100);
    SIH.AddText('cmd', True); // Second parameter True means AppendReturn
    SIH.AddDelay(500);

    SIH.AddText('ping google.de', True); // Perform a ping.

    SIH.Flush; // Isn't it easy?
  finally
    SIH.Free;
  end;
end;
Mcgrew answered 27/9, 2022 at 2:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.