it-swarm.com.de

Programmgesteuerter Mausklick in ein anderes Fenster

Ist es möglich, programmgesteuert auf eine Stelle in einem anderen Fenster zu klicken, ohne die Maus an diese Stelle zu bewegen, und selbst wenn das Fenster nicht oben ist? Ich möchte eine Art Nachricht an ein anderes Fenster senden, um einen Mausklick auf einen Ort zu simulieren.

Ich habe versucht, dies mit PostMessage zu erreichen:

PostMessage(WindowHandle, 0x201, IntPtr.Zero, CreateLParam(300,300));
PostMessage(WindowHandle, 0x202, IntPtr.Zero, CreateLParam(300,300));

Ich habe die CreateLParam-Funktion folgendermaßen erstellt:

private static IntPtr CreateLParam(int LoWord, int HiWord)
{
     return (IntPtr)((HiWord << 16) | (LoWord & 0xffff));
}

Das Problem ist, dass das Fenster an seinem Standort gesperrt wird. Ich denke, dass meine Anwendung auf die (1,1) -Koordinate klickt. Können mir einige bei diesem Problem weiterhelfen?

Bearbeiten: Dies ist PostMessage:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll")]
public static extern bool PostMessage(IntPtr WindowHandle, int Msg, IntPtr wParam, IntPtr lParam);

Und 0x201 und 0x202 sind WM_LBUTTONDOWN bzw. WM_LBUTTONUP.

22
Dagob

Sie können dies nicht durch Senden von Nachrichten tun, sondern verwenden die SendInput-Windows-API.

Aufrufmethode ClickOnPoint, dies ist ein Beispiel für ein Formularklickereignis, also this.handle ist ein Formular-Handle. Beachten Sie, dass dies Client-Koordinaten im Fenster sind, in dem das Handle gesendet wird. Sie können dies leicht ändern und Bildschirmkoordinaten senden. In diesem Fall benötigen Sie weder das Handle noch den ClientToScreen-Aufruf.

ClickOnPoint(this.Handle, new Point(375, 340));

UPDATE: benutze jetzt SendInput, tnx Tom.

btw. Ich habe nur Deklarationen verwendet, die für dieses Beispiel benötigt werden, für alles andere gibt es eine Nice-Bibliothek: Windows Input Simulator (C # SendInput Wrapper - Tastatur und Maus simulieren

  public class ClickOnPointTool
  {

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

#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


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

  }
30
Antonio Bakula

Ich habe in der Vergangenheit eine Möglichkeit gefunden, eine Nachricht an Windows Media Player zu senden , also habe ich diese verwendet, um das Klicken in einer Anwendung zu simulieren, die ich wollte!

Verwenden Sie diese Klasse (Code unten), um das Fenster zu finden und die gewünschten Nachrichten zu senden!

using System;
using System.Runtime.InteropServices;

namespace Mouse_Click_Simulator
{
    /// <summary>
    /// Summary description for Win32.
    /// </summary>
    public class Win32
    {
        // The WM_COMMAND message is sent when the user selects a command item from 
        // a menu, when a control sends a notification message to its parent window, 
        // or when an accelerator keystroke is translated.
        public const int WM_KEYDOWN = 0x100;
        public const int WM_KEYUP = 0x101;
        public const int WM_COMMAND = 0x111;
        public const int WM_LBUTTONDOWN = 0x201;
        public const int WM_LBUTTONUP = 0x202;
        public const int WM_LBUTTONDBLCLK = 0x203;
        public const int WM_RBUTTONDOWN = 0x204;
        public const int WM_RBUTTONUP = 0x205;
        public const int WM_RBUTTONDBLCLK = 0x206;

        // The FindWindow function retrieves a handle to the top-level window whose
        // class name and window name match the specified strings.
        // This function does not search child windows.
        // This function does not perform a case-sensitive search.
        [DllImport("User32.dll")]
        public static extern int FindWindow(string strClassName, string strWindowName);

        // The FindWindowEx function retrieves a handle to a window whose class name 
        // and window name match the specified strings.
        // The function searches child windows, beginning with the one following the
        // specified child window.
        // This function does not perform a case-sensitive search.
        [DllImport("User32.dll")]
        public static extern int FindWindowEx(
            int hwndParent, 
            int hwndChildAfter, 
            string strClassName, 
            string strWindowName);


        // The SendMessage function sends the specified message to a window or windows. 
        // It calls the window procedure for the specified window and does not return
        // until the window procedure has processed the message. 
        [DllImport("User32.dll")]
        public static extern Int32 SendMessage(
            int hWnd,               // handle to destination window
            int Msg,                // message
            int wParam,             // first message parameter
            [MarshalAs(UnmanagedType.LPStr)] string lParam); // second message parameter

        [DllImport("User32.dll")]
        public static extern Int32 SendMessage(
            int hWnd,               // handle to destination window
            int Msg,                // message
            int wParam,             // first message parameter
            int lParam);            // second message parameter
    }
}

Beispielsweise:

 Win32.SendMessage(iHandle, Win32.WM_LBUTTONDOWN, 0x00000001, 0x1E5025B);

Hier ist der Quellcode meiner Anwendung die ich erstellt habe, um die Anwendung "BlueStacks" in einem bestimmten Intervall automatisch anzuklicken!

Für FindWindow, wParam, lParam usw. können Sie mich gerne fragen, wie es geht! es ist nicht zu schwer :);) Hoffe es hat geholfen! :)

17
ACE