BatMan22 Posted August 25, 2018 Share Posted August 25, 2018 So my program below, watches for a certain window, and if a value in that window is over a certain value (CheckValue function), then attempts to fix the situation are made (PumpFix function). Now one of my problems with this program was that WinSelect wasn't working and the functions "Func _GetICNetMDIWindows()" and the function "Func _GetMDIHandlebyTitle($sTitle)" became necessary to select and activate the correct windows. The program works amazingly 95% of the time but 5% of the time if I open/close windows at the wrong time then I get a redim error... I'm not sure of the exact cause of this and what to do to fix it.. Ideas? expandcollapse popup#RequireAdmin #include <Array.au3> #include <WinAPISys.au3> #include <Misc.au3> #include <MsgBoxConstants.au3> #include <String.au3> #include <ScreenCapture.au3> Global $sBetweenme = "Ch2" & @LF ; basically what channel to search Global $sAndme = @LF & "mV" ; millivolts Global $Limit = 55 ; Panic over this value Global $aMDIWindows[0] Global $sParentWindowTitle = "IC Net" ; Program name, shouldn't ever change but Just In Case! Global $jpgsavelocation = "\\Ic2\PUBLIC\MacroShare\FML.jpg" ; Where to save screenshot! Global $quewindowprefix = "C:\Program Files\Metrohm\IC Net 2.2\IC Net\" ; Just the prefix before the xxxxxx.que Global $fullsystempathandname = "C:\Program Files\Metrohm\IC Net 2.2\IC Net\Systems\HPUV\HPuv_0405_ASFIXED.smt" ; FULL PATH AND SYSTEM NAME THAT YOU ARE USING! Global $systemnameonly = "HPUV\HPuv_0405_ASFIXED.smt" ; Just your system name Global $pumpnamewindow = "DPC Pump(HPUV\HPuv_0405_ASFIXED.smt)" ; Name of window when you double click pump Global $secondtopurgeDPCpump = "30000" ; 20 seconds Global $checkeveryXseconds = 15 _GetICNetMDIWindows() ; first window grab $checkeveryXseconds = $checkeveryXseconds * 1000 Local $i = 0 While $i = 0 ConsoleWrite("Check every: " & $checkeveryXseconds & "ms's" & @CRLF) Sleep($checkeveryXseconds) ; Check every X milliseconds! 1000 = 1second CheckValue() WEnd Func CheckValue() Local $sText = ControlGetText(_GetMDIHandlebyTitle("Watch window"), "", "MLCRangeColor7") If @error = 1 Then Sleep(5000) _GetICNetMDIWindows() ;~ Sleep(3000) ConsoleWrite("First read failed, trying again."& @CRLF) Local $sText = ControlGetText(_GetMDIHandlebyTitle("Watch window"), "", "MLCRangeColor7") If @error = 1 Then WindowFinder() EndIf EndIf ConsoleWrite("Current Reading is " & $sText & "mV" & @CRLF) TrayTip("mV reading is: ", $sText, 10) If $sText > $Limit Then _ScreenCapture_Capture($jpgsavelocation) PumpFix() Sleep(30000) EndIf EndFunc ;==>CheckValue Func WindowFinder() ConsoleWrite("ControlGetText fail/not found. Window Finder function launched." & @CRLF) _GetICNetMDIWindows() Local $sText = ControlGetText(_GetMDIHandlebyTitle("Watch window"), "", "MLCRangeColor7") If @error = 0 Then ConsoleWrite("Found the window after launching Window Finder function, no other action needed." & @CRLF) Return 0 EndIf If WinExists(_GetMDIHandlebyTitle($systemnameonly)) Then ConsoleWrite($systemnameonly & " Window Exist!" & @CRLF) Sleep(1000) _GetICNetMDIWindows() Local $sText = ControlGetText(_GetMDIHandlebyTitle("Watch window"), "", "MLCRangeColor7") If @error = 1 Then _GetICNetMDIWindows() WinActivate(_GetMDIHandlebyTitle($systemnameonly)) ;activate the System window ControlClick(_GetMDIHandlebyTitle($systemnameonly), "", "CCBitmap1", "left", 2) ; SystemValuesScreen _GetICNetMDIWindows() Local $sText = ControlGetText(_GetMDIHandlebyTitle("Watch window"), "", "MLCRangeColor7") EndIf Else ConsoleWrite($systemnameonly & " Window doesn't Exist!" & @CRLF) WinActivate("IC Net") Send("!o") Sleep(200) Send("{Escape}") Sleep(200) Send("{Escape}") Sleep(5000) WinMenuSelectItem("IC Net", "", "&Options", "HPUV\") ; Open Chomatogram Window Sleep(200) _GetICNetMDIWindows() ;~ Sleep(200) If WinExists(_GetMDIHandlebyTitle($systemnameonly)) Then WindowFinder() Else MsgBox(0, 0, "Failed at openening system window!") EndIf EndIf EndFunc ;==>WindowFinder Func ValueNotFound() ConsoleWrite("VNF Started") If WinExists(_GetMDIHandlebyTitle($systemnameonly)) Then ConsoleWrite($systemnameonly & "Window Exist!") _GetICNetMDIWindows() WinActivate(_GetMDIHandlebyTitle($systemnameonly)) ;activate the System window ControlClick(_GetMDIHandlebyTitle($systemnameonly), "", "CCBitmap1", "left", 2) ; Open Pump _GetICNetMDIWindows() Local $sText = ControlGetText(_GetMDIHandlebyTitle("Watch window"), "", "MLCRangeColor7") MsgBox(0, 0, $sText) Else ConsoleWrite($systemnameonly & "Window doesn't Exist!") WinActivate("IC Net") Sleep(200) WinMenuSelectItem("IC Net", "", "&Options", "HPUV\HPuv_0405_ASFIXED.smt") ; Open Chomatogram Window Sleep(200) _GetICNetMDIWindows() ;~ Sleep(200) If WinExists(_GetMDIHandlebyTitle($systemnameonly)) Then ValueNotFound() Else MsgBox(0, 0, "Failed at openening system window!") EndIf EndIf EndFunc ;==>ValueNotFound Func _SendEx($ss, $warn = "") ; prevent stuck keys! Local $iT = TimerInit() While _IsPressed("10") Or _IsPressed("11") Or _IsPressed("12") If $warn <> "" And TimerDiff($iT) > 1000 Then MsgBox($MB_TOPMOST, "Warning", $warn) EndIf Sleep(50) WEnd Send($ss) EndFunc ;==>_SendEx Func PumpFix() _GetICNetMDIWindows() ;this will get All the required MDI Childs windows ;~ _ArrayDisplay($aMDIWindows);show all the Childs windows If Not IsArray($aMDIWindows) Then Exit MsgBox(0, "Error", "IC Net isn't open sucka?") WinActivate(_GetMDIHandlebyTitle($quewindowprefix)) ;activate the Que window Sleep(300) ;~ ControlClick(_GetMDIHandlebyTitle($quewindowprefix), "", "Button4", "left", 1) ; Pause The Sequence WinMenuSelectItem(_GetMDIHandlebyTitle($quewindowprefix), "", "&Control", "Pause...") ; Pause The Sequence Sleep(300) WinActivate("IC Net") WinMenuSelectItem("IC Net", "", "&File", "&Open", "&System") ; Open System just in case it's closed Sleep(300) _SendEx($fullsystempathandname) Sleep(300) _SendEx("{Enter}") ;~ MouseClick("primary", 572, 59, 1) Sleep(500) _GetICNetMDIWindows() ;Refresh Open Windows Sleep(450) WinActivate(_GetMDIHandlebyTitle($systemnameonly)) ;activate the System window Sleep(400) ;~ MsgBox(0,0,"HPUV Activated") WinActivate(_GetMDIHandlebyTitle($systemnameonly)) ;activate the System window Sleep(400) WinMenuSelectItem(_GetMDIHandlebyTitle($systemnameonly), "", "&Control", "Sto&p determination") ; Stop Determination, duh. ;~ _SendEx("!cp"); Stop Single Run Sleep(400) ControlClick(_GetMDIHandlebyTitle($systemnameonly), "", "CCBitmap8", "left", 2) ; Open Pump Sleep(1000) _GetICNetMDIWindows() ;Refresh Open Windows Sleep(1000) WinActivate(_GetMDIHandlebyTitle($pumpnamewindow)) Sleep(1000) ControlSetText(_GetMDIHandlebyTitle($pumpnamewindow), "", "Edit3", "5.0") ; Set Pump to 5.0 Speed Sleep(1000) ControlClick(_GetMDIHandlebyTitle("Settings"), "", "Button6", "left", 1) ; ClickSetInthe"Settings"window Sleep($secondtopurgeDPCpump) ControlSetText(_GetMDIHandlebyTitle($pumpnamewindow), "", "Edit3", "0.2") ; Set Pump to 5.0 Speed Sleep(1000) ControlClick(_GetMDIHandlebyTitle("Settings"), "", "Button6", "left", 1) ; ClickSetInthe"Settings"window Sleep(1000) ControlClick(_GetMDIHandlebyTitle($quewindowprefix), "", "Button3", "left", 1) ; Start The Sequence Sleep(1000) _SendEx("!n") EndFunc ;==>PumpFix Func _GetICNetMDIWindows() Local $hParentWindow = WinActivate("IC Net") Local $aData = _WinAPI_EnumChildWindows($hParentWindow) ;~ _ArrayDisplay($aData) If IsArray($aData) Then ReDim $aMDIWindows[$aData[0][0]][2] ;handle;title Local $iIndexBound = 0 For $i = 1 To $aData[0][0] If StringInStr($aData[$i][1], "#32770") Then ;~ ConsoleWrite(WinGetTitle($aData[$i][0]) & @CRLF) $aMDIWindows[$iIndexBound][0] = $aData[$i][0] $aMDIWindows[$iIndexBound][1] = WinGetTitle($aData[$i][0]) $iIndexBound += 1 EndIf Next ReDim $aMDIWindows[$iIndexBound][2] If Not UBound($aMDIWindows) Then $aMDIWindows = 0 EndIf EndFunc ;==>_GetICNetMDIWindows Func _GetMDIHandlebyTitle($sTitle) Local $iFind = _ArraySearch($aMDIWindows, $sTitle, 0, 0, 0, 1) If $iFind > -1 Then Return $aMDIWindows[$iFind][0] Else Return 0 EndIf EndFunc ;==>_GetMDIHandlebyTitle Link to comment Share on other sites More sharing options...
Simpel Posted August 25, 2018 Share Posted August 25, 2018 (edited) Hi. It's not a runnable reproducer for me you gave us but maybe I got the point. Function _GetICNetMDIWindows() has the following line: If Not UBound($aMDIWindows) Then $aMDIWindows = 0 That destroys the array. Example: #include <Array.au3> Example() Example2() Func Example() Local $aArray[1] For $i = 0 To 100 ReDim $aArray[UBound($aArray) + 1] $aArray[$i] = $i Next _ArrayDisplay($aArray) EndFunc Func Example2() Local $aArray[1] $aArray = 0 ; ############################ That's the point For $i = 0 To 100 ReDim $aArray[UBound($aArray) + 1] $aArray[$i] = $i Next _ArrayDisplay($aArray) EndFunc You used _GetICNetMDIWindows() so many times (in which suddenly $aMDIWindows could be zero and destroyed) but you only test inside function PumpFix() IsArray($aMDIWindows). So probably you call _GetICNetMDIWindows() which at any time sets $aMDIWindows = 0 and then you call _GetICNetMDIWindows() again without checking IsArray($aMDIWindows) and chrashes. Simpel Edited August 25, 2018 by Simpel BatMan22 1 SciTE4AutoIt = 3.7.3.0 AutoIt = 3.3.14.2 AutoItX64 = 0 OS = Win_10 Build = 19044 OSArch = X64 Language = 0407/german H:\...\AutoIt3\SciTE H:\...\AutoIt3 H:\...\AutoIt3\Include (H:\ = Network Drive) Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. Link to comment Share on other sites More sharing options...
Simpel Posted August 25, 2018 Share Posted August 25, 2018 Maybe this is a reproducer stripped down to the main problem: #include <WinAPISys.au3> #include <Array.au3> Global $aMDIWindows[0] For $i = 1 To 10000 ConsoleWrite($i & @CRLF) _GetICNetMDIWindows() ; first window grab Next Func _GetICNetMDIWindows() Local $hParentWindow = WinActivate("Unbenannt") ; Notepad Local $aData = _WinAPI_EnumChildWindows($hParentWindow) _ArrayDisplay($aData) If IsArray($aData) Then ReDim $aMDIWindows[$aData[0][0]][2] ;handle;title Local $iIndexBound = 0 For $i = 1 To $aData[0][0] If StringInStr($aData[$i][1], "#32770") Then $aMDIWindows[$iIndexBound][0] = $aData[$i][0] $aMDIWindows[$iIndexBound][1] = WinGetTitle($aData[$i][0]) $iIndexBound += 1 EndIf Next ReDim $aMDIWindows[$iIndexBound][2] _ArrayDisplay($aMDIWindows) If Not UBound($aMDIWindows) Then ConsoleWrite("Not Ubound" & @CRLF) $aMDIWindows = 0 EndIf EndIf EndFunc ;==>_GetICNetMDIWindows Simpel BatMan22 1 SciTE4AutoIt = 3.7.3.0 AutoIt = 3.3.14.2 AutoItX64 = 0 OS = Win_10 Build = 19044 OSArch = X64 Language = 0407/german H:\...\AutoIt3\SciTE H:\...\AutoIt3 H:\...\AutoIt3\Include (H:\ = Network Drive) Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. Link to comment Share on other sites More sharing options...
BatMan22 Posted August 27, 2018 Author Share Posted August 27, 2018 On 8/25/2018 at 1:30 AM, Simpel said: Maybe this is a reproducer stripped down to the main problem: #include <WinAPISys.au3> #include <Array.au3> Global $aMDIWindows[0] For $i = 1 To 10000 ConsoleWrite($i & @CRLF) _GetICNetMDIWindows() ; first window grab Next Func _GetICNetMDIWindows() Local $hParentWindow = WinActivate("Unbenannt") ; Notepad Local $aData = _WinAPI_EnumChildWindows($hParentWindow) _ArrayDisplay($aData) If IsArray($aData) Then ReDim $aMDIWindows[$aData[0][0]][2] ;handle;title Local $iIndexBound = 0 For $i = 1 To $aData[0][0] If StringInStr($aData[$i][1], "#32770") Then $aMDIWindows[$iIndexBound][0] = $aData[$i][0] $aMDIWindows[$iIndexBound][1] = WinGetTitle($aData[$i][0]) $iIndexBound += 1 EndIf Next ReDim $aMDIWindows[$iIndexBound][2] _ArrayDisplay($aMDIWindows) If Not UBound($aMDIWindows) Then ConsoleWrite("Not Ubound" & @CRLF) $aMDIWindows = 0 EndIf EndIf EndFunc ;==>_GetICNetMDIWindows Simpel Ah, I think you're right. I didn't do a simple isarray check. sooo.. error when it attempts to redim it. Thanks man Link to comment Share on other sites More sharing options...
BatMan22 Posted August 28, 2018 Author Share Posted August 28, 2018 I guess I'm still confused, because isn't setting $aMDIWindows = 0 just basically deleting the array and then the next time the function _GetICNetMDIWindows() it gets re-made? Why does it error out? What am I doing wrong? Link to comment Share on other sites More sharing options...
Simpel Posted August 28, 2018 Share Posted August 28, 2018 I guess your test "if not ubound" isn't correct. It's possible th have ubound = 0 but there are no useable dates in it. Here to demonstrate: #include <WinAPISys.au3> #include <Array.au3> Global $aMDIWindows[0] For $i = 1 To 10000 ConsoleWrite($i & @CRLF) _GetICNetMDIWindows() ; first window grab Next Func _GetICNetMDIWindows() Local $hParentWindow = WinActivate("Unbenannt") ; Notepad Local $aData = _WinAPI_EnumChildWindows($hParentWindow) _ArrayDisplay($aData) If IsArray($aData) Then ReDim $aMDIWindows[$aData[0][0]][2] ; but after you have destroyed it once with "$aMDIWindows = 0" then a ReDim throughs '"ReDim" used without an array variable' Local $iIndexBound = 0 For $i = 1 To $aData[0][0] If StringInStr($aData[$i][1], "#32770") Then $aMDIWindows[$iIndexBound][0] = $aData[$i][0] $aMDIWindows[$iIndexBound][1] = WinGetTitle($aData[$i][0]) $iIndexBound += 1 EndIf Next ReDim $aMDIWindows[$iIndexBound][2] _ArrayDisplay($aMDIWindows) ConsoleWrite("!!! Not Ubound() is <> Ubound() = 0 - Result here is: " & UBound($aMDIWindows) & @CRLF) ;~ If Not UBound($aMDIWindows) Then If UBound($aMDIWindows) = 0 Then ConsoleWrite("Not Ubound" & @CRLF) $aMDIWindows = 0 EndIf EndIf EndFunc ;==>_GetICNetMDIWindows With that function _GetICNetMDIWindows() $aMDIWindows is never again remade. You declare it only once globally and destroyed it. So it's gone. Simpel SciTE4AutoIt = 3.7.3.0 AutoIt = 3.3.14.2 AutoItX64 = 0 OS = Win_10 Build = 19044 OSArch = X64 Language = 0407/german H:\...\AutoIt3\SciTE H:\...\AutoIt3 H:\...\AutoIt3\Include (H:\ = Network Drive) Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. Link to comment Share on other sites More sharing options...
BatMan22 Posted August 29, 2018 Author Share Posted August 29, 2018 (edited) 26 minutes ago, Simpel said: I guess your test "if not ubound" isn't correct. It's possible th have ubound = 0 but there are no useable dates in it. Here to demonstrate: #include <WinAPISys.au3> #include <Array.au3> Global $aMDIWindows[0] For $i = 1 To 10000 ConsoleWrite($i & @CRLF) _GetICNetMDIWindows() ; first window grab Next Func _GetICNetMDIWindows() Local $hParentWindow = WinActivate("Unbenannt") ; Notepad Local $aData = _WinAPI_EnumChildWindows($hParentWindow) _ArrayDisplay($aData) If IsArray($aData) Then ReDim $aMDIWindows[$aData[0][0]][2] ; but after you have destroyed it once with "$aMDIWindows = 0" then a ReDim throughs '"ReDim" used without an array variable' Local $iIndexBound = 0 For $i = 1 To $aData[0][0] If StringInStr($aData[$i][1], "#32770") Then $aMDIWindows[$iIndexBound][0] = $aData[$i][0] $aMDIWindows[$iIndexBound][1] = WinGetTitle($aData[$i][0]) $iIndexBound += 1 EndIf Next ReDim $aMDIWindows[$iIndexBound][2] _ArrayDisplay($aMDIWindows) ConsoleWrite("!!! Not Ubound() is <> Ubound() = 0 - Result here is: " & UBound($aMDIWindows) & @CRLF) ;~ If Not UBound($aMDIWindows) Then If UBound($aMDIWindows) = 0 Then ConsoleWrite("Not Ubound" & @CRLF) $aMDIWindows = 0 EndIf EndIf EndFunc ;==>_GetICNetMDIWindows With that function _GetICNetMDIWindows() $aMDIWindows is never again remade. You declare it only once globally and destroyed it. So it's gone. Simpel Yeah so I testing with it.. It seems that the If Not Ubound works, the line that seems to be the issue is that I should not set it to $aMDIWindows = 0. #include <File.au3> #include <Array.au3> Global $array[0] ;~ $array = _FileListToArray (@ScriptDir) ; Commenting out this line shows that the If not Ubound works? If not Ubound($array) Then MsgBox(0,0,"NotUboundArray") _ArrayDisplay($array) Maybe I should try... Func _GetICNetMDIWindows() Global $aMDIWindows[0] Local $hParentWindow = WinActivate("IC Net") Local $aData = _WinAPI_EnumChildWindows($hParentWindow) ;~ _ArrayDisplay($aData) If IsArray($aData) Then ReDim $aMDIWindows[$aData[0][0]][2] ;handle;title Local $iIndexBound = 0 For $i = 1 To $aData[0][0] If StringInStr($aData[$i][1], "#32770") Then ;~ ConsoleWrite(WinGetTitle($aData[$i][0]) & @CRLF) $aMDIWindows[$iIndexBound][0] = $aData[$i][0] $aMDIWindows[$iIndexBound][1] = WinGetTitle($aData[$i][0]) $iIndexBound += 1 EndIf Next ReDim $aMDIWindows[$iIndexBound][2] ;~ If Not UBound($aMDIWindows) Then $aMDIWindows = 0 EndIf EndFunc ;==>_GetICNetMDIWindows Edited August 29, 2018 by BatMan22 Link to comment Share on other sites More sharing options...
BatMan22 Posted August 29, 2018 Author Share Posted August 29, 2018 Okay well... redeclaring the variable in the actual function fixes the issue and now it doesn't error out anymore.. but I know that's not good practice. Link to comment Share on other sites More sharing options...
Simpel Posted August 29, 2018 Share Posted August 29, 2018 Instead of redeclaring this variable you can introduce a new variable, e.g. a bool one. Set this to False if Not Ubound() or Ubound()=0 and check against this first. And every time you enter this function set it first to True. BatMan22 1 SciTE4AutoIt = 3.7.3.0 AutoIt = 3.3.14.2 AutoItX64 = 0 OS = Win_10 Build = 19044 OSArch = X64 Language = 0407/german H:\...\AutoIt3\SciTE H:\...\AutoIt3 H:\...\AutoIt3\Include (H:\ = Network Drive) Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 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