如何使用 C# 获取第三方应用程序按钮的句柄?

发布于 2024-10-12 13:58:14 字数 451 浏览 10 评论 0原文

我正在尝试在第三方应用程序中生成点击事件。首先,我尝试模拟计算器中的点击。这是代码“

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

但是使用此代码我无法获取按钮的句柄。有人可以帮忙吗?还有其他方法可以模拟第三方应用程序上的按钮单击吗?

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空城仅有旧梦在 2024-10-19 13:58:14

您的一般方法是正确的,但您的代码存在两个潜在问题:

  1. FindWindowEx 仅查找指定窗口的直接子窗口。计算器按钮可能布置在作为主窗口子窗口的容器窗口中,因此该按钮不会是主窗口的直接子窗口。

  2. BM_CLICK<的文档/code>表示它通过发送鼠标向下和向上消息来模拟单击,因此您可能必须在发送此消息之前激活父窗口。

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.

逆光下的微笑 2024-10-19 13:58:14

时它开始工作

public const uint BM_CLICK = 0x00F5;

当我替换为

public const uint WM_LBUTTONDOWN = 0x0201; 
public const uint WM_LBUTTONUP = 0x0202;

并使用

SendMessage(buttonHandle, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero); 
SendMessage(buttonHandle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);

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);
扎心 2024-10-19 13:58:14

首先使用SPY++找到一个带有Handle的按钮。

在某些情况下,看起来像按钮的控件可以是图形控件。
不同的是图形控件不会有句柄,但Windows控件会有句柄。
如果该控件具有有效的句柄。然后使用 FindWindowEx

还给父窗口句柄(我认为第一个参数,可能您必须使用标题使用 GetWindow() )

然后发送单击消息。

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.

猫九 2024-10-19 13:58:14

如果你没有按钮的手柄,你可以模拟鼠标点击坐标:

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

但是,函数SetCursorPos将光标位置设置在屏幕的全局坐标中,所以首先你应该获得第三方应用程序窗口的位置。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文