Hi there,

I just bumped across this website through google and found it very neat. I am self taught at Delphi, and know very little. I know there are quite a few ways to send the virtual keypresses, but I only know of one and I doubt I am using it properly.

procedure TForm1.Timer1Timer(Sender: TObject);
var
Int10: Integer;
begin
if Odd(GetAsyncKeyState(VK_F10)) then //Hotkey on F10.
  begin
    Inc(Int10);
    Timer2.Interval:=StrToInt(Edit1.Text);
  end;
if odd(Int10) then //If on
  begin
    Timer2.Enabled:=True; //Enables the keypress.
  end
else //If off
  begin
    Timer2.Enabled:=False;//Disables the keypress.
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var
Window:hwnd;
begin
Window:=FindWindowA('notepad',nil); //Finds notepad.
if Window<>0 then
begin
keybd_event(Ord('B'), 0, 0, 0);
end;
end;

I found Delphi Tricks and there are a few ways of sending key presses, however I do not understand them. I only want Keydown in this application so it holds down B. I have tried googling and found some other examples, but I'm not sure if I am incorporating them in properly.

I appreciate your assistance!

Sincerely,
Ab.

Post Scriptum: I apologize if I was not being specific enough.

That timer event will not work like you expect. The Int10 is not guaranteed to have any specific value. While it may appear to work sometimes (just as a fluke of how the stack works), it will suddenly break and work differently.

In either case, you should not enable the timer in a timer event. Only disable.

The way to do it is:

procedure Form1.sendNsecondsWorthOfBtoNotepad( n: integer );
  // Add this procedure to the private, protected, or public part of your form class.
  begin
  timer1.interval := 100;    // one keypress every 1/10th second
  timer1.tag      := n /10;  // number of timeout events to process
  timer1.enabled  := TRUE
  end;

procedure Form1.Timer1Timer( sender: tObject );
  // This is the timeout event
  begin
  // Send the keystroke
  keybd_event(Ord('B'), 0, 0, 0);

  // One tenth second has passed
  timer1.tag := timer1.tag -100;

  // If time is up, stop sending keystrokes
  if timer1.tag = 0 then timer1.enabled := FALSE
  end;

procedure Form1.Button1Click( sender: tObject );
  // This procedure starts the process
  var ms: integer;
  begin
  // Convert the user's input if possible. (If not, complain.)
  try ms := strToInt( edit1.text )
  except
    showMessage( 'You must specify the number of milliseconds to send keystrokes' );
    edit1.setFocus;
    exit
    end;
  sendNsecondsWorthOfBtoNotepad( ms )
  end;

Hope this helps.

I'm still unsure of where to add the procedure even though it says:

//Add this procedure to the private, protected, or public part of your form class.

I tried to put it in a couple of different places (like under the public declarations), but it did not work (meaning I got an error). I know this is supposed to be obvious, but I unfortunately have little experience.

Make sure your form class looks something like this:

type
  TForm1 = class(TForm)
    ...
  public:
    { Public declarations }
    procedure sendNsecondsWorthOfBtoNotepad( n: integer );
  end;

...

implementation
{$R *.RES}

procedure Form1.sendNsecondsWorthOfBtoNotepad( n: integer );
  var ...
  begin
  ...
  end;

Hope this helps.

Thank you so much for replying, I really don't know how to thank you. The problem seemed to be solved, but another one came up! Here is your source:

[TEX]unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Timer1: TTimer;
Edit1: TEdit;
Button1: TButton;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure sendNsecondsWorthOfBtoNotepad( n: integer );
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.sendNsecondsWorthOfBtoNotepad(n: Integer);
begin
Timer1.Interval := 100;
Timer1.Tag := n /10;
Timer1.Enabled := True
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
keybd_event(Ord('B'), 0, 0, 0);
Timer1.Tag := Timer1.Tag -100;
if Timer1.Tag = 0 then Timer1.Enabled := False
end;

procedure TForm1.Button1Click(Sender: TObject);
var ms: Integer;
begin
try ms := StrToInt(Edit1.Text)
except
ShowMessage( 'You must specify the number of milliseconds to send keystrokes' );
Edit1.SetFocus;
exit
end;
sendNsecondsWorthOfBtoNotepad(ms)
end;
end.[/TEX]

The line:
[TEX]Timer1.Tag := n /10;[/TEX]
gives me the following errors:

[Error] Unit1.pas(32): Incompatible types: 'Integer' and 'Extended'
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'

I'm trying to fix it, but I do not understand what "extended" means.

Oh, and I'm jealous of your skill in Delphi!!!!

Ab.

It comes with time.

Sorry, for the error. I accidentally mixed C and Pascal. The line should read Timer1.Tag := n div 10; The "extended" is the IEEE 80-bit Extended Precision floating point type. Pascal converts single, double, and real to extended when performing calculations.

The "extended" is the IEEE 80-bit Extended Precision floating point type. Pascal converts single, double, and real to extended when performing calculations.

Ohh, I never knew that until now (Cool tid-bit).

Thanks for solving my question! =]

This question has already been answered. Start a new discussion instead.