The Concise Forms and Saved Settings Tutorial
Foreword:
Greetings, everyone! This is not a comprehensive tutorial by any means. If you would like a comprehensive tutorial on forms, visit here. If you want a more comprehensive tutorial on saving and loading settings for your forms... Ask me and I'll add detail
Table of Contents:
- Form Creation
- Form Objects
- Events
- INI Files
- Implement Multiple Settings Files
- FAQ
Form Creation:
You will need to make a couple of Thread Safe Calls to setup the form, the first of which is designated simply to populate and setup the form, while the second is to actually show the form to the user and grant it complete control until it is closed.
Simba Code:
var
settingsForm:TForm;
//Initialize those form variables!
procedure InitialiseForm;
begin
//A lot of junk that will be explained upcoming and must happen before the show call in the next thread safe call
end;
//Show that form to the user!
procedure ShowModal;
begin
settingsForm.ShowModal;
end;
begin
ThreadSafeCall('InitialiseForm', params);
ThreadSafeCall('ShowModal', params);
end.
So far, it looks pretty simple right?
Wrong! It really is! So how do we setup a blank form? Well that's fairly simple, we just need to initialize it and tell simba how we want it to look, like this:
Simba Code:
procedure InitialiseForm;
begin
settingsForm:= CreateForm;//Actually create the form (necessary call)
settingsForm.Width:= 475;//How many pixels wide will your form be?
settingsForm.Height:= 420;//How many pixels tall will your form be?
settingsForm.Caption:= 'Our Settings Form!';//The caption will be the text displayed at the very top of the form in the title bar
settingsForm.Color := ClWhite;//The default color of the form and all objects that will be added to it
settingsForm.Font.Color := ClBlack;//The default color of all text that will occur on the form
settingsForm.Font.Size := 8;//The default font size of all text that will occur on the form
//A lot more junk for the stuff inside the form
end;
Wow, we're keeping those "complicated" forms pretty simple still I hope (and to be fair, pretty empty)! Now we should have a blank form that just appears to be a new empty window. We should fill it up next - and that shall be with the inner objects I explain in the next section.
Form Objects:
- Shared properties
- .Create(TForm);//pass the form you created to this. This must be called first before setting any values of any object
- .Parent:= //Set it equal to the form you want this sobejct to appear on. By defualt it will set its other values to match the form's defaults
- .Caption:= The text the object will have
- .Left:= The amount of pixels from the left side of the form that the object will be on
- .Top:= The amount of pixels from the top side of the form that the object will be on
- .Width:= The maximum amount of pixels wide the object will be
- .Height:= The maximum amount of pixels tall the object will be
- TComboBox: A drop down list of options - one of which may be selected at a time.
- TEdit: A text box that the user can enter custom strings into
- TCheckBox: A check box that the user can check (good for boolean values)
- TLabel: A label box that the user cannot edit in any manner
- TButton: A button that can be pressed
An important feature of these objects include events. Simply put, whenever the designated action occurs (the event), the tied delegate (or procedure pointer in our case - feel free to read more about them here:
http://villavu.com/forum/showthread.php?t=102800) will be called. Ok, finally this part can sound a little daunting and confusing, but I swear it's not that bad after you get your head around it. Your procedure name MUST be styled as such:
Simba Code:
procedure ActionClick(Sender: TObject);//It MUST be a procedure and it MUST have that parameter (which you will never pass manually), the actual name of the procedure is up to you.
So how do we connect the desired events to the resulting action? We connect it through designated events for every object. But Kevin, what kind of situations do we even care about this? We care about this because we can use them to save the form, to load values, or to even make specific objects invisible due to other options making them useless!
Simba Code:
var
settingsForm: TForm;
timeToRun: TEdit;
RunForever: TCheckBox;
//Change the visibility of end early settings.
procedure SelectRunForever(Sender: TObject);
begin
timeToRun.Visible:= not RunForever.CHECKED;//When the boolean (checkbox) to run the script forever is true, then don't allow the user to see or edit the box that sets the time to run for.
end;
procedure InitialiseForm;
begin
//Keep previous logic in place and add:
timeToRun:= TEdit.Create(settingsForm);
timeToRun.Parent:= settingsForm;
RunForever:= TCheckBox.Create(settingsForm);
RunForever.Parent:= settingsForm;
timeToRun.Visible:= false;
timeToRun.Left:= 255;
timeToRun.Top:= 115;
RunForever.CAPTION:= 'Run Forever';
RunForever.Left:= 170;
RunForever.Top:= 115;
RunForever.CHECKED:= True;
RunForever.ONCLICK:= @SelectRunForever;//Whenever the box is clicked (checked or unchecked), call SelectRunForever
end;
Congratulations! This is what your form should now look like with the checkbox unchecked! (And that editable box should disappear when you check the box). Now let's look into combo boxes. These are the drop down menus that are really helpful for allowing the user to choose a pre-defined list of options. Like the other objects, the combo box has top, left, width, height, font, parent, and create properties. However, the combo box has several unique properties such as:
- .Style:= csDropDownList;//there are multiple cs* styles, however I like this one best. This defines the style of the combo box
- .Items;//This is the list of options in the combo box
- .Items.Add(value: String);//Use this to add a new value to the list of options in the combo box
- .ItemIndex:= 0;//Finally after all items have been added, you can default the currently selected item to a given value in the list through a value with an index starting at 0
Now let's look at this wonder in code:
Simba Code:
procedure InitialiseForm;
var
comboBox: TComboBox;
label: TLabel;
begin
//Same junk as before.
comboBox:= TComboBox.Create(settingsForm);
comboBox.Parent:= settingsForm;
comboBox.Left:= 255;
comboBox.Top:= 10;
comboBox.Width:= 30;
comboBox.Style:= csDropDownList;
comboBox.Items.Add('1');
comboBox.Items.Add('2');
comboBox.Items.Add('3');
comboBox.ItemIndex:= 0;
label:= TLabel.Create(settingsForm);
label.Parent:= settingsForm;
label.FONT.Size:= 10;
label.Left:= 165;
label.Top:= 10;
label.Caption:= 'XP Bar slot';
end;
Finally, we need a button and the ability to close our form to start the script. If you have everything else, then here is a piece of cake.
Simba Code:
procedure OnButtonClick(Sender: TObject);
begin
SetVariablesFromForm;//your own method to set all your variables to the .Caption values of the form
SaveForm;//Your own method to save your variables to a form using a technique I'm about to describe in the next section
settingsForm.MODALRESULT:= mrOk;//this command will set the form as ready to be closed and it will close automatically
end;
procedure InitialiseForm;
var
saveButton: TButton
begin
//Everything we had before
saveButton:= TButton.Create(settingsForm);
saveButton.Parent:= settingsForm;
saveButton.Left:= 140;
saveButton.Top:= 375;
saveButton.Caption:= 'Start!';
saveButton.OnClick:= @OnButtonClick;//this way clicking the button does something
INI Files
This is easily the simplest method of saving/writing settings to files (originally pointed to me by Mr. Amazing @
Ollybest - although I did the reading learning myself
). There are several built in methods for writing settings either to dedicated ini files or the default simba ini file (unused by anyone I know of, and therefore useless, so I suggest using your own per script).
Saving to files:
Simba Code:
WriteINI(sectionName, keyName, valueName, saveFileName: String);
WriteINI('Settings', 'PlayerName', 'bot 123', (AppPath + 'MySettingsFile.ini'));//example
The aforementioned example will find the "MySettingsFile.ini" file in the AppPath folder, go to the section labeled "Settings", and set the "PlayerName" variable to "bot 123". And if any of those don't already exist (file, section, variable), it will be automatically created for you. Easy!
Loading from files:
Simba Code:
ReadINI(sectionName, keyName, saveFileName: String): String;//returns the valueName set before
textBox.Caption:= ReadINI('Settings', 'PlayerName', (AppPath + 'MySettingsFile.ini'));//example - sets the caption of the text box to the value matching all the previous setup
Implement Multiple Settings Files:
This is a little more complicated than the aforementioned ideas and it assumes you already have created your own custom load and save forms. I will show everything at once with the upcoming code, but I will comment to try and help. Please ask if you have questions!
Simba Code:
var
SaveFileName: String;
procedure SaveForm(Sender: TObject);
begin
if(comboBox.ITEMINDEX<0)then
SaveFileName:= AppPath + 'ScriptName' + PlayerName + '.ini';//I will likely not include script name in my personal work so I can start using a single settings file that handles many scripts.
//Save your form to your file
end;
procedure LoadForm(Sender: TObject);
begin
if(comboBox.ITEMINDEX<0)then
Exit;
SaveFileName:= AppPath + comboBox.ITEMS[comboBox.ITEMINDEX];
if(not FileExists(SaveFileName))then
Exit;
//Expected remaining loading using this new file name variable instead of the constant it was before
end;
procedure InitialiseForm;
var
files: TStringArray;
begin
//Which file to load related setup
label.Left:= 5;
label.Top:= 315;
label.Caption:= 'Load file: ';
comboBox.Left:= 70;
comboBox.Top:= 315;
comboBox.Width:= 150;
comboBox.Style:= csDropDownList;
files:= GetFiles(AppPath, 'ini');
for i:=0 to high(files) do
begin
comboBox.Items.Add(files[i]);
WriteLn(files[i]);
end;
comboBox.ONCHANGE:= @LoadForm;//By not giving an index, it's -1 and then you can save a new form settings file
end;
FAQ:
Ask me some questions and I'll toss them up here.