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