PROCEDURE statement
- Last Updated: January 18, 2024
- 6 minute read
- OpenEdge
- Version 12.8
- Documentation
Defines an internal procedure as an ABL procedure or declares an internal procedure prototype for an external routine in a Windows dynamic link library (DLL) or UNIX shared library, or for an internal ABL procedure defined in an external procedure that is itself a super procedure of the declaration procedure. The following syntax boxes describe the syntax for each use of the statement, beginning with an internal procedure definition.
Syntax
|
This is the syntax to declare an internal procedure prototype for a routine in a Windows DLL or UNIX shared library, or for an internal ABL procedure defined in a super procedure:
|
- proc-name
- The name of the internal procedure.
To define the name of an internal ABL procedure that is an event handler for ActiveX controls (OCX event procedure), you must specify proc-name according to the following syntax:
{control-frame-name.control-name.event-name | ANYWHERE.event-name}For more information on naming event handlers for ActiveX controls using this syntax, see the notes for this reference entry.
- EXTERNAL "dllname"
- Declares the internal procedure as a Windows DLL or UNIX shared library routine. The dllname argument, specified as a string literal, is the name of the DLL or library containing the routine. The value of dllname can contain Unicode characters. See Internationalize ABL Applications for more information about Unicode.
- CDECL
- Tells ABL to use the C calling convention when accessing the routine.
- PASCAL
- Supported only for backward compatibility. This option is not valid for SpeedScript.
- STDCALL
- Tells ABL to use the standard Windows calling convention
when accessing the routine. This is the default.Note: The 64-bit Windows GUI and character clients ignore the CDECL, PASCAL, and STDCALL calling conventions if they are specified. The 64-bit Windows GUI and character clients always use the standard 64-bit FASTCALL calling convention.
- ORDINAL n
- Specifies the number of the DLL entry point (the nth routine) to invoke. If you use the
ORDINAL option, then proc-name can
specify any name used in the corresponding RUN statement to reference the
routine. If you omit the ORDINAL option, proc-name specifies which DLL routine you want to invoke.
For UNIX shared library routines, this option does not apply and is ignored.
- PERSISTENT
- Specifies that the DLL or shared library routine should remain loaded in memory until the AVM exits or the session executes the RELEASE EXTERNAL statement.
- THREAD-SAFE
- Specifies that the DLL or shared library routine is thread safe (the developer is responsible for making sure that is the case, for the given DLL or shared library). When a DLL or shared library is marked as THREAD-SAFE, multiple sessions can access it simultaneously, otherwise access to it is single-threaded, that is, only one session can access it at a time. This option is only valid when running an application on an instance of the Progress Application Server for OpenEdge; otherwise, this option does not apply and is ignored.
- PRIVATE
- Indicates the following about the internal procedure:
- It cannot be invoked from an external procedure—that is, from a procedure file external to the current procedure file.
- The INTERNAL-ENTRIES attribute on the procedure that defines it does not provide its name (unless the procedure that defines it is the current procedure file).
- The GET-SIGNATURE method on the procedure that defines it does not provide its signature (unless the procedure that defines it is the current procedure file).
- IN SUPER
- Declares that the definition of the internal procedure resides in a super procedure.
- procedure-body
- The body of an internal procedure definition. Define
procedure-body using the following
syntax:
procedure-logic . . . [ catch-block [ catch-block...]] [ finally-block ] [ END [ PROCEDURE ] . ]
Example
The following example declares an ABL internal procedure that computes the factorial of an integer entered as an INPUT parameter. The result is returned as an OUTPUT parameter. Note that the following procedure calls itself recursively to obtain the result:
r-factrl.p
|
The following example declares a DLL routine, MessageBox(), which displays a message:
r-dllex1.p
|
The following code fragment declares a UNIX shared library routine:
|
Notes
- You can terminate a PROCEDURE statement with either a period (.) or a colon (:), but typically use a colon (:) for a procedure definition or prototype that includes procedure-body and a period (.) for a procedure definition or prototype that omits any procedure-body.
- You can place an internal procedure definition or declaration before, after, or in the middle of your main procedure code. You cannot nest an internal procedure within another internal procedure.
- Use the RUN statement to invoke an internal procedure. You can
run an internal procedure from within the external procedure that defines it,
either from the main-line of the external procedure or from another internal
procedure defined in the external procedure. You can also run an internal
procedure defined in another external procedure using the IN proc-handle option of the RUN statement as long
as the external procedure meets one of these conditions:
- It is active on the procedure call stack
- It is an instance of a persistent procedure
- You cannot define shared objects, work tables, or temp-tables within an internal procedure.
- An internal procedure can reference any objects defined in the outer procedure block. For example, it can reference variables, buffers (explicit or implicit; shared or unshared), variables, run-time parameters, named frames, or temp-tables. If you define an object with the same name in the internal procedure and the external procedure, a reference within the internal procedure resolves to the local object.
- A buffer explicitly defined in an internal procedure is scoped to the internal procedure. Any other buffers are scoped to the outer procedure block.
- To define the internal procedure as an event handler for
ActiveX controls (OCX event procedure), you must specify proc-name according to the following
syntax:
{ control-frame-name .control-name .event-name | ANYWHERE .event-name }In control-frame-name.control-name.event-name, control-frame-name is the name (unquoted) of the control-frame that contains the ActiveX control. This is the name that the AppBuilder typically assigns to the control-frame (NAME widget attribute) when you insert the control into your user interface. The control-name is the value (unquoted) that you assign to the control Name property at design time in the AppBuilder Property Window. The event-name is the name (unquoted) of the ActiveX control event that you want to trigger execution of this procedure.
In ANYWHERE.event-name, ANYWHERE specifies an event procedure that handles the specified event in any ActiveX control. This event procedure executes only if you have not defined a control-frame-name.control-name.event-name event procedure that exactly matches the control/event combination at run time.
At design time, the AppBuilder lists the available events for a control and automatically creates a template for the OCX event procedure definition from the event that you select. For more information on how to create OCX event procedures in the AppBuilder, see the information on ActiveX controls in OpenEdge Programming Interfaces. For more information on how to work with OCX event procedures in an application, see OpenEdge Programming Interfaces.
- When you define an OCX event procedure, you can access the component handle (COM-HANDLE value) of the control that generates the event at run time using the COM-SELF system handle. You can also access the handle of the parent control-frame using the SELF system handle.
- The RETURN-VALUE function provides the value returned by the most recently executed RETURN statement of a local or remote procedure.
- You use the call object handle to dynamically invoke a Windows DLL routine or UNIX shared library routine at run time.
See also
Call object handle, COM-SELF system handle, DEFINE PARAMETER statement, END statement, RUN statement, TRIGGER PROCEDURE statement