首页 > 解决方案 > 如何找到另一个应用程序按钮句柄?视觉工作室 2019

问题描述

从我的应用程序发送信息后,我试图单击另一个程序的按钮。我正在使用 AppActivate 通过 Sendkeys 发送信息。它工作得很好,但将其他程序(游戏)发送到暂停菜单。如何告诉我的 VB 应用程序单击该取消暂停按钮?我在我的网络搜索中发现有一种方法可以在另一个程序中找到按钮的“按钮句柄”。我仍然是初学者,所以查看示例会有所帮助,但似乎每个人都只是发布这样的单行代码“SendMessage(ButtonHandle, BM_CLICK, 0, 0);或者他们说你可以使用 Spy++ 找到按钮可以指出我正确的方向吗?解释如何使用这些.

在此处输入图像描述

谢谢

标签: vb.net

解决方案


如果您没有 Spy++ 或等效工具,请快速尝试一下。

将 PictureBox 和 Label 拖放到窗体上。运行它并将图片框拖到其他应用程序中的按钮上,以查看它是否有自己的句柄。

如果它确实有自己的句柄,那么您将需要使用各种 API 来根据应用程序主窗口句柄获取句柄。

如果它没有句柄,那么您的“最佳”选择是获取主窗口句柄的左上角坐标,然后在距按钮所在的那个角的固定偏移处单击屏幕(再次使用 API)将会。

Public Class Form1

    Private prevHandle As IntPtr
    Private prevRC As Rect

    Public Structure PointAPI

        Public X As Integer
        Public Y As Integer

        Public Sub New(ByVal x As Integer, ByVal y As Integer)
            Me.X = x
            Me.Y = y
        End Sub

    End Structure

    Public Structure Rect
        Public Left As Integer
        Public Top As Integer
        Public Right As Integer
        Public Bottom As Integer
    End Structure

    Public Declare Function WindowFromPoint Lib "user32" (ByVal pt As PointAPI) As IntPtr
    Public Declare Function GetWindowRect Lib "user32" (ByVal handle As IntPtr, ByRef lpRect As Rect) As Integer

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        PictureBox1.BorderStyle = BorderStyle.FixedSingle
        PictureBox1.BackColor = Color.Red
        PictureBox1.Cursor = Cursors.Cross
    End Sub

    Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        MessageBox.Show("Drag the PictureBox around the screen...")
    End Sub

    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            prevHandle = IntPtr.Zero
        End If
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Dim pt As New PointAPI(Cursor.Position.X, Cursor.Position.Y)
            Dim handle As IntPtr = WindowFromPoint(pt)

            Label1.Text = handle.ToString("X")

            If Not handle.Equals(prevHandle) AndAlso Not prevHandle.Equals(IntPtr.Zero) Then
                ' erase previous rectanlge
                ControlPaint.DrawReversibleFrame(New Rectangle(prevRC.Left, prevRC.Top, prevRC.Right - prevRC.Left, prevRC.Bottom - prevRC.Top), Color.Black, FrameStyle.Thick)
            End If

            If Not handle.Equals(prevHandle) Then
                ' get new rectangle
                GetWindowRect(handle, prevRC)

                ' draw new rectangle
                ControlPaint.DrawReversibleFrame(New Rectangle(prevRC.Left, prevRC.Top, prevRC.Right - prevRC.Left, prevRC.Bottom - prevRC.Top), Color.Black, FrameStyle.Thick)
            End If

            ' store new handle
            prevHandle = handle
        End If
    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Left Then
            ControlPaint.DrawReversibleFrame(New Rectangle(prevRC.Left, prevRC.Top, prevRC.Right - prevRC.Left, prevRC.Bottom - prevRC.Top), Color.Black, FrameStyle.Thick)
        End If
    End Sub

End Class

推荐阅读