矩形孔尺寸不等于我电脑屏幕上的真实鼠标位置

Rectangular hole dimensions isn't equals to real mouse position on my computer screen

我在网上搜索过如何在 Form 上画一个矩形孔,我发现 this 用 Delphi 语言写的很好的例子,然后我尝试在 VB.NET 中重现这个例子, 直到现在我已经成功地在窗体上绘制了矩形孔,但是这个矩形的尺寸与我电脑屏幕上的真实鼠标位置不对应

并且相对于 Delphi 示例,我的示例难以适应 ClientToScreen 函数,这可能是解决此问题的方法。

有人可以帮我解决这个问题吗?

这是我最后一次尝试:

 <DllImport("user32.dll")> _
    Private Shared Function ClientToScreen(ByVal hWnd As IntPtr, ByRef lpPoint As Point) As Boolean
    End Function

    Dim mRect As Rectangle

    Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
        mRect = New Rectangle(e.X, e.Y, 0, 0)
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)

        If e.Button = Windows.Forms.MouseButtons.Left Then

            Dim gp As New System.Drawing.Drawing2D.GraphicsPath

            gp.AddRectangle(New Rectangle(0, 0, Me.Width, Me.Height))

            mRect = New Rectangle(mRect.Left, mRect.Top, e.X - mRect.Left, e.Y - mRect.Top)

            gp.AddRectangle(mRect)

            Me.Region = New Region(gp)

            Me.Invalidate()
        End If
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Using pen As New Pen(Color.Red, 3)
            e.Graphics.DrawRectangle(pen, mRect)
        End Using
    End Sub

产生以下结果:result

选项 1

您可以使用Me.PointToClient(Me.Location)计算窗体左上点和其客户区左上点之间的距离,并在您要计算位置时使用它:

代码

Public Class HoleForm
    Dim mRect As Rectangle
    Dim d
    Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
        mRect = New Rectangle(e.X - d.x, e.Y - d.y, 0, 0)
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)

        If e.Button = Windows.Forms.MouseButtons.Left Then

            Dim gp As New System.Drawing.Drawing2D.GraphicsPath

            gp.AddRectangle(New Rectangle(0, 0, Me.Width, Me.Height))

            mRect = New Rectangle(mRect.Left, mRect.Top, e.X - d.x - mRect.Left, e.Y - d.y - mRect.Top)

            gp.AddRectangle(mRect)

            Me.Region = New Region(gp)

            Me.Invalidate()
        End If
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim mRect2 = New Rectangle(mRect.Location, mRect.Size)
        mRect2.Offset(d)
        Using pen As New Pen(Color.Red, 3)
            e.Graphics.DrawRectangle(pen, mRect2)
        End Using
    End Sub

    Private Sub HoleForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        d = Me.PointToClient(Me.Location)
    End Sub
End Class

截图

选项2

您可以使用Me.TransparencyKey= Color.Red并用红色填充矩形,然后它就是您期望的洞。

代码

Public Class HoleForm
    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.TransparencyKey = Color.Red
    End Sub
    Dim mRect As Rectangle
    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        mRect = New Rectangle(e.X, e.Y, 0, 0)
        Me.Invalidate()
        MyBase.OnMouseDown(e)
    End Sub
    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)

        If e.Button = Windows.Forms.MouseButtons.Left Then
            mRect = New Rectangle(mRect.Left, mRect.Top, e.X - mRect.Left, e.Y - mRect.Top)
            Me.Invalidate()
        End If
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Using HoleBrush As New SolidBrush(Me.TransparencyKey)
            e.Graphics.FillRectangle(HoleBrush, mRect)
        End Using
        Using BorderPen As New Pen(Color.Blue, 3)
            e.Graphics.DrawRectangle(BorderPen, mRect)
        End Using
    End Sub
End Class

截图