如何在透明自定义控件下方的 PictureBox 中进行绘图

问题描述 投票:0回答:1

我有一个问题,要么很容易解决,要么太复杂,我已经为它疯狂了......接下来,我正在 VB.NET (WindowsForms) 中开发一个应用程序来截取屏幕截图并能够选择屏幕的一部分。我正在使用自定义用户控件来选择屏幕的一部分,到目前为止一切顺利,我的问题是,当制作箭头、矩形或手绘图时,这些图画不会出现在所选框架中,因为它位于下方并且不能看到绘图,因为该控件即使具有透明度,并且已捕获图片框的内容,它也不会显示在图片框的 Paint 事件中所做的绘图。我试图实现的一种选择是在控件本身中制作绘图,但是,当我保存剪辑时,绘图没有出现,因为它们在控件中而不是在图片框中......有点令人困惑,对吧?哈哈

这是我使用用户控件捕获图像的代码。

Imports System.Drawing.Drawing2D
Imports Controle_Customizado_PictureBox
Imports FontAwesome.Sharp

Public Class frm_transp_form
    Private imgInput As Image
    Private EndLocation As Point
    Private StartLocation As Point
    Private rect As Rectangle
    Private IsMouseDown As Boolean = False
    Private ctrlResize As New FrameControl()
    Private currentBtn As IconButton
    Private BottomBoardBtn As Panel
    Private ToolTipPersonal As New ToolTip

    'desenho linha freehand
    Private freehand As Boolean = False
    Private linefreehand As New GraphicsPath()

    Sub New()
        ' Esta chamada é requerida pelo designer.
        InitializeComponent()

        ' Adicione qualquer inicialização após a chamada InitializeComponent().
        BottomBoardBtn = New Panel With {
            .Size = New Size(15, 1)
        }
        pnl_menu.Controls.Add(BottomBoardBtn)
    End Sub

    Private Sub frm_transp_form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Size = New Size(Screen.AllScreens.Sum(Function(s As Screen) s.Bounds.Width), Screen.AllScreens.Max(Function(s As Screen) s.Bounds.Height))
        Me.MaximumSize = New Size(Me.Width, Me.Height)
        Me.MinimumSize = Me.MaximumSize

        pb_screen.Dock = DockStyle.Fill
        pb_screen.SendToBack()
        Dim bmp As Bitmap = New Bitmap(Screen.AllScreens.Sum(Function(s As Screen) s.Bounds.Width), Screen.AllScreens.Max(Function(s As Screen) s.Bounds.Height))
        Using g As Graphics = Graphics.FromImage(bmp)
            g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
            g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
            g.CopyFromScreen(SystemInformation.VirtualScreen.X, SystemInformation.VirtualScreen.Y, 0, 0, SystemInformation.VirtualScreen.Size, CopyPixelOperation.SourceCopy)
            'Me.BackgroundImage = bmp
            pb_screen.BackgroundImage = bmp
        End Using

        Me.Location = New Point(0, 0)
        Me.Cursor = Cursors.Arrow
        ctrlResize.DashNodeColor = Color.Gainsboro
        ctrlResize.Size = New Size(0, 0)
        ctrlResize.Location = New Point(0, 0)
        ctrlResize.DrawingcColor = pb_color.BackColor
        ctrlResize.BackColor = Color.Transparent
        pb_screen.Controls.Add(ctrlResize)
    End Sub

    Private Sub ActivateButton(senderBtn As Object, customcolor As Color)
        If senderBtn IsNot Nothing Then
            DisableButton()
            currentBtn = CType(senderBtn, IconButton)
            currentBtn.IconColor = customcolor
            BottomBoardBtn.BackColor = customcolor
            BottomBoardBtn.Location = New Point(currentBtn.Location.X + ((pnl_menu.Width - BottomBoardBtn.Width) / 2), currentBtn.Bottom)
            BottomBoardBtn.Visible = True
            BottomBoardBtn.BringToFront()
        End If
    End Sub

    Private Sub DisableButton()
        If currentBtn IsNot Nothing Then
            currentBtn.IconColor = Color.FromArgb(78, 78, 78)
        End If
    End Sub

    Private Sub Resetbutton()
        DisableButton()
        BottomBoardBtn.Visible = False
    End Sub

    Private Sub pb_screen_MouseDown(sender As Object, e As MouseEventArgs) Handles pb_screen.MouseDown
        IsMouseDown = True
        StartLocation = e.Location
        With ctrlResize
            .CanMove = True
            .DrawArrow = False
            .DrawHand = False
            .DrawRect = False
        End With
        pnl_menu.Visible = False

        If freehand Then
            linefreehand.StartFigure()
        End If

        Console.WriteLine("Startlocation: " & StartLocation.ToString)
    End Sub

    Private Sub pb_screen_MouseMove(sender As Object, e As MouseEventArgs) Handles pb_screen.MouseMove
        If IsMouseDown = True Then
            EndLocation = e.Location
            GetRectangle()
            Application.DoEvents()
            ctrlResize.Size = New Size(rect.Size)
            ctrlResize.Location = New Point((StartLocation.X), (StartLocation.Y))
            lbl_position.Text = ctrlResize.Width & "x" & ctrlResize.Height
            pnl_menu.Location = New Point(EndLocation.X + 5, EndLocation.Y - pnl_menu.Height)
            Application.DoEvents()

            If freehand Then
                linefreehand.AddLine(e.X, e.Y, e.X, e.Y)
            End If
            pb_screen.Controls(0).Invalidate()
            pb_screen.Invalidate()
        End If
    End Sub

    Private Sub pb_screen_Paint(sender As Object, e As PaintEventArgs) Handles pb_screen.Paint
        e.Graphics.ExcludeClip(ctrlResize.Bounds)
        Using b = New SolidBrush(Color.FromArgb(100, Color.Black))
            e.Graphics.FillRectangle(b, pb_screen.ClientRectangle)
        End Using

        If freehand Then
            DrawShapes(e.Graphics)
        End If
    End Sub

    Private Sub pb_screen_MouseUp(sender As Object, e As MouseEventArgs) Handles pb_screen.MouseUp
        If IsMouseDown = True Then
            EndLocation = e.Location
            IsMouseDown = False

            Console.WriteLine("Retangulo: " & rect.Size.ToString)
            pnl_menu.Visible = True
        End If
    End Sub

    Private Sub DrawShapes(ByVal g As Graphics)
        Try
            g.SmoothingMode = SmoothingMode.AntiAlias
            g.SmoothingMode = SmoothingMode.HighQuality
            g.SmoothingMode = SmoothingMode.HighSpeed

            Dim linecolor As Color = Color.Red
            Dim linepen As Single = 0.3F

            ''DESENHO FREEHAND
            Using handpen As Pen = New Pen(linecolor, linepen)
                g.DrawPath(handpen, linefreehand)
            End Using
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If freehand = False Then
            With ctrlResize
                .CanMove = False
                .DrawArrow = False
                .DrawHand = False
                .DrawRect = False
            End With
            freehand = True
        End If
    End Sub

    Private Function GetRectangle() As Rectangle
        rect = New Rectangle With {
            .X = Math.Min(StartLocation.X, EndLocation.X),
            .Y = Math.Min(StartLocation.Y, EndLocation.Y),
            .Width = Math.Abs(StartLocation.X - EndLocation.X),
            .Height = Math.Abs(StartLocation.Y - EndLocation.Y)
        }

        Return rect
    End Function

    Protected Overrides ReadOnly Property CreateParams As CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or &H2000000
            Return cp
        End Get
    End Property

    Private Sub pb_color_Click(sender As Object, e As EventArgs) Handles pb_color.Click
        'ColorDialog1.ShowDialog()
        If ColorDialog1.ShowDialog <> DialogResult.Cancel Then
            pb_color.BackColor = ColorDialog1.Color
            ctrlResize.DrawingcColor = ColorDialog1.Color
        End If
    End Sub

    Private Sub btn_arrow_Click(sender As Object, e As EventArgs) Handles btn_arrow.Click
        ActivateButton(sender, Color.FromArgb(78, 78, 78))

        With ctrlResize
            .CanMove = False
            .DrawArrow = True
            .DrawHand = False
            .DrawRect = False
        End With
    End Sub

    Private Sub btn_freehand_Click(sender As Object, e As EventArgs) Handles btn_freehand.Click
        ActivateButton(sender, Color.FromArgb(78, 78, 78))
        With ctrlResize
            .CanMove = False
            .DrawArrow = False
            .DrawHand = True
            .DrawRect = False
        End With
    End Sub

    Private Sub btn_rect_Click(sender As Object, e As EventArgs) Handles btn_rect.Click
        ActivateButton(sender, Color.FromArgb(78, 78, 78))
        With ctrlResize
            .CanMove = False
            .DrawArrow = False
            .DrawHand = False
            .DrawRect = True
        End With
    End Sub

    Private Sub btn_copy_Click(sender As Object, e As EventArgs) Handles btn_copy.Click
        ActivateButton(sender, Color.FromArgb(78, 78, 78))

        Dim selectedRectangle = New Rectangle(StartLocation.X, StartLocation.Y, ctrlResize.ClientRectangle.Width, ctrlResize.ClientRectangle.Height)
        Dim result = GetRectangeOnImage(pb_screen, selectedRectangle)
        Console.WriteLine("VALORES DO RETANGULO: " & selectedRectangle.ToString)
        Using bm = New Bitmap(CInt(result.Width), CInt(result.Height))

            Using g = Graphics.FromImage(bm)
                g.SmoothingMode = SmoothingMode.HighQuality
                g.CompositingQuality = CompositingQuality.HighQuality
                g.DrawImage(pb_screen.Image, 0, 0, result, GraphicsUnit.Pixel)
            End Using
            Dim img As Image = CType(bm.Clone(), Image)
            PictureBox1.Size = New Size(ctrlResize.Size)
            PictureBox1.Image = img
            PictureBox1.Visible = True
        End Using
    End Sub

    Public Function GetRectangeOnImage(ByVal p As PictureBox, ByVal selectionRect As Rectangle) As RectangleF
        Dim method = GetType(PictureBox).GetMethod("ImageRectangleFromSizeMode", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance)
        Dim imageRect = CType(method.Invoke(p, New Object() {p.SizeMode}), Rectangle)
        If p.Image Is Nothing Then Return selectionRect
        Dim cx = CSng(p.Image.Width) / CSng(imageRect.Width)
        Dim cy = CSng(p.Image.Height) / CSng(imageRect.Height)
        Dim r2 = Rectangle.Intersect(imageRect, selectionRect)
        r2.Offset(-imageRect.X, -imageRect.Y)
        Return New RectangleF(r2.X * cx, r2.Y * cy, r2.Width * cx, r2.Height * cy)
    End Function

    Private Sub btn_fechar_Click(sender As Object, e As EventArgs) Handles btn_fechar.Click
        ActivateButton(sender, Color.FromArgb(78, 78, 78))
        End
    End Sub
