C# (Bot Programming) - Send Mouse Input to an inactive Application with given coords?
I try my best to not ask for help in here since I am someone who can help himself most of the times by looking at some Documentations / Code Snippets. I reached some point where I got stuck and Documentations seem not to help at all. But I have hope that someone here got a solution.
So. I am out of the house and took my laptop with me. I kinda got bored and decided to put some rework on an older project of mine.
The Project itself was a Program that did collect in-game Money. It is working by clicking on hardcoded Coordinates Onscreen. That's where I thought I could make this a bit more user-friendly since while the Bot is running, the COMP can't be used anymore for anything else.
I've heard that AutoIt can perform such things stealthy in the background by having handles to the Object Instances and sending Messages to it (perform a click, etc.). That made me sleepless the last two nights. I did some research and once I thought I could start using Microsoft Spy++ to get the Class Names I encountered a problem. The closest I can get is the ToolbarWindow32 Class (Blue), but I need both Childrens (Red).
Even if I could solve the problem on WPE Pro, I still would have a problem with the Game itself because you can't get any further than the PluginContainer. That's why I need to work with coordinates again, but it doesn't work like that when you send the "Messages" with the Window handles. I've tried several methods already. Some didn't work and some just click at that Dekstop position (-> doesn't work if the window is not visible).
The best looking try was this one. Yet, it isn't what I am aiming for. It just gets the position of the Window and clicks there. I want this to happen in the background pretty much.
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _0xD3F_1
{
public partial class Main : Form
{
#region Imports
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
// Alternativ:
// FindWindow(default(string), lpWindowName)
// FindWindow((string)null, lpWindowName)
[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);
#endregion
#region Structs
#pragma warning disable 649
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;
}
#pragma warning restore 649
#endregion
#region Coords
// Removed since I wanted to do a full rework.
#endregion
public Main()
{
InitializeComponent();
}
private void Main_Load(object sender, EventArgs e)
{
// Removed since I wanted to do a full rework.
}
private void Start_Click(object sender, EventArgs e)
{
IntPtr windowHandle = FindWindow(default(string), "Snipping Tool");
ClickOnPoint(windowHandle, new Point(5, 5));
}
// Removed since I wanted to do a full rework.
public static void ClickOnPoint(IntPtr wndHandle, Point clientPoint)
{
var oldPos = Cursor.Position;
/// get screen coordinates
ClientToScreen(wndHandle, ref clientPoint);
/// set cursor on coords, and press mouse
Cursor.Position = new Point(clientPoint.X, clientPoint.Y);
var inputMouseDown = new INPUT();
inputMouseDown.Type = 0; /// input type mouse
inputMouseDown.Data.Mouse.Flags = 0x0002; /// left button down
var inputMouseUp = new INPUT();
inputMouseUp.Type = 0; /// input type mouse
inputMouseUp.Data.Mouse.Flags = 0x0004; /// left button up
var inputs = new INPUT[] { inputMouseDown, inputMouseUp };
SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
/// return mouse
Cursor.Position = oldPos;
}
}
}
Maybe some of you got better ideas. I appreciate any help. It's just a free-time project, but an upgrade to it would be sick.
All I know is that there are people out there who sell their "premium Bots" for MMORPG's or whatever game they made it for and those work perfectly fine in the background. So it must be somehow possible. I just don't get it at this time. Maybe I can oversleep it and I suddenly get an idea. :D
I accept everything as long it can run in the background, so the user can watch Netflix & co. while his in-game money rises.
I can even jump to another coding/scripting language if you got a solution technique that works there.
As always. I will credit everyone who tries to help me. That's the least I can do.
Once I got a solution. I also will add it to my Rythm Game Bots - because why not? ^^