Mouse move in game window by outer C# code - c#

I am playing a game, every time I need to move mouse and click into the game's screen to earn game point, so I am trying to write code by c# to click and move mouse in game's screen automatically ..
I got some help, so mouse click problems solved, but I am unable to move mouse in game's screen..
Can you please advice me what should I do ??
Should I use "SetWindowsHookEx" or other methods to move mouse in game window ??
Please advice me what should I do..
"Click" code below which I got, it's working fine :
public class ClickGameScreen
{
[DllImport("user32.dll")]
static extern bool ClientToScreen(IntPtr hWnd, ref Point lpPoint);
[DllImport("user32.dll")]
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
internal struct INPUT
{
public UInt32 Type;
public MOUSEKEYBDHARDWAREINPUT Data;
}
[StructLayout(LayoutKind.Explicit)]
internal struct MOUSEKEYBDHARDWAREINPUT
{
[FieldOffset(0)]
public MOUSEINPUT Mouse;
}
internal struct MOUSEINPUT
{
public Int32 X;
public Int32 Y;
public UInt32 MouseData;
public UInt32 Flags;
public UInt32 Time;
public IntPtr ExtraInfo;
}
public static void ClickScreen(IntPtr W_Handle , Point C_Point)
{
var oldPos = Cursor.Position;
ClientToScreen(W_Handle, ref C_Point);
Cursor.Position = new Point(C_Point.X, C_Point.Y);
var inputDown = new INPUT();
inputDown.Type = 0;
inputDown.Data.Mouse.Flags = 0x0002;
var inputUp = new INPUT();
inputUp.Type = 0;
inputUp.Data.Mouse.Flags = 0x0004;
var inputs = new INPUT[] { inputDown, inputUp };
SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
Cursor.Position = oldPos;
}
}
==============
ClickScreen(this.Handle, new Point(375, 340));
===============

I solved my problem, code below :
[DllImport("user32.dll")]
static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
private const int MOUSEEVENTF_MOVE = 0x0001;
public static void Move(int xDelta, int yDelta)
{
mouse_event(MOUSEEVENTF_MOVE, xDelta, yDelta, 0, 0);
}
//=========================================
Move(830, 160);
//=========================================

Related

How to simulate a hardware mouse click in game if it is not recognized?

I'd like to click in a game's button. I've tried with several ways, SendInput, and MouseEvent are some of them. Nevertheless I always got the same result, it doesn't work.
This is the original button.
And this is the button once I click on it with SendInput or MouseEvent
The color changes, but it doesn't work at all. (I also tried with leftClick, double LeftClick, and leftClickUp/Down.) My guess is that it is just supposed to work if the click isn't virtual? I'm not sure at all, since I don't have much idea about it.
Any idea?
Little update: As I've mentioned I have tried with SendInput, MouseEvent, InputSimulator and so on, the problem is always the same, while it works out of that game, it doesn't with that button. I'm pretty sure it could be because the game detect it's a virtual click simulation.
Since some fellas asked for code. (I'll repeat, this doesn't look a problem in the code tho...)
This one is for InputSimulator.
InputSimulator sim = new InputSimulator();
sim.Mouse.LeftButtonDoubleClick();
This one is using MouseEvent
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
private const int MOUSEEVENT_LEFTDOWN = 0x02;
private const int MOUSEEVENT_LEFTUP = 0x04;
private const int MOUSEEVENT_MIDDLEDOWN = 0x20;
private const int MOUSEEVENT_MIDDLEUP = 0x40;
private const int MOUSEEVENT_RIGHTDOWN = 0x08;
private const int MOUSEEVENT_RIGHTUP = 0x10;
static void Click(){
mouse_event(MOUSEEVENT_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENT_LEFTUP, 0, 0, 0, 0);
}
private void timer1_Tick(object sender, EventArgs e) {
Click();
}
This one is using SendInput. (MouseSimulator is a static class using SendInput.)
MouseSimulator.ClickLeftMouseButton();
This is the class for the MouseSimulator.
using System;
using System.Runtime.InteropServices;
public class MouseSimulator
{
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
[StructLayout(LayoutKind.Sequential)]
struct INPUT
{
public SendInputEventType type;
public MouseKeybdhardwareInputUnion mkhi;
}
[StructLayout(LayoutKind.Explicit)]
struct MouseKeybdhardwareInputUnion
{
[FieldOffset(0)]
public MouseInputData mi;
[FieldOffset(0)]
public KEYBDINPUT ki;
[FieldOffset(0)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
struct MouseInputData
{
public int dx;
public int dy;
public uint mouseData;
public MouseEventFlags dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[Flags]
enum MouseEventFlags : uint
{
MOUSEEVENTF_MOVE = 0x0001,
MOUSEEVENTF_LEFTDOWN = 0x0002,
MOUSEEVENTF_LEFTUP = 0x0004,
MOUSEEVENTF_RIGHTDOWN = 0x0008,
MOUSEEVENTF_RIGHTUP = 0x0010,
MOUSEEVENTF_MIDDLEDOWN = 0x0020,
MOUSEEVENTF_MIDDLEUP = 0x0040,
MOUSEEVENTF_XDOWN = 0x0080,
MOUSEEVENTF_XUP = 0x0100,
MOUSEEVENTF_WHEEL = 0x0800,
MOUSEEVENTF_VIRTUALDESK = 0x4000,
MOUSEEVENTF_ABSOLUTE = 0x8000
}
enum SendInputEventType : int
{
InputMouse,
InputKeyboard,
InputHardware
}
public static void ClickLeftMouseButton()
{
INPUT mouseDownInput = new INPUT();
mouseDownInput.type = SendInputEventType.InputMouse;
mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));
INPUT mouseUpInput = new INPUT();
mouseUpInput.type = SendInputEventType.InputMouse;
mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP;
SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
}
public static void ClickRightMouseButton()
{
INPUT mouseDownInput = new INPUT();
mouseDownInput.type = SendInputEventType.InputMouse;
mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN;
SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));
INPUT mouseUpInput = new INPUT();
mouseUpInput.type = SendInputEventType.InputMouse;
mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTUP;
SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
}
}
All of them work well out of the game, inside they just work as I described above.
Since this is happening with all buttons in the game, this is a gif showing what's happening versus what's is expecting.
This is the expected behavior.
https://gyazo.com/ffd6af281414c5b0b10e19cf7a27823d
Nevertheless this is what's happening. (You can see that the color change and it looks like if it was pressed but it clearly doesn't)
https://gyazo.com/20ebb3bc360a4a5bccbe3ea5207d201b
Your question has a really low quality. The design of the button is´t relevant, your code would be. But I´ll take a guess anyway.
Well. It looks like the click got registered. Could it be that your script presses the mousebutton and never releases it? Many UI´s wont trigger at the pressing but on the release of the button. I don´t know much about C# but in Powershell you need to tell the script to PRESS and to RELEASE the button seperatly.

