Mouse Event - Mouse not moving as intended - c#

I'm trying to move my cursor with Keyboard Arrow Keys. The result is that it will move, but only upwards and left.. towards the top left corner of the screen. It doesn't move downwards as intended.
Now, if I make my xSpeed and ySpeed greater than 3, it will work, but moving downwards and to the right will be slower. If I make the speed 10, then the result will be unnoticable, but that is way too fast for what I need this for.
[DllImport("User32.dll",EntryPoint = "mouse_event",CallingConvention = CallingConvention.Winapi)]
internal static extern void Mouse_Event(int dwFlags,int dx,int dy,int dwData,int dwExtraInfo);
[DllImport("User32.dll",EntryPoint = "GetSystemMetrics",CallingConvention = CallingConvention.Winapi)]
internal static extern int InternalGetSystemMetrics(int value);
private void UpdateLoop()
{
if (_hotKeys.Contains(Keys.Up))
MoveCursor(y: -YSpeed());
if (_hotKeys.Contains(Keys.Down))
MoveCursor(y: YSpeed());
if (_hotKeys.Contains(Keys.Left))
MoveCursor(x: -XSpeed());
if (_hotKeys.Contains(Keys.Right))
MoveCursor(x: XSpeed());
}
private void MoveCursor(int x = 0, int y = 0)
{
int to_x = MousePosition.X + x;
int to_y = MousePosition.Y + y;
int screenWidth = InternalGetSystemMetrics(0);
int screenHeight = InternalGetSystemMetrics(1);
int mic_x = (int)Math.Round(to_x * 65536.0 / screenWidth);
int mic_y = (int)Math.Round(to_y * 65536.0 / screenHeight);
Mouse_Event(0x0001 | 0x8000, mic_x, mic_y, 0, 0);
}
In this case, XSpeed and YSpeed are equal one.
public int XSpeed()
{
return int.Parse(tb_x.Text);
}
public int YSpeed()
{
return int.Parse(tb_y.Text);
}
Any help would be very appreciated!

Related

How to create script to automatically move mouse relative to current mouse position at a 45deg angle