End Class

这是我的用户控制代码

Imports System.ComponentModel
Imports System.Drawing.Drawing2D
Imports System.Windows

Partial Public Class FrameControl
    Inherits UserControl

    <DefaultValue(True)>
    Public Property CanMove As Boolean = True
    <DefaultValue(False)>
    Public Property DrawArrow As Boolean = False
    <DefaultValue(False)>
    Public Property DrawHand As Boolean = False
    <DefaultValue(False)>
    Public Property DrawRect As Boolean = False
    Public Property DrawingcColor As Color = Color.LightGreen
    Public Property PenSize As Single = 3.0F
    Public Property DashNodeColor As Color = Color.Black

    Public Event DrawUndoClicked As EventHandler
    Dim btn As Button
    Const WM_NCHITTEST As Integer = 132
    Const WM_SETCURSOR As Integer = 32
    Const WM_MOUSEMOVE As Integer = 32
    Const WM_NCLBUTTONDBLCLK As Integer = 163
    Private isMouseDown As Boolean

    'desenho flecha
    Private m_StartX, m_StartY, m_CurX, m_CurY As Single
    Dim MyLineArrows As New List(Of LineList)

    'desenho retangulo
    Private SelectedColor As Color = Color.LightGreen
    Private drawingRects As List(Of DrawingRectangle) = New List(Of DrawingRectangle)()

    'desenho linha freehand
    Private linefreehand As New GraphicsPath()

    Private sizeNodeRect As Integer = 7
    Private nodeSelected As PosSizableRect = PosSizableRect.None
    Public rect As Rectangle

    Private Enum PosSizableRect
        UpMiddle
        LeftMiddle
        LeftBottom
        LeftUp
        RightUp
        RightMiddle
        RightBottom
        BottomMiddle
        None
    End Enum

    Public Sub New()
        InitializeComponent()
        rect = ClientRectangle
        SetStyle(ControlStyles.SupportsTransparentBackColor, True)

        DoubleBuffered = True
        ResizeRedraw = True
        BackColor = Color.Transparent
        Timer1.Enabled = True
    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        Try
            Using p = New Pen(DashNodeColor, 2)
                Using b = New SolidBrush(DashNodeColor)
                    p.DashStyle = Drawing2D.DashStyle.Dash
                    e.Graphics.DrawRectangle(p, 0, 0, Width - 1, Height - 1)

                    For Each pos As PosSizableRect In [Enum].GetValues(GetType(PosSizableRect))
                        e.Graphics.DrawRectangle(p, GetRect(pos))
                        e.Graphics.FillRectangle(b, GetRect(pos))
                    Next
                End Using
            End Using

            If CanMove = False Then
                DrawShapes(e.Graphics)

            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Protected Overrides Sub WndProc(ByRef m As Message)
        Try
            Dim borderWidth As Integer = 10
            If m.Msg = WM_SETCURSOR Then
                If (m.LParam.ToInt32() And 65535) = 2 Then
                    Cursor.Current = If(CanMove, Cursors.SizeAll, Cursors.Arrow)
                    m.Result = CType(1, IntPtr)
                    Return
                End If
            End If
            If m.Msg = WM_MOUSEMOVE Then
                If (m.LParam.ToInt32() And 65535) = 2 Then
                    Cursor.Current = Cursors.Arrow
                    m.Result = CType(1, IntPtr)
                    Return
                End If
            End If
            If m.Msg = WM_NCLBUTTONDBLCLK Then
                m.Result = CType(1, IntPtr)
                Return
            End If
            MyBase.WndProc(m)
            If m.Msg = WM_NCHITTEST Then
                Dim pos = PointToClient(New Point(m.LParam.ToInt32() And 65535, m.LParam.ToInt32() >> 16))
                If (pos.X <= (ClientRectangle.Left + borderWidth)) AndAlso (pos.Y <= (ClientRectangle.Top + borderWidth)) Then
                    m.Result = New IntPtr(13)
                Else
                    If (pos.X >= (ClientRectangle.Right - borderWidth)) AndAlso (pos.Y <= (ClientRectangle.Top + borderWidth)) Then
                        m.Result = New IntPtr(14)
                    Else
                        If (pos.X <= (ClientRectangle.Left + borderWidth)) AndAlso (pos.Y >= (ClientRectangle.Bottom - borderWidth)) Then
                            m.Result = New IntPtr(16)
                        Else
                            If (pos.X >= (ClientRectangle.Right - borderWidth)) AndAlso (pos.Y >= (ClientRectangle.Bottom - borderWidth)) Then
                                m.Result = New IntPtr(17)
                            Else
                                If pos.X <= (ClientRectangle.Left + borderWidth) Then
                                    m.Result = New IntPtr(10)
                                Else
                                    If pos.Y <= (ClientRectangle.Top + borderWidth) Then
                                        m.Result = New IntPtr(12)
                                    Else
                                        If pos.X >= (ClientRectangle.Right - borderWidth) Then
                                            m.Result = New IntPtr(11)
                                        Else
                                            If pos.Y >= (ClientRectangle.Bottom - borderWidth) Then
                                                m.Result = New IntPtr(15)
                                            Else
                                                m.Result = (If(CanMove, New IntPtr(2), IntPtr.Zero))
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Private Sub FrameControl_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
        Try
            isMouseDown = True
            If DrawArrow Then
                m_StartX = e.X
                m_StartY = e.Y
                m_CurX = e.X
                m_CurY = e.Y

            ElseIf DrawRect Then
                drawingRects.Add(New DrawingRectangle() With {
                .Location = e.Location,
                .Size = Size.Empty,
                .StartPosition = e.Location,
                .DrawingcRectColor = DrawingcColor,
                .PenRectSize = PenSize
                })

            ElseIf DrawHand Then
                linefreehand.StartFigure()

            End If
        Catch ex As Exception
            Throw ex
        End Try

        '.Owner = CType(sender, Control),
    End Sub

    Private Sub FrameControl_MouseMove(sender As Object, e As MouseEventArgs) Handles MyBase.MouseMove
        Try
            If isMouseDown Then
                If DrawArrow Then
                    m_CurX = e.X
                    m_CurY = e.Y

                ElseIf DrawRect Then
                    Dim dr = drawingRects(drawingRects.Count - 1)

                    If e.Y < dr.StartPosition.Y Then
                        dr.Location = New Point(dr.Rect.Location.X, e.Y)
                    End If

                    If e.X < dr.StartPosition.X Then
                        dr.Location = New Point(e.X, dr.Rect.Location.Y)
                    End If

                    dr.Size = New Size(Math.Abs(dr.StartPosition.X - e.X), Math.Abs(dr.StartPosition.Y - e.Y))
                ElseIf DrawHand Then
                    linefreehand.AddLine(e.X, e.Y, e.X, e.Y)
                End If

                Me.Invalidate()
            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Private Sub FrameControl_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        UseDoubleBuffer()
    End Sub

    Private Sub FrameControl_MouseUp(sender As Object, e As MouseEventArgs) Handles MyBase.MouseUp
        Try
            isMouseDown = False
            If DrawArrow Then
                Dim DrawLine As New LineList
                DrawLine.X1 = m_StartX
                DrawLine.Y1 = m_StartY
                DrawLine.X2 = m_CurX
                DrawLine.Y2 = m_CurY
                MyLineArrows.Add(DrawLine)

            ElseIf DrawRect Then
                Dim dr = drawingRects.Last()
            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Try
            If CanMove Then
                linefreehand.Reset()
                drawingRects.Clear()
                MyLineArrows.Clear()
                Me.Invalidate()

            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Private Sub DrawShapes(ByVal g As Graphics)
        Try
            g.SmoothingMode = SmoothingMode.AntiAlias
            g.SmoothingMode = SmoothingMode.HighQuality
            g.SmoothingMode = SmoothingMode.HighSpeed

            'DESENHO DO RETANGULO
            For Each dr In drawingRects
                Using pen As Pen = New Pen(DrawingcColor, PenSize)
                    g.DrawRectangle(pen, dr.Rect)
                End Using
            Next

            'DESENHO DA FLECHA
            Dim x1, y1, x2, y2 As Integer
            Dim linecolor As Color = DrawingcColor
            Dim linepen As Single = PenSize

            For Each line In MyLineArrows
                x1 = line.X1 : x2 = line.X2
                y1 = line.Y1 : y2 = line.Y2
                Using Arrow1 As New Pen(linecolor, linepen)
                    Arrow1.EndCap = LineCap.Custom
                    Arrow1.CustomEndCap = New AdjustableArrowCap(2, 2, False)
                    g.DrawLine(Arrow1, x1, y1, x2, y2)
                End Using
            Next

            If isMouseDown Then
                Using Arrow As Pen = New Pen(linecolor, linepen)
                    Arrow.EndCap = LineCap.Custom
                    Arrow.CustomEndCap = New AdjustableArrowCap(2, 2, False)
                    g.DrawLine(Arrow, m_StartX, m_StartY, m_CurX, m_CurY)
                End Using
            End If
            'DESENHO FREEHAND
            Using handpen As Pen = New Pen(linecolor, linepen)
                g.DrawPath(handpen, linefreehand)
            End Using
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Private Sub UseDoubleBuffer()
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or
                     ControlStyles.UserPaint Or
                     ControlStyles.OptimizedDoubleBuffer, True)
    End Sub

    Private Function CreateRectSizableNode(ByVal x As Integer, ByVal y As Integer) As Rectangle
        Return New Rectangle(x - sizeNodeRect / 2, y - sizeNodeRect / 2, sizeNodeRect, sizeNodeRect)
    End Function

    Private Function GetRect(ByVal p As PosSizableRect) As Rectangle
        Select Case p
            Case PosSizableRect.LeftUp
                Return CreateRectSizableNode(ClientRectangle.X, ClientRectangle.Y)
            Case PosSizableRect.LeftMiddle
                Return CreateRectSizableNode(ClientRectangle.X, ClientRectangle.Y + +ClientRectangle.Height / 2)
            Case PosSizableRect.LeftBottom
                Return CreateRectSizableNode(ClientRectangle.X, ClientRectangle.Y + ClientRectangle.Height)
            Case PosSizableRect.BottomMiddle
                Return CreateRectSizableNode(ClientRectangle.X + ClientRectangle.Width / 2, ClientRectangle.Y + ClientRectangle.Height)
            Case PosSizableRect.RightUp
                Return CreateRectSizableNode(ClientRectangle.X + ClientRectangle.Width, ClientRectangle.Y)
            Case PosSizableRect.RightBottom
                Return CreateRectSizableNode(ClientRectangle.X + ClientRectangle.Width, ClientRectangle.Y + ClientRectangle.Height)
            Case PosSizableRect.RightMiddle
                Return CreateRectSizableNode(ClientRectangle.X + ClientRectangle.Width, ClientRectangle.Y + ClientRectangle.Height / 2)
            Case PosSizableRect.UpMiddle
                Return CreateRectSizableNode(ClientRectangle.X + ClientRectangle.Width / 2, ClientRectangle.Y)
            Case Else
                Return New Rectangle()
        End Select
    End Function

    Private Function GetNodeSelectable(ByVal p As Point) As PosSizableRect
        For Each r As PosSizableRect In [Enum].GetValues(GetType(PosSizableRect))

            If GetRect(r).Contains(p) Then
                Return r
            End If
        Next

        Return PosSizableRect.None
    End Function