C# Turn off selected monitor

I'm wondering if someone could help me I have been trying to find a way of turning off specific monitors in a basic application, there are a couple of posts on here about turning off all monitors and this works fine. The only topic I can see if this one here:
C# selectively turn off monitor
This does explain how to go about doing this but I'm still learning and not really sure how to expand the example into whats needed.
Turn off all monitors:
public void MonitorOff(IntPtr handle)
{
SendMessage(handle, WmSyscommand, (IntPtr)ScMonitorpower, (IntPtr)MonitorShutoff);
}
private void MonitorOn()
{
mouse_event(MouseeventfMove, 0, 1, 0, UIntPtr.Zero);
Thread.Sleep(40);
mouse_event(MouseeventfMove, 0, -1, 0, UIntPtr.Zero);
}
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern void mouse_event(Int32 dwFlags, Int32 dx, Int32 dy, Int32 dwData, UIntPtr dwExtraInfo);
private const int WmSyscommand = 0x0112;
private const int ScMonitorpower = 0xF170;
private const int MonitorShutoff = 2;
private const int MouseeventfMove = 0x0001;
[DllImport("user32")]
private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lpRect, MonitorEnumProc callback, int dwData);
private delegate bool MonitorEnumProc(IntPtr hDesktop, IntPtr hdc, ref Rect pRect, int dwData);
[StructLayout(LayoutKind.Sequential)]
private struct Rect
{
public int left;
public int top;
public int right;
public int bottom;
}
Count Monitors:
public void GetMonitors()
{
int monCount = 0;
//Rect r = new Rect();
MonitorEnumProc callback = (IntPtr hDesktop, IntPtr hdc, ref Rect prect, int d) => ++monCount > 0;
if (EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, callback, 0))
MessageBox.Show("You have " + monCount.ToString() + " monitors", "Windows Hook");
else
MessageBox.Show("An error occured while enumerating monitors");
}
Is anyone able to enplane this or show me the right route to take?, Thank you.

How to programatically simulate a button press?

