>> Rodney Roberts IS & Education Professional Homepage   >> Programming Tutorials And Downloads   >> Model Rockets & Boost/Gliders Programming

Science makes it known,
Engineering makes it work,
Art makes it beautiful.


Lazarus Sub-form, Grid Cell Background Color, StringGrid Cell Editor, and Calling FORTRAN
(Includes Downloads)

A Lazarus sub-form is a form  shown/used/called  by a higher level form using the sub-form's
ShowModal method (calls sub-form's FormShow(...)).  The ShowModal method transfers
exclusive control to the sub-form.

This page looks at part of an actual Lazarus application (MRmain) using sub-forms  (both use
TStringGrids; one changes the cell background color to red on an error condition, the other uses
a simple StringGrid cbsEllipsis Editor Style).  One calls procedures in external Librarys.1

untBT10 / FrmBT10  and  missle14 / FrmPayload  are two sub-forms in a Lazarus multiform
application to input and analyze a model rocket design.   These two units/forms are used
to  input/modify/review  body tube (or fuselage segment) data for a model rocket.  Both use units
NumRecGlbl.pas (requires include files genetyp.inc and nrtyp.inc - see Lazarus calling FORTRAN
for more information) and MRcommon.pas (requires include file missle.inc, calls procedures in
Object Pascal Library missle02.dll) for global data and common procedures.

Form Missle10 (see footnote 2 on that page) is another sub-form used by MRmain.

Sub-form BorderIcons Properties
Recommend disabling the sub-form window minimize
and exit buttons.

StringGrid Options
Recommended for editing cells

On the sub-form TLCLComponent (or any descendent)
that closes the form, in Object Inspector set
Property ModalResult (if available) to mrNone.
In the TLCLComponent's event procedure, set
  TLCLComponent can be a TButton, TMenuItem, etc.  Avoid using TForm.Close - it will set
Simplified exploded view of
single stage rocket with
conical nose, two body tubes,
one conical boattail, and
four fins

Rocket Layout (FreeCAD 0.12)

Stage 1, Body Tube 1 can be
used as a Payload Section.

Couplers (not shown) are
used to join nose, body tubes,
and conical transitions together.

For each stage, body tubes are numbered in sequence from stage upper edge or nose tip.
For a consistent User Interface, both sub-forms display body tube sequence, body tube length, and body tube radius in a TStringGrid.  Each
TStringGrid row represents a body tube.
Body tube sequence number is temporarily stored in NumRecGlbl variable iData[ ].
Body tube length, body tube radius, body tube mass, body tube cross-sectional area, and body tube surface area are stored in MRcommon
two dimensional arrays (matrices)2MRcommon variable nbt[ ] is the number of body tubes per stage array.
Cells are right justified using TStringGridPrepareCanvas.
Cells' text are edited using TStringGridSetEditText to allow editing of each cell when entered; recommended method.
Setting ModalResult to a non-zero value closes sub-form; this application uses mrClose to indicate error free close.

untBT10 / FrmBT10

Unit untBT10.pas3 contains several procedures that are not members of Class (TFrmBT10); procedure name is not prefixed with class name. These procedures can access instance FrmBT10 variables; however, the variable name must be prefixed with the instance name.  See procedure sortBT ( ) below for an example.

'Quick and dirty' demonstration of changing StringGrid Cell background color to Red when an error occurs; a Lazarus Sub-form in an actual application; and calling FORTRAN .dll subprograms via an Object Pascal .dll.

After using the form shown in Lazarus Tabsheets to enter the basic design parameters, untBT10 / FrmBT10 (shown at right overlaying the main form MRmain) initializes the body tube data and allows the user to verify/adjust body tube sequence (only partially visible in screenshot at right; column 1), length, diameter, and optionally mass for each stage.

When length and diameter for each body tube on all stages have been entered with no errors, body tube cross-sectional and surface area is calculated using procedure BTarea (...) in missle02.dll (declaration shown below right; calls FORTRAN FUNCTION SRCYLNDR (...) in mathproc.dll 4).

By changing the body tube sequence number, it is possible to move body tubes around.

If TFrmBT10.BTstrngGridSetEditText(...) detects an error, it highlights the cell in red; requiring a TFrmBT10.BTstrngGridDrawCell(...) procedure.

Added three variables to TFrmBT10 public (shown at right): selectedCol (currently edited column), selectedRow (currently edited row), and colorCellRed (true when error occurred, false otherwise).

When TFrmBT10.BTstrngGridSetEditText(...) detects an error, it :
calls BTsgError (...) (not shown; download source untBT10.pas, link above) to process the error;
BTsgError (...) invokes FrmBT10.BTstrngGrid.Repaint;
FrmBT10.BTstrngGrid.Repaint triggers TFrmBT10.BTstrngGridDrawCell(...).

TFrmBT10.BTstrngGridDrawCell(...) is invoked whenever the grid cell is drawn; hence the code at right will "reset" the grid cell color to white when the cell is re-entered and
colorCellRed = false.

When the user selects another stage OR clicks the Sort button OR clicks the Close button,
AND  stage number of body tubes > 1, sub-form re-sequences the stage body tube matrices with procedure sortBT ( ).5

Procedure sortBT ( ) sets boolean variable indxd to true since the index table iData[ ] contains body tube sequence numbers,
then for each body tube matrix:
moves the current stage body tube matrix column to NumRecGlbl array variable rData[ ];
calls nrlazrs Object Pascal procedure indxSort (...) 6 to re-sequence rData[ ];
moves rData[ ] to current stage body tube matrix column.

Close button:
closes sub-form and transfers control back to higher level form by setting ModalResult to a non-zero value.

Higher level form shows sub-form with:

Lazarus application glider01 (boost/glider, rocket/glider, lifting body, and Rogallo flexwing design data input) also uses untBT10 / FrmBT10Rocket/gliders, lifting bodies, and Rogallo flexwings may use body tube(s)

untBT10 source code snippet

untBT10 source code snippet

untBT10 source code snippet
missle14 / FrmPayload

Unit missle14.pas contains several procedures that are not members of Class (TFrmPayload).

A 'quick and dirty' demonstration of using StringGrid cbsEllipsis Editor Style and another example of a Lazarus Sub-form in an actual application.

After using untBT10 / FrmBT10 to finalize the body tube data, missle14 / FrmPayload (shown at right overlaying MRmain) is used to select one of Stage 1's body tubes for the payload section (if any).

A payload section is used to contain cameras, radio transmitters, scientific instruments or experiments, etc., during flight.

StringGrids use cell editors to change the content of cells.  Will be using the grid's EditorByStyle method for selecting a body tube for the payload section.  The simplest, generic Editor Style to use here is cbsEllipsis, which is a simple button, to be placed in column one ("Select BT") of the sub-form's StringGrid (btStringGrid).

Clicking in column one ("Select BT") triggers TFrmPayload.btStringGridSelectEditor(...), causing a button to appear in the editing cell.

Clicking on the button invokes TFrmPayload.btStringGridEditButtonClick(...), which then loads the selected body tube data into the Payload Section data.  User may then optionally adjust payload section coupler internal lengths and specify payload mass.

TFrmPayload.btStringGridSetEditText(...) cancels any text changes the user may make to btStringGrid.

Delete button:
Sets Payload Section data to zero.

Close button:
closes sub-form and transfers control back to higher level form by setting ModalResult to a non-zero value.

Higher level form shows sub-form with:


1. The projects on this website employs software reuse extensively; this page builds on other pages on this website.
External FORTRAN FUNCTIONS/SUBROUTINES are declared the same way as an Object Pascal external function/procedure, with correct
arguments and return type; refer to Free Pascal Programmer's Guide Chapter 12, Programming shared libraries and
Variable Storage Compatibility and Equivalency.
Have found when a Lazarus program's event procedure directly calls a FORTRAN subprogram, it may produce an Access Violation Exception
when the event procedure exits, even though no calculation errors occurred.  This exception does not occur when called via a Free Pascal
Library function/procedure.

2. Each column of the body tube (or fuselage segment) matrices stores the values of all the body tubes being used in the current stage.

3. untBT10 / FrmBT10  is also being used in a Lazarus application to input and analyze Rocket/Glider and other glider designs
(Rocket/Glider and Lifting Body fuselages can be similar to model rockets).  The glider modifications require untBT10 uses unit
missle18 and constant ModelRocket.     missle18 / FrmFinShpArea  is used to input fin/wing/stabilizer measurements and shape for
both model rockets and gliders.  Boost/Glider, Rocket/Glider, and Lifting Body specific data are defined in missle18 { public declarations }.

4. Several mathproc.dll subprograms are available for download at tir33.for subprograms.
FORTRAN uses the stdcall calling convention.  Unlike Pascal, by default FORTRAN subprograms expects their arguments to be passed
by reference.

5. Had two choices at this point - use proven procedures/SUBROUTINES (would require moving each body tube matrix column to a sort
space, re-sequence the sort space, move sort space back to body tube matrix column)  OR  develop new procedures/SUBROUTINES
specifically for the body tube matrix datatype (BodyTubeData).  Selected the first choice (use proven procedures/SUBROUTINES,
use NumRecGlbl variable rData[ ] for sort space); this method had been used/tested in Missle11 / Missle10 for sorting conical transitions
matrices by Length Nose Tip to Conical Transition; see procedure sortCTstage (...) in unit MRcommon.

6. indxSort (...) calls FORTRAN SUBROUTINEs RSORT3 (...) and SAVECOPY (...) in sttstcs.dll.  In this application, RSORT3 (...) is not
used - body tube matrix columns are already indexed by iData[ ].
The Pascal arrays are passed as a fixed size array datatype, most of the FORTRAN subprograms use variable bounds dimensioning.
Fixed size array datatypes defined in include files genetyp.inc, nrtyp.inc, and missle.inc.
SAVECOPY (...) external declaration in nrlazrs.pas
RC, IORDER are defined as fixed size array datatypes
SAVECOPY (...) subroutine header in sttstcs.for
R, IORDER are dimensioned with variable bounds - argument
N2 is the number of elements
FORTRAN matrices must be explicitly (statically) dimensioned - can not use variable bounds dimensioning.
This approach has been successfully used in both D and Free Pascal programs; it may be possible this approach was a contributing factor
to the Lazarus Access Violation Exception mentioned above.

Any and all © copyrights, ™ ® trademarks, or other intellectual property (IP) mentioned here are the property of their respective owners.  No infringment is intended.

Feel free to use any of the above in your project (without violating any intellectual property rights); please give credit (same idea as Copyleft). The source code files available for download on these pages are enhanced (including error fixes) and tested periodically - check often for revised versions (some portions of source code still in beta).

Page best viewed with Mozilla FireFox 3.6.13 (or higher), Safari 5.1.7., and Android Chrome 43.0.2357.93.   Avoid Smart Applications Speed Browser.

Free web hosting provided by:

Award Space Web Hosting

Free Web Hosting X10hosting Free Web Hosting. , &  FREE WEB HOSTING

>> Rodney Roberts IS & Education Professional Homepage   >> Programming Tutorials And Downloads   >> Model Rockets & Boost/Gliders Programming