一尘不染

以编程方式在另一个窗口中单击鼠标

c#

是否可以通过编程方式单击另一个窗口中的某个位置而不将鼠标移到该位置,即使该窗口不在顶部也是如此?我想向另一窗口发送一种消息,以模拟鼠标单击某个位置。

我试图用PostMessage做到这一点:

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

我通过以下方式创建了CreateLParam函数:

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

问题在于窗口被锁定在他的位置。我认为我的应用程序单击了(1,1)坐标。可以帮我解决这个问题吗?

编辑:这是PostMessage:

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

0x201和0x202分别是WM_LBUTTONDOWN和WM_LBUTTONUP。


阅读 220

收藏
2020-05-19

共1个答案

一尘不染

您无法通过发送消息来做到这一点,而是使用SendInput Windows API。

调用方法ClickOnPoint,这是表单单击事件的一个示例,this.handle表单句柄也是如此,请注意,这些是发送窗口巫婆句柄的客户端坐标,您可以轻松地更改它并发送屏幕坐标,在这种情况下,您不需要或下面的ClientToScreen调用。

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

更新:现在使用tnx Tom,使用SendInput。

顺便说一句 我只使用了此示例所需的声明,还有更多漂亮的库:Windows Input Simulator(C#SendInput包装器-
模拟键盘和鼠标)

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

  }
2020-05-19