C# Clicking on a certain point on the screen - c#

I am trying to perform a mouse click through c#. I used the mouse_event function to do it.
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
I tried two methods :
Moving the mouse to the point and clicking it :
Cursor.Position = new Point(100, 100);
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, Cursor.Position.X, Cursor.Position.Y, 0, 0);
Passing the x, y of the desired click to the function :
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP,100, 100, 0, 0);
Either way, I'm this weird error :
Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Users\or\Documents\Visual Studio 2010\Projects\ProjectName\ProjectName\bin\Debug\ProjectName.vshost.exe'.
Additional Information: A call to PInvoke function 'ProjectName!ProjectName.MainForm::mouse_event' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
Any ideas on a solution?

I would suggest you use the following p/invoke signature
private const uint MOUSEEVENTF_LEFTDOWN = 0x02;
private const uint MOUSEEVENTF_LEFTUP = 0x04;
[DllImport("user32.dll")]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, IntPtr dwExtraInfo);
Note, that while mouse_event is convenient, it has been superseded by SendInput. You can find a reasonable p/invoke declaration for SendInput and the Input structure at the following URL.
http://www.pinvoke.net/default.aspx/user32.SendInput

You have obviously got this code from legacy VB6 code. long is 64-bit in .NET and C#, unlike VB6 where it is 32-bit.
Switch from long to int, and it should be okay.
edit: I was a little fast: dwExtraInfo should be of type IntPtr.

Related

I want to be able to hold down control by code

I'm using c#, Visual Studio 2010 for a Windows application.
I want to hold down the Ctrl key, then release it after a while.
I tried this but it didnt work.
[DllImport("user32.dll")]
static extern bool keybd_event(byte bVk, byte bScan, uint dwFlags,
UIntPtr dwExtraInfo);
public const uint KEYEVENTF_KEYUP = 0x02;
public const uint VK_CONTROL = 0x11;
// Press the Control key.
keybd_event(VK_CONTROL,0,0,0);
//release the control key
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
But I get this error
The best overloaded method match for 'ImageR.Form1.keybd_event(byte, byte, uint, System.UIntPtr)
cannot convert from 'uint' to 'byte'
cannot convert from 'int' to 'System.UIntPtr'
I didn't find any good examples of do SendInput, the examples at http://www.pinvoke.net/default.aspx/user32.keybd_event didn't work for me.
The best solution to solve this was at http://inputsimulator.codeplex.com/
Now it's this simple:
//Press Ctrl
InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL);
//Release Ctrl
InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL);

P/Invoke - Int 4 byte, tried changing to UInt but it causes problems

The erros seems pretty common, but here it is:
eCA1901 P/Invoke declarations should be portable As it is declared in your code, parameter 'dwExtraInfo' of P/Invoke 'NativeMethods.mouse_event(int, int, int, int, int)' will be 4 bytes wide on 64-bit platforms. This is not correct, as the actual native declaration of this API indicates it should be 8 bytes wide on 64-bit platforms. Consult the MSDN Platform SDK documentation for help determining what data type should be used instead of 'int'
Here is the line of code:
[System.Runtime.InteropServices.DllImport("user32.dll")]
internal static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
Now i have tried changin to Uint or soemthing that is compatible with 64bit, or that can be used on both (Pint or something, can´t remember the name).
But if i change from Int to Uint or whatever, it breaks this code:
if (click == "Left")
{
NativeMethods.mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, MousePosition.X, MousePosition.Y, MousePosition.X, MousePosition.Y);
}
if (click == "Right")
{
NativeMethods.mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, MousePosition.X, MousePosition.Y, MousePosition.X, MousePosition.Y);
}
if (down == "Left"+"True")
{
NativeMethods.mouse_event(MOUSEEVENTF_LEFTDOWN , MousePosition.X, MousePosition.Y, MousePosition.X, MousePosition.Y);
}
if (down == "Right"+"True")
{
NativeMethods.mouse_event(MOUSEEVENTF_RIGHTDOWN, MousePosition.X, MousePosition.Y, MousePosition.X, MousePosition.Y);
}
As it says (can´t convert from int...)
It seems to "work" if i use (uint) on everything there, but i don´t think that´s a very optimal way to do it.
here are the MouseEvent codes:
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
Also tried changing them to Uint.
Now why i am going on about Uint is because i read that i should change it to that.
I have no real clue what Uint is compared to Int.
So if there is a better way, or i am doing it wrong, please tell.
Original declaration:
VOID WINAPI mouse_event(
_In_ DWORD dwFlags,
_In_ DWORD dx,
_In_ DWORD dy,
_In_ DWORD dwData,
_In_ ULONG_PTR dwExtraInfo
);
Correct C# declaration (one of possible options):
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern void mouse_event(
int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo);
Why last parameter is declared as IntPtr:
Because it is a pointer type in original declaration and it will be 8 bytes in case of 64-bit process. IntPtr is 4 bytes for 32-bit process and 8 bytes for 64-bit processes, which means if you want to compile your assembly as AnyCPU or x64 your mouse_event code stays the same.
If you don't want to cast last parameter to (IntPtr) every time you use mouse_event, you can provide an overload which does that:
static void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo)
{
mouse_event(dwFlags, dx, dy, dwData, (IntPtr)dwExtraInfo);
}
Also, I don't think you are providing valid values for dwData & dwExtraInfo parameters. Make sure that you follow documentation: MSDN

