How to get the handle of 3rd party application'

2019-07-04 03:48发布

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.

4条回答
贪生不怕死
2楼-- · 2019-07-04 04:13

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);
查看更多
男人必须洒脱
3楼-- · 2019-07-04 04:22

Your general approach is correct, but there are two potential problems with your code:

  1. 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.

  2. 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.

查看更多
孤傲高冷的网名
4楼-- · 2019-07-04 04:23

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.

查看更多
Rolldiameter
5楼-- · 2019-07-04 04:31

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.

查看更多
登录 后发表回答