SkaziChris Posted March 16, 2019 Share Posted March 16, 2019 Hello, Situation: I have 4-screen setup. I work via citrix session that is stretched across 2 monitors, but inside the session, it acts like a one single big monitor. So, whenever you press Maximize button in any app, it maximizes across 2 monitors ;/ So, I wrote a little UDF that identifies active windows that have size bigger than the screen VRES of 1 display, and then, it places the window on proper monitor (F9 -> left, F10 -> right). However, the script works fine for 5-10 minutes, and then fails with: Line 4086 (File <exe path>): Error: Subscript used on non-accessible variable. I have added IsHwnd checks, but this didn't help. Would you be so kind and help me pinpoint the issue? expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=add_tab_ol_512_swy_icon.ico #AutoIt3Wrapper_Outfile=Citrix_MaintainWindows_v1_x86.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <EditConstants.au3> ; *** End added by AutoIt3Wrapper *** #include <ImageSearch.au3> #include <MsgBoxConstants.au3> #include <GUIConstantsEx.au3> #Include <GUIEdit.au3> #include <WinAPI.au3> GUISetIcon("add_tab_ol_512_swy_icon.ico") TraySetIcon("add_tab_ol_512_swy_icon.ico") Global $y = 0, $x = 0 Global $temp_x = 0, $temp_y = 0 Global $_hWnd = "null" Global $try = 0 Global $error = "false" Global $msgx = "null" Global $Paused Global $EditBox1, $EditBox2 Global $monitor1resX=1680 Global $monitor1resY=990 Global $monitor2resX=1280 Global $monitor2resY=990 Global $currWindowPosX=0 Global $currWindowPosY=0 Global $msgtxt HotKeySet("{PAUSE}", "TogglePause") Func TogglePause() $Paused = NOT $Paused While $Paused sleep(100) ToolTip('Script is "Paused = SCRIPT IS NOT RUNNING = you wont get another message if you dont unpause it"',0,0) WEnd ToolTip("") EndFunc Func Terminate() Exit 0 EndFunc Func MoveLeft() Send("{F9}") ;This will move the app to the left screen by an external app (with F9 kb shortcut) Sleep(1000) EndFunc Func MoveRight() Send("{F10}") ;This will move the app to the left screen by an external app (with F10 kb shortcut) Sleep(1000) EndFunc Func MaintainWindowSize() ; windows that should be put on the LEFT side: $lewe = "Notepad;Word;Excel;Outlook;Explorer;Chrome;DBInventory;Message ;null" $array_left=StringSplit($lewe, ";") ; windows that should be put on the RIGHT side: $prawe = "SQL*Security;Oracle Centralized Security;Putty;Oracle SQL Developer" $array_right=StringSplit($prawe, ";") ; windows classes that should be put on the RIGHT side: $praweCl = "TMobaXtermForm;null" $array_rightCl=StringSplit($praweCl, ";") ; windows classes that should be put on the LEFT side: $leweCl = "ExploreWClass;CabinetWClass;null" $array_leftCl=StringSplit($leweCl, ";") $hw = WinActive("","") if IsHWnd($hw) Then WinActivate($hw) $wT=WinGetTitle( "[ACTIVE]" ) $aWindowSize = WinGetClientSize($hw) $width=$aWindowSize[0] else break EndIf ;resolution of the citrix session: 3340x1010 ;each monitor has res 1680x1050 ;so, if the app window has Vsize bigger than 2000, this means it is stretched to more than 1 monitor. ;therefore, position that window to the right monitor... if $width > 2000 Then ; wT=window titile if IsHWnd($hw) Then WinSetState($hw,"",@SW_RESTORE) $wT=WinGetTitle( "[ACTIVE]" ) $wC=_WinAPI_GetClassName($hw) else break EndIf ;MsgBox($MB_SYSTEMMODAL, "", $wC) For $i = 1 to $array_left[0] If stringinstr($wT , $array_left[$i]) Then MoveLeft() EndIf Next For $j = 1 to $array_right[0] If stringinstr($wT , $array_right[$j]) Then MoveRight() EndIf Next For $k = 1 to $array_rightCl[0] If stringinstr($wC , $array_rightCl[$k]) Then MoveRight() EndIf Next For $l = 1 to $array_leftCl[0] If stringinstr($wC , $array_leftCl[$l]) Then MoveLeft() EndIf Next EndIf EndFunc Func Main() While Not @error; Try MaintainWindowSize() Sleep(100) WEnd If @error Then; Catch MaintainWindowSize() EndIf EndFunc ;==>Main Main() Link to comment Share on other sites More sharing options...
SkaziChris Posted March 16, 2019 Author Share Posted March 16, 2019 Visualisation attached. Link to comment Share on other sites More sharing options...
Bilgus Posted March 17, 2019 Share Posted March 17, 2019 (edited) Can't really test it for you but how is this? expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=add_tab_ol_512_swy_icon.ico #AutoIt3Wrapper_Outfile=Citrix_MaintainWindows_v1_x86.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <EditConstants.au3> ; *** End added by AutoIt3Wrapper *** ;#include <ImageSearch.au3> #include <MsgBoxConstants.au3> #include <GUIConstantsEx.au3> #include <GUIEdit.au3> #include <WinAPI.au3> GUISetIcon("add_tab_ol_512_swy_icon.ico") TraySetIcon("add_tab_ol_512_swy_icon.ico") Global $y = 0, $x = 0 Global $temp_x = 0, $temp_y = 0 Global $_hWnd = "null" Global $try = 0 Global $error = "false" Global $msgx = "null" Global $bPaused Global $EditBox1, $EditBox2 Global $monitor1resX = 1680 Global $monitor1resY = 990 Global $monitor2resX = 1280 Global $monitor2resY = 990 Global $currWindowPosX = 0 Global $currWindowPosY = 0 Global $msgtxt HotKeySet("{PAUSE}", "TogglePause") Func TogglePause() $bPaused = Not $bPaused While $bPaused Sleep(100) ToolTip('Script is "Paused = SCRIPT IS NOT RUNNING = you wont get another message if you dont unpause it"', 0, 0) WEnd ToolTip("") EndFunc ;==>TogglePause Func Terminate() Exit 0 EndFunc ;==>Terminate Func MoveLeft() Send("{F9}") ;This will move the app to the left screen by an external app (with F9 kb shortcut) ConsoleWrite("Move Left" & @CRLF) Sleep(1000) EndFunc ;==>MoveLeft Func MoveRight() Send("{F10}") ;This will move the app to the left screen by an external app (with F10 kb shortcut) ConsoleWrite("Move Right" & @CRLF) Sleep(1000) EndFunc ;==>MoveRight Func MaintainWindowSize() ; windows that should be put on the LEFT side: ;I'd probably move these global and only update them in another function making them static for now.... Static Local $sLeftWinTitles = "Notepad;Word;Excel;Outlook;Explorer;Chrome;DBInventory;Message ;null" Static Local $aLeft = StringSplit($sLeftWinTitles, ";") ; windows that should be put on the RIGHT side: Static Local $sRightWinTitles = "SQL*Security;Oracle Centralized Security;Putty;Oracle SQL Developer" Static Local $aRight = StringSplit($sRightWinTitles, ";") ; windows classes that should be put on the RIGHT side: Static Local $sRightWinClasses = "TMobaXtermForm;null" Static Local $aRightCL = StringSplit($sRightWinClasses, ";") ; windows classes that should be put on the LEFT side: Static Local $sLeftWinClasses = "ExploreWClass;CabinetWClass;null" Static Local $aLeftCL = StringSplit($sLeftWinClasses, ";") ;;; Static Local $hWnd_Last = 0 ;Save last active Window so we don't check endlessly Local $sTitle, $aWindowSize, $iWidth, $sClass Local $hWnd = WinGetHandle("[ACTIVE]", "") If IsHWnd($hWnd) And $hWnd <> $hWnd_Last Then $hWnd_Last = $hWnd ;WinActivate($hWnd);Probably Not Needed?? $sTitle = WinGetTitle($hWnd) $aWindowSize = WinGetClientSize($hWnd) If @error Or Not IsArray($aWindowSize) Then Return SetError(1, 0, "") $iWidth = $aWindowSize[0] Else Return ;break EndIf ;resolution of the citrix session: 3340x1010 ;each monitor has res 1680x1050 ;so, if the app window has Vsize bigger than 2000, this means it is stretched to more than 1 monitor. ;therefore, position that window to the right monitor... If $iWidth > 2000 Then If IsHWnd($hWnd) Then WinSetState($hWnd, "", @SW_RESTORE) ;$sTitle = WinGetTitle($hWnd);Already have the title $sClass = _WinAPI_GetClassName($hWnd) Else Return ;break EndIf ;MsgBox($MB_SYSTEMMODAL, "", $sClass) If IsArray($aLeft) Then For $i = 1 To $aLeft[0] If StringInStr($sTitle, $aLeft[$i]) Then MoveLeft() EndIf Next Else Return SetError(2, 0, "") EndIf If IsArray($aRight) Then For $j = 1 To $aRight[0] If StringInStr($sTitle, $aRight[$j]) Then MoveRight() EndIf Next Else Return SetError(3, 0, "") EndIf If IsArray($aRightCL) Then For $k = 1 To $aRightCL[0] If StringInStr($sClass, $aRightCL[$k]) Then MoveRight() EndIf Next Else Return SetError(4, 0, "") EndIf If IsArray($aLeftCL) Then For $l = 1 To $aLeftCL[0] If StringInStr($sClass, $aLeftCL[$l]) Then MoveLeft() EndIf Next Else Return SetError(5, 0, "") EndIf EndIf EndFunc ;==>MaintainWindowSize Func Main() Local $iError = 0 While Not $iError ; Try MaintainWindowSize() $iError = @error Sleep(100) WEnd If $iError Then ; Catch MsgBox(0, "Error", $iError) ;MaintainWindowSize() EndIf EndFunc ;==>Main Main() Edited March 17, 2019 by Bilgus SkaziChris 1 Link to comment Share on other sites More sharing options...
SkaziChris Posted March 17, 2019 Author Share Posted March 17, 2019 Thanks so much Bilgus!!! Following part: If IsHWnd($hWnd) And $hWnd <> $hWnd_Last Then + corrected error handling fixed it!!! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now