I was playing with this just for fun.
I know you made this the way you know and the way you can, but let me say that soon or later you can't maintain this code, there are too much variables, too much to keep in mind.
The problem/bugs are on such lines of code:
Case (StringIsDigit($s_Tuesday_Start_Day) = 1 And
StringIsDigit($s_Tuesday_End_Day) = 1 And
(Number($s_Tuesday_Start_Day) >= Number($s_Tuesday_End_Morning)) And
(Number($s_Tuesday_End_Day) > Number($s_Tuesday_Start_Day)))
Or $b_Tuesday_Morning = 1
Let's talk about all the "And": it means that whenever a single condition is false, everything is false, no matter parenthesis are placed.
The real problem is that all comboboxes have the same range of hours, it is an inconsistent interface, I mean there is no sense that you can setup:
Morning start: 00
Morning end: 22
This range of hours are overlapping Day and Night periods. I really don't know what's mean for you "morning start hour", "morning end hour" and so on.
If you could split range hours into a non overlapping ranges, you need to do none error check because you don't allow user to create those errors.
It would be easy for you as a developer and as a "program user".
This is the way I made it:
#include <File.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <Date.au3>
#include <ComboConstants.au3>
Global $aDays[7][7] ; holds all control ID created by GUI
Global $aData[7][7] ; holds all data chosen by user on comboboxes and Checkboxes
Global $aRed[7][3] ; holds aRedZones that includes 2 comboboxes. So there are only 3 on any row
; columns constants
Global $CheckBox=0, $MorningStart = 1, $MorningEnd = 2, $DayStart=3 , $DayEnd=4, $NightStart=5, $NightEnd =6
; row constants
Global Const $Mon=0 , $Tue=1, $Wed=2 , $Thi=3, $Fri=4, $Sat=5, $Sun=6 ; row constants
Local Const $a_Days[7] = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
Local $a_Hours[25] = [" -", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]
;Red Zone Columns:
Local Const $Morning = 0 , $Day=1 , $Night = 2
Local Const $cbow = 40 ; comboboxes width to calculate positions
Local $h_GUI = GUICreate("Automat Counting", 672, 400, -1, -1)
Local Const $a_Times[3] = ["Morning", "Day", "Night"]
Local $a_WindowClientArea_Size = WinGetClientSize($h_GUI) ;$a_WindowClientArea_Size[0] = Width, $a_WindowClientArea_Size[1] = Height
GUISetFont(10)
GUICtrlCreateGroup("Days", 10, 10, $a_WindowClientArea_Size[0] - 20, 360)
GUICtrlCreateGroup("", 110, 35, 175, 315)
GUICtrlCreateLabel("Morning", 110, 25, 175, 24, BitOR($SS_CENTERIMAGE, $SS_CENTER))
GUICtrlSetColor(-1, 0x003e51)
GUICtrlSetBkColor(-1, 0x00c4ba)
GUICtrlCreateGroup("", 290, 35, 155, 315)
GUICtrlCreateLabel("Day", 290, 25, 155, 24, BitOR($SS_CENTERIMAGE, $SS_CENTER))
GUICtrlSetColor(-1, 0x003e51)
GUICtrlSetBkColor(-1, 0x00c4ba)
GUICtrlCreateGroup("", 450, 35, 155, 315)
GUICtrlCreateLabel("Night", 450, 25, 155, 24, BitOR($SS_CENTERIMAGE, $SS_CENTER))
GUICtrlSetColor(-1, 0x003e51)
GUICtrlSetBkColor(-1, 0x00c4ba)
$id_Launch = GUICtrlCreateButton("Start", $a_WindowClientArea_Size[0] / 2 - 100, $a_WindowClientArea_Size[1] - 35, 200, 25)
GUICtrlCreateLabel("Start", 160, 55 , 39, 24, $SS_CENTERIMAGE)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("End",240, 55, 39,24, $SS_CENTERIMAGE)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Start", 320, 55 , 39, 24, $SS_CENTERIMAGE)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("End", 400, 55 , 39, 24, $SS_CENTERIMAGE)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Start", 480, 55 , 39, 24, $SS_CENTERIMAGE)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("End", 560, 55 , 39, 24, $SS_CENTERIMAGE)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
For $irow=0 To 6
;Top Coordenate: 80 + 40*$irow = start at 80 minimum, then move down 40 pixels per each row
$aDays[$irow][$CheckBox] = GUICtrlCreateCheckbox($a_Days[$irow] , 20, 80 + 40*$irow, 80, 24)
GUICtrlSetState(-1, $GUI_CHECKED)
$aRed[$irow][0] = GUICtrlCreateGraphic( 79+($cbow* 2 ) - 10, 76 + 40*$irow, $cbow*3 +15 , 32)
GuiCtrlSetBkColor($aRed[$irow][0], 0xFF4444)
GUICtrlSetState(-1, $GUI_DISABLE)
$aRed[$irow][1] = GUICtrlCreateGraphic( 79+($cbow* 6) - 10, 76 + 40*$irow, $cbow*3 +15 , 32)
GuiCtrlSetBkColor($aRed[$irow][1], 0xFF4444)
GUICtrlSetState(-1, $GUI_DISABLE)
$aRed[$irow][2] = GUICtrlCreateGraphic( 79+($cbow* 10) - 10, 76 + 40*$irow, $cbow*3 +15 , 32)
GuiCtrlSetBkColor($aRed[$irow][2], 0xFF4444)
GUICtrlSetState(-1, $GUI_DISABLE)
For $icol=1 To 6
;Left Coordenate: 80+($cbow*2* $icol) = start left at 80 minimum. Then multiply by 2 the width of the combo to move to the right per each column
;Top Coordenate: 40*$irow + 80 = start at 80 minimum. Move down 40 pixel per each row
$aDays[$irow][$icol]= GUICtrlCreateCombo("", 80+($cbow* 2 * $icol), 80 + 40*$irow, $cbow, 24, $CBS_DROPDOWNLIST)
GUICtrlSetData($aDays[$irow][$icol], _ArrayToString($a_Hours), " -")
Next
Next
GUISetState(@SW_SHOW, $h_GUI)
Sleep(1000)
; hide Red Zones instead of checking its color pixels.
; with some screen animation... because I can!
For $irow=6 To 0 Step -1
GUICtrlSetState($aRed[$irow][$Night], $GUI_HIDE)
Sleep(100)
GUICtrlSetState($aRed[$irow][$Day], $GUI_HIDE)
Sleep(100)
GUICtrlSetState($aRed[$irow][$Morning], $GUI_HIDE)
Sleep(100)
Next
; Show one of them randomly, sleep and hide it,
; just to demonstrate how to show and hide.
Sleep(1000)
GUICtrlSetState($aRed[$Wed][$Day], $GUI_SHOW)
Sleep(1000)
GUICtrlSetState($aRed[$Wed][$Day], $GUI_HIDE)
; GUISetState(@SW_SHOW, $h_GUI) ; if you activate this line an comment out line 76, you will not see any animation on screen. You should also remove any Sleep call.
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case $id_Launch
Local $b_ComboError = 0
Update_Data()
Check_Data()
;_ArrayDisplay($aData, "Data Retrieved from Interface", "", 0,"|", "Day|Morning Start|Morning End|Day Start|Day End|Night Start|Night End")
EndSwitch
WEnd
Func Check_Data()
local $ms =0, $me=0, $ds=0 , $de=0, $ns=0, $ne=0 ; all data from one row
For $irow =0 To 6
; check full row values
$ms = GetaData($irow, $MorningStart)
$me = GetaData($irow, $MorningEnd)
$ds = GetaData($irow, $DayStart)
$de = GetaData($irow, $DayEnd)
$ns = GetaData($irow, $NightStart)
$ne = GetaData($irow, $NightEnd)
ConsoleWrite(StringPad(GetaData( $irow), 15) & " ms " & Pad($ms) & " me " & Pad($me)& " ds " & Pad($ds)& " de " & Pad($de) & " ns " & Pad($ns) & " ne "& Pad($ne) & @CRLF)
If ($ms = -1 and $me = -1) or ($ms < $me) Then
; If combos are not setup by user, RedZone should be hidden.
GUICtrlSetState($aRed[$irow][$Morning], $GUI_HIDE)
Else
GUICtrlSetState($aRed[$irow][$Morning], $GUI_SHOW)
EndIf
If (($ds = -1 and $de = -1) or ($ds < $de)) Then ; BUG: This is wrong, doesn't work properly I don't understand how it is supposed to work though
; If combos are not setup by user, RedZone should be hidden.
GUICtrlSetState($aRed[$irow][$Day], $GUI_HIDE)
Else
If ( $ms=-1 and $me=-1) Then
GUICtrlSetState($aRed[$irow][$Day], $GUI_HIDE)
ElseIf ($me > $ds) Then
GUICtrlSetState($aRed[$irow][$Day], $GUI_SHOW)
EndIf
EndIf
If ($ns= -1 and $ne = -1) or ($ns < $ne ) Then
; If combos are not setup by user, RedZone should be hidden.
GUICtrlSetState($aRed[$irow][$Night], $GUI_HIDE) ;
Else
GUICtrlSetState($aRed[$irow][$Day], $GUI_SHOW)
EndIf
Next
ConsoleWrite("------------------------------------------------------------" & @CRLF)
EndFunc
; Get Data of any control on screen,
; Examples:
; GetData( $Mon, $DayEnd) - Get data from Monday at DayEnd
; GetData( $Tue ) - Get the name of the day "Tuesday"
Func GetData($row, $col=0)
If $col = 0 Then
; we already have those names in our array
Return $a_Days[$row]
Else
return GUICtrlRead($aDays[$row][$col])
EndIf
EndFunc
; another way to get the data.
; instead of asking interface everytime, we use an Array
; just like $aDays, but we save here all screen data user.
Func Update_Data()
local $txt = ""
For $i=0 To 6
For $j=0 To 6
If $j=0 Then
$aData[$i][$j]= GUICtrlRead($aDays[$i][$j], $GUI_READ_EXTENDED) ; saves the day of the week on column Zero
;$aData[$i][$j]= GUICtrlRead($aDays[$i][$j]) = 1 ; saves True (checked) or False (unchecked) on column Zero
Else
$txt = GUICtrlRead($aDays[$i][$j])
If stringIsDigit($txt) Then
$aData[$i][$j] = int($txt) ; convert all data to integers numbers
Else
$aData[$i][$j] = -1 ; Zero is used by MidNight hour, so I setup -1 on empty selection.
EndIf
EndIf
Next
Next
EndFunc
; if you do not like all those square bracket on your code
; you could minimize their use by calling this function.
; Examples:
; GetaData( $Mon, $DayEnd) - Get data from Monday at DayEnd
; GetaData( $Mon, $DayEnd -1 ) - Since DayEnd is an integer, here we get $DayStart
; GetaData( $Tue ) - Get the name of the day "Tuesday" if you saved on Zero column the day of the week
Func GetaData($row, $col=0)
return $aData[$row][$col]
EndFunc
; a way to get a Value from the $aData only if
; is an Integer value >= 0
; local $data
; If IsValidHour( $Tue, $MorningEnd , $data)Then
; ; here $data is always a number defined by user: from Zero to 23
; Else
; ; here $data could be a string value (day of the week)
; ; or maybe -1
; ; of maybe True/False depending on what you saved on Zero Column.
; EndIf
Func IsValidaHour($row, $col, byRef $Value)
; we guarantee that we are returning and integer value
; greater than -1, that is, the user specified a valid
; hour.
; if col is Zero it returns false because it is the
; day of the week, it is a string what you get on $Value
$value = $aData[$row][$col]
return ($col > 0) and ($Value > -1)
EndFunc
Func Pad($tNumber, $padding = 2)
If $padding > 10 Then
Return "-1"
EndIf
Return StringRight('0000000000' & $tNumber, $padding)
EndFunc ;==>Pad
Func StringPad($sAString, $imaxLength)
Local $i = StringLen($sAString)
If $i <= $imaxLength Then
Return StringFormat("%-" & $imaxLength & "s" , $sAString)
EndIf
Return $sAString
EndFunc
#include <GUIConstants.au3>
$Main = GUICreate("StatusBar GUI", 380, 400,-1,-1, -1, $WS_EX_TOPMOST)
$label = GUICtrlCreateLabel("Default StatusBar Text", 0, 380, 400, 20, $SS_SUNKEN + $SS_CENTER)
GUISetState (@SW_SHOWNA, $Main)
$NextPause = 3
While 1
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE Then Exit
GUICtrlSetData($label, $NextPause)
Sleep( 1000 )
$NextPause = $NextPause - 1
If $NextPause <= 0 Then
Send( "A" )
$NextPause = 3
EndIf
Wend
It is important to use @SW_SHOWNA or @SW_SHOWNOACTIVATE, if you use anything different, it seems to loose the TopMost feature (in my test, not sure why).