以编程方式在另一个窗口中单击鼠标 [英] programmatically mouse click in another window

查看:24
本文介绍了以编程方式在另一个窗口中单击鼠标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在不将鼠标移动到该位置的情况下以编程方式单击另一个窗口中的某个位置,即使该窗口不在顶部?我想向另一个窗口发送一种消息来模拟鼠标单击某个位置.

Is it possible to click programmatically a location in another window without moving the mouse to that location and even if the window is not on-top? I want to send a kind of message to another window to simulate a mouse click on a location.

我尝试使用 PostMessage 来完成此操作:

I tried to accomplish this with PostMessage:

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

我以这种方式创建了 CreateLParam 函数:

I made the CreateLParam function this way:

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

问题是窗口被锁定在他的位置上.我认为我的应用程序点击了 (1,1) 坐标.有人能帮我解决这个问题吗?

The problem is that the window gets locked on his location. I think that my application clicks on the (1,1) coordinate. Can some on help me with this problem?

这是 PostMessage:

This is 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.

And 0x201 and 0x202 are WM_LBUTTONDOWN and WM_LBUTTONUP respectively.

推荐答案

你不能通过发送消息来做到这一点,而是使用 SendInput Windows API.

You can't do that by sending messages, instead use SendInput Windows API.

调用方法 ClickOnPoint,这是一个来自表单点击事件的例子,所以 this.handle 是表单句柄,注意这些是发送窗口女巫句柄上的客户端坐标,你可以很容易地改变这个和发送屏幕坐标,在这种情况下,您不需要下面的句柄或 ClientToScreen 调用.

Call method ClickOnPoint, this is an example from form click event, so this.handle is form handle, note that these are client coordinates on window witch handle is send, you can easily change this and send screen coordinates, and in that case you don't need handle or ClientToScreen call below.

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

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

UPDATE: using SendInput now, tnx Tom.

顺便说一句.我只使用了此示例所需的声明,还有一个不错的库:Windows Input Simulator (C# SendInput Wrapper - Simulate Keyboard和鼠标)

btw. I used only declarations needed for this sample, for anything more there is a nice library : Windows Input Simulator (C# SendInput Wrapper - Simulate Keyboard and Mouse)

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

  }

这篇关于以编程方式在另一个窗口中单击鼠标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