I am trying to generate an click event in a third party application. As a start I tried to simulate a click in calculator. Here's the code"
IntPtr hwnd = IntPtr.Zero;
IntPtr hwndChild = IntPtr.Zero;
//Get a handle for the Calculator Application main window
hwnd = FindWindow(null, "Calculator");
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "1");
//send BN_CLICKED message
SendMessage(hwndChild, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
But using this code I am not getting the handle of the button. Could someone help please. Is there any other way to simulate a button click on third party application?
Thanks.
Your general approach is correct, but there are two potential problems with your code:
FindWindowEx
only finds direct children of the specified window. It's possible that the calculator buttons are laid out in a container window which is a child of the main window, so the button wouldn't be a direct child of the main window.
The documentation for BM_CLICK
says that it simulates a click by sending mouse down and up messages and hence you may have to activate the parent window before sending this message.
It started to work when I replaced
public const uint BM_CLICK = 0x00F5;
with
public const uint WM_LBUTTONDOWN = 0x0201;
public const uint WM_LBUTTONUP = 0x0202;
and used
SendMessage(buttonHandle, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
SendMessage(buttonHandle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
First use SPY++ to find that is a button having Handle.
In some cases the controls that looks like Button can be graphic control.
The difference is the graphic control will not have Handle, but the Windows control will have handle.
If that control has valid Handle.Then use FindWindowEx
Also give Parent window Handle (I think first parameter, May be you have to use GetWindow() using the caption)
Then send click message.
If you haven't the handle of the button, you can emulate mouse clicking on coordinates:
class User32
{
[Flags]
public enum MouseEventFlags
{
LEFTDOWN = 0x00000002,
LEFTUP = 0x00000004,
MIDDLEDOWN = 0x00000020,
MIDDLEUP = 0x00000040,
MOVE = 0x00000001,
ABSOLUTE = 0x00008000,
RIGHTDOWN = 0x00000008,
RIGHTUP = 0x00000010
}
[DllImport("user32.dll")]
public static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll")]
public static extern void mouse_event(uint dwFlags,
uint dx,
uint dy,
uint dwData,
int dwExtraInfo);
[DllImport("user32.dll")]
public static extern void mouse_event(uint dwFlags,
uint dx,
uint dy,
uint dwData,
UIntPtr dwExtraInfo);
}
class Program
{
static void Main()
{
User32.SetCursorPos(25, 153);
User32.mouse_event((uint)User32.MouseEventFlags.LEFTDOWN, 25, 153, 0, 0);
User32.mouse_event((uint)User32.MouseEventFlags.LEFTUP, 25, 153, 0, 0);
}
}
But, function SetCursorPos set cursor position in global coordinates of screen, so fist you shoud get the possition of a third party application's window.