我正在尝试编写一个锁定表单位置的代码。
我添加了一个布尔属性,当为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
...但是其他方法不起作用,表格不再被锁定了!
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
答案 0 :(得分:0)
工作代码:
' [ Form Docking ]
'
' // By Elektro H@cker
#Region " Usage Examples "
' Private _FormDocking As New FormDocking(Me) With {.LockPosition = True}
'
' Private Shadows Sub Shown() Handles MyBase.Shown
'
' _FormDocking.Dock(FormDocking.DockPosition.WorkingArea_BottomRight)
'
' End Sub
#End Region
#Region " Form Docking "
Public Class FormDocking
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 Positions As Dictionary(Of DockPosition, Point)
''' <summary>
''' Dock Positions.
''' </summary>
Public Enum DockPosition As Short
Center_Screen = 0
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 " Constructor "
Public Sub New(ByVal form As Form)
Me.form = form
SetHandle()
End Sub
#End Region
#Region " Public Methods "
''' <summary>
''' Docks the form.
''' </summary>
Public Sub Dock(ByVal Position As DockPosition)
DisposedCheck()
If Positions Is Nothing Then
Renew_Positions(form)
End If
form.Location = Positions(Position)
End Sub
#End Region
#Region " Miscellaneous Methods "
''' <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
Positions = New Dictionary(Of DockPosition, Point) _
From {
{DockPosition.Center_Screen,
New Point((Screen.PrimaryScreen.Bounds.Width - UI_Size.Width) \ 2,
(Screen.PrimaryScreen.Bounds.Height - UI_Size.Height) \ 2)},
{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 " Event Handlers "
''' <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>
''' SetHandle
''' Assign the handle of the target form to this NativeWindow,
''' necessary to override WndProc.
''' </summary>
Private Sub SetHandle() Handles _
form.HandleCreated,
form.Load,
form.Shown
Try
If Not Me.Handle.Equals(Me.form.Handle) Then
Me.AssignHandle(Me.form.Handle)
End If
Catch ex As InvalidOperationException
End Try
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 "
''' <summary>
''' To detect redundant calls when disposing.
''' </summary>
Private IsDisposed As Boolean = False
''' <summary>
''' Prevents calls to methods after disposing.
''' </summary>
Private Sub DisposedCheck()
If Me.IsDisposed Then
Throw New ObjectDisposedException(Me.GetType().FullName)
End If
End Sub
''' <summary>
''' Disposes the objects generated by this instance.
''' </summary>
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
' IDisposable
Protected Overridable Sub Dispose(IsDisposing As Boolean)
If Not Me.IsDisposed Then
If IsDisposing Then
Me.LockPosition = False
Me.form = Nothing
Me.ReleaseHandle()
Me.DestroyHandle()
End If
End If
Me.IsDisposed = True
End Sub
#End Region
End Class
#End Region