将模拟事件发送到另一个窗口

时间:2011-01-10 22:56:11

标签: c# events mouse emulation

我以下列方式将鼠标事件发送到另一个应用程序。问题是,这适用于某些应用程序,但不适用于其他应用程序。 为什么呢?

using System.Runtime.InteropServices;
using System.Diagnostics;



namespace WpfApplication1
{

  public partial class MainWindow : Window
  {


    [DllImport("user32.dll")]
    private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);


    private const int downclick = 0x201;
    private const int upclick = 0x202;
    IntPtr handle = IntPtr.Zero;

    public MainWindow()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
      foreach (Process p in Process.GetProcessesByName("mspaint"))
      {
        IntPtr handle = p.MainWindowHandle;
        int X = 50;
        int Y = 380;
        IntPtr lParam = (IntPtr)((Y << 16) | X);
        IntPtr wParam = IntPtr.Zero;
        SendMessage(handle, downclick, wParam, lParam);
        SendMessage(handle, upclick, wParam, lParam);
      }  
    } 
  }
}

使用Spy ++我看到应用程序收到了以下数据:

<00062> 0004052C S WM_LBUTTONDOWN fwKeys:0000 xPos:50 yPos:380
<00063> 0004052C R WM_LBUTTONDOWN
<00064> 0004052C S WM_LBUTTONUP fwKeys:0000 xPos:50 yPos:380
<00065> 0004052C R WM_LBUTTONUP

我认为事件本身是正确的。但我不知道为什么它适用于某些软件而不适用于其他软件。如何将鼠标消息从一个窗口发送到另一个窗口? 我想要发送消息的软件并不总是可见的。

有可能吗?

1 个答案:

答案 0 :(得分:1)

不可能以任何可靠的方式 - 正如您在测试中发现的那样。鼠标消息只是输入的一部分。 Windows保持输入状态,只发送消息不会更新该输入状态。而且你也忽略了鼠标移动信息等。

例如,在WinForms应用程序中,您可以使用MousePosition属性来获取当前的鼠标位置。发送消息无法模拟该消息。

此外,您无法将鼠标消息发送到主窗口句柄,您必须找到要单击的确切按钮并将消息直接发送到正确的按钮。

所以如果应用程序只监听鼠标消息,它可能会起作用,但如果没有,它们就不会起作用。

他们支持模拟鼠标点击的方式,是SendInput功能。但这对最小化的应用程序无效。它完全通过整个Windows输入过程并移动鼠标光标 - 这意味着应用程序必须在屏幕上可见。

以下是一些信息,它讨论了键盘事件,但类似的逻辑适用: http://blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx http://blogs.msdn.com/b/oldnewthing/archive/2010/12/21/10107494.aspx