[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 273
  • Last Modified:

Simulate clicks/double clicks globally?

Hi,
How can I simulate single clicks and double clicks GLOBALLY(ie. anywhere in the screen)?
I want to do this only with the built-in components in Delphi.
(D2/Win95/Sample code expected)
0
yingkit
Asked:
yingkit
  • 9
  • 5
  • 3
  • +1
1 Solution
 
WiseGuyCommented:
So you want to sent a windows message but not to a specific window handle?
0
 
yingkitAuthor Commented:
What I want is just to send single/double clicks to any specified x,y coordinates on the screen...
0
 
WiseGuyCommented:
You would have to find out the windows message that decodes this.

Say this message is <M>.
Then you call this windows api method:

PostMessage(HWND_BROADCAST,M,X,Y)

it might be the other way around for the X and Y coordinates

PostMessage(HWND_BROADCAST,M,Y,X)


See the Win32.hlp file in program files\common files\borland shared\mshelp
0
Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

 
yingkitAuthor Commented:
Sample code?
0
 
WiseGuyCommented:
working on it.
 
0
 
yingkitAuthor Commented:
Thx
0
 
MadshiCommented:
Well, I see 3 possibilites:

(1) WiseGuy's suggestion.
(2) Use WindowFromPoint to get the window handle at the position, where you want to simulate the clicks. Then call PostMessage(window, WM_LBUTTONDOWN, ...) and PostMessage(window, WM_LBUTTONUP, ...).
(3) Use SetCursorPos. Then call Mouse_Event. This should work best. But the mouse is really moving to the simulated position.

Regards, Madshi.
0
 
WiseGuyCommented:
Well,

BroadCast doesn't work because the first window that accepts it takes the message from the queue. This window is hardly ever the one intended. The desktop is the most likely one.
So you would have to go with Madshi's option 2 or 3.

If I supply you with sample code, would you both consider that an answer
0
 
MadshiCommented:
Yes...   :-)   Post an answer...
0
 
WiseGuyCommented:
as soon as I got it working.

It turns out that only Mouse_Event works.
I call it, indirectly from a button.click.
This makes this click trigger all of the time.
I'm trying to solve this with a timer, so that the click event is finished before a new mouse event takes place.
0
 
men xinCEOCommented:
why dont you use mouse_event API?

to simulate single clicks :
mouse_event()
  mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0);
  mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0);

and double clicks is
  mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0);
  mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0);
  mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0);
  mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0);

(x,y) is your mousepoint!
0
 
WiseGuyCommented:
Solved it!
The timers where not needed, I accidently had a OnChange Eventhandler somewhere

It is quite an eleborate answer, that might pay itself in your grading Yingkit
I made the code in Delphi 5, so delphi 2 will complain about non-existing properties. I see NO reason why it would not work though.
Here it goes: (first form then unit)

object Form1: TForm1
  Left = 188
  Top = 107
  Width = 260
  Height = 252
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnDblClick = FormDblClick
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 32
    Top = 40
    Width = 7
    Height = 13
    Caption = 'X'
  end
  object Label2: TLabel
    Left = 32
    Top = 96
    Width = 7
    Height = 13
    Caption = 'Y'
  end
  object lblWhereX: TLabel
    Left = 56
    Top = 40
    Width = 6
    Height = 13
    Caption = '?'
  end
  object lblWhereY: TLabel
    Left = 54
    Top = 96
    Width = 6
    Height = 13
    Caption = '?'
  end
  object edtX: TEdit
    Left = 32
    Top = 56
    Width = 121
    Height = 21
    TabOrder = 0
    Text = '369'
  end
  object edtY: TEdit
    Left = 32
    Top = 112
    Width = 121
    Height = 21
    TabOrder = 1
    Text = '220'
  end
  object btnClick: TButton
    Left = 8
    Top = 160
    Width = 75
    Height = 25
    Caption = 'Click'
    TabOrder = 2
    OnClick = btnClickClick
  end
  object btnDblClick: TButton
    Left = 104
    Top = 160
    Width = 75
    Height = 25
    Caption = 'DblClick'
    TabOrder = 3
    OnClick = btnDblClickClick
  end
  object RadioGroup1: TRadioGroup
    Left = 160
    Top = 32
    Width = 89
    Height = 105
    Caption = 'Mouse button'
    ItemIndex = 0
    Items.Strings = (
      'left'
      'right'
      'middle')
    TabOrder = 4
  end
  object Timer1: TTimer
    OnTimer = Timer1Timer
  end
end

unit ufMain;

interface

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

