是否有 Hooking 的替代方法可以检测 Windows 窗体之外的事件?

Is there an alternative to Hooking to detect events outside of Windows Forms?

提问人:John89 提问时间:2/20/2021 最后编辑:John89 更新时间:4/6/2021 访问量:95

问:

我正在尝试弄清楚如何从窗口窗体外部检测和处理系统事件,例如按下的键和鼠标单击。有没有不需要 user32.dll 钩子的替代方案?

我的意思的粗略例子:

    Public Sub MouseClick(e As System.MouseEventArgs) Handles Mouse.LeftClick // Left mouse click event raised
        ' even if the user clicks on a browser link in google chrome. Ideally, the click would not even
        ' register in the chrome browser, preventing the user from being directed to the link destination 
        Dim bmp As New Bitmap(1, 1)
        Using g As Graphics = Graphics.FromImage(bmp)
            g.CopyFromScreen(Windows.Forms.Cursor.Position, New Point(0, 0), New Drawing.Size(1, 1))
        End Using
        Dim pixel As Drawing.Color = bmp.GetPixel(0, 0)
        ArgbID.Text = bmp.GetPixel(0, 0).ToString
        Dim p As New Point With {.X = ((Me.Width - Me.Splitter1.Width) / 2) + Me.Splitter1.Width - (ArgbID.Width / 2), .Y = ArgbID.Top}
        ArgbID.Location = p
        DisplayBox.BackColor = pixel
        Me.Invalidate()
    End Sub

我希望能够检测和处理窗体之外的事件。如果我必须使用钩子,那么这是最有前途的示例,它应该做我想做的事情: 代码项目 [在 C# 中处理全局鼠标和键盘钩子]

vb.net 表单 子系统 处理程序

评论


答:

0赞 John89 2/27/2021 #1

好的,所以我找到了一种方法,通过挂接到鼠标来创建我自己的事件处理程序。以下是我所做工作的摘要:
免责声明 - 此方法仍使用 System.Windows.Forms,因此您仍将在窗体本身中工作。

Private Sub Button_Click(sender As Object, e As EventArgs)
    Select Case True
        Case sender Is Btn_Help
        Case sender Is Btn_Ok
        Case sender Is Btn_GetPoint
            If ColorChooserClicked = False Then
                // Doing stuff here
                Dim ScreenLock As New TestFormNi With {.Opacity = 0.01,
                .WindowState = FormWindowState.Maximized, .FormBorderStyle = FormBorderStyle.None}
                ScreenLock.ShowDialog()
            Else
                // Other Stuff
            End If
    End Select
End Sub

和:

Imports System.Windows.Forms

Public Class TestFormNi
    Private time As Integer = 0
    Private Sub LoadFormNi(sender As Object, e As EventArgs) Handles MyBase.Load
        PictureBox1.Image = Cache.Img
        Timer1.Start()
        Me.TopMost = True
        Me.Invalidate()
    End Sub
    Private Sub ClickDetection(sender As Object, e As EventArgs) Handles Me.Click, PictureBox1.Click
        TestingForm.Btn_GetPoint.PerformClick()
        Me.Dispose()
        TestingForm.Focus()
    End Sub
    Private Sub Escape(sender As Object, e As KeyEventArgs) Handles Me.KeyDown, PictureBox1.KeyDown
        If e.KeyCode = Keys.Escape Then Me.Dispose()
    End Sub
    Private Sub AutoClose(sender As Object, e As EventArgs) Handles Timer1.Tick
        If time > 30 Then TestingForm.Btn_GetPoint.PerformClick() : Me.Dispose() : TestingForm.Focus()
        time += 1
    End Sub
End Class

这样,我就能够单击“屏幕”上的任意位置,并且单击事件仍将在 Windows 窗体中注册,因为显然,单击位置仍在 Windows.Forms 中;这也为我省去了必须创建一个句柄来禁止点击在其他应用程序中注册的麻烦。(例如,如果光标悬停在浏览器链接上,则会被重定向)

注 - 不透明度级别必须大于 0,否则表单将不会注册事件。