Using Form variables

Overview

When we create and use Calculation items, CalcIt provides automatically a Form to enter values for its parameters, execute the underlay Expression code and display the generated result. For simple calculation applications, that usually return a single value, this has to be adequate.

Form variables bring the ability for the CalcIt user to create his/her own custom Forms and completely control their functionality. This promotes the use of CalcIt much farther than for simple calculation or monolithic text processing purposes. Additionally the ability to create standalone CalcIt executable files makes the creation and use of custom Forms an unavoidable necessity.

To use Forms we need to successfully accomplice three simple tasks:

  1. Create a definition of the Form's layout, that is to define its size, its position on screen and what controls it carries. Visual Form Designer can help you greatly on this.
  2. Create Form variables based in a previously created layout. This really creates the Form.
  3. Provide a local function that is called every time an event is fired during the user interaction with the form and handle it as intended.

Contents in this topic

Defining Form Layouts

Before we create and use a Form we have to define its layout: How the Form looks like? What dimensions it has? Where in the desktop is positioned? What controls, that accept user input, incorporates? We create Form layouts using the command FORMDef.

FormDefID:=FORMDef(X, Y, W, H, Title, Properties List, Controls Definition list);

FORMDef returns an ID that can be used to create Form variables based on the layout it represents. Will see more on this at Creating Form variables.

An example of how a Form layout definition looks like:

const fid=FORMDef(400,200,230,250,'Euro Conversions',
            ctrLABEL ('ID1',010,000,'Change in Euro'),
            ctrPANEL ('ID2',010,016,205,40),
            ctrLEDIT ('ID3',010,080,100,'Product Price (Euro)'),
            ctrLEDIT ('ID4',115,080,100,'In Drachmas'),
            ctrLEDIT ('ID5',010,140,205,'Payment in Drachmas'),
            ctrBUTTON('ID6',060,180,100,30,'Calculate')
);

CalcIt provides a simple but effective Visual Form Designer to create Form definition statements fast without dealing much with their details. You use drag and drop to put controls in a form where you can define many of their properties. Prefer to use this tool than making the job by hand. See specific topic.

Note that FORMDef is a compile time only command. That means that is not executed at run time but completely is evaluated at compile time, before the execution of the code. For this to be possible all of its parameters must be able to be evaluated at compile time and consequently can only be constants. Expressions can be used if they contain only constants values because such expressions are evaluated at compile time and finally return a constant value. So, because the returned ID is generated at compile time it can be assigned to a constant, as in the example above. Assigning this ID to a constant is also the recommended way to handle it.


Creating and using Form variables

When we have acquire an ID for a layout is time to create a Form that really permits entering of data. It's time to create a Form variable:

set frm=FORM(FormDefID, InstanceID, CenterInScreen, Title, EventProc);

In the above example the frm Form variable is created. FormDefID is the value returned by a FORMDef command. InstanceID is any value the user chooses to identify the instance of the Form he/she creates. If there are more than one Forms in a code, this Instance ID has to be unique. For the rest of the parameters see at the Alphabetical Keywords List as will not interest us in this discussion.

After the execution of this command an instance of the requested Form layout is created. Through frm variable is now possible to handle the created Form and the Controls it contains. We handle a Form accessing for read or write its properties (like its Top position or its Title) and the properties of the Controls that may contain. Also, because the purpose of the Form is the interaction that a user can have with it, constantly his/her actions generate Events, like moving the mouse over the Form, entering text, clicking a Control etc. Also Controls and Forms can have a number of functions that can be used in the code to affect their operation, like to delete a row from a GRID control.

To access a property or use a function of the Form or one of its Controls the Form variable created as described above is used. For the Form itself follows a DOT and the name of property or function. For any of its Controls follows a expression enclosed in parentheses which returns Control's ID and, after the DOT, the name of property or function. See example below:

frm.Top:=100;       //Modifies the Top property of the Form
frm('ID1').Top:=20;
//Modifies the Top property of the Control with ID='ID1'

To respond in events generated from Controls or the Form the user has to create in his/her code one local function with specific name and interface.

function EventProc(FormID, ControlID, Action, &Data);

Especially for use inside EventProc there is a syntax to create Form variable aliases using the Form ID (or instance ID) of the Form created previously in our code.

set frm=FORM(FormDefID,100);

function EventProc(FormID, ControlID, Action, &Data);
 set AliasFrm=FORMID(100);
 ...
 ...
end;

In the code above global variable frm and AliasFrm are equivalent. They handle the same Form in the same way but with a different variable name. FORMID command can simplify programming in some situations and also is the only way to access Form variables declared locally in local functions:

function ShowAForm;
 set frm=FORM(FormDefID,100);
 ShowForm(frm);
end;

function EventProc(FormID, ControlID, Action, &Data);
 set f=FORMID(100);
 ...
 ...
end;

In the above code the local variable frm in function ShowAForm cannot be accessible in EventProc in other way than the use of FORMID command.

Form Properties & Events

The Form itself, like the Controls it can contain, has some Properties and fires some Events. Some of them are defined in the five first static parameters of the FORMDef command (Left, Top, Width, Height, Title). In the Properties List that follows the rest of them can also defined. All these are applied at the Form definition level. At run time a syntax through the Form variable is used. This was described in the above section: FormVar.PropertyName. Here is a list of Form Properties and Events:

Properties:

ACTIVECTRL, BORDER, BORDERWIDTH, COLOR, ENABLED, FONTBOLD, FONTCHARSET, FONTCOLOR, FONTNAME, FONTSIZE, HEIGHT, HINT, LEFT, TEXT, TOP, VISIBLE, WIDTH

Functions:

CLOSEFORM, SHOWFORM, WINHANDLE

Events:

OnClick, OnClose, OnMouseMove, OnTimer

 

Hiding CalcIt windows

When a code creates a Form possibly is not desirable to have the CalcIt windows appear behind. In this case we use the command Hide to hide them. When the code finishes the CalcIt windows reappear automatically. We can redisplay CalcIt windows again using Show command in our code, for example to see the Scratchpad window where possibly our code outputs data.

Redirecting text output

If we create a Form in our code and also hide CalcIt windows, is not possible to see the output of PRINT, PRINTARR. If we use these commands and want to see their output then we use SetOutput to redirect output in any Memo control in our Form.

SetOutput(frm,MemoControlID);

The above statement redirects the output of PRINT, PRINTARR to a MEMO control with MemoControlID in the Form instance handled via the variable frm. Note that only MEMO/RTFMEMO controls are accepted by this operation.

Printing Text (Printer)

The contents of the currently selected as output ctrMEMO or ctrRTFMEMO control, can be printed trough TOPRINTER command.

Form Controls

Here is the list of all available Controls. Click on any item of the list to find a description for the Control, the properties it supports, the functions that may has and the events it generates.

ctrBUTTON, ctrCHART, ctrCHECKBOX, ctrCHECKLISTBOX, ctrCODEEDIT, ctrCOMBOBOX, ctrEDIT, ctrGRID, ctrGROUPBOX, ctrLABEL, ctrLEDIT, ctrLISTBOX, ctrMEMO, ctrPAGE, ctrPANEL, ctrRADIOBUTTON, ctrRTFMEMO, ctrSPLITTER, ctrTABPAGE, ctrTRACKBAR

List Of Properties

A list of all Properties of all Controls and Form

ACTIVECTRL, ACTIVEPAGE, ALIGN, ALIGNMENT, ASKFORDEL, BEVELED, BEVELINNER, BEVELOUTER, BEVELWIDTH, BORDER, BORDERWIDTH, CELL, CHART3D, CHARTDATA, CHARTTYPE, CHECKED, COL, COLALIGN, COLCOUNT, COLOR, COLSIZING, COLWIDTH, DEFAULTCOLW, DEFAULTROWH, DROPCOUNT, ENABLED, FIXCOL, FIXCOLOR, FIXROW, FONTBOLD, FONTCHARSET, FONTCOLOR, FONTNAME, FONTSIZE, FREQUENCY, HEIGHT, HINT, HORZLINE, ITEMINDEX, LABELPOSITION, LABELTEXT, LEFT, LEGEND, LENGTH, LINE, LINEWIDTH, LISTITEMS, MARKS, MAX, MIN, NAME, NUMERIC, ORIENTATION, PACK, PAGEINDEX, POSITION, READONLY, ROW, ROWCOUNT, ROWHEIGHT, ROWINSERTS, ROWSELECT, ROWSIZING, SCROLLBARS, SLIDERSIZE, TEXT, TOP, VERTLINE, VISIBLE, WIDTH, WORDWRAP

List Of Functions

A List of all function used by Controls or Form

CLEARROW, CLOSEFORM, COUNT, DELETEROW, EMPTYROW, INSERTROW, LINESCOUNT, MOVEROW, SELECTED, SETOUTPUT, SHOWFORM, SWAPROWS, WINHANDLE

List Of Events

A List of all Events generated by Controls and Form

OnAfterDel, OnAfterIns, OnChange, OnClick, OnClose, OnKeyPress, OnMouseMove, OnTimer, OnValidValue

Form Example

The code below implements a simple text editor.

const fid=
FORMDef(10,10,562,514,'Example Editor',
  ctrPANEL('ID1',0,0,556,447,prALIGN=alCLIENT,prBORDERWIDTH=2,
    ctrMEMO('ed',3,3,550,441,'',prALIGN=alCLIENT,prBORDER=bsNONE,prFONTNAME='Courier New',prFONTSIZE=10,prSCROLLBARS=ssBOTH,prWORDWRAP=FALSE)),
  ctrPANEL('ID2',0,447,556,41,prALIGN=alBOTTOM,prBORDERWIDTH=2,
    ctrBUTTON('load',11,8,75,25,'Load'),
    ctrBUTTON('save',100,8,75,25,'Save'),
    ctrBUTTON('exit',189,8,75,25,'Exit',prFONTBOLD=TRUE)));
FName:='';
set f=FORM(fid,100,true);
ShowForm(f);
function EventProc(FrmID,CtrID,EventID,&Data);
 Select
  case(EventID=OnClick and CtrID eq 'load');
   FName:=SelectFile('','Text Files (*.txt)|*.txt');
   if(FName ne '');
    set r=READ(FName);
    f('ed').Text:=Arr2Text(r);
   end;
  case(EventID=OnClick and CtrID eq 'save');
   if(FName eq '');
    FName:=GetSaveFile('','Text Files (*.txt)|*.txt');
   end;
   if(FName ne '');
    Text2Arr(f('ed').Text,r);
    Write(FName,r);
   end;
  case(EventID=OnClick and CtrID eq 'exit');
   CloseForm(f);
 end;
end;