Windows/Window: Add SnapToBorder
This commit is contained in:
parent
7ffff9ab0e
commit
4dbc0aabc7
@ -7,6 +7,8 @@ Imports DigitalData.Modules.Logging
|
||||
Public Class Window
|
||||
Private _Logger As Logger
|
||||
|
||||
Private Const WINDOW_SNAP_OFFSET = 35
|
||||
|
||||
Public Enum Anchor
|
||||
TopLeft
|
||||
BottomLeft
|
||||
@ -387,4 +389,89 @@ Public Class Window
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
|
||||
<StructLayout(LayoutKind.Sequential)>
|
||||
Public Structure WINDOWPOS
|
||||
Public hwnd As IntPtr
|
||||
Public hwndInsertAfter As IntPtr
|
||||
Public x As Integer
|
||||
Public y As Integer
|
||||
Public cx As Integer
|
||||
Public cy As Integer
|
||||
Public flags As Integer
|
||||
End Structure
|
||||
|
||||
Public Shared Sub SnapToDesktopBorder(pForm As Form, pLParam As IntPtr, Optional pWidthAdjustment As Integer = 0)
|
||||
If pForm Is Nothing Then
|
||||
' Satisfies rule: Validate parameters
|
||||
Throw New ArgumentNullException("pForm")
|
||||
End If
|
||||
|
||||
' Snap client to the top, left, bottom or right desktop border
|
||||
' as the form is moved near that border
|
||||
Try
|
||||
' Marshal the LPARAM value which is a WINDOWPOS struct
|
||||
Dim oNewPosition As New WINDOWPOS
|
||||
oNewPosition = CType(Marshal.PtrToStructure(pLParam, GetType(WINDOWPOS)), WINDOWPOS)
|
||||
|
||||
If oNewPosition.y = 0 OrElse oNewPosition.x = 0 Then
|
||||
Return ' Nothing to do!
|
||||
End If
|
||||
|
||||
' Adjust the client size for borders and caption bar
|
||||
Dim oClientRect As Rectangle = pForm.RectangleToScreen(pForm.ClientRectangle)
|
||||
oClientRect.Width += SystemInformation.FrameBorderSize.Width - pWidthAdjustment
|
||||
oClientRect.Height += (SystemInformation.FrameBorderSize.Height + SystemInformation.CaptionHeight)
|
||||
|
||||
' Now get the screen working area (without taskbar)
|
||||
Dim oWorkingRect As Rectangle = System.Windows.Forms.Screen.GetWorkingArea(pForm.ClientRectangle)
|
||||
|
||||
' Left border
|
||||
If oNewPosition.x >= oWorkingRect.X - WINDOW_SNAP_OFFSET AndAlso
|
||||
oNewPosition.x <= oWorkingRect.X + WINDOW_SNAP_OFFSET Then
|
||||
oNewPosition.x = oWorkingRect.X
|
||||
End If
|
||||
|
||||
' Get screen bounds and taskbar height
|
||||
' (when taskbar is horizontal)
|
||||
Dim oScreenRect As Rectangle = System.Windows.Forms.Screen.GetBounds(System.Windows.Forms.Screen.PrimaryScreen.Bounds)
|
||||
Dim oTaskbarHeight As Integer = oScreenRect.Height - oWorkingRect.Height
|
||||
|
||||
' Top border (check if taskbar is on top
|
||||
' or bottom via WorkingRect.Y)
|
||||
If oNewPosition.y >= -WINDOW_SNAP_OFFSET AndAlso
|
||||
(oWorkingRect.Y > 0 AndAlso oNewPosition.y <=
|
||||
(oTaskbarHeight + WINDOW_SNAP_OFFSET)) OrElse
|
||||
(oWorkingRect.Y <= 0 AndAlso oNewPosition.y <=
|
||||
(WINDOW_SNAP_OFFSET)) Then
|
||||
If oTaskbarHeight > 0 Then
|
||||
oNewPosition.y = oWorkingRect.Y ' Horizontal Taskbar
|
||||
Else
|
||||
oNewPosition.y = 0 ' Vertical Taskbar
|
||||
End If
|
||||
End If
|
||||
|
||||
' Right border
|
||||
If oNewPosition.x + oClientRect.Width <=
|
||||
oWorkingRect.Right + WINDOW_SNAP_OFFSET AndAlso
|
||||
oNewPosition.x + oClientRect.Width >=
|
||||
oWorkingRect.Right - WINDOW_SNAP_OFFSET Then
|
||||
oNewPosition.x = oWorkingRect.Right - (oClientRect.Width +
|
||||
SystemInformation.FrameBorderSize.Width)
|
||||
End If
|
||||
|
||||
' Bottom border
|
||||
If oNewPosition.y + oClientRect.Height <=
|
||||
oWorkingRect.Bottom + WINDOW_SNAP_OFFSET AndAlso
|
||||
oNewPosition.y + oClientRect.Height >=
|
||||
oWorkingRect.Bottom - WINDOW_SNAP_OFFSET Then
|
||||
oNewPosition.y = oWorkingRect.Bottom - (oClientRect.Height +
|
||||
SystemInformation.FrameBorderSize.Height)
|
||||
End If
|
||||
|
||||
' Marshal it back
|
||||
Marshal.StructureToPtr(oNewPosition, pLParam, True)
|
||||
Catch ex As ArgumentException
|
||||
End Try
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user