Page 1 of 2 12 LastLast
Results 1 to 25 of 29

Thread: The Form Tutorial

  1. #1
    Join Date
    Apr 2007
    Posts
    3,152
    Mentioned
    3 Post(s)
    Quoted
    1 Post(s)

    Default The Form Tutorial

    The Form Turorial

    The problem that i found with the tutorial is that its quite long. Thats good because it teaches lots-o-knowledge. The downside is that this is a forum. And unless i make 25 posts it wont be easily navigate able. So i have now put it in wiki format, with some fixing of errors, here

    *note*If you want the updated version, go to the wiki version. It's easier to navigate and will be updated past what is on the forums.

    Chapter 1 - Beginning
    - 1.0 Preface
    - 1.1 Using the Form Editor
    - 1.2 Properties
    - 1.3 Events
    - 1.4 Methods
    - 1.5 Making a Simple Form
    - 1.6 Good Form Syntax

    Chapter 2 - Alternative Forms
    - 1.0 Preface
    - 1.1 ReadLn
    - 1.2 GetApplication
    - 1.3 MessageDlg
    - 1.4 InputQuery/InputBox
    - 1.5 ShowMessage

    Chapter 3 - Good Things to Know
    - 1.1 Parent Vs. Owner
    - 1.2 To be Determined

    Chapter 4 - Working with Various Components
    - 1.1 Timer
    - 1.2 MainMenu
    - 1.3 Tabs
    - 1.4 PopupMenu
    - 1.5 Statusbar
    - 1.6 Dialogs
    - 1.7 etc

    Chapter 5 - Drawing
    - 1.1 Drawing
    - 1.2 Adding Images
    - 1.3 Adding Images/Drawing on Objects

    Chapter 6 - Projects
    - 1.1 Making a Calculator
    - 1.2 Making an Analog Clock
    - 1.3 Making a Game

    Chapter 1 - Beginning
    1.0 Preface
    In Windows, most elements of the user interface are windows. All windows of a SCAR are based on TForm object. Form objects are the basic building blocks of a SCAR form, the actual windows with which a user interacts when they run the application. Forms have their own properties, events, and methods with which you can control their appearance and behavior. Here is a list of the supported objects in SCAR
    • TApplication
    • TButton
    • TCanvas
    • TCheckBox
    • TColorDialog
    • TColorPicker
    • TComboBox
    • TEdit
    • TFindDialog
    • TFontDialog
    • TForm
    • TGroupBox
    • TImage
    • TLabel
    • TListBox
    • TMainMenu
    • TMemo
    • TMenuItem
    • TMenu
    • TOpenDialog
    • TPageControl
    • TPanel
    • TPopupMenu
    • TProgressBar
    • TRadioButton
    • TReplaceDialog
    • TRichEdit
    • TSaveDialog
    • TScrollBar
    • TShape
    • TStatusBar
    • TStatusPanel
    • TTabControl
    • TTabSheet
    • TTimer


    and more, as of SCAR 3.20

    1.1 Using the Form Editor
    I personally don't use the Form Editor that much, and when i do its briefly, to maybe check something or make a quick .dfm file. Even though I don't use it, I'm going to go over it because i guess its easier for a person that's new to forms to learn to use it, though i don't suggest becoming completely dependent on it, because it is quite lacking, and has some errors.

    - Now i hope you already know this, but you go to "Tools -> Form Editor" to get to it. Once you're there you have 3 windows:



    - To add a Form Component your form, all you do is click on one of the form components' icons in the Form Designer and click again on your form. When you click on your form, the object's attributes are all at their default, except for the left and right(that changes based on where you click). If you also want to change the default size and shape of your object you can drag out the shape onto your form instead of clicking on the form.

    - To edit a property, you have to click on the appropriate property that you want edited, and change it, either by dropping down the drop-down menu(if that property is constrained to certain parameters) or just typing in the change.

    - To export a form, so that you can use it in your script, is also quite simple. First, save your form as a .dfm file to somewhere that you can find.
    Then close the form editor and go to Tools -> Load DFM From Form. Then find your form and click open. You should notice some code pop up into your debug box. Starting with this generic code -
    SCAR Code:
    procedure InitForm;
    begin
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end.
    add the beginning code to the InitForm procedure, and the vars above it.
    *Note* you may have a problem with your code right now. When you run it, you will probably get an error saying that it cant run with an invisible form. If this is the case, then delete "Visible := true" from the form's properties in the InitForm.
    Then run the code, you should see your form pop up, with whatever components you placed on it. That is your first form!

    1.2 Properties
    Properties, are what you use to change the appearance of your form components, and how they work. Some of the most common properties are: left, top, width, height, visible, enabled, and cursor. Though, properties are simple, they are needed to make your forms do what you want. They are, for the most part, self explanatory.
    - Left will start the left of your component at that pixel of its parent.
    - Top will start the top of your component at that pixel of its parent.
    - Width and Height will make your component that tall and wide, in pixels.
    - Visible, if false will make that component invisible
    - Enabled, if false will disable that component
    - Cursor, depending on the input will change what your cursor looks like upon mousing over the component

    The biggest reason i have a section on properties, is that many are not needed in your script. For example, the default output from the form editor for a simple for is
    SCAR Code:
    frmDesign := CreateForm;
    frmDesign.Left := 250;
    frmDesign.Top := 114;
    frmDesign.Width := 696;
    frmDesign.Height := 480;
    frmDesign.Caption := 'frmDesign';
    frmDesign.Color := clBtnFace;
    frmDesign.Font.Color := clWindowText;
    frmDesign.Font.Height := -11;
    frmDesign.Font.Name := 'MS Sans Serif';
    frmDesign.Font.Style := [];
    frmDesign.Visible := True;
    frmDesign.PixelsPerInch := 96;
    however, the color, font properties, visible, and pixels per inch aren't needed because they are set to that be default. It can be shortened to
    SCAR Code:
    frmDesign := CreateForm;
    frmDesign.Left := 250;
    frmDesign.Top := 114;
    frmDesign.Width := 696;
    frmDesign.Height := 480;
    frmDesign.Caption := 'frmDesign';
    (or even further if you really want to shorten it.)

    All components have default heights and widths too. So if you know that you want your form to be the default size of a form, then just dont put it in, and it will work just as well. I just find it to be easier to leave default properties, out and it shortens your code too!


    1.3 Events
    Events are a bit more complicated than properties. Every component has its own set of events at its disposal. Every time the event for that event happens, whichever procedure you're sending it to is called. To put that more simply. The names of events, which are fairly self explanatory, tell what the event catches. For example, the OnClick event catches every time the mouse it left clicked on that component. Every time that event happens, it will call the specified procedure and run that code.

    Now, lets say you have this form.
    SCAR Code:
    var
      frmDesign : TForm;
      Button1 : TButton;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      frmDesign.Left := 259;
      frmDesign.Top := 132;
      frmDesign.Caption := 'Clicker';
      Button1 := TButton.Create(frmDesign);
      Button1.OnClick:= @buttonclick;
      Button1.Parent := frmDesign;
      Button1.Left := 69;
      Button1.Top := 61;
      Button1.Width := 75;
      Button1.Caption := 'Click Me';
    end;

    procedure SafeInitForm;
    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    procedure SafeShowFormModal;
    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end;

    begin
      SafeInitForm;
      SafeShowFormModal;
    end.
    Now when the button is clicked, you want it to pop up a message saying "You've clicked this button x number of times!". To do this, you'll need to implement the OnClick event. just add
    SCAR Code:
    button1.OnClick := @YourProcedureName;//any name will work...well any name that would usually work as a procedure name :)
    to your InitForm procedure (preferably grouped with the other button1 properties). The only thing that should look unfamiliar is the @. That my friends is a function sender. It basically just reroutes your code to go to that procedure when the event is called. Now just create a procedure with the name you inputted earlier.

    But wait! theres a catch. All events' procedures have special parameters that need to be there for the script to work. To find these parameters, go to Tools -> Event Handlers List, and find OnClick. In the debug box, its now going to have
    Quote Originally Posted by SCAR
    procedure OnClick(Sender: TObject);
    Just stick "(Sender: TObject);" on to the end of your procedure and thats it. Then every time you click the button it will run whatever code you have in that procedure. in our case, the final code will look something like this -
    SCAR Code:
    var
      frmDesign : TForm;
      Button1 : TButton;
      i: integer;
     
    procedure YourProcedureName(Sender: TObject);
    begin
      i := i + 1;
      ShowMessage('You''ve clicked this button ' + IntToStr(i) + ' times!');
    end;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      frmDesign.Left := 259;
      frmDesign.Top := 132;
      frmDesign.Caption := 'Clicker';
      Button1 := TButton.Create(frmDesign);
      Button1.Parent := frmDesign;
      Button1.Left := 69;
      Button1.Top := 61;
      Button1.Width := 75;
      Button1.Caption := 'Click Me';
      button1.OnClick := @YourProcedureName;
    end;

    procedure SafeInitForm;
    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    procedure SafeShowFormModal;
    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end;

    begin
      SafeInitForm;
      SafeShowFormModal;
    end.

    There are a few things to know though.
    1. You must have a procedure with the name you sent it, else your script will not compile.
    2. You can put the event for more than one component in the same procedure. For example.
    SCAR Code:
    Button1 := TButton.Create(frmDesign);
      Button1.Parent := frmDesign;
      Button1.Left := 69;
      Button1.Top := 61;
      Button1.Width := 75;
      Button1.Caption := 'Click Me';
      button1.OnClick := @YourProcedureName;
      Button2 := TButton.Create(frmDesign);
      Button2.Parent := frmDesign;
      Button2.Left := 100;
      Button2.Top := 61;
      Button2.Caption := 'Click Me Too!';
      button2.OnClick := @YourProcedureName;
    then, often you'll run into the problem of no knowing which button was clicked. This, though, can be easily fixed by using a case. the sender variable holds the name of the object that was clicked, so you could do this.
    SCAR Code:
    procedure YourProcedureName(Sender: TObject);
    begin
      case sender of
      button1: begin
                 i := i + 1;
                 ShowMessage('You''ve clicked this button ' + IntToStr(i) + ' times!');
               end;
      button2: begin
                 e := e + 1;
                 ShowMessage('You''ve clicked this button ' + IntToStr(e) + ' times!');
               end;
    end;
    3. You can mix and match events as long as their parameters match. For example. the parameters for OnCreate are (Sender: TObject). So you could put that in the same procedure as OnClick, but the parameters for the OnMouseDown event are (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer), so you couldnt put that in the same procedure, even though, the OnClick event has Sender as a parameter too.


    1.4 Methods
    Methods are quite simple. They are just pre-built procedures and functions that are built into the object. Free, SendToBack, BringToFront, and Repaint are all methods. There's not much to explain about them. Each object has their own set of methods, though there are some that are consistent within all objects (the 4 above are by the way). You essentially add your own if you were to make yourself a record with a form component in it, but that is something that you'll learn in a different tutorial.


    1.5 Making a Simple Form
    Well, now that you've learned the basics, lets make a form! Im not going to make anything too complicated just, yet, but bear with me for the moment.

    Firstly, Open up your Form Editor and lets start out with a simple form with two Tbuttons on it, a Tlistbox, and a TEdit too. You can change the names to Ok, Cancel, List, and Name (in that order). And You can change the Caption of the buttons to Ok, and Cancel.

    Now Save that and put it into a working script (like in 1.1).
    i came out with this
    SCAR Code:
    program New;
    var
      frmDesign : TForm;
      Ok, Clear: TButton;
      List: TListbox;
      Name: TEdit;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      frmdesign.Position := poScreenCenter; //a property that can take poScreenCenter, poDefault, poDefaultPosOnly, poDefaultSizeOnly, poDesktopCenter, poMainFormCenter, and poOwnerFormCenter
      frmDesign.Width := 269;
      frmDesign.Height := 359;
      frmDesign.Caption := 'Add Names';
      frmdesign.AutoScroll := False;        //Keeps the form from adding a scrollbar.
     
      Ok := TButton.Create(frmDesign);      //Every Object must be created before using it.
      Ok.Parent := frmDesign;               //every object must have a parent (except for TForm) usually its the same as the owner
      Ok.SetBounds(88,288, 75, 25);         //Adds the Width, Height, Left, and Top in one line.
      Ok.Caption := 'Ok';

      Clear := TButton.Create(frmDesign);
      Clear.Parent := frmDesign;
      Clear.SetBounds(160,16,75,25);
      Clear.Caption := 'Clear';

      Name := TEdit.Create(frmDesign);
      Name.Parent := frmDesign;
      Name.SetBounds(24,16,121,21);

      List := TListBox.Create(frmDesign);
      List.Parent := frmDesign;
      List.SetBounds(24, 48, 209, 233);
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end.
    Now add OnClick Events to Ok, and Clear and add this procedure up top
    SCAR Code:
    procedure Go(Sender: TObject);
    begin
      case sender of
        Ok: begin
              List.Items.Append(Name.Text); //Adds an item to the end of the list. The text of the item is the text in the Tedit.
              Name.Clear;                   //Clears the text from the Tedit.
              Name.SetFocus;                //Keeps the cursor in the TEdit.
            end;
        Clear: Name.Clear;                  //Clears the text from the Tedit.
        List: if List.ItemIndex <> 0 then   //ItemIndex is the currently selected Item (starts at 0).
                Name.Text := List.Items[List.ItemIndex]; //Changes, the text of the TEdit to the text of the selected item in the TListbox
      end;
    end;
    Now you have a simple form that adds things into a list.


    1.6 Good Form Syntax
    One of the worst thing i see in people that are new to forms is what i've been showing you since the beginning of the chapter -
    SCAR Code:
    frmdesign.left := 3;
    I kept it like that to make it easier to understand, but there is a better way to do it.

    If you surround the properties, methods, and events by
    SCAR Code:
    {form component}.create(frmdesign);
    with {form component} do
    begin
    //properties, methods, and events
    end;
    then its much better. It looks neater, and you don't have to type in the object's name before every property.

    Another hood habit to get into is putting your main procedure into a try/finally block. It will possibly keep your form from crashing SCAR, and is generally just a good thing to do.

    Chapter 2 - Alternative Forms
    2.0 Preface
    The only reason i put this in here, is because sometimes you don't need to make your own form. There are a bunch of already made "forms" that you can use, and while many people know about ReadLn, I'm not so sure about GetApplication and others. But just, for future reference! you can use #10#13 in any of these, and the text will become multi-lined!


    2.1 ReadLn
    ReadLn is basically a command that you can use to make a form with a question, and a TEdit for the user to type the answer in. It looks like this -

    Pretty simple, the syntax for that would look something like this
    SCAR Code:
    begin
      if Pos(LowerCase('all of it'), ReadLn('How much wood could a woodchuck chuck' + #10#13 + 'if a woodchuck could Chuck Norris?')) <> - 1 then
        WriteLn('Yayz!');
    end.
    //or just the ReadLn as...
    //ReadLn('How much wood could a woodchuck chuck' + #10#13 + 'if a woodchuck could Chuck Norris?')
    Thats basically it, you ask a question, and the user inputs something.


    2.2 GetApplication
    GetApplication is a bit more complicated. Basically all you'll be doing is pulling up the message box. The Syntax of using it is
    SCAR Code:
    GetApplication.MessageBox({What you want to say}, {Caption of your form}, {type of form});
    The big, interesting, and useful part of this is there are 7 different forms that you can make with just this one thing!

    0 -


    1 -


    2 -


    3 -


    4 -


    5 -


    6 -

    Thats all well and good, but how are you supposed to get what they clicked?! Fear not young lad! I haveth the answer! Usually what i do is something along the lines of -
    SCAR Code:
    case GetApplication.MessageBox('Imma try an'' save again if thats ok!', 'Save', 3) of
    mrYes: Save
    mrNo: DontSave
    //mrCancel: not needed because i dont want it to do anything upon canceling
    end;

    Now if you're wondering how you're going to know all of the variables, then look at the next section

    2.2 MessageDlg
    This is almost exactly like GetApplication.MessageDlg, but it is quite a bit more customizable. With this you can add icons, add different combinations of buttons, and more.

    The Syntax for this command is
    SCAR Code:
    function MessageDlg ( const Message  : string; DialogType  : TMsgDlgType; Buttons : TMsgDlgButtons; HelpContext : Longint ) : Integer;

    The Message can be anything, and the DialogType may have one of the following values:
    mtWarning : Displays a exclamation symbol
    mtError : Displays a red 'X'
    mtInformation : Displays an 'i' in a bubble
    mtConfirmation : Displays an question mark
    mtCustom : Displays just the message

    The Buttons value may be one or more of the following values:
    mbYes : Displays a 'Yes' button
    mbNo : Displays a 'No' button
    mbOK : Displays an 'OK' button
    mbCancel : Displays a 'Cancel' button
    mbAbort : Displays an 'Abort' button
    mbRetry : Displays a 'Retry' button
    mbIgnore : Displays an 'Ignore' button
    mbAll : Displays an 'All' button
    mbNoToAll : Displays a 'No to all' button
    mbYesToAll : Displys a 'Yes to all' button
    mbHelp : Displays a 'Help' button

    You must put these values in between brackets ( "[ ]" ), and you can leave HelpContext as 0 for now. Now for examples!
    SCAR Code:
    MessageDlg('You shouldnt be here! Leave now?', mtWarning, [mbYes,mbNo,mbAbort, mbRetry], 0);
    That will show up as


    Now to that list i was telling you about!
    1. mrOK = 1
    2. mrCancel = 2
    3. mrAbort = 3
    4. mrRetry = 4
    5. mrIgnore = 5
    6. mrYes = 6
    7. mrNo = 7
    8. mrAll = 8
    9. mrNoToAll = 9
    10. mrYesToAll = 10

    you can use the enumerated values of the actual return values when checking to see which button was pressed.


    1.4 InputQuery/InputBox
    Now for more! InputQuery and InputBox are almost the same as ReadLn. Except for a few things. As far as i know InputQuery, InputBox, and ShowMessage (in the next section) need forms to already have been created, in order to work. Their synax are as follows -
    SCAR Code:
    function InputBox ( const Caption, Prompt, Default  : string ) : string;
    function InputQuery ( const Caption, Prompt  : string; var UserValue  : string ) : Boolean;
    First, InputBox. InputBox works the same as ReadLn in the effect that it gets input from the user. Thats where their similarities end. It allows you to Change the caption of the window as well as setting the window text. But the really cool thing about InputBox, is that it allows you to set default text. For example, with the following script...
    SCAR Code:
    var
      frmDesign : TForm;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      frmDesign.Position := poScreenCenter;
      frmDesign.Width := 354;
      frmDesign.Height := 254;
      frmDesign.Caption := 'frmDesign';
      InputBox('Ham','Do you like ham?','Yesm, i love ham!');
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end.
    will look like this, when run - . Not much else to say!

    Now to MessageQuery! MessageQuery, is a bit different. It also gets test from the user, but it returns true or false depending on whether text was inputted or not. It also requires a variable to be inputted as the Value parameter. With this code...
    SCAR Code:
    program New;
    var
      frmDesign : TForm;
      a: string;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      frmDesign.Position := poScreenCenter;
      frmDesign.Width := 354;
      frmDesign.Height := 254;
      if InputQuery('Yays','You am here?', a) then
        writeln(a);
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end.
    it looks a little something like this!


    1.5 ShowMessage
    Now for the final one...ShowMessage! It also requires a form to be created o be used. And it is also quite an easy one.
    SCAR Code:
    procedure ShowMessage ( const Text  : string ) ;
    All you need to do is to type in the text you want to output and it will do so for you! In other words, this -
    SCAR Code:
    var frmdesign: TForm;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      frmDesign.Position := poScreenCenter;
      frmDesign.Width := 354;
      frmDesign.Height := 254;
      ShowMessage('I''ve got a lovely bunch of coconuts!');
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end.
    will look like this -


    Chapter 3 - Good Things to Know
    3.1 - Parent vs. Owner
    While its true that most of the time your parent and owner will be the same object, they are not the same thing. The owner is the object's name that you put into the () after creating it. For example -
    SCAR Code:
    Button := TButton.create(frmdesign);

    In that case frmdesign is the owner of the object Button. When you free an owner, it takes care of freeing all of the owned components, so you dont have to. That is why you dont have to go around freeing all of the components on your form when you close it. The form is the owner of all of the objects, so it frees them all.


    The parent on the other hand is a property of an object. For example -
    SCAR Code:
    Button.parent := Panel;
    In this case Panel is the parent of Button. The the child of the parent (any object that uses Panel as its parent in the example above) will be "on top" of the owner. That means that the position of the object will be based off of the parent. Example- (simple example...not the whole code)

    Panel. left := 40;
    Button.parent := Panel;
    button.left := 5;

    With the form as Button's parent, the left of the button would be 5 pixels past the left edge of the form. With Panel as Button's parent, it will be 5 pixels past the left of the Panel.

    Now for a nice big example with pictures .
    SCAR Code:
    var
      frmDesign : TForm;
      Onbutton, Offbutton: TButton;
      Panel: TPanel;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      frmDesign.Position := poScreenCenter;
      frmDesign.Width := 354;
      frmDesign.Height := 254;
      offbutton := TButton.Create(frmDesign);
      with offbutton do
      begin
        Parent := frmDesign;
        Left := 60;
        Top := 60;
        Width := 100;
        Caption := 'Im on the Form!';
      end;
      panel := Tpanel.Create(frmDesign);
      with panel do
      begin
        Parent := frmDesign;
        Left := 60;
        Top := 100;
      end;
      onbutton := TButton.Create(frmDesign);
      with onbutton do
      begin
        Parent := Panel;
        Left := 5;
        Top := 5;
        Width := 100;
        Caption := 'Im on the Panel!';
      end;
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end.
    Normally with 5 as the top and left, the Onbutton would be way to the left of the form, but with Panel as the parent look at it now!




    Chapter 4 - Working with Various Components
    1.1 Timer
    Now lets say we want to make a stop watch. and show it as a form. Hmmm...i think i see a problem with that. You arent going to make it update the form! But fear not! Timers, are the solution. All a timer basically does is, it calls the Procedure that you send from the event, OnTimer. And it calls that procedure every interval milliseconds. You set the interval of the timer after creating it. got it? Well lets go make that stopwatch just to be sure.

    All you need to make a timer is this
    SCAR Code:
    var timer: TTimer;
    begin
      timer := timer.create(frmdesign);
      timer.interval := 1000; // can be anything...1000 is 1 second by the way.
      timer.OnTimer := @//procedurename
    end;
    So this is what my code looks like after adding the form, two buttons (called start and stop, a label,and the timer.
    SCAR Code:
    var
      frmdesign: TForm;
      Start, Stop: TButton;
      Timer: TTimer;
      time: TLabel;

    procedure GoStop(Sender: TObject);
    begin

    end;

    procedure Update(Sender: TObject);
    begin

    end;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      with frmDesign do
      begin
        Position := poScreenCenter;
        Height := 100;
        Width := 400;
        Caption := 'Stop Watch';
        autoscroll := false;
      end;
      Start := TButton.create(frmdesign);
      with start do
      begin
        parent := frmdesign;
        SetBounds(5, 5, 35,25);
        Caption := 'Start';
        OnClick := @GoStop;
      end;
      Stop := TButton.create(frmdesign);
      with stop do
      begin
        parent := frmdesign;
        SetBounds(5, 35, 35,25);
        Caption := 'Stop';
        OnClick := @GoStop;
      end;
      Time := TLabel.create(Frmdesign);
      with time do
      begin
        caption := '00:00:00';
        parent := frmdesign;
        SetBounds(50,0, 100, 100);
        Font.Size := 40;
      end;
     
      Timer := TTimer.create(frmdesign);
      Timer.interval := 100;
      Timer.OnTimer := @Update;
      Timer.enabled := false;
    end;

    procedure SafeInitForm;
    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    procedure SafeShowFormModal;
    var
      v: TVariantArray;
    begin
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end;

    begin
      try
        SafeInitForm;
        SafeShowFormModal;
      finally
        FreeForm(frmDesign);
      except
        WriteLn('meh!!!');
      end;
    end.
    Now in the GoStop procedure we can just add a simple case and disable/enable the timer based on which button was clicked.
    SCAR Code:
    procedure GoStop(Sender: TObject);
    begin
      case sender of
        Start: Timer.Enabled := true;
        Stop: Timer.Enabled := false;
      end;
    end;
    Now for the cool Part. Add 4 global variables - mil, sec, min, hour. Then add this into your Update procedure
    SCAR Code:
    procedure Update(Sender: TObject);
    begin
      mil := mil + 1;                  //adds a millisecond
      if mil >= 100 then
      begin
        mil := 0;                      //resets the miliseconds
        sec := sec + 1;                //adds a second
        if sec >= 60 then
        begin
          sec := 0;                    //resets the seconds
          min := min + 1;              //adds a minute
          if min >= 60 then
          begin
            min := 0;                  //resets the minutes
            hour := hour + 1;          //adds an hour
          end;
        end;
      end;
      time.caption := inttostr(hour) + ':' + inttostr(min) + ':' + inttostr(sec) + ':' + inttostr(mil);
    end;
    And there is your...probably not so accurate, but still working example of a stopwatch.


    1.2 MainMenu
    And Now! The TMainMenu. Of the few people that I've seen use MainMenus in SCAR, i don't think i've seen anyone make an actual useful one (meaning more than 1 menu with 2-3 options). I don't plan to make a useful one right now, this one is just a proof of concept. Also, just so you know, the way i do this, you won't have a variable to look at and automatically know what menu it is, but the way i do it is more efficient and easier to add/subtract menus

    Ok, now start off with a blank form.
    SCAR Code:
    var
      frmDesign : TForm;

    procedure InitForm;
    begin
      frmDesign := CreateForm;
      frmDesign.Position := poScreenCenter;
      frmDesign.Width := 354;
      frmDesign.Height := 254;
      frmDesign.Caption := 'frmDesign';
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    var
      v: TVariantArray;
    begin
      GetSelf.WindowState := wsMinimized; //Minimizes SCAR for you.
      try
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
      finally
        FreeForm(frmDesign);
      except
        WriteLn('meh!!!');
      end;
      GetSelf.WindowState := wsMaximized; //Maximaizes SCAR for you.
    end.
    Now add: a TMainMenu, an array of array of TMenuItem, and an array of TStringArray as global variables. The String array is to hold the names of your menu. So set the length of your array and add some Menu names!
    SCAR Code:
    SetArrayLength(Names, 4);   //include the name of the Menus at the beginning (File, Edit, etc)
      Names[0] := ['File', 'New', 'Open', 'Save', 'Save As', 'Exit'];
      Names[1] := ['Edit', 'Cut', 'Copy', 'Paste', 'Delete', 'Select All'];
      Names[2] := ['Tools', 'Options'];                 //got all these from the SCAR menus :P
      Names[3] := ['Help', 'Help', 'Manual', 'About'];
    Now to creating the actual menus. This is where it might get a little bit complicated.
    SCAR Code:
    SetArrayLength(Menu, GetArrayLength(names));   //Sets the length of the Menu array to the number of menus
      Main := TMainMenu.Create(frmdesign);           //Creates the MainMenu that holds all of the items
      for i := 0 to high(names) do                   //Cycles through each Names array
      begin
        SetArrayLength(Menu[i], GetArrayLength(Names[i]));//Sets the length of menu items to the number of items in the corresponding names array
        for e := 0 to high(names[i]) do              //Cycles through each item in Names[i]
        begin
          Menu[i][e] := TMenuItem.Create(frmdesign); //Creates each MenuItem
          Menu[i][e].Caption := Names[i][e];         //Makes the Caption of each Item, the specified string
          if e = 0 then                              //if its the first item in the array then
            Main.Items.Add(Menu[i][e])               //add it as a Menu
          else                                       //else
            Main.Items.Items[i].add(Menu[i][e]);     //add it as an Item to the "i" menu
          Menu[i][e].OnClick := @MenuClick;          //OnClick event for the menu items
        end;
      end;
    This is why we have an array of array. You could do it as just an array, but then it would get more confusing. This way you at least will know which menu its in. Also, your OnClick event will work like it did in the earlier chapter (using a case). So it should look something like this.
    SCAR Code:
    procedure MenuClick(Sender: TObject);
    begin
      case sender of
        Menu[0][1]: begin   //I skipped [0][0] because thats the actual menu, and you probably
                    end;    //won't want an onclick for that one. (though you can)
        Menu[0][2]: begin
                    end;
        /////etc/////
    end;
    And in the end the entire script should look like this.
    SCAR Code:
    var
      frmDesign : TForm;
      Main: TMainMenu;
      Menu: array of array of TMenuItem;
      Names: array of TStringArray;
     
    procedure MenuClick(Sender: TObject);
    begin
      case sender of
        Menu[0][1]: begin   //I skipped [0][0] because thats the actual menu, and you probably
                    end;    //won't want an onclick for that one. (though you can)
        Menu[0][2]: begin
                    end;
        /////etc/////
    end;
     
    procedure InitForm;
    var i, e: integer;
    begin
      frmDesign := CreateForm;
      frmDesign.Position := poScreenCenter;
      frmDesign.Width := 354;
      frmDesign.Height := 254;
      frmDesign.Caption := 'frmDesign';
      SetArrayLength(Names, 4);
      Names[0] := ['File', 'New', 'Open', 'Save', 'Save As', 'Exit'];
      Names[1] := ['Edit', 'Cut', 'Copy', 'Paste', 'Delete', 'Select All'];
      Names[2] := ['Tools', 'Options'];
      Names[3] := ['Help', 'Help', 'Manual', 'About'];
      SetArrayLength(Menu, GetArrayLength(names));   //Sets the length of the Menu array to the number of menus
      Main := TMainMenu.Create(frmdesign);           //Creates the MainMenu that holds all of the items
      for i := 0 to high(names) do                   //Cycles through each Names array
      begin
        SetArrayLength(Menu[i], GetArrayLength(Names[i]));//Sets the length of menu items to the number of items in the corresponding names array
        for e := 0 to high(names[i]) do              //Cycles through each item in Names[i]
        begin
          Menu[i][e] := TMenuItem.Create(frmdesign); //Creates each MenuItem
          Menu[i][e].Caption := Names[i][e];         //Makes the Caption of each Item, the specified string
          if e = 0 then                              //if its the first item in the array then
            Main.Items.Add(Menu[i][e])               //add it as a Menu
          else                                       //else
            Main.Items.Items[i].add(Menu[i][e]);     //add it as an Item to the "i" menu
          Menu[i][e].OnClick := @MenuClick;          //OnClick event for the menu items
        end;
      end;
    end;

    procedure ShowFormModal;
    begin
      frmDesign.ShowModal;
    end;

    var
      v: TVariantArray;
    begin
      GetSelf.WindowState := wsMinimized; //Minimizes SCAR for you.
      try
      setarraylength(V, 0);
      ThreadSafeCall('InitForm', v);
      setarraylength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
      finally
        FreeForm(frmDesign);
      except
        WriteLn('meh!!!');
      end;
      GetSelf.WindowState := wsMaximized; //Maximaizes SCAR for you.
    end.


    1.3 Tabs
    Now tabs are pretty nifty and can come in handy for quite a few things. There are two types of tabs that i'll be teaching about, the TTabControl and the TPageControl. They are quite similar, but for a few things. First off, the TTabControl contains all of its tabs in its own object, but the TPageControl on the other hand, needs TTabSheets to hold its tabs (like the MainMenu).

    1.3 TTabControl
    The TTabControl is more suited towards applcations where the objects in each tab are all the same, like a tabbed text editor (like notepad++). The only thing on your tab is the box you type into. The TTabControl has some extra options, but in general the TPageControl is easier to use. Now for the learning part

    First start off with a blank form. then add
    SCAR Code:
    Tab: TTabControl;
    into your global vars. Then you have to create the TTabControl.
    SCAR Code:
    Tabs := TTabControl.Create(frmdesign);
      Tabs.Parent := frmdesign;
      Tabs.SetBounds(0,0,frmdesign.width, 21);
      Tabs.Tabs.Append('First');  //the name of the tab you want.
      Tabs.Tabs.Append('Second');
      Tabs.Tabs.Append('Third');
      Tabs.Tabs.Append('Fourth');
    Now you have working tabs! The only problem is that you cant tell the difference between any of them, because you dont have anything on them. So now how about you add a TMemo to the global variables. Create it with this code (inserted after the creation of the TTabControl).
    SCAR Code:
    Memo := TMemo.Create(frmdesign);
      with Memo do
      begin
        Parent := frmdesign;
        SetBounds(0, tab.height, frmdesign.width - 7, frmdesign.height - tab.Height - 32);
      end;
    Ok now that thats done, add a TStringArray to your global variables and set its array length to 4. Also, add an onChange event to Tab and add this to the procedure you send it to-
    SCAR Code:
    Memo.text := s[Tab.TabIndex];//tabindex is the currently selected tab
    Now add an OnChanging event to tab and add this-
    SCAR Code:
    procedure Changing(Sender: TObject; var AllowChange: Boolean);
    begin
      s[Tab.TabIndex] := memo.text; //this saves the text before the tab is changed.
    end;
    Now you should have a fully functioning, tab-changing type thing.

    1.3 TPageControl
    The TPageControl is more suited towards applications where each tab has its own different items, like in an options menu. That's because you can set those objects' owner to the TTabSheets and they will change with the changing of the tab.


    Well thats it for now. It should be updated pretty soon! I welcome any suggestions, and comments. Also if anything is hard to understand, then feel free to ask, and i'll make things more clear, up here in the first post.
    SCAR Tutorials: The Form Tutorial | Types, Arrays, and Classes
    Programming Projects: NotePad | Tetris | Chess


  2. #2
    Join Date
    Feb 2007
    Location
    Alberta,Canada
    Posts
    2,358
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Amazing Definatly ++rep, and I was really looking for a tut like this, congrads dude, looks like it took alot of work.
    “Ignorance, the root and the stem of every evil.”

  3. #3
    Join Date
    Jan 2008
    Location
    NC, USA.
    Posts
    4,429
    Mentioned
    0 Post(s)
    Quoted
    4 Post(s)

    Default

    TUT CUP FO U! This is amazing!
    Quote Originally Posted by irc
    [00:55:29] < Guest3097> I lol at how BenLand100 has become noidea
    [01:07:40] <@BenLand100> i'm not noidea i'm
    [01:07:44] -!- BenLand100 is now known as BenLand42-
    [01:07:46] <@BenLand42-> shit
    [01:07:49] -!- BenLand42- is now known as BenLand420
    [01:07:50] <@BenLand420> YEA

  4. #4
    Join Date
    Feb 2007
    Location
    Alberta,Canada
    Posts
    2,358
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    oooh i got a suggestion. Maybe show how to add a picture for a background (copytocanvas stuff) and maybe show how to use tabs.
    “Ignorance, the root and the stem of every evil.”

  5. #5
    Join Date
    Apr 2007
    Posts
    3,152
    Mentioned
    3 Post(s)
    Quoted
    1 Post(s)

    Default

    both are already on the list at the top . It's too bad i cant do any html...it would be a lot easier to traverse my tut if i could
    SCAR Tutorials: The Form Tutorial | Types, Arrays, and Classes
    Programming Projects: NotePad | Tetris | Chess


  6. #6
    Join Date
    Sep 2008
    Location
    Sweden
    Posts
    70
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    Thanks alot, really helped me when improving my script

  7. #7
    Join Date
    Oct 2008
    Location
    C:\Simba\Includes\
    Posts
    7,566
    Mentioned
    19 Post(s)
    Quoted
    180 Post(s)

    Default

    Very nice tutorial! I knew about form editing in VB08 but I didn't know they were kind of the same, just set around Scar. I will defiantly use this! Thanks, ++Rep!!

    ~Camo
    Away for awhile, life is keeping me busy. | Want to get my attention in a thread? @Kyle Undefined; me.
    { MSI Phoenix || SRL Stats Sigs || Paste || Scripts || Quotes || Graphics }

    When posting a bug, please post debug! Help us, help you!

    I would love to change the world, but they won't give me the source code. || To be the best, you've got to beat the rest. || Logic never changes, just the syntax.
    If you PM me with a stupid question or one listed in FAQ, or about a script that is not mine, I will NOT respond.


    SRL is a Library of routines made by the SRL community written for the Program Simba. We produce Scripts for the game Runescape.


  8. #8
    Join Date
    Dec 2008
    Posts
    160
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    wow i cant thank yu enouph ty

  9. #9
    Join Date
    Mar 2007
    Location
    <3
    Posts
    2,683
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Nice one.

  10. #10
    Join Date
    Sep 2006
    Posts
    6,089
    Mentioned
    77 Post(s)
    Quoted
    43 Post(s)

    Default

    Nice work
    Hup Holland Hup!

  11. #11
    Join Date
    Feb 2006
    Location
    Amsterdam
    Posts
    6,136
    Mentioned
    28 Post(s)
    Quoted
    17 Post(s)

    Default

    You should WIKIwize this!
    SRL is a Library of routines made by the SRL community written for the Program Simba.
    We produce Scripts for the game Runescape.

  12. #12
    Join Date
    Dec 2006
    Location
    Program TEXAS home of AUTOERS
    Posts
    7,934
    Mentioned
    26 Post(s)
    Quoted
    237 Post(s)

    Default

    wow dude like only great form tut atm, others were really good too but unfinished

    gj , good tut for beginners.

  13. #13
    Join Date
    Mar 2007
    Posts
    1,700
    Mentioned
    0 Post(s)
    Quoted
    8 Post(s)

    Default

    I prefer never to use the 'with' statement. Why? Watch this:
    http://www.codegearguru.com/video/019/With.html

    And another good tutorial for Parent vs Owner:
    http://www.codegearguru.com/video/01...rVsParent.html

  14. #14
    Join Date
    Feb 2007
    Location
    Alberta,Canada
    Posts
    2,358
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    wow those videos are awesome. Question: I like the form editor he's using, its obiously for dephi, so my question is, if i use that to create a form for my script, will it be compatible with scar?
    “Ignorance, the root and the stem of every evil.”

  15. #15
    Join Date
    May 2007
    Location
    England
    Posts
    4,140
    Mentioned
    11 Post(s)
    Quoted
    266 Post(s)

    Default

    If Delphi saves the forms made in it as a .dfm, then yes, it should work.
    <3

    Quote Originally Posted by Eminem
    I don't care if you're black, white, straight, bisexual, gay, lesbian, short, tall, fat, skinny, rich or poor. If you're nice to me, I'll be nice to you. Simple as that.

  16. #16
    Join Date
    Apr 2007
    Posts
    3,152
    Mentioned
    3 Post(s)
    Quoted
    1 Post(s)

    Default

    Quote Originally Posted by ~~Joker~~ View Post
    wow dude like only great form tut atm, others were really good too but unfinished

    gj , good tut for beginners.
    mine is also unfinished at the moment , but i actually plan to, and have already started finishing it, so...ya i know what you mean.

    Quote Originally Posted by WT-Fakawi View Post
    You should WIKIwize this!
    for what?

    Quote Originally Posted by lordsaturn View Post
    I prefer never to use the 'with' statement. Why? Watch this:
    http://www.codegearguru.com/video/019/With.html

    And another good tutorial for Parent vs Owner:
    http://www.codegearguru.com/video/01...rVsParent.html
    firefox and IE, and opera, and safari refuse to play those videos, though i think i may have already looked at the owner vs. parent one. and my reasoning for using with is because it saves typing and is neater, im not sure what reasoning that video might have, but i sure havent run into any problems with it, so i dont feel bad recommending it to other people.

    Quote Originally Posted by Blumblebee View Post
    wow those videos are awesome. Question: I like the form editor he's using, its obiously for dephi, so my question is, if i use that to create a form for my script, will it be compatible with scar?
    as long as you don't use any components that arent compatible with SCAR, then i don't see why not, though you may have a problem with some properties not being in SCAR too.
    SCAR Tutorials: The Form Tutorial | Types, Arrays, and Classes
    Programming Projects: NotePad | Tetris | Chess


  17. #17
    Join Date
    Oct 2006
    Location
    ithurtsithurtsithurtsithurts
    Posts
    2,930
    Mentioned
    7 Post(s)
    Quoted
    135 Post(s)

    Default

    Quote Originally Posted by Dan Cardin View Post
    firefox and IE, and opera, and safari refuse to play those videos, though i think i may have already looked at the owner vs. parent one. and my reasoning for using with is because it saves typing and is neater, im not sure what reasoning that video might have, but i sure havent run into any problems with it, so i dont feel bad recommending it to other people.
    Here's a summary of the what the video talked about (taken from the video itself):
    Summary of With:
    • Can in some instances make code more concise and/or clear.
    • Can introduce (very) hard to find bugs.
    • Other drawbacks:
      [-]Prevents some refactorings.
      [-]Code can be harder to manipulate.
    I'd recommend watching the video yourself if you can get it to work, of course.

  18. #18
    Join Date
    Mar 2007
    Posts
    1,700
    Mentioned
    0 Post(s)
    Quoted
    8 Post(s)

    Default

    @Blumblebee

    Yes, it is possible. You can create a form in a plugin for scar, such as SMM's form plugin.

  19. #19
    Join Date
    Feb 2007
    Location
    Alberta,Canada
    Posts
    2,358
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    mhkay, mind pointing me in a direction of a good program to use?
    “Ignorance, the root and the stem of every evil.”

  20. #20
    Join Date
    Mar 2007
    Posts
    1,700
    Mentioned
    0 Post(s)
    Quoted
    8 Post(s)

    Default

    http://www.codegear.com/products/delphi/win32
    it costs a lot, but it's not too hard to get a hold of. I know i didn't pay for it

    or if you insist on being legal:
    http://turboexplorer.com/delphi

  21. #21
    Join Date
    Feb 2007
    Location
    Alberta,Canada
    Posts
    2,358
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    thanks a bunch dude +rep
    “Ignorance, the root and the stem of every evil.”

  22. #22
    Join Date
    Apr 2007
    Posts
    3,152
    Mentioned
    3 Post(s)
    Quoted
    1 Post(s)

    Default

    The problem that i found with the tutorial is that its quite long. Thats good because it teaches lots-o-knowledge. The downside is that this is a forum. And unless i make 25 posts it wont be easily navigate able. So i have now put it in wiki format, with some fixing of errors, here

    EDIT: and i expect to continue adding to it soon.
    SCAR Tutorials: The Form Tutorial | Types, Arrays, and Classes
    Programming Projects: NotePad | Tetris | Chess


  23. #23
    Join Date
    Dec 2007
    Posts
    2,766
    Mentioned
    2 Post(s)
    Quoted
    37 Post(s)

    Default

    One of the best tutorials I've ever seen...

    Rep + even if its old...

  24. #24
    Join Date
    Apr 2007
    Posts
    3,152
    Mentioned
    3 Post(s)
    Quoted
    1 Post(s)

    Default

    Its not that old . It still expanding though. Ive updated quite a bit in the wiki version.
    SCAR Tutorials: The Form Tutorial | Types, Arrays, and Classes
    Programming Projects: NotePad | Tetris | Chess


  25. #25
    Join Date
    Apr 2008
    Location
    Marquette, MI
    Posts
    15,252
    Mentioned
    138 Post(s)
    Quoted
    680 Post(s)

    Default

    Wow, never knew this was here until I searched for a TMenu guide. Helped me out a lot, thanks! I'm sure I'll be using it again. Although it is for SCAR, I few small edits, and the TMainMenu part worked for Simba.

Page 1 of 2 12 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. THE big form tutorial ~ by MK
    By MasterKill in forum OSR Advanced Scripting Tutorials
    Replies: 125
    Last Post: 08-04-2013, 07:32 PM
  2. Complete Form Tutorial
    By BobboHobbo in forum OSR Advanced Scripting Tutorials
    Replies: 10
    Last Post: 05-29-2012, 01:36 PM
  3. Newbie Form Tutorial
    By Da 0wner in forum OSR Advanced Scripting Tutorials
    Replies: 45
    Last Post: 12-15-2009, 05:48 AM
  4. Form TPopupMenu tutorial
    By Freddy1990 in forum OSR Advanced Scripting Tutorials
    Replies: 13
    Last Post: 12-14-2009, 07:25 PM
  5. Ultimate form tutorial
    By jhildy in forum OSR Advanced Scripting Tutorials
    Replies: 9
    Last Post: 02-21-2008, 05:07 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •