|
|
|
|
|
- Principle
- Declaring and calling internal procedures
- Characteristics of internal procedures
- Use in callback
- Internal Procedure parameter
- Access to the variables from an internal procedure
- Nesting internal procedures
- Sibling internal procedures
- Recursive calls
- Named parameters
- Dynamic compilation
- Internal procedure and extension attributes
- Special case: using internal procedures with asynchronous functions
- Limitations
Several features require a procedure called once or several times via a WLanguage function ("Callback"). For example, the following functions are in this case: fListFile, TreeListItem, AlbumPicker in iOS, etc. A procedure must be created for these functions but several drawbacks appear: - Loss of code locality: it is not possible to see the final algorithm as a whole. Several backs and forths must be performed between the calling code and the WLanguage procedure.
- Difficulty sharing information with the WLanguage procedure: It is generally necessary to use global variables (to pass parameters to the callback or retrieve results).
In this case, the internal procedures are used to simplify the writing of callback features and to fix the problems caused when using a standard procedure. Declaring and calling internal procedures An internal procedure is declared in the code of an existing process (process associated with a control, window procedure, global procedure or class method, ...). The syntax is as follows: PROCEDURE INTERNE <Nom de la procédure>() <Code de la procédure> FIN Remarks: - The internal procedures must be declared in the process where they are used.
- Parameter input assistance is activated: a tooltip specifying the type of parameter expected is displayed when the internal procedure call is entered..
- The processing code before and after the internal procedure declaration code is executed in sequence: the internal procedure code is not executed..
Example:
INTERNAL PROCEDURE MaProcédureInterne()
END
- An internal procedure can be directly called by its name, like any standard procedure. This call can be placed before or after the declaration of internal procedure.
Example:
MaProcédureInterne()
INTERNAL PROCEDURE MaProcédureInterne()
END
MaProcédureInterne()
This allows you to get a code that is easy to read. - The exceptions triggered by the internal procedures can be processed outside the internal procedure.
Characteristics of internal procedures Use in callback The internal procedure can be used in a WLanguage functions that expects a WLanguage procedure as parameter (like fListFile, TreeListItem, ...). Warning: In this case, the parameter corresponding to the internal procedure name must correspond directly to the internal procedure name (the procedure name must not be enclosed in quotation marks).. No to do:
Res = TreeListItem(ARBRE_RecetteTV, "Recettes" + TAB + "Desserts", "DérouleTout")
INTERNAL PROCEDURE DérouleTout(ARBRE_RecetteTV, CheminFils, FilsTrouvé, Niveau, Pointeur)
...
END
Do:
Res = TreeListItem(ARBRE_RecetteTV, "Recettes" + TAB + "Desserts", DérouleTout)
INTERNAL PROCEDURE DérouleTout(ARBRE_RecetteTV, CheminFils, FilsTrouvé, Niveau, Pointeur)
...
END
Internal Procedure parameter The internal procedure can be used as parameter in a procedure. In this case, the parameter type will be "Procedure". Example:
INTERNAL PROCEDURE MaProcédureInterne()
END
MonAutreProcédure(MaProcédureInterne)
PROCEDURE MonAutreProcédure(p is procedure)
p()
Access to the variables from an internal procedure The variables declared in the same process as the declaration of internal procedure can be called in the internal procedure. There is no need to use global variables anymore. This concept is called "Closure". Example: sListeElément is string
sSéparateur is string = RC
TreeListItem(ARBRE_ChampArbre, "", MaProcédureInterne)
INTERNAL PROCEDURE MaProcédureInterne(NomArbre, Branche)
sListeElément += [sSéparateur] + Branche
END
Nesting internal procedures The internal procedures can be nested. Each internal procedure can access the variables of procedures that include it. Example: VariableExterne is int
Trace(VariableExterne)
MaProcédureInterne1()
INTERNAL PROCEDURE MaProcédureInterne1()
VariableInterne1 is int
Trace(VariableExterne + VariableInterne1)
MaProcédureInterne2()
INTERNAL PROCEDURE MaProcédureInterne2()
VariableInterne2 is int
Trace(VariableExterne + VariableInterne1 + VariableInterne2)
END
END
Sibling internal procedures Two internal procedures found in the same procedure can be called between themselves (sibling internal procedures). Example: INTERNAL PROCEDURE MaProcédurePrincipale()
INTERNAL PROCEDURE MaProcédureInterne1()
...
END
INTERNAL PROCEDURE MaProcédureInterne2()
...
MaProcédureInterne1()
END
END
Recursive calls An internal procedure can be called itself in recursive way. Named parameters If an internal procedure includes parameters with default values, you have the ability to call the internal procedure by naming its parameters. Two syntaxes are possible: - Single-line named parameters,
- Multiline named parameters.
Dynamic compilation You can use an internal procedure in a dynamically compiled code (with Compile, for example). Example: lsCode is string = [
// Code compilé dynamiquement
sListeElément est une chaîne
sSéparateur est une chaîne = RC
ArbreListeFils(ARBRE_ChampArbre, "", MaProcédureInterne)
PROCEDURE INTERNE MaProcédureInterne(NomArbre, Branche)
sListeElément += [sSéparateur] + Branche
FIN
]
lsRésultat is string
lsRésultat = Compile("MaProc",lsCode)
Internal procedure and extension attributes extension attributes can be used with internal procedures. For example, a single process can run an internal procedure in a secondary thread, then call a second procedure in the main thread to refresh the interface. Example:
ExécutionAsynchrone()
INTERNAL PROCEDURE ExécutionAsynchrone() <thread>
ThreadPause(5 s)
AprèsExécutionAsynchrone()
END
INTERNAL PROCEDURE AprèsExécutionAsynchrone() <main thread>
Trace("Terminé ...")
END
Special case: using internal procedures with asynchronous functions Internal procedures can be used as callbacks for asynchronous functions.. WARNING: In this case, the code located after the call to the function using an asynchronous WLanguage procedure will be executed BEFORE the code of the Internal procedure.. Example: In this WINDEV Mobile example, the code after AlbumPicker will be executed BEFORE the internal procedure. The internal procedure will be called when the picker is validated by the user. AlbumPicker(albumImage, SélectionPhoto)
INTERNAL PROCEDURE SélectionPhoto(sCheminImage)
IMG_ChampImage = sCheminImage
END
- An internal procedure cannot be named like the procedures that contain it.
- Two internal procedures of same level cannot have the same name, even if they are declared in different code blocks (IF THEN ELSE, ...).
- The internal procedures are not available in dynamic compilation.
- The execution of an internal procedure cannot be automated.
- The automatic management of errors is not available for the internal procedures.
- If the option "Scope of local variables limited to current block " is enabled in the "Compilation" tab of the project description, declaring internal procedures using variables "with scope limitation" will result in a generation error.. Example:
- the following code causes a compilation error:
PROCEDURE MaProcedure()
IF MaCondition THEN
str is string
INTERNAL PROCEDURE ma_proc_interne()
str = "truc"
END
END
- To correct this code, it is necessary not to declare the variable in the IF statement:
PROCEDURE MaProcedure()
str is string
IF MaCondition THEN
INTERNAL PROCEDURE ma_proc_interne()
str = "truc"
END
END
In Java and Android, we recommend always declaring internal procedures in the scope of the procedure itself.. Thus, if undeclared variables are used, compilation errors will be displayed.
This page is also available for…
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|