newbie
newbie

Reputation: 23

send mouse click

I am trying to simulate mouse click without using mouse by sendmessage somehow it not working but there is no error show. here is my new code

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

Can you someone show me how to put X Y coordination that it will click on a child window. I saw many post teaching how to do that but i can't know understand it and the system said do not ask question in other people question :(

Upvotes: 2

Views: 6210

Answers (2)

Matteo Umili
Matteo Umili

Reputation: 4017

To me the problem is that MSPaintApp window should be searched by using FindWindow("MSPaintApp", null) because MSPaintApp is the class name, not the window caption.

Then, Afx:00007FF765740000:8 is not child of MSPaintApp, but is child of MSPaintView that is child of MSPaintApp.

Also you don't have to "simulate" a BM_CLICK, but you have to simulate a WM_LBUTTONDOWN and then a WM_LBUTTONUP

Please consider this sample that seems to work (on 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));
    }
}

Upvotes: 4

aaronrhodes
aaronrhodes

Reputation: 616

I'm going back many years here but I'm pretty sure mouse event window messages aren't delivered when applications are minimised. I'm sure a minimised window is treated differently anyway.

That aside, does this code work when the window is not minimised? You might want to use Spy++ to look at the structure of the window a little more as I think you will need to get the hWnd of whatever you're trying to click and send the message there. Very much depends on how the application itself was written and how the UI is drawn.

Upvotes: 1

Related Questions