发送鼠标点击

问题描述:

我试图模拟鼠标点击不使用鼠标通过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协调,这会点击一个子窗口上。我看到很多顶岗怎么做,但我不知道理解和系统说不要在其他人问问题问:(

对我来说,问题是,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)); 
    } 
} 
+0

谢谢你很多codroipo。你是我的英雄!!!我试了一下,看起来就像我希望的那样工作。但这真的让我背后有一个大问题。你怎么知道paint的hwndmain是MsPaintApp。和hwndView = MSPaintView?我的意思是也许下一个代码我可能会写差异程序。我如何正确地获得程序的hwndmain和hwndview? – newbie

+0

@EakzilaKung由于Spy ++,我们知道'hwndMain'是'MSPaintApp'。 hwndView也一样。如果你想编写一个模拟点击其他程序窗口的泛型方法,我认为你不能,因为程序使用了大量的'窗口'。在Paint中,我们知道要绘制,我们必须点击“MSPaintView”的第一个子窗口,其他程序肯定会使用另一个Windows体系结构(具有不同的类名称)。例如在Paint中,如果我们想要点击'Paste'按钮,我们需要找到相应的窗口来发送相应的消息 –

+0

这对我来说真的很复杂。在我读到上面的消息后。我与其他程序一起尝试,它真的有很多孩子。而且看起来更加复杂的是,我需要处理的孩子是孩子内的孩子。而这//// IntPtr hwndView = FindWindowEx(hwndMain,IntPtr.Zero,“MSPaintView”,null);为什么后面的孩子是IntPtr.Zero和String类的名字是MSPaintView。我认为MSPaintView是MsPaintApp之后的孩子。我很抱歉...我真的不知道,我觉得我问一些愚蠢的问题。我尝试自己寻找答案,但根本不了解 – newbie

我在这里可以追溯到很多年,但我敢肯定鼠标事件窗口消息不会在应用程序最小化时传递,我敢肯定最小化窗口的处理方式不同,无论如何,

不管这个代码在窗口没有最小化的时候工作吗?你可能想用Spy ++来查看在窗口的结构中,我认为你需要获得你想要点击的任何东西的hWnd,并在那里发送消息,这很大程度上取决于应用程序本身是如何编写的以及如何绘制UI。

+0

好吧,它根本不动。无所谓油漆最小化或没有。我也会看看Spy ++和hWnd。谢谢 – newbie

+0

我有一个快速浏览一下,有似乎是仿真鼠标输入(想必你不知道鼠标事件被订阅的并在目标应用程序中使用的基础上)更好的方式。 看看这里: http://stackoverflow.com/questions/8021954/sendinput-doesnt-perform-click-mouse-button-unless-i-move-cursor – aaronrhodes