Just run this prior to starting up VirtualBox (it will leave an icon in the system tray if you want to kill it)
Code: Select all
#include <MsgBoxConstants.au3>
#include <Array.au3>
AutoItSetOption ( "WinTitleMatchMode", 2 ) ; Default to match on partial name (anything that matches the pattern Oracle VM VirtualBox :)
; Declare 2D arrays to hold window state information
; The IS array holds the most current window state And
; then compares it against the WAS array
Local $isState[0][2], $wasState[0][2]
; Get initial window data
GetVMWindows($isState, $wasState)
Dim $partial_title ; holds split up title that matches similar windows
; Loop indefinately looking for changes every quarter second, on every 10th loop, reinitialize the window data
$count = 0
While (1)
For $i = 0 To _ArrayMaxIndex ($isState)
; switch over to using the exact title of the window otherwise AutoIt just uses the most recent match
AutoItSetOption ( "WinTitleMatchMode", 3 )
; get the minimize (16) and maximize (32) states of the window
$isState[$i][1] = BitAnd(WinGetState($isState[$i][0] ),16)+BitAnd(WinGetState($isState[$i][0] ),32)
; if the window state has changed since the last check update the state of the other matching windows
ConsoleWrite ($isState[$i][1] & " = " & $wasState[$i][1] & @CRLF)
If ($isState[$i][1] <> $wasState[$i][1]) Then
$partial_title = StringSplit ( $isState[$i][0], " : ", 1) ; the title without the : 1, : 2, etc
SetWindowState($isState[$i][1], $isState, $wasState, $isState[$i][0], $partial_title[1])
EndIf
Next
; If this is the 10th time through reset count and update window data in case new windows were added or changed titles
If $count = 10 Then
$count = 1
GetVMWindows($isState, $wasState)
Else
$count = $count + 1
EndIF
; wait a quarter second
Sleep(250)
WEnd
; Gets the title and state for windows that are multiple monitor VMs. This is done for the "IS" and for the "WAS" arrays
Func GetVMWindows(ByRef $iState, ByRef $wState)
; Retrieve a list of window handles that match anything with "Oracle VM Virtual Box :" (the semicolon is a giveaway that it's a multiple monitor VM
AutoItSetOption ( "WinTitleMatchMode", 2 )
; Clean out anything in the array already from 0 to the size of the array
_ArrayDelete($iState, "0-"&_ArrayMaxIndex ($iState)+1)
_ArrayDelete($wState, "0-"&_ArrayMaxIndex ($wState)+1)
; Get any windows that are Virtual Box multiple monitor windows
Local $vmWindows = WinList("Oracle VM VirtualBox :")
; Loop through the array displaying only visable windows with a title.
For $i = 1 To $vmWindows[0][0]
If $vmWindows[$i][0] <> "" And BitAND(WinGetState($vmWindows[$i][1]), 2) Then
; get the minimize (16) and maximize (32) states of the window
Local $simpleState = BitAnd(WinGetState($vmWindows[$i][0] ),16)+BitAnd(WinGetState($vmWindows[$i][0] ),32)
; add title into secondary index 0 and state into secondary index 1 of the array
_ArrayAdd($iState, $vmWindows[$i][0]&"|"& $simpleState , 0)
_ArrayAdd($wState, $vmWindows[$i][0]&"|"& $simpleState , 0)
EndIf
Next
EndFunc
; Determines if the windows all need to be minimized, maximized or restored (a size that isn't maximized but still visible)
Func SetWindowState($stateToSet, ByRef $IsStateArray, ByRef $WasStateArray, $windowTitle, $matchTitle)
Local $partial_title
; Look through all windows in the array
For $i = 0 to _ArrayMaxIndex ($IsStateArray)
$partial_title = StringSplit ( $IsStateArray[$i][0], " : ", 1)
; if it's a window belonging to the set of windows for a particular VM
If $partial_title[1]=$matchTitle Then
; Set the matching to be exact, otherwise it just grabs whatever window was last open
AutoItSetOption ( "WinTitleMatchMode", 3 )
; If a window was maximized, maximize all windows
If BitAND ( $stateToSet, 32 ) Then
WinSetState($IsStateArray[$i][0],"", @SW_MAXIMIZE)
;WinActivate($IsStateArray[$i][0],"")
; If a window was minimized, minimize all similar windows
ElseIf BitAND ( $stateToSet, 16 ) Then
WinSetState($IsStateArray[$i][0],"", @SW_MINIMIZE)
; If a window was restored (not maximized or minimized) restore the other windows (not the one you restored or it will go back to maximized)
ElseIf $stateToSet = 0 and $IsStateArray[$i][0] <> $windowTitle Then
WinSetState($IsStateArray[$i][0],"", @SW_RESTORE)
EndIf
; Update all the window states to the current state
$IsStateArray[$i][1] = $stateToSet
$WasStateArray[$i][1] = $stateToSet
EndIf
Next
EndFunc