End Class

这是带有用户控制的捕获屏幕的示例

我接受 C# 和 VB.net 中的建议

c# vb.net user-controls picturebox
1个回答
0
投票

不是完整的答案,所以只是社区维基,但我想建议对用户控件的深层嵌套

If
/
Else
部分(
WndProc()
方法)进行改进:

Protected Overrides Sub WndProc(ByRef m As Message)

    Dim borderWidth As Integer = 10
    If m.Msg = WM_SETCURSOR AndAlso (m.LParam.ToInt32() And 65535) = 2 Then
        Cursor.Current = If(CanMove, Cursors.SizeAll, Cursors.Arrow)
        m.Result = CType(1, IntPtr)
        Return
    End If

    If m.Msg = WM_MOUSEMOVE AndAlso (m.LParam.ToInt32() And 65535) = 2 Then
        Cursor.Current = Cursors.Arrow
        m.Result = CType(1, IntPtr)
        Return
    End If

    If m.Msg = WM_NCLBUTTONDBLCLK Then
        m.Result = CType(1, IntPtr)
        Return
    End If
    MyBase.WndProc(m)

    If m.Msg <> WM_NCHITTEST Then Return

    Dim pos = PointToClient(New Point(m.LParam.ToInt32() And 65535, m.LParam.ToInt32() >> 16))
    If pos.X <= (ClientRectangle.Left + borderWidth) AndAlso pos.Y <= (ClientRectangle.Top + borderWidth) Then
         m.Result = New IntPtr(13)
    Else If pos.X >= (ClientRectangle.Right - borderWidth) AndAlso pos.Y <= (ClientRectangle.Top + borderWidth) Then
        m.Result = New IntPtr(14)
    Else If pos.X <= (ClientRectangle.Left + borderWidth) AndAlso pos.Y >= (ClientRectangle.Bottom - borderWidth) Then
        m.Result = New IntPtr(16)
    Else If pos.X >= (ClientRectangle.Right - borderWidth) AndAlso pos.Y >= (ClientRectangle.Bottom - borderWidth) Then
        m.Result = New IntPtr(17)
    Else If pos.X <= (ClientRectangle.Left + borderWidth) Then
        m.Result = New IntPtr(10)
    Else If pos.Y <= (ClientRectangle.Top + borderWidth) Then
        m.Result = New IntPtr(12)
    Else If pos.X >= (ClientRectangle.Right - borderWidth) Then
        m.Result = New IntPtr(11)
    Else If pos.Y >= (ClientRectangle.Bottom - borderWidth) Then
        m.Result = New IntPtr(15)
    Else
        m.Result = (If(CanMove, New IntPtr(2), IntPtr.Zero))
    End If
End Sub

再次,正如评论中所指出的,原始方法中的

Try
/
Catch
不仅没有帮助,而且主动让事情变得更糟,所以我只是将其删除。这也大大减少了嵌套/缩进,从而可以删除一堆
End If
行,并使代码MUCH更易于理解。

我怀疑也可以将其转换为通过字典查找为

11
调用找到正确的整数值(从
17
IntPtr()
),这会更好。但由于有两组输入(X 与 Y),这可能比乍看起来更棘手。

© www.soinside.com 2019 - 2024. All rights reserved.