So the purpose of the program is that upon pressing xbutton2 I want the program to automatically move my mouse at a 45 degree angle relative to my mouse's current position and automatically press the K key afterwards.
I was considering just having the .ahk script run a get mouse position then move relative move to an X and Y coordinate however it didn't work as any move movement already in place would override it.
I also got a C# script from another coder who was able to achieve a similar output, however it's not functional in-game and wasn't built for the same purpose (can be repurposed) I will include the paste-bin if it helps.
https://pastebin.com/dxXKfQpj > C# Code
Here is my code:
*xbutton2::
MouseGetPos, x, y
MouseMove, x+5.5, y+6.5
MouseMove, x+5.5, y+6.5
Send K
return```
What I havve used years ago for an application to control other applications the hard way:
public class Win32Input
{
[DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
private enum InputType
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 2,
}
[Flags()]
private enum MOUSEEVENTF
{
MOVE = 0x0001, // mouse move
LEFTDOWN = 0x0002, // left button down
LEFTUP = 0x0004, // left button up
RIGHTDOWN = 0x0008, // right button down
RIGHTUP = 0x0010, // right button up
MIDDLEDOWN = 0x0020, // middle button down
MIDDLEUP = 0x0040, // middle button up
XDOWN = 0x0080, // x button down
XUP = 0x0100, // x button down
WHEEL = 0x0800, // wheel button rolled
VIRTUALDESK = 0x4000, // map to entire virtual desktop
ABSOLUTE = 0x8000, // absolute move
}
[StructLayout(LayoutKind.Sequential)]
private struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public MOUSEEVENTF dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct INPUT
{
public InputType type;
public MOUSEINPUT mi;
}
public static uint Move(int x, int y)
{
float ScreenWidth = Screen.PrimaryScreen.Bounds.Width;
float ScreenHeight = Screen.PrimaryScreen.Bounds.Height;
INPUT input_move = new INPUT();
input_move.type = InputType.INPUT_MOUSE;
input_move.mi.dx = (int)Math.Round(x * (65535 / ScreenWidth), 0);
input_move.mi.dy = (int)Math.Round(y * (65535 / ScreenHeight), 0);
input_move.mi.mouseData = 0;
input_move.mi.dwFlags = (MOUSEEVENTF.MOVE | MOUSEEVENTF.ABSOLUTE);
input_move.mi.time = 0;
input_move.mi.dwExtraInfo = GetMessageExtraInfo();
INPUT[] input = { input_move };
return SendInput(1, input, Marshal.SizeOf(input_move));
}
}
I remember copying this code from a internet resource. Possibly SO.
If you want to move it 45 degrees it should be that displacement in x is equal to y so :
xbutton2::
MouseGetPos, x, y
MouseMove, x+6.5, y+6.5
MouseMove, x+6.5, y+6.5
Send K
return
I guess your displacements were ok for you, maybe your problem is that you are playing a game which skews AHK capability to move and send keys correctly. Here is another forum talking about in more details.
You also say movements are overriden. Are you running more than one AHK script at a time? If so maybe one of them gets stuck in a loop (happened to me).
Hope that helps!

SharpGL (OpenGL in C#) Solar System - Camera position is Calculated Wrong

I am currently learning OpenGL and I am trying to write simple solar system application similar to the one in tutorial, yet for some reason camera behavior is really weird and I am not sure what is causing this. I want my camera to look at the sun, but all I am getting are some really weird angles of planets or nothing at all, it might not even be pure camera problem. Can somebody tell me what exactly I am doing wrong? I would appreciate some code. If someone is willing to help and prefer to check application instead of reading code here, link is added below.
The camera here will be as close to the tutorial as possible (FPS), but I got also dragging/scrolling system instead of this.
public class Camera
{
private static float eyeX, eyeY, eyeZ;
private static float centerX, centerY, centerZ;
private const float movingSpeed = 0.3f;
private const float rotationSpeed = 0.25f;
private static double i, j, k;
public static float Height { get; set; }
public static float Slope { get; set; }
public void InitCamera()
{
eyeX = 0f;
eyeY = 15f;
eyeZ = 25f;
centerX = 0;
centerY = 2;
centerZ = 0;
Look();
}
public void Look()
{
Gl.MatrixMode(OpenGL.GL_MODELVIEW);
Gl.LoadIdentity();
Gl.LookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, 0, 1, 0);
}
public void UpdateDirVector()
{
i = -Math.Sin(((double)Slope).ToRadians());
j = Math.Sin(((double)Height).ToRadians());
k = Math.Cos(((double)Slope).ToRadians());
centerX = eyeX - (float)i;
centerY = eyeY - (float)j;
centerZ = eyeZ - (float)k;
}
public static void CenterMouse()
{
if (GlCenter == null)
return;
var pos = (Point) GlCenter;
WinApi.SetCursorPos((int)Math.Round(pos.X), (int)Math.Round(pos.Y));
}
public void Update(int pressedButton)
{
if (GlCenter == null)
return;
var pos = (Point)GlCenter;
var halfHeight = GlHeight / 2;
var halfWidth = GlWidth / 2;
var position = new Pointer();
WinApi.GetCursorPos(ref position);
var diffX = (float)pos.X - position.x;
var diffY = (float)pos.Y - position.y;
if (position.y < halfHeight)
Height -= rotationSpeed * diffY;
else if (position.y > halfHeight)
Height += rotationSpeed * -diffY;
if (position.x < halfWidth)
Slope += rotationSpeed * -diffX;
else if (position.x > halfWidth)
Slope -= rotationSpeed * diffX;
UpdateDirVector();
CenterMouse();
if (pressedButton == 1) // LPM
{
eyeX -= (float)i * movingSpeed;
eyeY -= (float)j * movingSpeed;
eyeZ -= (float)k * movingSpeed;
}
else if (pressedButton == -1) // PPM
{
eyeX += (float)i * movingSpeed;
eyeY += (float)j * movingSpeed;
eyeZ += (float)k * movingSpeed;
}
Look();
}
}
Planet.cs:
public class Planet
{
private readonly PlanetTypes _planetType;
private readonly Position _position;
private float _orbitAngle;
private readonly float _sizeRadius;
private readonly float _velocity;
private readonly string _texturePath;
private uint _list;
private float _rotationAngle;
public Planet(float radius, PlanetTypes planetType, Position position, string texturePath, bool hasMoon)
{
_sizeRadius = radius;
_planetType = planetType;
_position = position;
_orbitAngle = Rng.Next(360);
_velocity = (float)Rng.NextDouble() * 0.3f;
_texturePath = texturePath;
}
public void Create()
{
var quadric = Gl.NewQuadric();
Gl.QuadricNormals(quadric, OpenGL.GLU_SMOOTH);
Gl.QuadricTexture(quadric, (int) OpenGL.GL_TRUE);
_list = Gl.GenLists(1);
Gl.NewList(_list, OpenGL.GL_COMPILE);
Gl.PushMatrix();
Gl.Rotate(270, 1, 0, 0);
Gl.Sphere(quadric, _sizeRadius, 32, 32);
Gl.PopMatrix();
Gl.EndList();
}
public void DrawOrbit()
{
Gl.Begin(OpenGL.GL_LINE_STRIP);
for (var i = 0; i <= 360; i++)
Gl.Vertex(_position.X * (float)Math.Sin(i * Math.PI / 180), 0, _position.X * (float)Math.Cos(i * Math.PI / 180));
Gl.End();
}
public void Draw()
{
DrawOrbit();
LoadTexture($"{_texturesPath}{_texturePath}");
Gl.PushMatrix();
_orbitAngle += _velocity;
_rotationAngle += 0.6f;
Gl.Rotate(_orbitAngle, 0, 1, 0);
Gl.Translate(-_position.X, -_position.Y, -_position.Z);
Gl.Rotate(_rotationAngle, 0, 1, 0);
Gl.CallList(_list);
Gl.PopMatrix();
}
}
Sun.cs
public class Sun
{
private uint _list;
private float _rotation;
private readonly string _texturePath;
public Sun(string texturePath)
{
_texturePath = texturePath;
}
public void Create()
{
var quadratic = Gl.NewQuadric();
Gl.QuadricNormals(quadratic, OpenGL.GLU_SMOOTH);
Gl.QuadricTexture(quadratic, (int)OpenGL.GL_TRUE);
_list = Gl.GenLists(1);
Gl.NewList(_list, OpenGL.GL_COMPILE);
Gl.PushMatrix();
Gl.Rotate(90, 1, 0, 0);
Gl.Sphere(quadratic, 3, 32, 32);
Gl.PopMatrix();
Gl.EndList();
}
public void Draw()
{
LoadTexture($"{_texturesPath}{_texturePath}");
Gl.PushMatrix();
_rotation += 0.05f;
Gl.Rotate(_rotation, 0, 1, 0);
Gl.CallList(_list);
Gl.PopMatrix();
}
}
Stars.cs
public class Stars
{
private readonly List<Position> starPositions = new List<Position>();
public void CreateStars(int amount)
{
var count = 0;
while (count <= amount)
{
var p = default(Position);
p.X = Rng.Next(110) * (float)Math.Pow(-1, Rng.Next());
p.Z = Rng.Next(110) * (float)Math.Pow(-1, Rng.Next());
p.Y = Rng.Next(110) * (float)Math.Pow(-1, Rng.Next());
if (!(Math.Pow(Math.Pow(p.X, 2) + Math.Pow(p.Y, 2) + Math.Pow(p.Z, 2), 1 / 3f) > 15))
continue;
starPositions.Add(p);
count++;
}
}
public void Draw()
{
Gl.Begin(OpenGL.GL_POINTS);
Gl.Color(1, 1, 1);
Gl.PointSize(3);
foreach (var starPos in starPositions)
Gl.Vertex(starPos.X, starPos.Y, starPos.Z);
Gl.End();
}
}
SolarSystem.cs (basically a collection of everything above, enums aren't necessary, I left them cause they might be useful in the future)
public class SolarSystem
{
public static Random Rng { get; } = new Random();
private readonly Stars _stars;
private readonly Sun _sun;
private readonly List<Planet> _planets;
public SolarSystem()
{
Camera = new Camera();
_stars = new Stars();
_sun = new Sun("sun.bmp");
_planets = new List<Planet>();
}
public void CreateScene()
{
_planets.Add(new Planet(0.5f, PlanetTypes.Mercury, new Position(5, 0, 0), "mercury.bmp", false)); // tylko tutaj pliki, wszedzie indziej przeksztaƂcone na .bmp
_planets.Add(new Planet(0.7f, PlanetTypes.Venus, new Position(11, 0, 0), "venus.bmp", false));
_planets.Add(new Planet(1, PlanetTypes.Earth, new Position(15, 0, 0), "earth.bmp", true));
_planets.Add(new Planet(1, PlanetTypes.Mars, new Position(22, 0, 0), "mars.bmp", false));
_planets.Add(new Planet(1.5f, PlanetTypes.Jupiter, new Position(28, 0, 0), "jupiter.bmp", false));
_planets.Add(new Planet(1.2f, PlanetTypes.Saturn, new Position(35, 0, 0), "saturn.bmp", false));
_planets.Add(new Planet(1.2f, PlanetTypes.Uranus, new Position(41, 0, 0), "uranus.bmp", false));
_planets.Add(new Planet(1.2f, PlanetTypes.Neptune, new Position(51, 0, 0), "neptune.bmp", false));
_planets.Add(new Planet(1.2f, PlanetTypes.Pluto, new Position(60, 0, 0), "pluto.bmp", false));
_stars.CreateStars(500);
_sun.Create();
foreach (var planet in _planets)
planet.Create();
}
public Camera Camera { get; }
public void DrawScene()
{
_stars.Draw();
_sun.Draw();
foreach (var planet in _planets)
planet.Draw();
}
public enum PlanetTypes
{
Mercury,
Venus,
Earth,
Mars,
Jupiter,
Saturn,
Neptune,
Uranus,
Pluto
}
}
API (including pointer position translation, because only this way I was able to center cursor, it will be removed with dragging camera system)):
public static class WinApi
{
[DllImport("GDI32.dll")]
public static extern void SwapBuffers(uint hdc);
[DllImport("user32.dll")]
public static extern void SetCursorPos(int x, int y);
[DllImport("user32.dll")]
public static extern void GetCursorPos(ref Pointer point);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int X;
public int Y;
}
[DllImport("User32", EntryPoint = "ClientToScreen", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ClientToScreen(
IntPtr hWnd,
ref POINT pt);
[EnvironmentPermission(SecurityAction.LinkDemand, Unrestricted = true)]
public static Point? TransformToScreen(
Point point,
Visual relativeTo)
{
var hwndSource = PresentationSource.FromVisual(relativeTo) as HwndSource;
if (hwndSource == null)
return null;
var root = hwndSource.RootVisual;
// Transform the point from the root to client coordinates.
var transformToRoot = relativeTo.TransformToAncestor(root);
var pointRoot = transformToRoot.Transform(point);
var m = Matrix.Identity;
var transform = VisualTreeHelper.GetTransform(root);
if (transform != null)
{
m = Matrix.Multiply(m, transform.Value);
}
var offset = VisualTreeHelper.GetOffset(root);
m.Translate(offset.X, offset.Y);
var pointClient = m.Transform(pointRoot);
pointClient = hwndSource.CompositionTarget.TransformToDevice.Transform(pointClient);
var pointClientPixels = new POINT();
pointClientPixels.X = (0 < pointClient.X)
? (int)(pointClient.X + 0.5)
: (int)(pointClient.X - 0.5);
pointClientPixels.Y = (0 < pointClient.Y)
? (int)(pointClient.Y + 0.5)
: (int)(pointClient.Y - 0.5);
var pointScreenPixels = pointClientPixels;
if (ClientToScreen(
hwndSource.Handle,
ref pointScreenPixels))
{
return new Point(
pointScreenPixels.X,
pointScreenPixels.Y);
}
return new Point();
}
}
Extensions.cs
public static class Extensions
{
public static double ToDegrees(this double radians)
{
return radians * (180.0 / Math.PI);
}
public static double ToRadians(this double degrees)
{
return Math.PI * degrees / 180.0;
}
}
MainWindow.cs
public partial class MainWindow
{
private DispatcherTimer _dispatcherTimer;
private uint _hdc;
public static string _texturesPath = #"Data\Textures\";
private SolarSystem _solarSystem;
private int _movement;
public static OpenGL Gl { get; private set; }
public static Point? GlCenter { get; private set; }
public static int GlHeight { get; private set; }
public static int GlWidth { get; private set; }
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
ContentRendered += MainWindow_ContentRendered;
}
private void MainWindow_ContentRendered(object sender, EventArgs e)
{
Gl = openGLControl.OpenGL;
var source = (HwndSource)PresentationSource.FromVisual(openGLControl);
var hWnd = source?.Handle;
if (hWnd != null) _hdc = (uint)hWnd;
_solarSystem = new SolarSystem();
_solarSystem.Camera.InitCamera();
float[] materialAmbient = { 0.5f, 0.5f, 0.5f, 1.0f };
float[] materialDiffuse = { 1f, 1f, 1f, 1.0f };
float[] materialShininess = { 10.0f };
float[] lightPosition = { 0f, 0f, 0f, 1.0f };
float[] lightAmbient = { 0.85f, 0.85f, 0.85f, 0.0f };
Gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, lightAmbient);
Gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPosition);
Gl.Material(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_SHININESS, materialShininess);
Gl.Material(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_DIFFUSE, materialDiffuse);
Gl.Material(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_AMBIENT, materialAmbient);
Gl.Enable(OpenGL.GL_LIGHTING);
Gl.Enable(OpenGL.GL_LIGHT0);
Gl.Enable(OpenGL.GL_DEPTH_TEST);
_solarSystem.CreateScene();
Gl.ClearColor(0, 0, 0, 1);
GlCenter = WinApi.TransformToScreen(new Point(openGLControl.Width / 2, openGLControl.Height / 2), openGLControl);
GlHeight = (int)openGLControl.Height;
GlWidth = (int)openGLControl.Width;
Camera.CenterMouse();
_dispatcherTimer = new DispatcherTimer();
_dispatcherTimer.Tick += DispatcherTimer_Tick;
_dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1);
_dispatcherTimer.Start();
}
private void DispatcherTimer_Tick(object sender, EventArgs e)
{
Gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
_solarSystem.Camera.Update(_movement);
_solarSystem.DrawScene();
WinApi.SwapBuffers(_hdc);
Gl.Flush();
}
private void OpenGLControl_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
_movement = 1;
else
_movement = -1;
}
private void OpenGLControl_MouseUp(object sender, MouseButtonEventArgs e)
{
_movement = 0;
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.C)
{
GlCenter = WinApi.TransformToScreen(new Point(openGLControl.Width / 2, openGLControl.Height / 2), openGLControl); // new Point((int)(Left), (int)(Top));
}
}
public static uint LoadTexture(string filename)
{
if (string.IsNullOrEmpty(filename))
throw new ArgumentException(filename);
Gl.Enable(OpenGL.GL_TEXTURE_2D);
var texture = new uint[1];
var id = texture[0];
Gl.GenTextures(1, texture);
Gl.BindTexture(OpenGL.GL_TEXTURE_2D, id);
var bmp = new Bitmap(filename);
var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
Gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, 3, bmpData.Width, bmpData.Height, 0, OpenGL.GL_BGR, OpenGL.GL_UNSIGNED_BYTE, bmpData.Scan0);
Gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR);
Gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR);
bmp.UnlockBits(bmpData);
return id;
}
}
Link to whole Application:
https://www.dropbox.com/sh/uhfyeayxn8l7q9y/AAA8tFda5-ZLAjTUzJcwKUm6a?dl=0
UPDATE 1:
I have changed Look() function to:
public void Look()
{
Gl.MatrixMode(OpenGL.GL_PROJECTION);
Gl.LoadIdentity();
Gl.Viewport(0, 0, GlWidth, GlHeight);
Gl.Perspective(45.0f, GlWidth / (double) GlHeight, 1, 200.0);
Gl.LookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, 0, 1, 0);
Gl.MatrixMode(OpenGL.GL_MODELVIEW);
}
And now it works.
Now I can see that my application is loading incorrect textures for some reason. I guess thats because method LoadTextures() I wrote, is using Gl.GenTextures(1, texture). (There is no Gen(Single)Texture method in sharpgl or I am getting it all wrong).
UPDATE 2:
So basically most of my textures doesn't work because they are not power of two, but from what I have read, they don't have to be anymore. SO my current question is: How to force sharpGL to display NPOT textures?
UPDATE 3:
Turns out I can load them like this, but well, they are upside down :).
_texture = new Texture();
...
Gl.Enable(OpenGL.GL_TEXTURE_2D);
_texture.Create(Gl, $"{_texturesPath}{_texturePath}");
_texture.Bind(Gl);
UPDATE 4:
I can flip texture to display it properly, but question is why this is happening?
Gl.Enable(OpenGL.GL_TEXTURE_2D);
var bmp = new Bitmap($"{_texturesPath}{_texturePath}");
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
_texture.Create(Gl, bmp);
_texture.Bind(Gl);
UPDATE 5:
While question from Update 4 still stands, I got last question: How can I recalculate Camera so it is not limited to look up / down only to -90/90 degree?
You don't appear to be setting up your viewing frustrum correctly, and are using it in an uninitialized state. You have code for it, but it is commented out in MainWindow.xaml.cs:123.
You must setup the frustrum. At least once before drawing. It can be either perspective or orthographic.
gl.MatrixMode(OpenGL.GL_PROJECTION);
gl.LoadIdentity();
gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);

Onscreen cursor positioning with user's input [duplicate]

I want to simulate mouse movement every x seconds. For that, I'll use a timer (x seconds) and when the timer ticks I'll make the mouse movement.
But, how can I make the mouse cursor move using C#?
Take a look at the Cursor.Position Property. It should get you started.
private void MoveCursor()
{
// Set the Current cursor, move the cursor's Position,
// and set its clipping rectangle to the form.
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(Cursor.Position.X - 50, Cursor.Position.Y - 50);
Cursor.Clip = new Rectangle(this.Location, this.Size);
}
First Add a Class called Win32.cs
public class Win32
{
[DllImport("User32.Dll")]
public static extern long SetCursorPos(int x, int y);
[DllImport("User32.Dll")]
public static extern bool ClientToScreen(IntPtr hWnd, ref POINT point);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
public POINT(int X, int Y)
{
x = X;
y = Y;
}
}
}
You can use it then like this:
Win32.POINT p = new Win32.POINT(xPos, yPos);
Win32.ClientToScreen(this.Handle, ref p);
Win32.SetCursorPos(p.x, p.y);

High CPU usage when getting color under cursor

I'm working on an app, moving the mouse in a certain area and clicking the mouse if something is not the color black.
However, I am getting a really high CPU usage while using this method too get the color below the cursor. After 5 completed runs from startY to endY - the application is lagging that much it takes around 5-10 sec. to get too the end of the area. With this part commented out, the application runs fine and each run doesn't increase in the too complete.
Here is my while loop:
private void moveMouse(int startX, int endX, int startY, int endY)
{
int newPosX = startX;
int newPosY = startY;
while (running)
{
Application.DoEvents();
//this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(newPosX, newPosY);
Thread.Sleep(3);
if (colorCursor.Get(newPosX, newPosY))
{
MyMouse.sendClick();
countClicks++;
lblStatus.Text = "Klik: " + countClicks;
}
newPosX += 10;
if (newPosX > endX)
{
newPosY += 25;
newPosX = startX;
}
if (newPosY > endY)
{
newPosY = startY;
Thread.Sleep(1000);
}
}
}
Color below cursor:
public class ColorUnderCursor
{
[DllImport("gdi32")]
public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos);
//[DllImport("user32.dll", CharSet = CharSet.Auto)]
//public static extern bool GetCursorPos(out POINT pt);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
public bool Get(int x, int y)
{
IntPtr dc = GetWindowDC(IntPtr.Zero);
long color = GetPixel(dc, x, y);
Color underMouse = Color.FromArgb((int)color);
if(underMouse != Color.FromArgb(0, 0, 0, 0))
return true;
return false;
}
}
How I can minimize this heavy usage of the CPU.
Solution:
It was my method "Get" which was causing the problem. I solved it by this method below, and running the whole thing inside a backgroundworker.
public bool GetPixel(Point position)
{
using (var bitmap = new Bitmap(1, 1))
{
using (var graphics = Graphics.FromImage(bitmap))
{
graphics.CopyFromScreen(position, new Point(0, 0), new Size(1, 1));
}
if (bitmap.GetPixel(0, 0) != Color.FromArgb(255, 0, 0, 0) && bitmap.GetPixel(0, 0) != Color.FromArgb(255, 255, 255, 255))
return true;
return false;
}
}
Try to move logic into Invoke call like this
private void moveMouse(int startX, int endX, int startY, int endY)
{
this.BeginInvoke(new Action(() => { InvokeMouseMove(startX, endX, startY, endY)
}));
}
private void InvokeMouseMove(int startX, int endX, int startY, int endY)
{
int newPosX = startX;
int newPosY = startY;
while (running)
{
Application.DoEvents();
//this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(newPosX, newPosY);
if (colorCursor.Get(newPosX, newPosY))
{
MyMouse.sendClick();
countClicks++;
lblStatus.Text = "Klik: " + countClicks;
}
newPosX += 10;
if (newPosX > endX)
{
newPosY += 25;
newPosX = startX;
}
if (newPosY > endY)
{
newPosY = startY;
}
}
}

How to move mouse cursor using C#?

I want to simulate mouse movement every x seconds. For that, I'll use a timer (x seconds) and when the timer ticks I'll make the mouse movement.
But, how can I make the mouse cursor move using C#?
Take a look at the Cursor.Position Property. It should get you started.
private void MoveCursor()
{
// Set the Current cursor, move the cursor's Position,
// and set its clipping rectangle to the form.
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(Cursor.Position.X - 50, Cursor.Position.Y - 50);
Cursor.Clip = new Rectangle(this.Location, this.Size);
}
First Add a Class called Win32.cs
public class Win32
{
[DllImport("User32.Dll")]
public static extern long SetCursorPos(int x, int y);
[DllImport("User32.Dll")]
public static extern bool ClientToScreen(IntPtr hWnd, ref POINT point);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
public POINT(int X, int Y)
{
x = X;
y = Y;
}
}
}
You can use it then like this:
Win32.POINT p = new Win32.POINT(xPos, yPos);
Win32.ClientToScreen(this.Handle, ref p);
Win32.SetCursorPos(p.x, p.y);

Categories