C++ To C# mouse_event - c#

I am trying to figure out how to do
mouse_event(MOUSEEVENTF_ABSOLUTE, pixels_x, 0, 0, 0);
in C#, I have found the way to do it with Cursor but it doesn't work like mouse_event in C++.

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, IntPtr dwExtraInfo);
the above will allow you to call mouse_event from C#, pass the same numeric values you're using in C++ and you should be covered

Related

SetWindowPos above other window

So, I have an application. I want it to always sit exactly one z-level above a target application. It is just going to display a status message in the title bar, it's ugly but it's the requirement I have to meet.
Like this:
I looked into WM_NCPAINT and it's not really a feasible solution at this stage of the project (prototyping/proposals).
I've discovered the SetWindowPos() function within user32.dll:
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, Swp uFlags);
And hook all z-level related events (of all applications) with:
SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_FOCUS, IntPtr.Zero, ZOrderChanged, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS | WINEVENT_SKIPOWNTHREAD);
And this seems to work to some extent. However, as I can only set to be directly behind the target app, I have to call SetWindowPos() twice, to achieve this, once to aquire the z-level of the target and once to swap the two around:
private void ZOrderChanged(IntPtr hWinEventHook, uint eventType, IntPtr lParam, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
SetWindowPos(Handle, _foxViewHWnd, 0, 0, 0, 0, Swp.Noactivate | Swp.Nomove | Swp.Nosize);
SetWindowPos(_foxViewHWnd, Handle, 0, 0, 0, 0, Swp.Noactivate | Swp.Nomove | Swp.Nosize);
}
This is inefficient, flickers and reeks of code-smell, would anyone know how to avoid this?

Windows UI Automation double click mouse

I'm currently using the following code to double click a mouse button.
[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);
public static void DoubleClick(AutomationElement element)
{
Point p = element.GetClickablePoint();
Cursor.Position = new System.Drawing.Point((int)p.X, (int)p.Y);
mouse_event(0x02 | 0x04, (uint)p.X, (uint)p.Y, 0, 0);
mouse_event(0x02 | 0x04, (uint)p.X, (uint)p.Y, 0, 0);
}
However, I believe this is leaving resources open that causes my automated tests to not exit cleanly, causing crashes. Plus, it requires the mouse to be actually be on the clickable point, which has the potential to cause issue if the tester moves the mouse at the wrong time. Is there a better was to do this?

Move Mouse to Position and Left Click

I'm working on an Windows Form Application in C#, Framework 4 (32 bit).
I have a list that holds coords of the mouse, and I can capture them. So far so good.
But at some point, I want to go to those coords and left mouse click on it.
This is how it looks like right now:
for (int i = 0; i < coordsX.Count; i++)
{
Cursor.Position = new Point(coordsX[i], coordsY[i]);
Application.DoEvents();
Clicking.SendClick();
}
And the Clicking class:
class Clicking
{
private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002;
private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004;
private static extern void mouse_event(
UInt32 dwFlags, // motion and click options
UInt32 dx, // horizontal position or change
UInt32 dy, // vertical position or change
UInt32 dwData, // wheel movement
IntPtr dwExtraInfo // application-defined information
);
// public static void SendClick(Point location)
public static void SendClick()
{
// Cursor.Position = location;
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, new System.IntPtr());
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, new System.IntPtr());
}
}
But I'm getting this error:
Could not load type 'program.Clicking' from assembly 'program, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because the method 'mouse_event' has no implementation (no RVA).
And i realy don't understand what the problem is... Do you guys know what the problem is? or do you know an better way to do what i'm trying to do?
Have you included the following line?
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData,
UIntPtr dwExtraInfo);
This will import the function mouse_event from the user32 dll, which is what you are trying to use within your program. Currently your program does not know about this method within the DLL untill you specify wher it comes from.
The website PInvoke.net user32 Mouse Event is quite handy for the basics on this sort of thing.
The answer to Directing mouse events [DllImport(“user32.dll”)] click, double click will be of great help to your understanding as well.
The flags are what commands you want to send into the mouse_input function, in that example you can see that he is sending both mouse down and mouse up in the same line, this is fine because the mouse_event function will split those flags up and execute them consecutively.
Also note that this method has been superseded by the SendInput command, a good example of SendInput and SetMousePos can be found At this Blog
I guess you are missing the following line
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

How to click on a "pane" using UI automation library?

We have an application in which I need to click on a Pane. I tried to use the following code, which I use to click on a button, but it gave Unsupported pattern exception.
InvokePattern click_pattern = (InvokePattern)adjust_button.GetCurrentPattern(InvokePattern.Pattern);
click_pattern.Invoke();
Is there any other way to do it?
Even though the object is clickable, depending on how the click is being handled internally, you may not necessarily be able to use the InvokePattern to perform a click. That appears to be the case here.
As an alternative, you can use some code to move the mouse cursor over the pane and issue a click using P/Invoke. Something like this:
private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002;
private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004;
[DllImport("user32.dll")]
private static extern void mouse_event(UInt32 dwFlags, UInt32 dx, UInt32 dy, UInt32 dwData, IntPtr dwExtraInfo);
...
...
AutomationElement paneToClick;
...
...
Cursor.Position = paneToClick.GetClickablePoint();
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, new IntPtr());
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, new IntPtr());

What should i do make this code work in VS 2010?

I have used this code manually to simulate a mouse click by system through code.
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class Form1 : Form
{
[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 Form1()
{
}
public void DoMouseClick()
{
//Call the imported function with the cursor's current position
int X = Cursor.Position.X;
int Y = Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
}
//...other code needed for the application
}
But now i am using VS 2010 and Windows 7 and i get the error on execution of this code now
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
So any suggestions for this ...
The error i encounter is:
PInvokeStackImbalance was Detected
A call to PInvoke function 'ClickingApp!ClickingApp.Form1::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.
The problem is with the P/Invoke signature try this.
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy,
uint dwData, UIntPtr dwExtraInfo);
DWORD is 32 bits while a C# long is 64 bits
Also just noticed you are specifying the calling convention, it is better to not specify it when using P/Invoke for the Windows API, or you could using CallingConvention.Winapi, the wrong calling convention is typically the cause of a stack imbalance.

Categories

Resources