My solution to minimizing/maximizing all "monitors" at once
Posted: 23. Mar 2015, 18:38
It has always bothered me that if I am running a multi-monitor VM that VirtualBox can't just minimize the other monitors if I minimize one. I used AutoIt (a small little scripting automation language available at https://www.autoitscript.com/site/autoit/) to put this together. I'm attaching the code below if you want to tweak it or compile it yourself and I attempted to attach a zip with a compiled .exe file.
Just run this prior to starting up VirtualBox (it will leave an icon in the system tray if you want to kill it)
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