1

I had searching on internet about how draw a rectangular hole on Form, and I found this good example in Delphi language, then I have tried reproduce this example in VB.NET, until now I had success in draw the rectangle hole on Form, but the dimensions this rectangle is not correspond with real mouse position on my computer screen

And also relative to Delphi example, had dificulties for adapt ClientToScreen function to my example, that probably could be solution for this problem.

Someone could help me with this, please?

Here is my last attempt:

 <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

That produces the following: result

Community
  • 1
  • 1

1 Answers1

0

Option 1

You can calculate the distance between top left point of form and top left point of its client area using Me.PointToClient(Me.Location) and use it when you want to calculate location:

Code

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

Screenshot

enter image description here

Option2

You can use Me.TransparencyKey= Color.Red and fill the rectangle with red color, then it will be a hole as you expect.

Code

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

Screenshot

enter image description here

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398