WPF throws PInvokeStackImbalance when call mouse_event - c#

Here is my code, as soon as I call mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, (long)0, (long)0); I recieve the PInvokeStackImbalance exception. Does someone knows why?
[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);
[DllImport("user32.dll")]
internal extern static int SetCursorPos(int x, int y);
private const long MOUSEEVENTF_LEFTDOWN = 0x02;
private const long MOUSEEVENTF_LEFTUP = 0x04;
private const long MOUSEEVENTF_RIGHTDOWN = 0x08;
private const long MOUSEEVENTF_RIGHTUP = 0x10;
public void dragTest()
{
long x = 400;
long y = 400;
SetCursorPos((int)x, (int)y);
mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, (long)0, (long)0);
x += 100;
y += 100;
SetCursorPos((int)x, (int)y);
mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
}

Mouse event parameters should be uint according to PInvoke.Net and not long
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData,
UIntPtr dwExtraInfo);

Related

mouse_event not firing on a specific application (C#)

I am trying to programatically simulate a left button mouse click:
[DllImport("user32.dll")]
static extern bool SetCursorPos(int x, int y);
[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 static void LeftMouseClick(int xpos, int ypos)
{
SetCursorPos(xpos, ypos);
mouse_event(MOUSEEVENTF_LEFTDOWN, xpos, ypos, 0, 0);
System.Threading.Thread.Sleep(1000);
mouse_event(MOUSEEVENTF_LEFTUP, xpos, ypos, 0, 0);
}
The cursor moves to the appropriate position on the screen, but the click is not firing there. Any thoughts?
EDIT: I did a couple of tests. The method i use does not seem to be the issue (it clicks on applications like steam, skype successfully). When calling the click method when the cursor is above the application that i specifically want to click on (an android emulator) nothing happens. The mouse cursor moves to the spot but wont click... Going to test another emulator now.
I wrote a helper class for another project I was working on which wrapped up the mouse event:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
class MouseHelper
{
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;
}
/// <summary>
/// Synthesizes keystrokes, mouse motions, and button clicks.
/// </summary>
[DllImport("user32.dll")]
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
[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()
{
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)));
}
public static void DoMouseClick2()
{
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
}
All I needed to do was call MouseHelper.DoMouseClick() whenever I wanted a mouse click. I suspect the mouse move functionality could be added as an enhancement.

How to make an application running in a wpf window ignore clicks or mouse events

