Here's a condensed version of the error message:
You'll see through the code, I predefined some of the variables so they'd be global, and thus accessible to the function. I can't figure out how to make vCheckbox...global though. I tried putting global vChecbox1 := "" near the top of the function, but that doesn't work. Even if it did work, I assume that it would still throw an error when it got to "vCheckbox2."---------------------------
Error: A control's variable must be global or static.
Specifically: vCheckbox1
Line#
---> 227: Gui,o:Add,CheckBox,Checked%fchar% vCheckbox%a_index%,%item%
---------------------------
Ideas? Maybe I should just keep this in the code "in-line" rather than a separate function?
Spoiler
NOT WORKING CODE!
Code: Select all
#NoEnv
#SingleInstance Force
SetTitleMatchMode, 2
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
;!+w:: Alt+Shift+w but gets called from master script.
WinGetActiveTitle, myWinTarget ; Get name of active Window so we can wait for it later.
WinGetPos, X, Y, W, H, A ; "A" to get the active window's pos.
X := X + (W * 0.05) ; Use these with GUI Show, below.
Y := Y + (H * 0.2)
;Menu, Tray, Icon, Swiss-knife.ico
Gui, Destroy
Gui, -MinimizeBox +alwaysOnTop
Gui, Font, s10
Gui, Add, Edit, x14 y8 w220 h25 vStudentName, Student ; Box to type in name.
Gui, Add, Radio, xs y40 w80 h20 vGender checked, &Male ; Radio group for gender.
Gui, Add, Radio, xp+80 y42 w80 h20 , &Female
Gui, Add, Radio, xp+80 y42 w80 h20 , &Neutral
;Gui, Font, s8
;Gui Add, Text, x257 y6 w123 h120 +wrap cGray, [n] = name`n[y] = He She They`n[m] = Him Her Them`n[r] = His Her Their`n[s] = His Hers Theirs
;Gui, Font, s10
Gui Add, Tab3, x12 y64 vCurrTab, Notices|Tests
Gui Tab, 1 ;====Notices==========================================================
IniRead, AllSchools, SchoolList.ini ; Gets `n-delimited list from ini file.
AllSchools := StrReplace(AllSchools,"`n","|",SchRows) ; Must|convert|to|this.
SchRows++ ; The number of strReplacements +1
Gui, Add, ListBox, r%SchRows% w330 vSchChoice Choose1, %AllSchools%
global AllSections := ""
IniRead, AllSections, NoticeDefinitions.ini
AllNotices := ""
Loop, Parse, AllSections, `n, `r
If !RegExMatch(A_LoopField, "\Q-Options\E") ; Exclude ini sections with -Options at the end.
AllNotices .= A_LoopField "`n"
global NoteChoice := ""
AllNotices := StrReplace(AllNotices,"`n","|",NoteRows)
NoteRows++
;Gui, Add, ListBox, r%NoteRows% w330 sort vNoteChoice gDblClick, %AllNotices%
Gui, Add, ListBox, r%NoteRows% w330 vNoteChoice gDblClick, %AllNotices% ; Removed sort
Gui, Add, Button, w65 h30 Section, Insert
Gui, Add, Button, ys x+5 w60 h30, Schools
Gui, Add, Button, ys x+5 w60 h30, Notices
Gui, Add, Button, ys x+5 w60 h30, Esc
Gui Tab, 2 ;====Tests======================================================
IniRead, MySuffixes, TestSuffixes.ini
MySuffixes := StrReplace(MySuffixes,"`n","|")
Gui, Add, ComboBox, w330 vSuffChoice Choose1, %MySuffixes%
IniRead, AllTests, TestBank.ini
AllTests := StrReplace(AllTests,"`n","|",TestRows)
TestRows++
Gui, Add, ListBox, r%TestRows% w330 sort vTestChoice gDblClick, %AllTests%
Gui, Add, Button, w65 h30 Section, Insert
Gui, Add, Button, ys x+5 w60 h30, Suffix
Gui, Add, Button, ys x+5 w60 h30, Tests
Gui, Add, Button, ys x+5 w60 h30, Esc
Gui Tab ;=====End of Tabs================================================
Gui Show, x%X% y%Y%, MultiTool 2.0 v5-5-2021
Return
ButtonEsc:
GuiEscape:
GuiClose:
ExitApp
DblClick:
IfNotEqual A_GuiControlEvent,DoubleClick
Return
Else
ButtonInsert:
Gui, Submit
IfEqual, CurrTab, Notices ; Checks which tab is being used.
{
IniRead, MyEntry, NoticeDefinitions.ini, %NoteChoice% ; From notice type, goes back to INI, gets notice content.
} ;===== This is the end of IfEqual, CurrTab, Notices.=====
IfEqual, CurrTab, Tests
{
IniRead, MyEntry, TestBank.ini, %TestChoice%,
ifNotEqual, SuffChoice, ; Only gets Suffix Description if comboBox is not empty.
IniRead, MySuffDesc, TestSuffixes.ini, %SuffChoice%
MyEntry := StrReplace(MyEntry,"[sd]",MySuffDesc)
MyEntry := StrReplace(MyEntry,"[sf]",SuffChoice A_Space)
}
;======== check for options ========================================================
If InStr(MyEntry, "<Options>") ; Options tag found in expansion text.
myOptionsFunc(MyEntry)
;=======end of options==========
ContinueScript:
IniRead, MyContactInfo, SchoolList.ini, %SchChoice%, ContactInfo ; From school choice, gets contact info.
IniRead, MySchPhone, SchoolList.ini, %SchChoice%, SchPhone
MyEntry := StrReplace(MyEntry,"[c]",MyContactInfo)
MyEntry := StrReplace(MyEntry,"[p]",MySchPhone)
IfEqual, Gender, 1 ; Checks the results of the gender radio buttons group and assigns variables.
{
varHeShe = he
varHimHer = him
varHisHer = his
varHisHers = his
}
IfEqual, Gender, 2
{
varHeShe = she
varHimHer = her
varHisHer = her
varHisHers = hers
}
IfEqual, Gender, 3
{
varHeShe = they
varHimHer = them
varHisHer = their
varHisHers = theirs
}
MyEntry := StrReplace(MyEntry,"[n]",StudentName) ; Makes the replacements.
MyEntry := StrReplace(MyEntry,"[y]",varHeShe) ; Gender pronouns.
MyEntry := StrReplace(MyEntry,"[m]",varHimHer)
MyEntry := StrReplace(MyEntry,"[r]",varHisHer)
MyEntry := StrReplace(MyEntry,"[s]",varHisHers)
MyEntry := StrReplace(MyEntry,"!","{!}") ; These special characters need {braces} to type correctly.
MyEntry := StrReplace(MyEntry,"#","{#}")
MyEntry := StrReplace(MyEntry,"+","{+}")
IfEqual, Gender, 3
{
MyEntry := StrReplace(MyEntry,"they is","they are") ; Fix gramar is gender neutral.
MyEntry := StrReplace(MyEntry,"they has","they have")
}
MyEntry := RegExReplace(MyEntry, "^\w|(?:\.|:)\s+\K\w", "$U0") ; Makes sure most sentences are capitalized.
IfEqual, CurrTab, Notices
{
MyEntry =`n%MyEntry% ; Adds an new-line at beginning so below regex will work.
MyEntry := RegExReplace(MyEntry,"(\n)+[ a-zA-Z0-9]+=") ; Removes all Key names from notice definitions.
;CulledEntry := RegExReplace(MyEntry,"(\n)+[ a-zA-Z0-9,/&+.\-#]+=") ; Removes all Key names. Added special chars 9-2-18.
StringReplace, MyEntry, MyEntry,`n, , All ; Gets rid of any leftover <Enter>s.
}
gui, Hide
winwaitactive, %myWinTarget% ; Wait for the previously active Window.
SendEvent %MyEntry% ; Types notice or test into text field(s)
;========= Notes about SEND modes ============
;SendInput is faster but you can't see progress of typing.
;Send is the same as SendEvent. It is more visual but prone to errors.
;SendPlay doesn't seem to work... Maybe because UAC is active.
ExitApp
;========= Other Buttons go to here if clicked ===============
; The excellent opensource and free Notepad3 from: https://www.rizonesoft.com/documents/notepad3/
ButtonSchools:
run, %A_ScriptDir%\Notepad3\Notepad3.exe "%A_ScriptDir%\SchoolList.ini",, UseErrorLevel
If ErrorLevel
run, SchoolList.ini ; If Notepad3 is not found, will be prompted to choose default ini opener.
return
ButtonNotices:
run, %A_ScriptDir%\Notepad3\Notepad3.exe "%A_ScriptDir%\NoticeDefinitions.ini",, UseErrorLevel
If ErrorLevel
Run, NoticeDefinitions.ini
return
ButtonSuffix:
run, %A_ScriptDir%\Notepad3\Notepad3.exe "%A_ScriptDir%\TestSuffixes.ini",, UseErrorLevel
If ErrorLevel
run, TestSuffixes.ini
return
ButtonTests:
run, %A_ScriptDir%\Notepad3\Notepad3.exe "%A_ScriptDir%\TestBank.ini",, UseErrorLevel
If ErrorLevel
run, TestBank.ini
return
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
myOptionsFunc(MyEntry){
; MsgBox, options tag found. Section is: %NoteChoice%
OptSection := ""
Loop, Parse, AllSections, `n, `r
If RegExMatch(A_LoopField, NoteChoice . "\Q-Options\E")
OptSection .= A_LoopField
IniRead, AllOptions, NoticeDefinitions.ini, %OptSection% ; must get list of keys ;var,file,sect
MsgBox Inside function.`n=========`nMyEntry is: %MyEntry%`n=========`nNoteChoice is: %NoteChoice%`n=========`nOptSection is: %OptSection%`n=========`nAllOptions is: %AllOptions%
vCount=
myOptions=
Gui, +Owner
Gui, o:Destroy
Gui, o:-MinimizeBox +alwaysOnTop
Gui, o:Add, Text,, Select one or more options:
Loop, Parse, AllOptions, `n,`r ; Parses list.
{
fchar := SubStr(A_LoopField, 1, 1)
If fchar is Number
{
item := SubStr(A_LoopField, 3, 99)
}
else
{
item := A_LoopField
}
;MsgBox, fchar: %fchar%`nitem : %item%
Gui, o:Add, CheckBox, Checked%fchar% vCheckbox%a_index%, %item% ;Dynamically make one checkbox per item.
vCount = %a_index%
}
Gui, o:Add, Button, default xm w50 gMyOpts, Use
Gui, o:Add, Button, yp x+5 w50 gCancelOpts, Cancel
Gui, o:Show,x%X% y%Y% , Option Items
Return
MyOpts: ; Go here when user clicks Okay button.
Gui, o:Submit
vCount=
Loop, parse, AllOptions, `n
{
If Checkbox%a_index% <> 0
{
If fchar is Number
{
item := SubStr(A_LoopField , 3, 99)
}
else
{
item := A_LoopField
}
myOptions = %myOptions%`n, %item%
vCount++
;MsgBox % vCount "|" MyOptions
}
}
myOptions := SubStr(myOptions, 3, 99)
IfEqual, vCount, 2
myOptions := StrReplace(myOptions,", " . item," and " . item)
myOptions := StrReplace(myOptions,", " . item,", and " . item)
MyEntry := StrReplace(MyEntry,"<Options>",myOptions) ; Replace Options tag with checked items.
Gosub, ContinueScript
Return
CancelOpts:
ExitApp
}