我正在尝试编写一个锁定表单位置的代码。
我添加了一个布尔属性,当 True 时表单位置将被锁定,当 False 时表单应返回正常状态。
public class blahblah blah
    Inherits NativeWindow
    Implements IDisposable
Public Property LockPosition As Boolean = False
Private WithEvents form As Form = Nothing
Public Sub New(ByVal form As Form)
    Me.form = form
End Sub
Private Sub OnHandleCreated() _
Handles form.HandleCreated
    Me.AssignHandle(Me.form.Handle)
End Sub
Private Sub OnHandleDestroyed() _
Handles form.HandleDestroyed
    Me.ReleaseHandle()
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
    If Me.LockPosition Then
        Select Case m.Msg
            Case &HA1
                ' Cancels any attempt to drag the window by it's caption.
                If m.WParam.ToInt32 = &H2 Then Return
            Case &H112
                ' Cancels any clicks on the Move system menu item.
                If (m.WParam.ToInt32 And &HFFF0) = &HF010& Then Return
        End Select
    End If
    ' Return control to base message handler.
    MyBase.WndProc(m)
End Sub
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
    If Not Me.disposedValue Then
        If disposing Then
            Me.LockPosition = False
        End If
    End If
    Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
    Dispose(True)
    GC.SuppressFinalize(Me)
End Sub
end class
上面的代码在我第一次实例化类时工作,当我处理类并再次为新表单实例化它时出现问题,我不知道问题是属性,分配的句柄还是windows 消息,但是当我尝试将 LockPosition 属性设置为 True 以用于另一个表单时,它不会锁定任何内容,这就是我使用它的方式:
编辑:
我发现在 New 构造函数中传递的表单无关紧要,问题是它只有在对象在任何过程之外实例化时才有效!
...所以这将起作用,表单将被锁定:
Public Class Form1
    Private _formdock As New FormDock(Me) With {.LockPosition = True}
    Private Shadows Sub Shown() Handles MyBase.Shown
        _formdock.Dock(FormDock.DockPosition.WorkingArea_BottomRight)
    End Sub
End Class
...但是这个 else 不起作用,表格不再被锁定!
Public Class Form1
    Private Shadows Sub Shown() Handles MyBase.Shown
        Dim _formdock As New FormDock(Me) With {.LockPosition = True}
        _formdock.Dock(FormDock.DockPosition.WorkingArea_BottomRight)
    End Sub
End Class
那么为什么会发生这种情况以及我该如何解决呢?
这是完整的课程:
' [ Form Dock ]
'
' // By Elektro H@cker
#Region " Usage Examples "
' Dim _formdock As New FormDock(Me) With {.LockPosition = True}
'
' Private Shadows Sub shown() Handles MyBase.Shown
'
'    _formdock.Dock(FormDock.DockPosition.WorkingArea_BottomRight)
'
' End Sub
#End Region
#Region " Form Dock "
Public Class FormDock
    Inherits NativeWindow
    Implements IDisposable
#Region " Variables, Properties and Enumerations "
    ''' <summary>
    ''' While the property still Enabled it will locks the formulary position.
    ''' </summary>
    Public Property LockPosition As Boolean = False
    ''' <summary>
    ''' Stores the formulary to Dock.
    ''' </summary>
    Private WithEvents form As Form = Nothing
    ''' <summary>
    ''' Stores the size of the formulary to Dock.
    ''' </summary>
    Private UI_Size As Size = Nothing
    ''' <summary>
    ''' Stores the Dock positions.
    ''' </summary>
    Private Dock_Positions As Dictionary(Of DockPosition, Point)
    ''' <summary>
    ''' Dock Positions.
    ''' </summary>
    Public Enum DockPosition As Short
        Bounds_BottomLeft = 1
        Bounds_BottomRight = 2
        Bounds_TopLeft = 3
        Bounds_TopRight = 4
        WorkingArea_BottomLeft = 5
        WorkingArea_BottomRight = 6
        WorkingArea_TopLeft = 7
        WorkingArea_TopRight = 8
    End Enum
#End Region
#Region " New Constructor "
    Public Sub New(ByVal form As Form)
        Me.form = form
    End Sub
#End Region
#Region " Public Procedures "
    ''' <summary>
    ''' Docks the form.
    ''' </summary>
    Public Sub Dock(ByVal Position As DockPosition)
        If Dock_Positions Is Nothing Then
            Renew_Positions(form)
        End If
        form.Location = Dock_Positions(Position)
    End Sub