Currently I am trying to run an unreal 4 application in a wpf window. However I only want the users to see the window not click it or use it. I have tried all sorts of workarounds for this but none seem to actually work. Any help would be greatly appreciated. Thank you. Below is the code I'm using to run application in wpf window.
[DllImport("user32.dll", EntryPoint="GetWindowThreadProcessId", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);
[DllImport("user32.dll", SetLastError=true)]
private static extern IntPtr FindWindow (string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError=true)]
private static extern long SetParent (IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", EntryPoint="GetWindowLongA", SetLastError=true)]
private static extern long GetWindowLong (IntPtr hwnd, int nIndex);
[DllImport("user32.dll", EntryPoint="SetWindowLongA", SetLastError=true)]
public static extern int SetWindowLongA([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError=true)]
private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags);
[DllImport("user32.dll", SetLastError=true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
private const int SWP_NOOWNERZORDER = 0x200;
private const int SWP_NOREDRAW = 0x8;
private const int SWP_NOZORDER = 0x4;
private const int SWP_SHOWWINDOW = 0x0040;
private const int WS_EX_MDICHILD = 0x40;
private const int SWP_FRAMECHANGED = 0x20;
private const int SWP_NOACTIVATE = 0x10;
private const int SWP_ASYNCWINDOWPOS = 0x4000;
private const int SWP_NOMOVE = 0x2;
private const int SWP_NOSIZE = 0x1;
private const int GWL_STYLE = (-16);
private const int WS_VISIBLE = 0x10000000;
private const int WS_CHILD = 0x40000000;
/// <summary>
/// Force redraw of control when size changes
/// </summary>
/// <param name="e">Not used</param>
protected void OnSizeChanged(object s, SizeChangedEventArgs e)
{
this.InvalidateVisual();
this.Width = WpfUserAppControl.Width = 200;
this.Height = WpfUserAppControl.Height = 200;
//Application.Current.MainWindow.Width = Window.GetWindow(this.AppContainer).Width;
MoveWindow(_appWin, 100, 100, (int)WpfUserAppControl.Height, (int)WpfUserAppControl.Width, true);
}
/// <summary>
/// Create control when visibility changes
/// </summary>
/// <param name="e">Not used</param>
protected void OnVisibleChanged(object s, RoutedEventArgs e)
{
// If control needs to be initialized/created
if (_iscreated == false)
{
// Mark that control is created
_iscreated = true;
// Initialize handle value to invalid
_appWin = IntPtr.Zero;
try
{
var procInfo = new System.Diagnostics.ProcessStartInfo(this.exeName);
procInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(this.exeName);
_childp = System.Diagnostics.Process.Start(procInfo);
_childp.WaitForInputIdle();
while (_childp.MainWindowHandle == IntPtr.Zero)
{
System.Threading.Thread.Sleep(10);
}
_appWin = _childp.MainWindowHandle;
}
catch (Exception ex)
{
Debug.Print(ex.Message + "Error");
}
// Put it into this form
var helper = new WindowInteropHelper(Window.GetWindow(this.AppContainer));
SetParent(_appWin, helper.Handle);
AppControl.
// Remove border and whatnot
SetWindowLongA(_appWin, GWL_STYLE, WS_VISIBLE);
// Move the window to overlay it on this window
MoveWindow(_appWin, 100, 100, (int)WpfUserAppControl.Height, (int)WpfUserAppControl.Width, true);
_childp.Exited += _childp_Exited;
SetWindowPos(_appWin, -2, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOACTIVATE);
}
}
Best solution I have found for this so far is to run another window application after unreal is loaded that is transparent.
Use IsHitTestVisible property from UIElement base object. Set False value to Window.IsHitTestVisible.
IsHitTestVisible = "False"
I hope it helps.

Simulating a Click on C# Web Browser at a specific point

I'm trying to force a mouse click within my webbrowser at a specific point.
I'm using the following code:
public void DoMouseClick(int X, int Y)
{
//Call the imported function with the cursor's current position
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, int dx, int dy, int cButtons, int 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;
However this code doesn't appear to be working at all, it isn't clicking there? I also am not sure whether this code actually moves the phsyical mouse or not, I need something that simulates a click not moves my mouse there and does the click.
I cannot use the HTMLElement stuff because that doesn't allow you to click a specific co-ordinate in the element, which I require, I need to click a very specific spot.
Could any one help with this
I got this, I used it for some auto-clicker stuff.. I can't and will not take any credit for this, I even think I found the code here on stackoverflow..
[Flags]
public enum MouseEventFlags
{
LeftDown = 0x00000002,
LeftUp = 0x00000004,
MiddleDown = 0x00000020,
MiddleUp = 0x00000040,
Move = 0x00000001,
Absolute = 0x00008000,
RightDown = 0x00000008,
RightUp = 0x00000010
}
[DllImport("user32.dll", EntryPoint = "SetCursorPos")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetCursorPos(out MousePoint lpMousePoint);
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
public static void SetCursorPosition(int X, int Y)
{
SetCursorPos(X, Y);
}
public static void SetCursorPosition(MousePoint point)
{
SetCursorPos(point.X, point.Y);
}
public static MousePoint GetCursorPosition()
{
MousePoint currentMousePoint;
var gotPoint = GetCursorPos(out currentMousePoint);
if (!gotPoint) { currentMousePoint = new MousePoint(0, 0); }
return currentMousePoint;
}
public static void MouseEvent(MouseEventFlags value)
{
MousePoint position = GetCursorPosition();
mouse_event
((int)value,
position.X,
position.Y,
0,
0)
;
}
[StructLayout(LayoutKind.Sequential)]
public struct MousePoint
{
public int X;
public int Y;
public MousePoint(int x, int y)
{
X = x;
Y = y;
}
}

How to track mouse X/Y position and print it to a label? [duplicate]

This question already has answers here:
Capturing mouse/keyboard events outside of form (app running in background)
(2 answers)
Closed 5 years ago.
I know how to modify cursor position from examples on MSDN.
My question is how to check position of mouse while mouse moves and then print X and Y position to representing labels?
EDIT: Lets say I want to track my mouse position from my entire screen.
EDIT 2: My app will be in the back ground/minimized.
I'm already using Mouse Hooks:
namespace Program
{
public partial class MouseHook
{
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr 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 DoMouseClick()
{
int X = Cursor.Position.X;
int Y = Cursor.Position.Y;
IntPtr newP = new IntPtr(Convert.ToInt64("0", 16));
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, newP);
}
}
}
Here is the msdn documentation on system level mouse event handling calls (low level mouse proc).
Here is an example of using low level mouse procs to change the scroll event.
In the answer in the second link use WM_MOUSEMOVE from here instead of WM_MOUSEWHEEL.
One thing to note: for this program to continue to capture mouse events when the mouse is over a program with elevated privileges, this program will have to be launch with elevated privileges.
Code (not tested):
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace CatchMouseMove
{
class InterceptMouse
{
const int INPUT_MOUSE = 0;
const int MOUSEEVENTF_WHEEL = 0x0800;
const int WH_MOUSE_LL = 14;
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Main()
{
_hookID = SetHook(_proc);
if (_hookID == null)
{
MessageBox.Show("SetWindowsHookEx Failed");
return;
}
Application.Run();
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
int xPos = 0;
int yPos = 0;
if (nCode >= 0 && MouseMessages.WM_MOUSEMOVE == (MouseMessages)wParam)
{
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
//do stuff with xPos and yPos
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
private enum MouseMessages
{
WM_MOUSEMOVE = 0x0200
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public int mouseData;
public int flags;
public int time;
public IntPtr dwExtraInfo;
}
public struct INPUT
{
public int type;
public MOUSEINPUT mi;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public uint dwFlags;
public int time;
public int dwExtraInfo;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
}
You need to set a Windows hook in order to achieve this. The MSDN article How to set a Windows hook in Visual C# .NET shows how to set a mouse hook.
I tried it, it captures the mouse all over the form, even when the mouse cursor is over a control.
You can use the EventArgs of the MouseMove event, because it holds the mouse coordinates. From there you can easily set the text property of the label to the X or Y coordinate you will take from e (the MouseMove EventArgs).
private void Form_MouseMove(object sender, MouseEventArgs e)
{
// Update the mouse coordinates displayed in the textbox.
myTextBox.Text = e.Location.ToString();
}

How do I press and move the mouse in C#?

I need to send mouse signals in C# so that other applications register them. To be exact, I need to simulate mouse buttons and the move of the mouse. Is there a way to do this in C#? (Windows)
The mouse's cursor position is a settable property - you can use it to move the mouse wherever you want.
You need to call the SendInput API function.
See here for P/Invoke defnitions.
As far as the buttonpresses go, you can do the following
[DllImport("user32.dll")]
public static extern uint SendInput(uint nInputs, ref Input pInputs, int cbSize);
const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
const uint MOUSEEVENTF_LEFTUP = 0x0004;
const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
const uint MOUSEEVENTF_RIGHTUP = 0x0010;
public static void DoMouseClick()
{
var input =
new Input
{
type = 0,
mouseinput =
new Mouseinput
{
dx = Cursor.Position.X,
dy = Cursor.Position.Y,
dwFlags = MOUSEEVENTF_LEFTDOWN
}
};
SendInput(1, ref input, 28);
}
[StructLayout(LayoutKind.Explicit, Size = 28)]
public struct Input
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public Mouseinput mouseinput;
};
[StructLayout(LayoutKind.Explicit, Size = 28)]
public struct Mouseinput
{
[FieldOffset(0)]
public int dx;
[FieldOffset(4)]
public int dy;
[FieldOffset(8)]
public uint mouseData;
[FieldOffset(12)]
public uint dwFlags;
[FieldOffset(16)]
public uint time;
[FieldOffset(20)]
public uint dwExtraInfo;
}

Categories

Resources