Perform a mouse Click event on another Application using C#

久未见 提交于 2019-12-18 18:28:19

问题


what i need to do is that I need to control another application installed on the same machine using my custom application. For example if i needed to use the standard windows calculator I would simply send the input events to the calculator. I have used some code snippets to make this possible and I have now triggered both mouse and keyboard events. but the problem is that i can be sure that the keyboard event will hit the target application because it has the process handle. but i cannot be sure about the mouse. and also if the target application goes into background, i cannot initiate mouse clicks on it. I need help to find a way to make sure that the mouse click is done on the application only.

I need to send mouse co-ordinates and click as well. for example "sendMouseClick("Notepad", 100, 400); which will send a click to Notepad, even though it stays minimized.

***************************************************** IMPORTANT NOTE***************************************************** A similar question is answered previously but that is in reference to first finding the state of the other application and then sending the inputs either keyboard or mouse, what i need to do is to send an application a set of instructions that must work whether the application is in foreground or not. For "The other Guys":: if you dont want to help or cant help, thats okay but please do know that i havent stolen the question or anything. I simply want to achieve this task in C#.

The code I have to simulate keyboard key Press is:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;

namespace SimulateKeyPress
{
    partial class Form1 : Form
{
    private Button button1 = new Button();
    private Button button2 = new Button();
    private Button button3 = new Button();

    [STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }

    public Form1()
    {
        button1.Location = new Point(10, 10);
        button1.TabIndex = 1;
        button1.Text = "Click to automate Calculator";
        button1.AutoSize = true;
        button1.Click += new EventHandler(button1_Click);

        button2.Location = new Point(150, 140);
        button2.TabIndex = 0;
        button2.Text = "Click to Exit Calculator";
        button2.AutoSize = true;

        button2.Location = new Point(80, 80);
        button2.TabIndex = 2;
        button2.Text = "Click to Run Calculator";
        button2.AutoSize = true;

        button2.Click += new EventHandler(button2_Click);
        this.DoubleClick += new EventHandler(Form1_DoubleClick);

        this.Controls.Add(button1);
        this.Controls.Add(button2);
       // this.Controls.Add(button3);
    }

    // Get a handle to an application window.
    [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindow(string lpClassName,
        string lpWindowName);

    // Activate an application window.
    [DllImport("USER32.DLL")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    // Send a series of key presses to the Calculator application. 
    private void button1_Click(object sender, EventArgs e)
    {
        // Get a handle to the Calculator application. The window class 
        // and window name were obtained using the Spy++ tool.
        IntPtr calculatorHandle = FindWindow("CalcFrame", "Calculator");


        //Process firstProc = new Process();
        //firstProc.StartInfo.FileName = "calc.exe";
        //firstProc.EnableRaisingEvents = true;

        //firstProc.Start();

        // Verify that Calculator is a running process. 
        if (calculatorHandle == IntPtr.Zero)
        {
            MessageBox.Show("Calculator is not running.");   
            return;
        }

        // Make Calculator the foreground application and send it  
        // a set of calculations.
        SetForegroundWindow(calculatorHandle);
        SendKeys.SendWait("1024");
        SendKeys.SendWait("*");
        SendKeys.SendWait("32");
        SendKeys.SendWait("=");
    }
    private void button2_Click(object sender, EventArgs e)
    {
        System.Diagnostics.Process.Start("calc.exe");

    }
    private void button3_Click(object sender,EventArgs e) 
    {
        Process [] proc =Process.GetProcessesByName("Calculator");
        proc[0].Kill();
    }
    // Send a key to the button when the user double-clicks anywhere  
    // on the form. 
    private void Form1_DoubleClick(object sender, EventArgs e)
    {
        // Send the enter key to the button, which raises the click  
        // event for the button. This works because the tab stop of  
        // the button is 0.
        SendKeys.Send("{ENTER}");
    }
}
}

the previous help on stack overflow, msdn and other sites provides the code to simulate a mouse click in the same application. But i need to send mouse hits to another application.


回答1:


Maybe this could help you

Code

The task

  • Getting the mouse's current position
  • Sending the mouse event

Windows forms

...
using System.Runtime.InteropServices;

namespace yournamespace
{

 public partial class yourclassname
 {
[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;

    int X = Cursor.Position.X;
    int Y = Cursor.Position.Y;
    mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
  }
}   

WPF

Things are a bit harder in WPF

double mousePointX;
double mousePointY;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(out POINT lpPoint);

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
  public int X;
  public int Y;

  public POINT(int x, int y)
  {
      this.X = x;
      this.Y = y;
  }
}

private void WritePoint(object sender, RoutedEventArgs e)
{
    POINT p;
    if (GetCursorPos(out p))
    {
        System.Console.WriteLine(Convert.ToString(p.X) + ";" + Convert.ToString(p.Y));
    }
}
[DllImport("User32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);

[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

private Point ConvertPixelsToUnits(int x, int y)
{
    // get the system DPI
    IntPtr dDC = GetDC(IntPtr.Zero); // Get desktop DC
    int dpi = GetDeviceCaps(dDC, 88);
    bool rv = ReleaseDC(IntPtr.Zero, dDC);

    // WPF's physical unit size is calculated by taking the 
    // "Device-Independant Unit Size" (always 1/96)
    // and scaling it by the system DPI
    double physicalUnitSize = (1d / 96d) * (double)dpi;
    Point wpfUnits = new Point(physicalUnitSize * (double)x,
    physicalUnitSize * (double)y);

    return wpfUnits;          
}
private void WriteMouseCoordinatesInWPFUnits()
{
    POINT p;
    if (GetCursorPos(out p))
    {
    Point wpfPoint = ConvertPixelsToUnits(p.X, p.Y);
    System.Console.WriteLine(Convert.ToString(wpfPoint.X) + ";" +   Convert.ToString(wpfPoint.Y));

    mousePointY = wpfPoint.Y;
    mousePointX = wpfPoint.X
    }
}

Now the most important part of the code

 [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;

    ...    
        mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP,   Convert.ToUInt32(mousePointX), Convert.ToUInt32(mousePointY), 0, 0); 
    ...

Warning

  • The code is tested
  • The code is not a "copy & paste code


来源:https://stackoverflow.com/questions/26502035/perform-a-mouse-click-event-on-another-application-using-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!