How can I simulate a button press in .NET?
I can do it with AutoHotKey with ease:
#Persistent
SetTimer,PressTheKey,1000
Return
PressTheKey:
Send, {F5}
Return
Any application will know that the button was pressed (just like it was pressed by me). I tried doing the same with:
[DllImport("user32.dll", SetLastError = true)]
public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
or:
[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
or using Windows Input Simulator (https://inputsimulator.codeplex.com/):
inputSimulator.Keyboard.KeyDown(VirtualKeyCode.VK_H)
They all worked in Notepad or some other apps, but they never worked in my full screen game. Any idea how I can achieve it? I would like a solution which simulates a click globally on the system level.
There is a lib out there called Interceptor that is a wrapper for the windows keyboard driver, however there are limitations - namely win8 or above are not supported - and it seems that work on it has ceased (11 months ago now). Have a look into that if it suits your needs.
I've read somewhere that there are ways to do this via the DirectInput API - as to whether this is the case I'm unsure. I've used Interceptor a few times and it worked for my needs at the time.
Hope this helps
Also
Link
Edit: Fixed links
I learned that my application is using DirectInput (thanks Gabe). This made me focus more on SendInput and I managed to send an "A" key to my application like this:
// A = 30
keyboardDirectInput.Press(30);
All key codes are available here: https://msdn.microsoft.com/en-us/library/windows/desktop/bb321074%28v=vs.85%29.aspx
The KeyboardDirectInput class:
public class KeyboardDirectInput
{
[DllImport("user32.dll")]
static extern UInt32 SendInput(UInt32 nInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, Int32 cbSize);
public void Press(VirtualKeys key)
{
INPUT[] InputData = new INPUT[2];
InputData[0].type = (int)InputType.INPUT_KEYBOARD;
InputData[0].ki.wScan = (short)key;
InputData[0].ki.dwFlags = (int)KEYEVENTF.SCANCODE;
InputData[1].type = (int)InputType.INPUT_KEYBOARD;
InputData[1].ki.wScan = (short)key;
InputData[1].ki.dwFlags = (int)(KEYEVENTF.KEYUP | KEYEVENTF.SCANCODE);
if (SendInput(2, InputData, Marshal.SizeOf(InputData[1])) == 0)
{
Logger.GetInstance().Warn("SendInput failed (CODE {0})", Marshal.GetLastWin32Error());
}
}
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(4)]
public HARDWAREINPUT hi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(0)]
public int type;
}
[StructLayout(LayoutKind.Sequential)]
public struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[Flags]
public enum KEYEVENTF
{
KEYDOWN = 0,
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
UNICODE = 0x0004,
SCANCODE = 0x0008,
}
[Flags]
public enum InputType
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 2
}
}

Dynamically changing Mouse speed

