フォームの位置をロックするコードを書き込もうとしています。
ブール値のプロパティを追加しました。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