Balder1978
asked on
How to perform mouse click outside the application
I'm trying to find a way to perform a mouse click event outside my C# app.
I use the SetCursorPos API to set the cursors position, the I would like to perform a left mouse click as one would normally do.
I've tried using SendInput, but no luck with that yet.
Any ideas?
Thank!
I use the SetCursorPos API to set the cursors position, the I would like to perform a left mouse click as one would normally do.
I've tried using SendInput, but no luck with that yet.
Any ideas?
Thank!
ASKER
It doesn't work :(
Hopefully someone will be able to answer your question rather quickly. However, failing that I can garauntee you the correct answer in about 12 hours.
So don't fret about this too much
ASKER
OK, thanks man :)
If you can't wait until later, a quick search told me that I think you want to use "SendMessage" not "SendInput"
Here's a site I found that goes into this a bit:
http://www.geocities.com/practicalvb/vb/windows/messages.html
The values for MouseDown and MouseUp are:
Private Const WM_LBUTTONUP = 0xH202
Private Const WM_LBUTTONDOWN = 0xH201
Then when you want to perform a mouse click you just need to execute three commands
SendMessage(<mousedown>)
Thread.Sleep(<whatever your click rate is... 200?>)
SendMessage(<mouseUp>)
As for the actual command, I haven't seen anything clear cut, but I know it is very basic...
SendMessage(null, WM_LBUTTONDOWN , 0, 0); (or something like that)
At any rate, if you need the solution now, try playing with the code above. Otherwise check back here in about 11 hours.
Uh-oh.. I may have the mouse message values wrong....
I found this in my WinUser.H file:
#define WM_LBUTTONDOWN 0x0201
#define WM_LBUTTONUP 0x0202
Which means the .Net code would look something like:
private const uint WM_LBUTTONDOWN = 0x0201;
private const uint WM_LBUTTONUP = 0x0202;
Basically just take the "H" out of the original declaration
I found this in my WinUser.H file:
#define WM_LBUTTONDOWN 0x0201
#define WM_LBUTTONUP 0x0202
Which means the .Net code would look something like:
private const uint WM_LBUTTONDOWN = 0x0201;
private const uint WM_LBUTTONUP = 0x0202;
Basically just take the "H" out of the original declaration
ASKER
Thanks! I'll have a go at it.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
just for the sake of completeness attached below is the program that I initially created with this functionality. It is a "clicker" program for one of those web based games.
The form contains 3 labels, 2 text boxes and 2 buttons. I threw this together for personal use, so I apoligise in advance for using poor programming practices and not having any documentation.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServ ices;
using System.Threading;
namespace Clicker
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private double interval;
private int clicks;
private bool quit;
private System.Windows.Forms.MainM enu mainMenu1;
private System.Windows.Forms.MenuI tem menuItem1;
private System.Windows.Forms.Label label3;
private const UInt32 MouseEventLeftDown = 0x0002;
private const UInt32 MouseEventLeftUp = 0x0004;
[DllImport("user32.dll")]
private static extern void mouse_event(UInt32 dwFlags,UInt32 dx,UInt32 dy,UInt32 dwData,IntPtr dwExtraInfo);
private System.Windows.Forms.Butto n button1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextB ox txtClicks;
private System.Windows.Forms.TextB ox txtInterval;
private System.Windows.Forms.Butto n button2;
private System.ComponentModel.Cont ainer components = null;
public Form1()
{
InitializeComponent();
quit = false;
interval = 2.5;
clicks = 300;
txtClicks.Text = clicks.ToString();
txtInterval.Text = interval.ToString();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Butto n();
this.txtClicks = new System.Windows.Forms.TextB ox();
this.label1 = new System.Windows.Forms.Label ();
this.label2 = new System.Windows.Forms.Label ();
this.txtInterval = new System.Windows.Forms.TextB ox();
this.button2 = new System.Windows.Forms.Butto n();
this.mainMenu1 = new System.Windows.Forms.MainM enu();
this.menuItem1 = new System.Windows.Forms.MenuI tem();
this.label3 = new System.Windows.Forms.Label ();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(200, 16);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "Start";
this.button1.Click += new System.EventHandler(this.b utton1_Cli ck);
//
// txtClicks
//
this.txtClicks.Location = new System.Drawing.Point(112, 16);
this.txtClicks.Name = "txtClicks";
this.txtClicks.Size = new System.Drawing.Size(64, 20);
this.txtClicks.TabIndex = 1;
this.txtClicks.Text = "350";
this.txtClicks.TextChanged += new System.EventHandler(this.t xt_TextCha nged);
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 16);
this.label1.Name = "label1";
this.label1.TabIndex = 2;
this.label1.Text = "Number of Clicks";
//
// label2
//
this.label2.Location = new System.Drawing.Point(8, 40);
this.label2.Name = "label2";
this.label2.TabIndex = 3;
this.label2.Text = "Click Interval (sec.)";
//
// txtInterval
//
this.txtInterval.Location = new System.Drawing.Point(112, 40);
this.txtInterval.Name = "txtInterval";
this.txtInterval.Size = new System.Drawing.Size(64, 20);
this.txtInterval.TabIndex = 4;
this.txtInterval.Text = "2.5";
this.txtInterval.TextChang ed += new System.EventHandler(this.t xt_TextCha nged);
//
// button2
//
this.button2.Location = new System.Drawing.Point(200, 40);
this.button2.Name = "button2";
this.button2.TabIndex = 5;
this.button2.Text = "Quit";
this.button2.Click += new System.EventHandler(this.b utton2_Cli ck);
//
// mainMenu1
//
this.mainMenu1.MenuItems.A ddRange(ne w System.Windows.Forms.MenuI tem[] {
this.menuItem1});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.Text = "Save Settings";
this.menuItem1.Click += new System.EventHandler(this.m enuItem1_C lick);
//
// label3
//
this.label3.Location = new System.Drawing.Point(0, 72);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(296, 32);
this.label3.TabIndex = 6;
this.label3.Text = "label3";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 93);
this.Controls.AddRange(new System.Windows.Forms.Contr ol[] {
this.label3,
this.button2,
this.txtInterval,
this.label2,
this.label1,
this.txtClicks,
this.button1});
this.MaximumSize = new System.Drawing.Size(300, 140);
this.Menu = this.mainMenu1;
this.MinimumSize = new System.Drawing.Size(300, 140);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormS tartPositi on.CenterS creen;
this.Text = "The Clicker";
this.Load += new System.EventHandler(this.F orm1_Load) ;
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void SendLeftClick()
{
mouse_event(MouseEventLeft Down, 0, 0, 0, new System.IntPtr());
mouse_event(MouseEventLeft Up, 0, 0, 0, new System.IntPtr());
}
private bool IsValid()
{
int hour = 0;
int minute = 0;
int second = 0;
bool isValid = true;
try
{
interval = Convert.ToDouble(txtInterv al.Text);
clicks = Convert.ToInt32(txtClicks. Text);
if(interval<2||interval>50 0)
throw new Exception("Invalid time interval.\n\nValid range is 2 to 500 sec.");
if(clicks<0||clicks>1000)
throw new Exception("Invalid click number.\n\nValid range is 0 to 1000");
hour += (int)(clicks*interval)/360 0;
minute += (int)((clicks*interval)/60 )%(60);
second += (int)(clicks*interval)%60;
label3.Text = "Click Time - " +
hour.ToString("00") + ":" +
minute.ToString("00") + ":" +
second.ToString("00");
}
catch(Exception e)
{
label3.Text = e.Message;
isValid = false;
}
catch
{
label3.Text = "Your numeric values are not valid,\n\nClicks: Int; Interval: Double";
isValid = false;
}
return isValid;
}
private void button1_Click(object sender, System.EventArgs e)
{
Thread myClicker = new Thread(new ThreadStart(RunClicker));
myClicker.IsBackground = true;
myClicker.Start();
}
private void RunClicker()
{
if(IsValid())
{
for(int i=0;i<clicks;i++)
{
Thread.Sleep((int)(interva l*1000));
this.Text = "Click #: " + (i+1);
Application.DoEvents();
if (quit)
break;
else
SendLeftClick();
}
Thread.CurrentThread.Abort ();
}
}
private void button2_Click(object sender, System.EventArgs e)
{
quit = true;
this.Close();
GC.Collect();
GC.WaitForPendingFinalizer s();
}
private void menuItem1_Click(object sender, System.EventArgs e)
{
}
private void Form1_Load(object sender, System.EventArgs e)
{
if (!IsValid())
throw new Exception("Program Failed to Load Properly");
}
private void txt_TextChanged(object sender, System.EventArgs e)
{
IsValid();
}
}
}
The form contains 3 labels, 2 text boxes and 2 buttons. I threw this together for personal use, so I apoligise in advance for using poor programming practices and not having any documentation.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServ
using System.Threading;
namespace Clicker
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private double interval;
private int clicks;
private bool quit;
private System.Windows.Forms.MainM
private System.Windows.Forms.MenuI
private System.Windows.Forms.Label
private const UInt32 MouseEventLeftDown = 0x0002;
private const UInt32 MouseEventLeftUp = 0x0004;
[DllImport("user32.dll")]
private static extern void mouse_event(UInt32 dwFlags,UInt32 dx,UInt32 dy,UInt32 dwData,IntPtr dwExtraInfo);
private System.Windows.Forms.Butto
private System.Windows.Forms.Label
private System.Windows.Forms.Label
private System.Windows.Forms.TextB
private System.Windows.Forms.TextB
private System.Windows.Forms.Butto
private System.ComponentModel.Cont
public Form1()
{
InitializeComponent();
quit = false;
interval = 2.5;
clicks = 300;
txtClicks.Text = clicks.ToString();
txtInterval.Text = interval.ToString();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Butto
this.txtClicks = new System.Windows.Forms.TextB
this.label1 = new System.Windows.Forms.Label
this.label2 = new System.Windows.Forms.Label
this.txtInterval = new System.Windows.Forms.TextB
this.button2 = new System.Windows.Forms.Butto
this.mainMenu1 = new System.Windows.Forms.MainM
this.menuItem1 = new System.Windows.Forms.MenuI
this.label3 = new System.Windows.Forms.Label
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(200, 16);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "Start";
this.button1.Click += new System.EventHandler(this.b
//
// txtClicks
//
this.txtClicks.Location = new System.Drawing.Point(112, 16);
this.txtClicks.Name = "txtClicks";
this.txtClicks.Size = new System.Drawing.Size(64, 20);
this.txtClicks.TabIndex = 1;
this.txtClicks.Text = "350";
this.txtClicks.TextChanged
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 16);
this.label1.Name = "label1";
this.label1.TabIndex = 2;
this.label1.Text = "Number of Clicks";
//
// label2
//
this.label2.Location = new System.Drawing.Point(8, 40);
this.label2.Name = "label2";
this.label2.TabIndex = 3;
this.label2.Text = "Click Interval (sec.)";
//
// txtInterval
//
this.txtInterval.Location = new System.Drawing.Point(112, 40);
this.txtInterval.Name = "txtInterval";
this.txtInterval.Size = new System.Drawing.Size(64, 20);
this.txtInterval.TabIndex = 4;
this.txtInterval.Text = "2.5";
this.txtInterval.TextChang
//
// button2
//
this.button2.Location = new System.Drawing.Point(200, 40);
this.button2.Name = "button2";
this.button2.TabIndex = 5;
this.button2.Text = "Quit";
this.button2.Click += new System.EventHandler(this.b
//
// mainMenu1
//
this.mainMenu1.MenuItems.A
this.menuItem1});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.Text = "Save Settings";
this.menuItem1.Click += new System.EventHandler(this.m
//
// label3
//
this.label3.Location = new System.Drawing.Point(0, 72);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(296, 32);
this.label3.TabIndex = 6;
this.label3.Text = "label3";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 93);
this.Controls.AddRange(new
this.label3,
this.button2,
this.txtInterval,
this.label2,
this.label1,
this.txtClicks,
this.button1});
this.MaximumSize = new System.Drawing.Size(300, 140);
this.Menu = this.mainMenu1;
this.MinimumSize = new System.Drawing.Size(300, 140);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormS
this.Text = "The Clicker";
this.Load += new System.EventHandler(this.F
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void SendLeftClick()
{
mouse_event(MouseEventLeft
mouse_event(MouseEventLeft
}
private bool IsValid()
{
int hour = 0;
int minute = 0;
int second = 0;
bool isValid = true;
try
{
interval = Convert.ToDouble(txtInterv
clicks = Convert.ToInt32(txtClicks.
if(interval<2||interval>50
throw new Exception("Invalid time interval.\n\nValid range is 2 to 500 sec.");
if(clicks<0||clicks>1000)
throw new Exception("Invalid click number.\n\nValid range is 0 to 1000");
hour += (int)(clicks*interval)/360
minute += (int)((clicks*interval)/60
second += (int)(clicks*interval)%60;
label3.Text = "Click Time - " +
hour.ToString("00") + ":" +
minute.ToString("00") + ":" +
second.ToString("00");
}
catch(Exception e)
{
label3.Text = e.Message;
isValid = false;
}
catch
{
label3.Text = "Your numeric values are not valid,\n\nClicks: Int; Interval: Double";
isValid = false;
}
return isValid;
}
private void button1_Click(object sender, System.EventArgs e)
{
Thread myClicker = new Thread(new ThreadStart(RunClicker));
myClicker.IsBackground = true;
myClicker.Start();
}
private void RunClicker()
{
if(IsValid())
{
for(int i=0;i<clicks;i++)
{
Thread.Sleep((int)(interva
this.Text = "Click #: " + (i+1);
Application.DoEvents();
if (quit)
break;
else
SendLeftClick();
}
Thread.CurrentThread.Abort
}
}
private void button2_Click(object sender, System.EventArgs e)
{
quit = true;
this.Close();
GC.Collect();
GC.WaitForPendingFinalizer
}
private void menuItem1_Click(object sender, System.EventArgs e)
{
}
private void Form1_Load(object sender, System.EventArgs e)
{
if (!IsValid())
throw new Exception("Program Failed to Load Properly");
}
private void txt_TextChanged(object sender, System.EventArgs e)
{
IsValid();
}
}
}
ASKER
Very, very good!!! Thanks alot man!!!
here are mouse API calls:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/mouseinput.asp
I have this code on my home computer so I don't have the exact syntax handy. But as I recall this is very easy to perform.
I want to say it's something like:
sendinput(1,0,null); // (1 is the left click and 2 is the right click).
This is, of course, after you have declared your API method call.