发送鼠标点击

时间:2016-01-08 13:22:03

标签: c#

我试图通过sendmessage模拟鼠标点击而不使用鼠标 不知怎的,它没有工作,但没有错误显示。 这是我的新代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Diagnostics;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private const int BM_CLICK = 0x00F5;

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

    public Form1()
    {
        InitializeComponent();
    }



        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr hwndChild = IntPtr.Zero;
            IntPtr hwnd = IntPtr.Zero;
            hwnd = FindWindow(null, "MSPaintApp");
            hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Afx:00007FF765740000:8", null);
            SendMessage(hwndChild, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
        }
    }
}

你能否告诉我如何将X Y协调点击在子窗口上。我看到很多帖子教学如何做到这一点,但我不知道理解它,系统说不要在别人的问题中提问:(

2 个答案:

答案 0 :(得分:1)

我在这里回了很多年,但我非常确定在应用程序最小化时不会传递鼠标事件窗口消息。我确定最小化窗口的处理方式不同。

除此之外,当窗口未最小化时,此代码是否有效?您可能希望使用Spy ++来更多地查看窗口的结构,因为我认为您需要获取您尝试单击并在其中发送消息的任何内容。很大程度上取决于应用程序本身的编写方式以及UI的绘制方式。

答案 1 :(得分:1)

问题是我应该使用MSPaintApp来搜索FindWindow("MSPaintApp", null)窗口,因为MSPaintApp是类名,而不是窗口标题。

然后,Afx:00007FF765740000:8不是MSPaintApp的孩子,而是MSPaintView的孩子,是MSPaintApp的孩子。

此外,您不必“模拟”BM_CLICK,但您必须模拟WM_LBUTTONDOWN,然后模拟WM_LBUTTONUP

请考虑这个似乎有用的示例(在Windows 7上)

class Program
{
    private const uint WM_LBUTTONDOWN = 0x201;
    private const uint WM_LBUTTONUP = 0x202;
    private const uint MK_LBUTTON = 0x0001;

    public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr parameter);

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);

    static IntPtr childWindow;

    static void Main(string[] args)
    {                     
        IntPtr hwndMain = FindWindow("MSPaintApp", null);
        IntPtr hwndView = FindWindowEx(hwndMain, IntPtr.Zero, "MSPaintView", null);
        // Getting the child windows of MSPaintView because it seems that the class name of the child isn't constant
        EnumChildWindows(hwndView, new EnumWindowsProc(EnumWindow), IntPtr.Zero);
        // Simulate press of left mouse button on coordinates 10, 10
        SendMessage(childWindow, WM_LBUTTONDOWN, new IntPtr(MK_LBUTTON), CreateLParam(10, 10));
        // Simulate release of left mouse button on coordinates 100, 100
        SendMessage(childWindow, WM_LBUTTONUP, new IntPtr(MK_LBUTTON), CreateLParam(100, 100)); 
    }

    static bool EnumWindow(IntPtr handle, IntPtr pointer)
    {
        // Get the first child because it seems that MSPaintView has only this child
        childWindow = handle;
        // Stop enumerating the windows
        return false;
    }

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