Guys, I have a C# Winforms application with a panel inside the form. What I want to do is, whenever the mouse pointer enters this panel, I want to slow the movement speed of the mouse by 50%. Once the pointer moves outside this panel, I want to speed of the mouse to resume normal 100% speed. How can I accomplish this in C#?
This article might help
Here's the code from the article:
using System;
using System.Runtime.InteropServices;
namespace MouseSpeedSwitcher
{
class Program
{
public const UInt32 SPI_SETMOUSESPEED = 0x0071;
[DllImport("User32.dll")]
static extern Boolean SystemParametersInfo(
UInt32 uiAction,
UInt32 uiParam,
UInt32 pvParam,
UInt32 fWinIni);
static void Main(string[] args)
{
SystemParametersInfo(
SPI_SETMOUSESPEED,
0,
uint.Parse(args[0]),
0);
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
public const UInt32 SPI_GETMOUSESPEED = 0x0070;
const UInt32 SPIF_UPDATEINIFILE = 0x01;
const UInt32 SPIF_SENDWININICHANGE = 0x02;
[DllImport("User32.dll")]
static extern Boolean SystemParametersInfo(
UInt32 uiAction,
UInt32 uiParam,
IntPtr pvParam,
UInt32 fWinIni);
static unsafe void Main(string[] args)
{
MouseOptions m = new MouseOptions();
MouseOptions.GetDefaults();
int speed;
SystemParametersInfo(SPI_GETMOUSESPEED, 0, new IntPtr(&speed), 0);
Console.WriteLine(speed);
MouseOptions.SetDefaults();
SystemParametersInfo(SPI_GETMOUSESPEED, 0, new IntPtr(&speed), 0);
Console.WriteLine(speed);
Console.ReadLine();
}
public class MouseOptions
{
[DllImport("user32.dll")]
public static extern int SystemParametersInfo( int uAction, int uParam, IntPtr lpvParam, int fuWinIni );
[DllImport("kernel32.dll")]
public static extern int GetLastError();
public const int SPI_GETMOUSESPEED = 112;
public const int SPI_SETMOUSESPEED = 113;
private static int intDefaulSpeed = 10;
private static int intCurrentSpeed;
private static int intNewSpeed;
public static void GetDefaults()
{
intCurrentSpeed = GetMouseSpeed();
}
public static void SetDefaults()
{
if ( intCurrentSpeed == 20 )
{
SetMouseSpeed(intDefaulSpeed);
}
else if ( intCurrentSpeed < 10 )
{
SetMouseSpeed(intDefaulSpeed);
}
}
public static int GetMouseSpeed()
{
int intSpeed = 0;
IntPtr ptr;
ptr = Marshal.AllocCoTaskMem(4);
SystemParametersInfo(SPI_GETMOUSESPEED, 0, ptr, 0);
intSpeed = Marshal.ReadInt32(ptr);
Marshal.FreeCoTaskMem(ptr);
return intSpeed;
}
public static void SetMouseSpeed( int intSpeed )
{
IntPtr ptr = new IntPtr(intSpeed);
int b = SystemParametersInfo(SPI_SETMOUSESPEED, 0, ptr, 0);
if (b == 0)
{
Console.WriteLine("Not able to set speed");
}
else if ( b == 1 )
{
Console.WriteLine("Successfully done");
}
}
}
}
}
As it was not very clear how to use code from the answers, I found more concise solution for changing Mouse speed. Add this code to class where you want to change the speed:
[DllImport("user32.dll", CharSet = CharSet.Auto),]
public static extern int SystemParametersInfo(uint uiAction, uint uiParam, uint pvParam, uint fWinIni);
And then call SystemParametersInfo with required Mouse speed:
//SPEED is an integer value between 0 and 20. 10 is the default.
SystemParametersInfo(113,0,SPEED,0);
Not forget to add using System.Runtime.InteropServices; Credits.

Control another application using C#

I need to control other application by simulating mouse movement and keyboard input. How do I accomplish this in C#? Is it even possible?
Have you looked at White TestStack?
Sample code:
Application application = Application.Launch("foo.exe");
Window window = application.GetWindow("bar", InitializeOption.NoCache);
Button button = window.Get<Button>("save");
button.Click();
I don't think it can get better than that. The library is created by ThoughtWorks.
See "To send a keystroke to a different application" on this page:
http://msdn.microsoft.com/en-us/library/ms171548.aspx
You can use p/invoke, I stole the following code for mouse clicks in random spots on a button with a known handle:
[Flags]
public enum MouseEventFlags
{
LEFTDOWN = 0x00000002,
LEFTUP = 0x00000004,
MIDDLEDOWN = 0x00000020,
MIDDLEUP = 0x00000040,
MOVE = 0x00000001,
ABSOLUTE = 0x00008000,
RIGHTDOWN = 0x00000008,
RIGHTUP = 0x00000010
}
[StructLayout(LayoutKind.Sequential)]
public struct Rectangle
{
public int X;
public int Y;
public int Width;
public int Height;
}
private static void Click(IntPtr Handle)
{
lock (typeof(MouseAction))
{
Rectangle buttonDesign;
GetWindowRect(Handle, out buttonDesign);
Random r = new Random();
int curX = 10 + buttonDesign.X + r.Next(100 - 20);
int curY = 10 + buttonDesign.Y + r.Next(60 - 20);
SetCursorPos(curX, curY);
//Mouse Right Down and Mouse Right Up
mouse_event((uint)MouseEventFlags.LEFTDOWN, curX, curY, 0, 0);
mouse_event((uint)MouseEventFlags.LEFTUP, curX, curY, 0, 0);
}
}
[DllImport("user32.dll")]
static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll")]
private static extern void mouse_event(
long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr hWnd, out Rectangle rect);
you can use AutoIT, it's freeware, and it has a dll version that you can import into C# (DllImport). It allows you to click on controls, write strings to edit boxes, make combobox selections etc on another application from C#.
Use the SendMessage Native Win32 API. DllImport this method from the User32.dll. You can use this API to send both keyboard & mouse messages
I tried to do the same: to use the mouse i used this class
(you need to add using System.Runtime.InteropServices;)
public class MouseClick1 //public is important here**
{
[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 int CoordX { get; set; }
public int CoordY { get; set; }
public void Click1()
{
Cursor.Position = new Point(CoordX, CoordY);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
}
and after on your form1 (presuming the name is form1) you can
public partial class form1 : Form
{
MouseClick1 button1 = new MouseClick1();
MouseClick1 button2 = new MouseClick1();
[...]
public void Simulate_button1and2_Click(object sender, EventArgs e)
{
button1.CoordX = 1652; //random coordinates
button1.CoordY = 225;
button2.CoordX = 1650;
button2.CoordY = 250;
button1.Click1();
button1.Click2();
}
}
To have the coordinates on your pointer, I use a timer and a label:
private void timer1_Tick(object sender, EventArgs e)
{
Coord.Text = Cursor.Position.X.ToString() + " : " + Cursor.Position.Y.ToString(); //Premet d'avoir les coord en direct
}
Work fine with me.

Categories