I'm tracking vertical mouse movement, subtracting the previous position from the current position. I am using
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
mouse_event(0x0001, 0, 4, 0, 0)
to move the mouse down 4 pixels. Everything works fine until the mouse reaches position 1440 (the height of my display). I test the program in an FPS game using
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out PointInter lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct PointInter
{
public int X, Y;
public static explicit operator Point(PointInter point) => new Point(point.X, point.Y);
}
public static Point GetCursorPosition()
{
GetCursorPos(out var lpPoint);
return (Point)lpPoint;
}
and I get the following values:
1423
1427
1431
1435
1439
1439
1439
1439
I can't find a working option that will allow me to either reset the mouse position to 0, or somehow get around this limitation, because it's impossible to track the number of pixels. I tried the NeatInput library, it sometimes shows values 1441, 1442, 1443, but no more, and if i move mouse by 10 pix down the values are still not correct. I tried to find something like absolute mouse shift but couldn't find. Can anyone please help me with the solution?
I want to make a mouse macroer. Which can both do simulated mouse events, or using my computers own cursor on screen.
The macro shall be created by typing in methods in the IDE. These methods shall then execute mouse events on a certain .exe´s window. By using coordinates.
For example this is my goal of a method executing a simulated or not simulated mouse left click on a certain .exe´s window:
Psuedo code:
//Following method left clicks with the offset (x, y)
//from the windows top left corner. If the bool isSimulated
//is set to true the click will be simulated else the computers
//own mouse cursor will be moved and execute the mouse event.
LeftMouseClickOnWindow(x, y, isSimulated);
To chrisp the problem even more, simulated mouse clicks should function while the window is minimized or when unfocused.
I am wondering what the best approach to create this kind of util is.
Is user32.dll´s functions a good approach?
Is it easier to do it in C++ rather than C#?
Any advices, sources, example codes and comments is warmly appreciated!
Both C++ and C# are great. AutoHotKey can do the job, but I'm like you - I love to write my own stuff. Another option is AutoIt, and you can use its dll in your C# project... but then you have to make sure that it's installed on every system... not a luxury that I've encountered often.
Here's something to play around with. Hopefully it'll get you going... note that it's C#. Before you run this code, make sure that you don't have anything important open where your mouse is at... this will move 20 times in a diagonal to the lower right and perform a click every time it moves. You don't want this to close your stuff accidentally. So, just minimize it all, prior to running this.
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ConsoleApplication
{
class Program
{
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
//private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
//private const int MOUSEEVENTF_RIGHTUP = 0x10;
public void DoMouseStuff()
{
Cursor.Current = new Cursor(Cursor.Current.Handle);
var point = new Point(Cursor.Position.X, Cursor.Position.Y);
for (int i = 0; i < 20; i++, point.X += 10, point.Y += 10)
{
Cursor.Position = point;
Program.mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, (uint)Cursor.Position.X, (uint)Cursor.Position.Y, 0, 0);
System.Threading.Thread.Sleep(100);
}
}
static void Main(string[] args)
{
var prog = new Program();
prog.DoMouseStuff();
}
}
}
You'll need to set references for System.Windows.Forms & System.Drawing, if you don't have those set already. I made it as a console app, so, setting for me was required. As you notice, I included System.Threading.Thread.Sleep(100);... this is so that you can see what's going on. So, I'm basically slowing down the whole thing. It moves and it clicks every time it moves (which is approximately once every 100 milliseconds).
Familiarize yourself with the Cursor and user32.dll.
Last, but not least, here's MSDN documentation on mouse & keyboard simulation: http://msdn.microsoft.com/en-us/library/ms171548.aspx
To give some background, I am developing a piece of software that assists players with the game Star Wars: The old republic. The game has very limited user interface capabilities, so i am developing an external application that will parse the log in real time, and output visual clues to help the user maximize their in-game performance. For example, if a character gets a certain "buff" the combat-log will show it, and i want to place a visual clue on the screen (so the user doesn't need to pay attention to small icons at the perimeter of the screen).
Before i begin, i wanted to create a few "proof of concept" scripts for myself to figure out how i am going to hand the major parts. The one i am stuck on is where i have my question:
I need to be able to show a graphic, likely a PNG file with transparency, on the screen over the game. The user needs to be able to click through that image so they can continue to interact with the game. I am a bit lost on how to go about that. The requirements would be:
Show an image (or multiple images, for that matter)
Have that image stick over-top the other application, even without application "focus"
Have that image be non-interactive (or click-through-able).
I am developing the application in C#
Any guidance on where to begin would be very much appreciated!
I have started looking at doing some similar things, so this might be able to give you a start.
For a first version, you might start by looking at the "AllowTransparency", and "TransparencyKey" , and "TopMost" properties of Form.
(I have found that the TransparencyKey doesn't work with White (255,255,255), but that specific non-white colors work fine...not sure why).
This would work as a click-throughable form that would stand above other forms...but since it is transparent, you can't display images in the transparent part. But if all you need is a hud that fits around the target application, this might be the easiest way.
If this top level form doesn't end up in front of the game...you might try putting the game in Windowed mode.
When running in full-screen mode, games generally draw to the screen directly through ActiveX, Direct3D, OpenGL, DirectDraw, etc.
Drawing on top of these would require injecting code into the DirectX, OpenGL, orother engine's draw/update/refresh function (basically tell DirectX3D to draw your stuff at the end of each draw cycle). There are some existing software that does this: for example, Steam Overlay, fraps, xfire.
A quick google search found "Game Overlay" which although I haven't downloaded or tried, says that it can overlay form applications on top of games for you.
(Seems that that program is under a company that was just dissolved, and I couldn't seem to get it to work for me anyway...)
It is possible to create a form that is not completely transparent but is click throughable by making native Windows calls..I'll see if I can create an example over the next few days.
I found an old test project and cleaned it up a bit.
Basically when run it will draw 500 random red lines to the front of the screen that are clickthrough-able. Then it draws 1000 random white lines (i.e. erases). Then repeats.
In writing the code I wanted to get a proof of concept for a couple of things: How to be able to draw on the full surface of a form, How to programmatically make the form become full size over multiple screens, How to make use of Background Workers, and How this proof of concept might work as a transparent overlay.
Instructions:
Create a new Windows Forms Project named TranparentOverlay_simpleExample
In design view, set the following properties on Form1:
BackColor: White
FormBorderStyle: None
Location: -1280, 0 (i.e. the top left corner of your screens, with one screen probably just 0,0)
TopMost: True
TransparencyKey: White
WindowState: Maximized
Now enter the code view for Form1 and replace it with the following:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
namespace TransparentOverlay_simpleExample
{
public partial class Form1 : Form
{
BackgroundWorker bw = new BackgroundWorker();
Random rand = new Random(DateTime.Now.Millisecond);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool BringWindowToTop(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, uint wMsg, UIntPtr wParam, IntPtr lParam); //used for maximizing the screen
const int WM_SYSCOMMAND = 0x0112; //used for maximizing the screen.
const int myWParam = 0xf120; //used for maximizing the screen.
const int myLparam = 0x5073d; //used for maximizing the screen.
int oldWindowLong;
[Flags]
enum WindowStyles : uint
{
WS_OVERLAPPED = 0x00000000,
WS_POPUP = 0x80000000,
WS_CHILD = 0x40000000,
WS_MINIMIZE = 0x20000000,
WS_VISIBLE = 0x10000000,
WS_DISABLED = 0x08000000,
WS_CLIPSIBLINGS = 0x04000000,
WS_CLIPCHILDREN = 0x02000000,
WS_MAXIMIZE = 0x01000000,
WS_BORDER = 0x00800000,
WS_DLGFRAME = 0x00400000,
WS_VSCROLL = 0x00200000,
WS_HSCROLL = 0x00100000,
WS_SYSMENU = 0x00080000,
WS_THICKFRAME = 0x00040000,
WS_GROUP = 0x00020000,
WS_TABSTOP = 0x00010000,
WS_MINIMIZEBOX = 0x00020000,
WS_MAXIMIZEBOX = 0x00010000,
WS_CAPTION = WS_BORDER | WS_DLGFRAME,
WS_TILED = WS_OVERLAPPED,
WS_ICONIC = WS_MINIMIZE,
WS_SIZEBOX = WS_THICKFRAME,
WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
WS_CHILDWINDOW = WS_CHILD,
//Extended Window Styles
WS_EX_DLGMODALFRAME = 0x00000001,
WS_EX_NOPARENTNOTIFY = 0x00000004,
WS_EX_TOPMOST = 0x00000008,
WS_EX_ACCEPTFILES = 0x00000010,
WS_EX_TRANSPARENT = 0x00000020,
//#if(WINVER >= 0x0400)
WS_EX_MDICHILD = 0x00000040,
WS_EX_TOOLWINDOW = 0x00000080,
WS_EX_WINDOWEDGE = 0x00000100,
WS_EX_CLIENTEDGE = 0x00000200,
WS_EX_CONTEXTHELP = 0x00000400,
WS_EX_RIGHT = 0x00001000,
WS_EX_LEFT = 0x00000000,
WS_EX_RTLREADING = 0x00002000,
WS_EX_LTRREADING = 0x00000000,
WS_EX_LEFTSCROLLBAR = 0x00004000,
WS_EX_RIGHTSCROLLBAR = 0x00000000,
WS_EX_CONTROLPARENT = 0x00010000,
WS_EX_STATICEDGE = 0x00020000,
WS_EX_APPWINDOW = 0x00040000,
WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE),
WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST),
//#endif /* WINVER >= 0x0400 */
//#if(WIN32WINNT >= 0x0500)
WS_EX_LAYERED = 0x00080000,
//#endif /* WIN32WINNT >= 0x0500 */
//#if(WINVER >= 0x0500)
WS_EX_NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children
WS_EX_LAYOUTRTL = 0x00400000, // Right to left mirroring
//#endif /* WINVER >= 0x0500 */
//#if(WIN32WINNT >= 0x0500)
WS_EX_COMPOSITED = 0x02000000,
WS_EX_NOACTIVATE = 0x08000000
//#endif /* WIN32WINNT >= 0x0500 */
}
public enum GetWindowLongConst
{
GWL_WNDPROC = (-4),
GWL_HINSTANCE = (-6),
GWL_HWNDPARENT = (-8),
GWL_STYLE = (-16),
GWL_EXSTYLE = (-20),
GWL_USERDATA = (-21),
GWL_ID = (-12)
}
public enum LWA
{
ColorKey = 0x1,
Alpha = 0x2,
}
[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
/// <summary>
/// Make the form (specified by its handle) a window that supports transparency.
/// </summary>
/// <param name="Handle">The window to make transparency supporting</param>
public void SetFormTransparent(IntPtr Handle)
{
oldWindowLong = GetWindowLong(Handle, (int)GetWindowLongConst.GWL_EXSTYLE);
SetWindowLong(Handle, (int)GetWindowLongConst.GWL_EXSTYLE, Convert.ToInt32( oldWindowLong | (uint)WindowStyles.WS_EX_LAYERED | (uint)WindowStyles.WS_EX_TRANSPARENT));
}
/// <summary>
/// Make the form (specified by its handle) a normal type of window (doesn't support transparency).
/// </summary>
/// <param name="Handle">The Window to make normal</param>
public void SetFormNormal(IntPtr Handle)
{
SetWindowLong(Handle, (int)GetWindowLongConst.GWL_EXSTYLE, Convert.ToInt32(oldWindowLong | (uint)WindowStyles.WS_EX_LAYERED));
}
/// <summary>
/// Makes the form change White to Transparent and clickthrough-able
/// Can be modified to make the form translucent (with different opacities) and change the Transparency Color.
/// </summary>
public void SetTheLayeredWindowAttribute()
{
uint transparentColor = 0xffffffff;
SetLayeredWindowAttributes(this.Handle, transparentColor, 125, 0x2);
this.TransparencyKey = Color.White;
}
/// <summary>
/// Finds the Size of all computer screens combined (assumes screens are left to right, not above and below).
/// </summary>
/// <returns>The width and height of all screens combined</returns>
public static Size getFullScreensSize()
{
int height = int.MinValue;
int width = 0;
foreach (Screen screen in System.Windows.Forms.Screen.AllScreens)
{
//take largest height
height = Math.Max(screen.WorkingArea.Height, height);
width += screen.Bounds.Width;
}
return new Size(width, height);
}
/// <summary>
/// Finds the top left pixel position (with multiple screens this is often not 0,0)
/// </summary>
/// <returns>Position of top left pixel</returns>
public static Point getTopLeft()
{
int minX = int.MaxValue;
int minY = int.MaxValue;
foreach (Screen screen in System.Windows.Forms.Screen.AllScreens)
{
minX = Math.Min(screen.WorkingArea.Left, minX);
minY = Math.Min(screen.WorkingArea.Top, minY);
}
return new Point( minX, minY );
}
public Form1()
{
InitializeComponent();
MaximizeEverything();
SetFormTransparent(this.Handle);
SetTheLayeredWindowAttribute();
BackgroundWorker tmpBw = new BackgroundWorker();
tmpBw.DoWork += new DoWorkEventHandler(bw_DoWork);
this.bw = tmpBw;
this.bw.RunWorkerAsync();
}
private void MaximizeEverything()
{
this.Location = getTopLeft();
this.Size = getFullScreensSize();
SendMessage(this.Handle, WM_SYSCOMMAND, (UIntPtr)myWParam, (IntPtr)myLparam);
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
int numRedLines = 500;
int numWhiteLines = 1000;
Size fullSize = getFullScreensSize();
Point topLeft = getTopLeft();
using (Pen redPen = new Pen(Color.Red, 10f), whitePen = new Pen(Color.White, 10f)) {
using (Graphics formGraphics = this.CreateGraphics()) {
while (true) {
bool makeRedLines = true;
for (int i = 0; i < numRedLines + numWhiteLines; i++)
{
if (i > numRedLines)
{
makeRedLines = false;
}
//Choose points for random lines...but don't draw over the top 100 px of the screen so you can
//still find the stop run button.
int pX = rand.Next(0, (-1 * topLeft.X) + fullSize.Width);
int pY = rand.Next(100, (-1 * topLeft.Y) + fullSize.Height);
int qX = rand.Next(0, (-1 * topLeft.X) + fullSize.Width);
int qY = rand.Next(100, (-1 * topLeft.Y) + fullSize.Height);
if (makeRedLines)
{
formGraphics.DrawLine(redPen, pX, pY, qX, qY);
}
else
{
formGraphics.DrawLine(whitePen, pX, pY, qX, qY);
}
Thread.Sleep(10);
}
}
}
}
}
}
}
The lists of Enums are values used in native windows calls and converting RGB colors like White into uints makes dealing with native Windows a bit of a pain.
But, at last, we now have an invisible canvas that covers all screens, and we can draw to it just as with any other graphics object (so it is just about as easy to draw text or pictures as lines).
(I think that if you draw a translucent picture to the graphics object, that you could make yourself a translucent overlay rather than fully opaque/transparent overlays).
This example can't place overlays over fullscreen 3d games, but works fine for those same games run in Windowed mode.
(P.S. I just tested this in Team Fortress 2, it draws over it in Windowed mode, but not fullscreen, so I'm guessing The Old Republic will be similar).
The following links might be useful to anyone trying to hook into the drawing routine for Direct3D versions 9, 10, and 11.
http://spazzarama.com/2011/03/14/c-screen-capture-and-overlays-for-direct3d-9-10-and-11-using-api-hooks/
https://github.com/spazzarama/Direct3DHook
It doesn't provide a full featured overlay, but the example project above successfully writes the frames per second on top of Team Fortress 2 for me. It has good instructions on how to start using it. It should guide you through the process of setting up SlimDX Runtime and EasyHook.
The way that I have done this in the past is to get the handle for the main window, often the only way to do it is to traverse the entire window list, looking for the one with the title that you want. That is problematic if there are two instances of the game open at the same time with the same title.
Once you have that window handle, you can add visual elements over the top of what is already there by specifying how many pixels over, how many pixels down and how many layers "out" (the z-index) you want it to be relative to the upper left pixel of the window.
One approach to the multiple window is to start your c# program that looks to see if there is an instance of the game already being played, issuing a message and terminating if there is, if not, then starting an instance of the game your self as a child process. I think you can get back the hwin at that time, but if not you can search the window list for the target title after the game is running.
I'm trying to create a DateTimePicker with week numbers displayed, as shown here (Code project example).
It works fairly well, except for one minor detail; The calender popping up when trying to select a date is not the right size. As you can see, the calendar area is sort of "cramped", especially along the right edge.
I can click the bottom right corner here, and drag it out a little - just enough to expand it so that it looks right:
I can't seem to find any way to force the calendar to be the correct/full size from the beginning, or to resize it.
Finally found a solution that seems to work - at least for now.
It seems there are two windows in the calendar part of the DateTimePicker. Apparently my code would automatically find the correct size for the inner one (more or less at least?), but not the outer one.
A bit of research has led to the code below. The following links provide some useful and relevant info:
GetWindowLong function (Used for getting info about the window to edit)
GetParent function (Finding the outer window, so we could apply settings to that too)
The trick was to add a little to the height and width of the (inner) window, then apply the same height and width to the outer window (which I access using the GetParrent() function). I found the "correct" size by trial and error: When the size matched what was needed for the contents of the calendar, it could not be resized any longer.
Yes, this feels a little like a hack, and no, I haven't been able to verify that it works perfectly on other computers than my own yet. I'm a little worried about having to give specific values for height and width, but I'm hoping this won't be affected by screen resolutions or whatever else.
Hope someone else in a similar situation will find the code useful.
(The following can directly replace a regular DateTimePicker to show week numbers in the calendar)
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class DatePickerWithWeekNumbers : DateTimePicker
{
[DllImport("User32.dll")]
private static extern int GetWindowLong(IntPtr handleToWindow,
int offsetToValueToGet);
[DllImport("User32.dll")]
private static extern int SetWindowLong(IntPtr h,
int index,
int value);
private const int McmFirst = 0x1000;
private const int McmGetminreqrect = (McmFirst + 9);
private const int McsWeeknumbers = 0x4;
private const int DtmFirst = 0x1000;
private const int DtmGetmonthcal = (DtmFirst + 8);
[DllImport("User32.dll")]
private static extern IntPtr SendMessage(IntPtr h,
int msg,
int param,
int data);
[DllImport("User32.dll")]
private static extern IntPtr GetParent(IntPtr h);
[DllImport("User32.dll")]
private static extern int SendMessage(IntPtr h,
int msg,
int param,
ref Rectangle data);
[DllImport("User32.dll")]
private static extern int MoveWindow(IntPtr h,
int x,
int y,
int width,
int height,
bool repaint);
[Browsable(true), DesignerSerializationVisibility(
DesignerSerializationVisibility.Visible)]
public bool DisplayWeekNumbers { get; set; }
protected override void OnDropDown(EventArgs e)
{
// Hex value to specify that we want the style-attributes
// for the window:
const int offsetToGetWindowsStyles = (-16);
IntPtr pointerToCalenderWindow = SendMessage(Handle,
DtmGetmonthcal,
0,
0);
int styleForWindow = GetWindowLong(pointerToCalenderWindow,
offsetToGetWindowsStyles);
// Check properties for the control - matches available
// property in the graphical properties for the DateTimePicker:
if (DisplayWeekNumbers)
{
styleForWindow = styleForWindow | McsWeeknumbers;
}
else
{
styleForWindow = styleForWindow & ~McsWeeknumbers;
}
// Get the size needed to display the calendar (inner window)
var rect = new Rectangle();
SendMessage(pointerToCalenderWindow, McmGetminreqrect, 0, ref rect);
// Add to size as needed (I don't know why
// this was not correct initially!)
rect.Width = rect.Width + 28;
rect.Height = rect.Height + 6;
// Set window styles..
SetWindowLong(pointerToCalenderWindow,
offsetToGetWindowsStyles,
styleForWindow);
// Dont move the window - just resize it as needed:
MoveWindow(pointerToCalenderWindow,
0,
0,
rect.Right,
rect.Bottom,
true);
// Now access the parrent window..
var parentWindow = GetParent(pointerToCalenderWindow);
// ...and resize that the same way:
MoveWindow(parentWindow, 0, 0, rect.Right, rect.Bottom, true);
base.OnDropDown(e);
}
}
For me, setting MCS_WEEKNUMBERS via the DateTimePicker's DTM_SETMCSTYLE message automatically resulted in the correct size of the MonthCal control:
SendMessage(Handle, DTM_FIRST + 11, 0, SendMessage(Handle, DTM_FIRST + 12, 0, 0) | MCS_WEEKNUMBERS);
Where DTM_FIRST = 0x1000 and MCS_WEEKNUMBERS = 0x4 as in Kjartan's solution. DTM_FIRST + 11 is DTM_SETMCSTYLE and DTM_FIRST + 12 is DTM_GETMCSTYLE in Microsoft's documentation.
Unlike Kjartan's solution, this call must be used before the first dropdown, but right at form initialization didn't work for me in some cases, so I delayed it to when the form was already created and visible in these cases. One call is enough, the DateTimePicker will save the style for future dropdowns.
Ok, Try to comment line in Program.cs
Application.EnableVisualStyles();
and then try to execute.
Here is the original question but it is considered to java:
Simulate mouse clicks at a certain position on inactive window in Java?
Anyways, I'm building a bot to run in the background. This bot requires me to click. Of course, I want to be able to do other things while the bot is running.
So I was wondering if it was possible for me to simulate a mouse click at a certain position on an inactive window.
If this is possible, I would greatly appreciate it if any of you could help me.
Thanks!
Yes it is possible, here's the code I used for a previous school project:
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
public const int MOUSEEVENTF_LEFTDOWN = 0x02;
public const int MOUSEEVENTF_LEFTUP = 0x04;
public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
public const int MOUSEEVENTF_RIGHTUP = 0x10;
//This simulates a left mouse click
public static void LeftMouseClick(Point position)
{
Cursor.Position = position;
mouse_event(MOUSEEVENTF_LEFTDOWN, position.X, position.Y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, position.X, position.Y, 0, 0);
}
EDIT : It seems that the mouse_event function was replaced by SendInput() but it still works (Windows 7 and earlier)