Send keyboard and mouse events to DirectX application in C#?

I need to send global keystrokes and mouse events to another application, which is coincidentally using using DirectX. (No controls/handles other than the window itself)
For example, I need to hold key X for 2 seconds and then release it...
I need to push Right Click down on coordinates x:600 and y:350, move the mouse 100 pixels down and then release the Right Click.
I also need to push 2 or more keys at once, like X and Y, and stop X after 2 seconds and Y after 2 more seconds.
So basically I would need full control of the input system...
It would also be ideal if I could control the application while maximized or in background. (optionally)
For the skeptics... The teacher made a DirectX application for drawing for our school. I am asked to make an application that draws samples on it, like a train or flower or something... I will be reading images and use the input to set the color and click on the canvas...
There are some possibilities. You may have a look at System.Windows.Forms.SendKeys and you can pInvoke some Win32 functions like SetForegroundWindow(), LockSetForegroundWindow() from gdi32.dll or from user32.dll SetCursorPos() and mouse_event to perform clicks:
Here a snippet for the Mouse events I used a while ago.
/**
* Mouse functions
*/
[DllImport("user32.dll", ExactSpelling=true)]
public static extern long mouse_event(Int32 dwFlags, Int32 dx, Int32 dy, Int32 cButtons, Int32 dwExtraInfo);
[DllImport("user32.dll", ExactSpelling=true)]
public static extern void SetCursorPos(Int32 x, Int32 y);
public const Int32 MOUSEEVENTF_ABSOLUTE = 0x8000;
public const Int32 MOUSEEVENTF_LEFTDOWN = 0x0002;
public const Int32 MOUSEEVENTF_LEFTUP = 0x0004;
public const Int32 MOUSEEVENTF_MIDDLEDOWN = 0x0020;
public const Int32 MOUSEEVENTF_MIDDLEUP = 0x0040;
public const Int32 MOUSEEVENTF_MOVE = 0x0001;
public const Int32 MOUSEEVENTF_RIGHTDOWN = 0x0008;
public const Int32 MOUSEEVENTF_RIGHTUP = 0x0010;
public static void PerformLeftKlick(Int32 x, Int32 y)
{
SetCursorPos(x, y);
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
Hope that pushes you in the right direction. A good resource is http://pinvoke.net/
If you want to use a library for C# that will make your work easier then read following link -
http://www.codeproject.com/Articles/117657/InputManager-library-Track-user-input-and-simulate
Other than .Net C# you can use other language alternative like in Java where, there is no confusion of direct x or normal input -
http://docs.oracle.com/javase/7/docs/api/java/awt/Robot.html

How to programatically trigger a mouse left click in C#?

How could I programmatically trigger a left-click event on the mouse?
Thanks.
edit: the event is not triggered directly on a button. I'm aiming for the Windows platform.
To perform a mouse click:
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long 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 static void DoMouseClick()
{
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
To move the cursor where you want:
[DllImport("user32.dll")]
static extern bool SetCursorPos(int X, int Y);
public static void MoveCursorToPoint(int x, int y)
{
SetCursorPos(x, y);
}
If it's right on a button, you can use
button1.PerformClick();
Otherwise, you can check out this MSDN article which discusses simulating mouse (and keyboard) input.
Additionally, this project may be able to help you out as well. Under the covers, it uses SendInput.
https://web.archive.org/web/20140214230712/http://www.pinvoke.net/default.aspx/user32.sendinput
Use the Win32 API to send input.
Update:
Since I no longer work with Win32 API, I will not update this answer to be correct when the platform changes or websites become unavailable. Since this answer doesn't even conform to Stackoverflow standards (does not contain the answer itself, but rather a link to an external, now defunct resource), there's no point giving it any points or spending any more time on it.
Instead, take a look at this question on Stackoverflow, which I think is a duplicate:
How to simulate Mouse Click in C#?

How do I set the 'always on top' flag/setting on a window that is external to my application?

Is there a managed way to set the always on top flag/setting on a window that is external to my application or will I need to P/Invoke a native function?
And if P/Invoke is the only way what is the function call required and from which dll?
Since asking the question I have been researching this and came across what looks like a good example of how to achieve this via p/invoking SetWindowPos in 'user32.dll'. I will come back and accept this answer if this works.
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
public static void MakeTopMost (IntPtr hWnd)
{
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
}
Simple answer:
TopMost = true;

Categories