Search code examples
vb.netformswindowstate

VB.NET - Move form to next monitor and maximise


Does anyone know how to move a form to the next window to the right (or cycle around if current monitor is the last one) and maximize it? I've been playing around and written some code (self taught, so please be kind) which moves the form if it is in a "Normal" windowstate, but I'm stuck on the maximizing part. I would have thought WindowState = Maximized would do it, but setting that on the form results in the move function not responding.

Below is the code I have so far:

Module Monitor

    Public totalMonitors As Integer = System.Windows.Forms.Screen.AllScreens.Count

    Private xPositionForMonitors As New Dictionary(Of Integer, Integer)
    Private yPositionForMonitors As New Dictionary(Of Integer, Integer)
    Private currentMonitorIndex As Integer
    Private newMonitorIndex As Integer

    Public Sub buildMonitorArray()

        For m As Integer = 0 To (totalMonitors - 1)
            xPositionForMonitors.Add(m, System.Windows.Forms.Screen.AllScreens(m).WorkingArea.Location.X)
            yPositionForMonitors.Add(m, System.Windows.Forms.Screen.AllScreens(m).WorkingArea.Location.Y)
        Next

    End Sub

    Public Sub moveToNextMonitor(targWindow As Form)

        identifyCurrentMonitor(targWindow)
        targWindow.SetDesktopLocation(xPositionForMonitors(newMonitorIndex) + 1, 0)

    End Sub

    Private Sub identifyCurrentMonitor(targWindow As Form)

        For c As Integer = 0 To (totalMonitors - 1)
            If targWindow.Location.X + 10 > xPositionForMonitors(c) Then
                currentMonitorIndex = c
            End If
        Next

        newMonitorIndex = currentMonitorIndex + 1
        If newMonitorIndex = totalMonitors Then newMonitorIndex = 0

    End Sub

End Module

Currently, I'm calling the buildMonitorArray function on form load, and then using moveToNextMonitor(Me) on the form.


Solution

  • You need to set the WindowState to Normal before you move it and then set it back to its original state once it is moved. I have converted your code to a class so that you don't have to worry about calling the buildMonitorArray method before you move any forms. To call your method, you will need to call Monitor.moveToNextMonitor since this is now a class. If you still prefer to use a module, then you can just port the code changes over into your module and it should still work the same way.

    Public Class Monitor
    
    Shared Sub New()
        buildMonitorArray()
    End Sub
    
    Public Shared totalMonitors As Integer = System.Windows.Forms.Screen.AllScreens.Count
    
    Private Shared xPositionForMonitors As New Dictionary(Of Integer, Integer)
    Private Shared yPositionForMonitors As New Dictionary(Of Integer, Integer)
    
    Public Shared Sub buildMonitorArray()
        For m As Integer = 0 To (totalMonitors - 1)
            xPositionForMonitors.Add(m, System.Windows.Forms.Screen.AllScreens(m).WorkingArea.Location.X)
            yPositionForMonitors.Add(m, System.Windows.Forms.Screen.AllScreens(m).WorkingArea.Location.Y)
        Next
    End Sub
    
    Public Shared Sub moveToNextMonitor(targWindow As Form)
        Dim newMonitorIndex As Integer = identifyCurrentMonitor(targWindow)
        Dim originalState = targWindow.WindowState
        Try
            If originalState <> FormWindowState.Normal Then
                targWindow.WindowState = FormWindowState.Normal
            End If
            targWindow.SetDesktopLocation(xPositionForMonitors(newMonitorIndex) + 1, 0)
        Finally
            targWindow.WindowState = originalState
        End Try
    End Sub
    
    Private Shared Function identifyCurrentMonitor(targWindow As Form) As Integer
        Dim currentMonitorIndex As Integer
        Dim newMonitorIndex As Integer
        For c As Integer = 0 To (totalMonitors - 1)
            If targWindow.Location.X + 10 > xPositionForMonitors(c) Then
                currentMonitorIndex = c
            End If
        Next
    
        newMonitorIndex = currentMonitorIndex + 1
        If newMonitorIndex = totalMonitors Then newMonitorIndex = 0
        Return newMonitorIndex
    End Function
    
    End Class