What is Preprocessor and How it Works ?
Preprocessor Primer ( .pdf )
What is Preprocessor and How it Works ?
Preprocessor Primer ( .pdf )
What is Preprocessor and How it Works ?
Preprocessor Primer ( .pdf )
( Status Bar, Check Box )
We are continuing with Viva_HMG.hbp, Main.prg and Main.fmg.
While using a table and while navigating between its records, we need some extra info to show to user: Name of table, current record and record count in the table. So user always feels comfortable by knowing where is he / she; which table, which record?
The status bar control is convenient for this purpose and though this is a quite simple control, IDE has a builder for it: Status bar builder.
When you choose this builder ( after open the .fmg file by IDE of course ), a dialog box will open:
By using this dialog box we can define a status bar. We can prefer define status bar manually too:
DEFINE STATUSBAR FONT "Tahoma" SIZE 9 STATUSITEM "" WIDTH 300 STATUSITEM "" WIDTH 40 DATE WIDTH 90 CLOCK WIDTH 90 END STATUSBAR
After define status bar, we need assign values to its items. We don’t need assign values to DATE and CLOCK items, because these items will be updated by system (HMG) automatically.
First a little procedure :
PROCEDURE InitEdit()
EditReco.StatusBar.Item( 1 ) := cTableFNam
ReadData()
RETURN // InitEdit()
Change ON INIT event of EditReco form from ReadData() to InitEdit(.
And add this line at end of ReadData() procedure.
EditReco.StatusBar.Item( 2 ) := LTRIM( STR( RECN() ) ) + "\" + ; LTRIM( STR( LASTREC() ) )
Let’s look at the result :
Whenever active record change, Item( 2 ) of Status Bar will be updated ( 5/25 ) in above picture.
In this step, user must use “Save” button every time current record edited. Whereas “Read” process is different; whenever current record changed, values of text boxes automatically updated. What about automatic save? May be, we can do this; but user may don’t want such automation. Asking a question like “Do you want save?” every change doesn’t a good way.
The better way may be: put a control to form such “Auto save” with On / Off option.
Yes, fortunately we have such control: Check Box.
We can replace a Check Box control to EditReco form with chbAutoSave name and Auto Save caption:
Now, how we will implement Auto Save process?.
By adding a little IF clause to ACTION events of navigation buttons:
Top : (IF(EditReco. chbAutoSave.Value , SaveData(), ), DBGOTOP(), ReadData() )
Next : (IF(EditReco. chbAutoSave.Value , SaveData(), ), DBSKIP(), ReadData() )
Previous : ( IF(EditReco. chbAutoSave.Value , SaveData(), ), DBSKIP( -1 ), ReadData() )
Last : (IF(EditReco. chbAutoSave.Value , SaveData(), ), DBGOBOTTOM(), ReadData() )
To be continued …
Execute a C or Assembler procedure
CALL <idProcedure> [WITH <exp list>]
Terminate program processing
CANCEL* | QUIT
Call a procedure
DO <idProcedure> [WITH <argument list>]
Terminate program processing
QUIT | CANCEL*
Execute a DOS command or program
RUN | !* <xcCommandLine>
Assign a procedure invocation to a key
SET KEY <nInkeyCode> TO [<idProcedure>]
Compile procedures/functions into the current .OBJ file
SET PROCEDURE TO [<idProgramFile>[.<ext>]]
Suspend program processing until a key is pressed
WAIT [<expPrompt>] [TO <idVar>]
Declare a module identifier
ANNOUNCE <idModule>
Define a sequence of statements for a BREAK
BEGIN SEQUENCE <statements>... [BREAK [<exp>]] <statements>... [RECOVER [USING <idVar>]] <statements>... END [SEQUENCE]
Execute one of several alternative blocks of statements
DO CASE CASE <lCondition1> <statements>... [CASE <lCondition2>] <statements>... [OTHERWISE] <statements>... END[CASE]
Execute a loop while a condition is true (.T.)
[DO] WHILE <lCondition> <statements>... [EXIT] <statements>... [LOOP] <statements>... END[DO]
Declare an exit procedure
EXIT PROCEDURE <idProcedure> [FIELD <idField list> [IN <idAlias>]] [LOCAL <identifier> [[:= <initializer>]]] [MEMVAR <identifer list>] . . <executable statements> . [RETURN]
Declare a list of procedure or user-defined function names
EXTERNAL <idProcedure list>
Execute a block of statements a specified number of times
FOR <idCounter> := <nStart> TO <nEnd> [STEP <nIncrement>] <statements>... [EXIT] <statements>... [LOOP] NEXT
Declare a user-defined function name and formal parameters
[STATIC] FUNCTION <idFunction>[(<idParam list>)] [LOCAL <identifier> [[:= <initializer>], ... ]] [STATIC <identifier> [[:= <initializer>], ... ]] [FIELD <identifier list> [IN <idAlias>]] [MEMVAR <identifier list>] . . <executable statements> . RETURN <exp>
Execute one of several alternative blocks of statements
IF <lCondition1> <statements>... [ELSEIF <lCondition2>] <statements>... [ELSE] <statements>... END[IF]
Declare an initialization procedure
INIT PROCEDURE <idProcedure> [(<idParam list>)] [FIELD <idField list> [IN <idAlias>]] [LOCAL <identifier> [[:= <initializer>]]] [MEMVAR <identifer list>] . . <executable statements> . [RETURN]
Place a single-line comment in a program file
NOTE This is a comment line
Create private parameter variables
PARAMETERS <idPrivate list>
Declare a procedure name and formal parameters
[STATIC] PROCEDURE <idProcedure> [(<idParam list>)] [FIELD <idField list> [IN <idAlias>] [LOCAL <identifier> [[:= <initializer>], ... ]] [MEMVAR <identifier list>] [STATIC <identifier> [[:= <initializer>], ... ]] . . <executable statements> . [RETURN]
Declare a module request list
REQUEST <idModule list>
Terminate a procedure, user-defined function or program
RETURN [<exp>]
Branch out of a BEGIN SEQUENCE…END construct
BREAK(<exp>) --> NIL
Evaluate a code block
EVAL(<bBlock>, [<BlockArg list>]) --> LastBlockValue
Return the result of an expression based on a condition
[I]IF(<lCondition>, <expTrue>, <expFalse>) --> Value
Determine the position of the last actual parameter passed
PCOUNT() --> nLastArgumentPos
Assign an action block to a key
SETKEY(<nInkeyCode>, [<bAction>]) --> bCurrentAction
Toggle Alt-C and Ctrl-Break as program termination keys
SETCANCEL([<lToggle>]) --> lCurrentSetting
Convert CALL command numeric parameters from double to int
WORD(<nNumber>) --> NIL
Control Structures – Decision making; IF..ENDIF
/*
Control Structures - Decision making; IF..ENDIF For more information refer here */ PROCEDURE Main() CLS DO WHILE .T. ACCEPT "Enter first number : " TO cString1 ACCEPT "Enter second Number : " TO cString2 nNumber1 := VAL( cString1 ) nNumber2 := VAL( cString2 ) IF nNumber1 = 0 .AND. nNumber2 = 0 EXIT ELSE IF nNumber1 > nNumber2 ? nNumber1, "is greater than", nNumber2 ELSEIF nNumber1 < nNumber2 ? nNumber1, "is less than", nNumber2 ELSE ? nNumber1, "is equal to", nNumber2 ENDIF ? ENDIF ENDDO RETURN // Main()
Produces a message that say program execution point and backward calling sequence; for debugging purposes.
Download here ( source only ).