#End Region
#Region " Miscellaneous Procedures "
    ''' <summary>
    ''' Renews the Dock positions according to the the current form Size.
    ''' </summary>
    Private Sub Renew_Positions(ByVal form As Form)
        UI_Size = form.Size
        Dock_Positions = New Dictionary(Of DockPosition, Point) _
        From {
                 {DockPosition.Bounds_BottomLeft,
                               New Point(Screen.PrimaryScreen.Bounds.X,
                                         Screen.PrimaryScreen.Bounds.Height - UI_Size.Height)},
                 {DockPosition.Bounds_BottomRight,
                           New Point(Screen.PrimaryScreen.Bounds.Width - UI_Size.Width,
                                     Screen.PrimaryScreen.Bounds.Height - UI_Size.Height)},
                 {DockPosition.Bounds_TopLeft,
                               New Point(Screen.PrimaryScreen.Bounds.X,
                                         Screen.PrimaryScreen.Bounds.Y)},
                 {DockPosition.Bounds_TopRight,
                               New Point(Screen.PrimaryScreen.Bounds.Width - UI_Size.Width,
                                         Screen.PrimaryScreen.Bounds.Y)},
                 {DockPosition.WorkingArea_BottomLeft,
                               New Point(Screen.PrimaryScreen.WorkingArea.X,
                                         Screen.PrimaryScreen.WorkingArea.Height - UI_Size.Height)},
                 {DockPosition.WorkingArea_BottomRight,
                               New Point(Screen.PrimaryScreen.WorkingArea.Width - UI_Size.Width,
                                         Screen.PrimaryScreen.WorkingArea.Height - UI_Size.Height)},
                 {DockPosition.WorkingArea_TopLeft,
                               New Point(Screen.PrimaryScreen.WorkingArea.X,
                                         Screen.PrimaryScreen.WorkingArea.Y)},
                 {DockPosition.WorkingArea_TopRight,
                               New Point(Screen.PrimaryScreen.WorkingArea.Width - UI_Size.Width,
                                         Screen.PrimaryScreen.WorkingArea.Y)}
            }
    End Sub
#End Region
#Region " Form EventHandlers "
    ''' <summary>
    ''' Renews the Dock positions according to the the current form Size,
    ''' when Form is Shown.
    ''' </summary>
    Private Sub OnShown() _
    Handles form.Shown
        If Not UI_Size.Equals(Me.form.Size) Then
            Renew_Positions(Me.form)
        End If
    End Sub
    ''' <summary>
    ''' Renews the Dock positions according to the the current form Size,
    ''' When Form is resized.
    ''' </summary>
    Private Sub OnResizeEnd() _
    Handles form.ResizeEnd
        If Not UI_Size.Equals(Me.form.Size) Then
            Renew_Positions(Me.form)
        End If
    End Sub
    ''' <summary>
    ''' OnHandleCreated
    ''' Assign the handle of this NativeWindow to the form handle,
    ''' necessary to override WndProc.
    ''' </summary>
    Private Sub OnHandleCreated() _
    Handles form.HandleCreated
        Me.AssignHandle(Me.form.Handle)
    End Sub
    ''' <summary>
    ''' Releases the Handle.
    ''' </summary>
    Private Sub OnHandleDestroyed() _
    Handles form.HandleDestroyed
        Me.ReleaseHandle()
    End Sub
#End Region
#Region " Windows Messages "
    ''' <summary>
    ''' WndProc Message Interception.
    ''' </summary>
    Protected Overrides Sub WndProc(ByRef m As Message)
        If Me.LockPosition Then
            Select Case m.Msg
                Case &HA1
                    ' Cancels any attempt to drag the window by it's caption.
                    If m.WParam.ToInt32 = &H2 Then Return
                Case &H112
                    ' Cancels any clicks on the Move system menu item.
                    If (m.WParam.ToInt32 And &HFFF0) = &HF010& Then Return
            End Select
        End If
        ' Return control to base message handler.
        MyBase.WndProc(m)
    End Sub
#End Region
#Region "IDisposable Support"
    Private disposedValue As Boolean ' To detect redundant calls
    ' IDisposable
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                Me.LockPosition = False
            End If
            ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
            ' TODO: set large fields to null.
        End If
        Me.disposedValue = True
    End Sub
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region
End Class
#End Region