type
  TForm1 = class(TForm)
    edtX: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    edtY: TEdit;
    btnClick: TButton;
    btnDblClick: TButton;
    RadioGroup1: TRadioGroup;
    Timer1: TTimer;
    lblWhereX: TLabel;
    lblWhereY: TLabel;
    procedure btnClickClick(Sender: TObject);
    procedure btnDblClickClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormDblClick(Sender: TObject);
  private
    { Private declarations }
    procedure WMLButtonDown(var Message: TWMLButtonDown); //message WM_LBUTTONDOWN;
  public
    { Public declarations }
    procedure SimulateDblClick(Msg : Cardinal; X, Y : Cardinal);
    procedure SimulateClick(Msg1, Msg2 : Cardinal; X, Y : Cardinal);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.btnClickClick(Sender: TObject);
var
  X,Y : Cardinal;
begin
  X := StrToInt(edtX.Text);
  Y := StrToInt(edtY.Text);
  case (self.RadioGroup1.ItemIndex) of
    -1: begin
      exit;
    end; {case-statement}
    0: begin
      // simulate left button click
      SimulateClick(MOUSEEVENTF_LEFTDOWN,MOUSEEVENTF_LEFTUP,X,Y);
    end; {case-statement}
    1: begin
      SimulateClick(MOUSEEVENTF_RIGHTDOWN,MOUSEEVENTF_RIGHTUP,X,Y);
    end; {case-statement}
    2: begin
      SimulateClick(MOUSEEVENTF_MIDDLEDOWN,MOUSEEVENTF_MIDDLEUP,X,Y);
    end; {case-statement}
  end; {case}
end;

procedure TForm1.btnDblClickClick(Sender: TObject);
var
  X,Y : Cardinal;
begin
  X := StrToInt(edtX.Text);
  Y := StrToInt(edtY.Text);
  case (self.RadioGroup1.ItemIndex) of
    -1: begin
      exit;
    end; {case-statement}
    0: begin
      // simulate left button click
      SimulateClick(MOUSEEVENTF_LEFTDOWN,MOUSEEVENTF_LEFTUP,X,Y);
      SimulateClick(MOUSEEVENTF_LEFTDOWN,MOUSEEVENTF_LEFTUP,X,Y);
    end; {case-statement}
    1: begin
      SimulateClick(MOUSEEVENTF_RIGHTDOWN,MOUSEEVENTF_RIGHTUP,X,Y);
      SimulateClick(MOUSEEVENTF_RIGHTDOWN,MOUSEEVENTF_RIGHTUP,X,Y);
    end; {case-statement}
    2: begin
      SimulateClick(MOUSEEVENTF_MIDDLEDOWN,MOUSEEVENTF_MIDDLEUP,X,Y);
      SimulateClick(MOUSEEVENTF_MIDDLEDOWN,MOUSEEVENTF_MIDDLEUP,X,Y);
    end; {case-statement}
  end; {case}
end;

procedure TForm1.SimulateClick(Msg1, Msg2: Cardinal; X, Y: Cardinal);
begin
  SetCursorPos(X,Y);
  mouse_event(MOUSEEVENTF_ABSOLUTE+Msg1,X,Y,0,0);
  mouse_event(MOUSEEVENTF_ABSOLUTE+Msg2,X,Y,0,0);
end;

procedure TForm1.SimulateDblClick(Msg: Cardinal; X, Y: Cardinal);
begin
  SetCursorPos(X,Y);
  mouse_event(MOUSEEVENTF_ABSOLUTE+Msg,X,Y,0,0);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  aPoint : TPoint;
begin
  GetCursorPos(aPoint);
  lblWhereX.Caption := IntToStr(aPoint.x);
  lblWhereY.Caption := IntToStr(aPoint.y);
end;

procedure TForm1.WMLButtonDown(var Message: TWMLButtonDown);
var
  aMes : TMessage;
begin
  Message.Result := 1;
  aMes := TMessage(Message);
end;

procedure TForm1.FormDblClick(Sender: TObject);
begin
  ShowMessage('DblClick');
end;

end.

0
 
yingkitAuthor Commented:
EXCELLENT!
Thank you very much.
0
 
WiseGuyCommented:
yingkit,

what did you grade me?
0
 
yingkitAuthor Commented:
An "A" is given.
0
 
WiseGuyCommented:
Thanx,

I couldn't find what grade was given to me for what answer.


Yes, I already have answered more then one question

CU, Ramon
0
 
MadshiCommented:
WiseGuy, you can see that from the points you got. This q. was worth 40 points. If you got 4*40, you got an A grade. If you got 3*40 = B. 2*40 = C. 1*40 = D.
0
 
WiseGuyCommented:
I see,

I had noticed that I got more points than offered, but I thought it was related to the amount of experts participating in the discussion.

Thank you for salvaging me from my erronous way. :)
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 9
  • 5
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now