ONLINE HELP
 WINDEVWEBDEV AND WINDEV MOBILE

Help / WLanguage / WLanguage syntax / WLanguage procedures
  • Principle
  • Declaring and calling internal procedures
  • Example
  • 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
WINDEV
WindowsLinuxUniversal Windows 10 AppJavaReports and QueriesUser code (UMC)
WEBDEV
WindowsLinuxPHPWEBDEV - Browser code
WINDEV Mobile
AndroidAndroid Widget iPhone/iPadIOS WidgetApple WatchMac CatalystUniversal Windows 10 App
Others
Stored procedures
Principle
Several features require a procedure called once or several times via a WLanguage function ("Callback"). For example, this is the case for the following functions: fListFile, TreeListItem, AlbumPicker in iOS, etc.
A procedure must be created for these functions but several drawbacks appear:
  • Loss of code locality: The final algorithm cannot be entirely displayed. Several backs and forths must be performed between the calling code and the WLanguage procedure.
  • Difficulty to share information wiht the WLanguage procedure: In most cases, global variables must be used (to pass parameters to the callback or to retrieve the 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:
INTERNAL PROCEDURE <Procedure name>()
<Procedure code>
END
Remarks:
  • The internal procedures must be declared in the process where they are used.
  • The assisted input is enabled for the parameters: a tooltip specifying the expected parameter type is displayed when typing the call to the internal procedure.
  • The code of process found before and after the declaration code of internal procedure is run in sequence: the code of internal procedure is not run.
    Example:
    // Code before the internal procedure: This code is run.
    INTERNAL PROCEDURE MyInternalProcedure()
    // Code of the internal procedure.
    // This code is not run.
    END
    // Code after the internal procedure: This code is run.
  • 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:
    // Call placed before
    MyInternalProcedure()
     
    // Declare the internal procedure
    INTERNAL PROCEDURE MyInternalProcedure()
    // Code of the internal procedure run during the call to MyInternalProcedure()
    END
     
    // Call placed after
    MyInternalProcedure()

    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.
WINDEVWEBDEV - Server code

Example

The following code is used to list all child elements of a node found in a TreeView control:
// List the "children" of the "Desserts" node in the "TREE_TVRecipe" TreeView
// The "ExpandAll" procedure is called
// for each "child" element found in the "Desserts" node
Res = TreeListItem(TREE_TVRecipe, "Recipes" + TAB + "Desserts", ExpandAll)
 
INTERNAL PROCEDURE ExpandAll(TREE_TVRecipe, ChildPath, ChildFound, Level, Pointer)
// Is the element found a leaf?
IF TreeTypeItem(TREE_TVRecipe, ChildPath + ChildFound) = tvLeaf THEN
RETURN // Go back to the TreeListItem function
ELSE
// Is the element found collapsed?
IF TreeStatus(TREE_TVRecipe, ChildPath + ChildFound) = tvCollapse THEN
TreeExpand(TREE_TVRecipe, ChildPath + ChildFound)
END
END
// Collapse the TreeView Table control
TreeCollapse(TREE_TVRecipe, "Recipes")
END
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, ...).
Caution: In this case, the parameter corresponding to the name of internal procedure must directly correspond to the name of internal procedure (the procedure name must not be enclosed in quotes).
Not to do:
// List the "children" of the "Desserts" node in the "TREE_TVRecipe" TreeView
Res = TreeListItem(TREE_TVRecipe, "Recipes" + TAB + "Desserts", "ExpandAll")
 
INTERNAL PROCEDURE ExpandAll(TREE_TVRecipe, ChildPath, ChildFound, Level, Pointer)
...
END
Do:
// List the "children" of the "Desserts" node in the "TREE_TVRecipe" TreeView
Res = TreeListItem(TREE_TVRecipe, "Recipes" + TAB + "Desserts", ExpandAll)
 
INTERNAL PROCEDURE ExpandAll(TREE_TVRecipe, ChildPath, ChildFound, Level, Pointer)
...
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:
// Declare the internal procedure
INTERNAL PROCEDURE MyInternalProcedure()
// code run during the call to the procedure passed as parameter
END
 
MyOtherProcedure(MyInternalProcedure)
PROCEDURE MyOtherProcedure(p is procedure)
 
p()
AndroidAndroid Widget Java This feature is not available.

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:
sElementList is string
sSeparator is string = CR
TreeListItem(TREE_TreeeViewControl, "", MyInternalProcedure)
 
INTERNAL PROCEDURE MyInternalProcedure(TreeViewName, Branch)
sElementList += [sSeparator] + Branch
END

Nesting internal procedures

The internal procedures can be nested. Each internal procedure can access the variables of procedures that include it.
Example:
ExternalVariable is int
Trace(ExternalVariable)
MyInternalProcedure1()
INTERNAL PROCEDURE MyInternalProcedure1()
InternalVariable1 is int
Trace(ExternalVariable + InternalVariable1)
MyInternalProcedure2()
INTERNAL PROCEDURE MyInternalProcedure2()
InternalVariable2 is int
Trace(ExternalVariable + InternalVariable1 + InternalVariable2)
END
END

Sibling internal procedures

Two internal procedures found in the same procedure can be called between themselves (sibling internal procedures).
Example:
INTERNAL PROCEDURE MyMainProcedure()
 
INTERNAL PROCEDURE MyInternalProcedure1()
...
END
 
INTERNAL PROCEDURE MyInternalProcedure2()
...
// Call the sibling procedure
MyInternalProcedure1()
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.
For more details, see Named parameters in a procedure.

Dynamic compilation

You can use an internal procedure in a dynamically compiled code (with Compile, for example).
Example:
lsCode is string = [
// Code compiled dynamically
sElementList is string
sSeparator is string = CR
TreeListItem(TREE_TreeeViewControl, "", MyInternalProcedure)
 
INTERNAL PROCEDURE MyInternalProcedure(TreeViewName, Branch)
sElementList += [sSeparator] + Branch
END
 
]
 
lsResult is string
 
lsResult = Compile("MyProc",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:
// Code of a button for example ...
AsynchronousExecution()
 
INTERNAL PROCEDURE AsynchronousExecution() <thread>
 
// Here, process run in the background
// in a secondary thread (no access to the interface)
ThreadPause(5s)
 
// Process completed, call process of main thread again
// therefore allowed to refresh the interface
AfterAsynchronousExecution()
END
 
INTERNAL PROCEDURE AfterAsynchronousExecution() <main thread>
Trace("Completed ...")
END
Special case: Using internal procedures with asynchronous functions
The internal procedures can be used as "Callback" for asynchronous functions.
CAUTION: In this case, the code after the call to the function that uses an asynchronous WLanguage procedure will be execute BEFORE the code of 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, PhotoSelection)
INTERNAL PROCEDURE PhotoSelection(sImagePath)
IMG_ImageControl = sImagePath
END
// Code run after the AlbumPicker function but
// BEFORE the code of internal procedure.
Limitations
  • 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.
Minimum version required
  • Version 20
This page is also available for…
Comments
Click [Add] to post a comment

Last update: 05/26/2022

Send a report | Local help