Copyright: ©1995 TopSpeed Corporation
Citation: ©1995 TopSpeed Corporation, All Rights Reserved


Contents
Template Language Reference

 Introduction

 Template Organization

 Defaults and Template Data

 Programmer Input

 Logic and Source Generation Control

 Miscellaneous

 Template Symbols

 Annotated Examples


TLR01OPEN
Template Language Reference

 Introduction

Template Language Overview

What Templates Are

Template Types

What Templates Do

Pre-Processing and Source Code Generation

Embed_Points (#EMBED)

Template Prompts

Data Dictionary Interface

Template Structure

Template Source Format

The Template Registry File

Customizing Default Templates

Adding New Template Sets

 Template Organization

 Defaults and Template Data

 Programmer Input

 Logic and Source Generation Control

 Miscellaneous

 Template Symbols

 Annotated Examples


TLR02OPEN
Template Language Reference

 Introduction

 Template Organization

Template Code Sections

#TEMPLATE (begin template set)

#APPLICATION (source generation control section)

#PROGRAM (global area)

#MODULE (module area)

#PROCEDURE (begin a procedure template)

#GROUP (reusable statement group)

#UTILITY (utility execution section)

#CODE (define a code template)

#CONTROL (define a control template)

#EXTENSION (define an extension template)

Embed Points

#EMBED (define embedded source point)

#AT (insert code in an embed point)

#ATSTART (template intialization code)

#ATEND (template reset code)

#EMPTYEMBED (generate empty embed point comments)

#POSTEMBED (generate ending embed point comments)

#PREEMBED (generate beginning embed point comments)

Template Code Section Constraints

#WHERE (define #CODE embed point availability)

#RESTRICT (define section use constraints)

#ACCEPT (section valid for use)

#REJECT (section invalid for use)

 Defaults and Template Data

 Programmer Input

 Logic and Source Generation Control

 Miscellaneous

 Template Symbols

 Annotated Examples


TLR03OPEN
Template Language Reference

 Introduction

 Template Organization

 Defaults and Template Data

Default Data and Code

#WINDOWS (default window structures)

#REPORTS (default report structures)

#LOCALDATA (default local data declarations)

#GLOBALDATA (default global data declarations)

#DEFAULT(default global data declarations)

Symbol Management Statements

#DECLARE (declare a user-defined symbol)

#ALIAS (access a symbol from another instance)

#ADD (add to multi-valued symbol)

#DELETE (delete a multi-valued symbol instance)

#DELETEALL (delete multiple multi-valued symbol instances)

#PURGE (delete all single or multi-valued symbol instances)

#CLEAR (clear single-valued symbol)

#FREE (free a multi-valued symbol)

#FIX (fix a multi-value symbol)

#FIND (super-fix multi-value symbols)

#SELECT (fix a multi-value symbol)

#SET (assign value to a user-defined symbol)

#UNFIX (unfix a multi-value symbol)

#DECLARE Attributes

UNIQUE (no duplicates allowed)

SAVE (save symbol between generations)

 Programmer Input

 Logic and Source Generation Control

 Miscellaneous

 Template Symbols

 Annotated Examples


TLR04OPEN
Template Language Reference

 Introduction

 Template Organization

 Defaults and Template Data

 Programmer InputInput and Validation Statements

#PROMPT (prompt for programmer input)

#VALIDATE (validate prompt input)

#ENABLE (enable/disable prompts)

#BUTTON (call another page of prompts)

#FIELD (control prompts)

#PREPARE (setup prompt symbols)

#PROMPT Entry Types

CHECK (check box)

COMPONENT (list of KEY fields)

CONTROL (list of window fields)

DROP (droplist of items)

EMBED (enter embedded source)

EMBEDBUTTON (enter embedded source)

FIELD (list of data fields)

FILE (list of files)

FORMAT (call listbox formatter)

FROM (list of symbol values)

KEY (list of keys)

KEYCODE (list of keycodes)

OPTION (display radio buttons)

PICTURE (call picture formatter)

PROCEDURE (add to logical procedure tree)

RADIO (one radio button)

SPIN (spin box)

Display and Formatting Statements

#BOXED (prompt group box)

#DISPLAY (display-only prompt)

#IMAGE (display graphic)

#SHEET (declare a group of #TAB controls)

#TAB (declare a page of a #SHEET control)

 Logic and Source Generation Control

 Miscellaneous

 Template Symbols

 Annotated Examples


TLR05OPEN
Template Language Reference

 Introduction

 Template Organization

 Defaults and Template Data

 Programmer Input

 Logic and Source Generation Control

Template Logic Control Statements

#FOR (generate code multiple times)

#IF (conditionally generate code)

#LOOP (iteratively generate code)

#CASE (conditional execution structure)

#INSERT (insert code from a #GROUP)

#BREAK (break out of a loop)

#CYCLE (cycle to top of loop)

#RETURN (return from #GROUP)

#GENERATE (generate source code section)

#ABORT (abort source generation)

File Management Statements

#CREATE (create source file)

#OPEN (open source file)

#CLOSE (close source file)

#READ(read one line of a source file)

#REDIRECT (change source file)

#APPEND (add to source file)

#REMOVE (delete a source file)

#REPLACE (conditionally replace source file)

#PRINT (print a source file)

Conditional Source Generation Statements

#SUSPEND (begin conditional source)

#RELEASE (commit conditional source generation)

#RESUME (delimit conditional source)

#? (conditional source line)

 Miscellaneous

 Template Symbols

 Annotated Examples


TLR06OPEN
Template Language Reference

 Introduction

 Template Organization

 Defaults and Template Data

 Programmer Input

 Logic and Source Generation Control

 Miscellaneous

Miscellaneous Statements

#! (template code comments)

#< (aligned target language comments)

#CLASS (define a formula class)

#COMMENT (specify comment column)

#ERROR (display source generation error)

#EXPORT (export symbol to text)

#HELP (specify template help file)

#INCLUDE (include a template file)

#IMPORT (import from text script)

#MESSAGE (display source generation message)

#PROTOTYPE (procedure prototype)

#PROJECT (add file to project)

Built-in Template Functions

EXTRACT (return attribute)

EXISTS (return embed point existence)

FILEEXISTS (return file existence)

INLIST (return item exists in list)

INSTANCE (return current instance number)

ITEMS (return multi-valued symbol instances)

QUOTE (replace string special characters)

REPLACE (replace attribute)

SEPARATOR (return attribute string delimiter position)

 Template Symbols

 Annotated Examples


TLR07OPEN
Template Language Reference

 Introduction

 Template Organization

 Defaults and Template Data

 Programmer Input

 Logic and Source Generation Control

 Miscellaneous

 Template Symbols	Symbols Dependent on %Application

Symbols Dependent on %File

Symbols Dependent on %ViewFiles

Symbols Dependent on  %Field

Symbols Dependent on %Key

Symbols Dependent on %Relation

Symbols Dependent on %Module

Symbols Dependent on %Procedure

Window Control Symbols

Report Control Symbols

Formula Symbols

File Schematic Symbols

File Driver Symbols

Miscellaneous Symbols

 Annotated Examples


TLR08OPEN
Template Language Reference

 Introduction

 Template Organization

 Defaults and Template Data

 Programmer Input

 Logic and Source Generation Control

 Miscellaneous

 Template Symbols

 Annotated Examples

Procedure Template: Window

%StandardWindowCode #GROUP

%StandardWindowHandling #GROUP

%StandardAcceptedHandling #GROUP

%StandardControlHandling #GROUP

Code Template: ControlValueValidation

%CodeTPLValidationCode #GROUP

Control Template: DOSFileLookup

Extension Template: DateTimeDisplay

%DateTimeDisplayCode #GROUP


Chapter 1 - Introduction
Introduction

Template Language Overview

What Templates Are

Template Types

What Templates Do

Pre-Processing and Source Code Generation

Embed_Points (#EMBED)

Template Prompts

Data Dictionary Interface

Template Structure

Template Source Format

The Template Registry File

Customizing Default Templates

Adding New Template Sets


Template Language Overview

Clarion for Windows' Template Language is a flexible script language complete with control structures, user interface elements, variables, file I/O, and more. The Template Language "drives" the Application Generator both at application design time and during source code generation.

During application design, the programmer is asked for specific information about the application being generated. These prompts for information come directly from the templates.

During source code generation, the template is in control of the source code statements generated for each procedure in the application, and also controls what source files receive the generated code.

This process makes the Templates completely in control of the Application Generator. The benefit to the programmer of this is the complete flexibility to generate code that is directly suited to the programmer's needs.

See Also:

What Templates Are

Template Types

What Templates Do

Pre-Processing and Source Code Generation

Embed Points

Template Prompts

Data Dictionary Interface

Template Structure


What Templates Are

A template is a complete set of instructions, both Template and "target" language statements, which the Application Generator uses to process the programmer's input for application customizations then generate "target" language (usually, but not limited to, Clarion language) source code.

Clarion's templates are completely reuseable. They generate only the exact code required for each specific instance of its use; they do not inherit unused methods. The templates are also polymorphic, since the programmer specifies the features and functions of each template that are required for the procedure. This means one template can generate different functionality based upon the programmer's desires.

Some of the most important aspects of template functionality supported by the Template Language include:

Support for controls (#PROMPT) that gather input from the developer, storing that input in user-defined template variables (symbols).

Pre-defined template variables (Built-in Symbols) containing information from the data dictionary and Clarion for Windows' application development environment.

Specialized #PROMPT entry types, which give the programmer a list of appropriate choices for such things as data file or key selection.

Unconditional and conditional control structures (#FOR, #LOOP, #IF, #CASE) which branch source generation execution based on an expression or the contents of a symbol (variable). This allows the Application Generator to generate only the exact source code needed to produce the programmer's desired functionality in their application.

Statements (#EMBED) that define specific points where the developer can insert (embed) or not insert their own source code to further customize their application.

Support for code templates (#CODE), control templates (#CONTROL), and extension templates (#EXTENSION) that add their specific (extended) functionality to any procedure template. This makes any procedure type polymorphic, in that, the procedure can include functionality normally performed by other types of procedures.

Template code is contained in one or more ASCII files (*.TPL or *.TPW) which the Application Generator pre-compiles and incorporates into the REGISTRY.TRF file. It is this template registry file that the Application Generator uses during application design.

Once in the registry, the template code is completely reusable from application to application. It generates custom source code for each application based upon the application's data dictionary and the options selected by the programmer while working with the Application Generator.

The programmer can customize the templates in the registry (or in the *.TP* files) to fit their own specific standard design requirements. This means that each procedure template can be designed to appear exactly as the programmer requires as a starting point for their applications. Multiple "default" starting points can be created, so the programmer can have a choice of starting point designs for each procedure type.

When the programmer has customized the template source (*.TP* file), the Application Generator automatically updates the registry. When the programmer has customized the registry, the template source files can be re-generated from the registry, if necessary.

The Application Generator always makes a copy of the template, as stored in the registry, when creating a procedure or first populating a procedure with a code, control, or extension template. Once this copy is made, the programmer further customizes it to produce exactly the functionality required by the application for that procedure.

The template language can generate more than source code: it can even be used to create add-in utilities (see #UTILITY).


Template Types

There are four main types of templates: procedure, code, control, and extension templates.

Procedure templates (#PROCEDURE) generate procedures and/or functions in an application. This is the choice you make when asked to choose the starting point for a "ToDo" procedure in the Application Generator.

Code templates (#CODE) generate executable code into a specific embed point. The developer can only insert them at an embed point within a procedure. A list of the available code templates appears from which to choose.

Control templates (#CONTROL) place a related set (one or more) of controls on a procedure's window and generate the executable source code into the procedure's embed points to provide the controls' standard functionality.

Extension templates (#EXTENSION) generate executable source code into one or more embed points to add specific functionality to a procedure that is not "tied" to any window control.


What Templates Do

The template code files contain template language statements and  standard "target" language source code which the Application Generator places in your generated source code files. They also contain the prompts for the Application Generator which determine the standard customizations the developer can make to the generated code.

The programmer's response (or lack of) to the prompts "drives" the control statements that process the template language code, and produces the logic that generates the source code. The templates also contain control statements which instruct the Application Generator how to process the standard code. The function of a template is to generate the "target" language source code, customized per the programmer's response to the prompts and design of the window or report.

There are some lines of code from templates that are inserted directly into your generated source code. For example, if you accept a default Copy command menu item in your application window, the following code is inserted in your generated source exactly as it appears in the template file:

ITEM('&Copy'),USE(?Copy),STD(STD:Copy),MSG('Copy item to Windows clipboard')

Some of the standard code in the template is a mix of "target" (Clarion) language statements and template language statements. For example, when the contents of a template variable (symbol) needs to be inserted in the generated source code, the Application Generator expands the symbol to the value the application will use, as it generates the source code for the application. Within the template code, the percent sign (%) identifies a variable (symbol). In the example below, the Application Generator will fill in the field equate label for the control as it writes the source code file, substituting it for the %Control variable:

SELECT(%Control)

To support customizing the template starting point at design time, Clarion's template language provides prompt statements that generate the template's user interface, so that the Application Generator can query the developer for the information needed to customize the application. The basic interface consists of command buttons, check boxes, radio buttons, and entry controls placed on the Procedure Properties dialog. These statements can also create custom dialog boxes to gather input from the developer. While working with the Application Generator, therefore, some of the dialogs and other interface elements the developer sees are not part of the Application Generatorrather they are produced by the template.

For example, the following statement displays a file selection dialog from the application's data dictionary, then stores the programmer's choice for a data file in a variable (symbol) called %MyFile:

#PROMPT('Pick a file',FILE),%MyFile

It makes no difference what the programmer names the files and fields, nor what database driver is selected. The programmer picks them from a file selection dialog.

The template also contains control structures to instruct the Application Generator on how to generate the code( such as, #IF, #LOOP, #CASE). These control statements work in the same manner as Clarion language control structures.


Pre-Processing and Source Code Generation

Before allowing you to create an application using the templates, the Application Generator pre-processes the template code (.TPL and .TPW) files. The Application Generator verifies the registry is up to date by testing the time stamps and file sizes of all the template source code files.

The Application Generator utilizes the templates as stored in binary form in the registry file, as it gathers customizations from the developer with the prompts and dialogs available through the Procedure Properties dialog. The Application Generator stores the template starting point for each procedure and the customization from the programmer in the .APP file.

At source code generation time, the Application Generator processes the application's procedures as stored in the .APP file against the template, a second time. Some of the more important steps it uses to produce the source code are:

It executes the template language control statements to process the template and the procedure's customizations in the correct order.

It resolves the template symbolsboth built-in and user-defined.

It creates the source code files and writes the source code as generated by the template, line by line, including the previously evaluated symbols.

It evaluates embed points and writes the source code, as embedded by the developer and stored in the .APP file, in the correct location within the generated source code.


Embed Points (#EMBED)

One of the most important template language statements is #EMBED, which defines an embed point. These extend the structure and functionality of the procedure template by allowing the programmer to add their own custom code. The embed points indicate "targets" at which the developer can add their own custom code to the generated source. These are also the "targets" for the source code generated by control and extension templates.

Each procedure template allows for a certain number of default points at which embeds are allowed. These are typically points which coincide with messages (events) from the operating environment (Windows), such as when the end user moves focus from or to a field. The template programmer can add to, or subtract from, the list.

When the developer customizes the template, pressing the Embeds button in the Procedure Properties dialog provides access to all the embed points available in a procedure. The Actions popup menu selection in the Window Formatter also provides access to the embed points for a specific control.

The developer adds custom codeeither hand coded from scratch in the editor, or created with a code template--at the embed point. The embed points are also the points into which control templates and extension templates generate executable code to support their functionality.

The Application Generator stores the embed point's code (no matter what its origination) in the .APP file. At code generation time, the Application Generator processes the template, producing source; when it reaches an embed point, it places the developer's code, line by line, into the generated source code document.


Template Prompts

Input Validation Statements and Prompt Entry types place controls on the Procedure Properties window or Actions dialog which the developer sees when using the template to design an application. These range from a simple string telling the Developer what to do (#DISPLAY), to command buttons, check boxes, or radio buttons. There are also specialized entry types which provide the programmer a list of choices for input, such as the data fields in the dictionary.

Standard Windows controls can be used to get information fromn the programmer on the Procedure Properties window, the Actions dialog, or custom prompt dialogs. The common control type--entry field, check box, radio button, and drop-down listare all directly supported via the #PROMPT statement.

#PROMPT places the prompt, the input control, and the symbol in a single statement. The general format is the #PROMPT keyword, the string to display the actual prompt, a variable type for the symbol, then the symbol or variable name. The Application Generator places the prompt and the control in the Procedure Properties or Actions dialog (depending on whether the prompt comes from a the procedure template or a code, control, or extension template). When the developer fills the control with a value, then closes the dialog, the symbol holds the value.

The #BUTTON  statement provides additional "space" for developer input when there is more developer input required than can fit in the one dialog. This places a button in the dialog, which displays an additional custom dialog when pressed. The additional dialogs are called "prompt pages."

#ENABLE allows prompts to be conditionally enabled based on the programmer's response to some other prompt. #BOXED supports logical grouping of related prompts. Once the programmer has input data into a prompt, the #VALIDATE statement allows the template to check its validity.

These tools provide a wide range of flexibility in the type of information a template can ask the programmer to provide. They also provide multiple ways to expedite the programmer's job, by providing "pick-lists" from which the programmer may choose wherever appropriate.


Data Dictionary Interface

The templates use information from the Data Dictionary extensively to generate code specifically for the declared database. There are several symbols that specifically give the templates access to all the declarations: %File, %Field, %Key, and %Relation. These, and all the symbols related to them, give the templates access to all the ifnormation in the Data Dictionary.

Pay special attention to the %FileUserOptions, %FieldUserOptions, %KeyUserOptions, and %RelationUserOptions symbols. These are the symbols that contain the values the user enters in the User Options text control on the Options tab of the File Properties, Field Properties, Key Properties, and Relation Properties dialogs. This can be a powerful tool to customize any output from the Data Dictionary.

The best way to use these %UserOptions symbols is to set them up so the user enters their custom preferences which your template supports in the for of attributes with parameters, with each attribute separated by a comma. This gives them the same appearance as Clarion language data structure attributes. By doing this, you can use the EXTRACT built-in template function to get the value from the user. For example, if the user enters the following in a User Options for a field:

MYCUSTOMOPTION(On)

The template code can parse this using EXTRACT:

#IF(EXTRACT(%FieldUserOptions,'MYCUSTOMOPTION'.1) = On)

#!Do Something related to this option being turned on

#ENDIF

This is a very powerful tool, which allows for infinite flexibility in the way your custom templates generate source code.


Template Structure

Template Source Format

The Template Registry File

Customizing Default Templates

Adding New Template Sets


Template Source Format

The structure of the ASCII template source file is different than the structure of a Clarion source file. To read the ASCII source for a template, start out with the following guidelines:

Any statement beginning with a pound symbol (#) identifies a template language statement.

A percent sign (%) before an item within any statement (template or "target" language) identifies a template symbol (variable), which the Application Generator processes at code generation time.

Any statement that begins without the pound (#) or percent (%) is a "target" language statement which is written directly into a source code file.

The template files are organized by code sections that terminate with the beginning of the next section or the end of the file. The template code generally divides into ten sections.

#TEMPLATE begins a template set (template class). This is the first statement in the template set (required) which identifies the template set for the registry.

#APPLICATION begins the source generation control section. This is the section of the template that controls the "target" language code output to source files, ready to compile. One registered template set must have a #APPLICATION section.

#PROGRAM begins the global section of the generated source code, the main program module. One registered template set must have a #PROGRAM section.

#MODULE begins a template section that generates the beginning code for a source code module other than the global (program) file. One registered template set must have a #MODULE section.

#PROCEDURE begins a procedure template. This is the fundamental "target" language procedure or function generation template.

#GROUP begins a reusable statement group containing code which may be #INSERTed into any other section of the template. This is the equivalent of a template language procedure or function.

#CODE begins a code template section which generates executable code into a specific embed point. The developer can only insert them at an embed point within a procedure. A list of the available code templates appears from which to choose.

#CONTROL begins a control template. Control templates place a related set (one or more) of controls on a procedure's window and generate the executable source code into embed points that provides the controls' standard functionality.

#EXTENSION begins an extension template. Extension templates generate executable source code into one or more embed points of a procedure to add specific functionality to the procedure that is not "tied" to any window control.

#UTILITY begins a utility execution section.This is an optional section of the template that performs a utility function, such as cross-reference or documentation generation. This is similar to #APPLICATION in that it generates output to ASCII files.

A template set must have a #TEMPLATE section to name the set for registration in the REGISTRY.TRF template registry file. At least one registered template set must have #APPLICATION, #PROGRAM, and #MODULE sections.


The Template Registry File

The Template Registry file (REGISTRY.TRF)  is a specialized data repository which stores template code and defaults in binary form. All the template elements available in the Application Generator come from the registry. As you add elements from the template into your application, the Application Generator retrieves the code from the registry then stores it along with your customizations, in the .APP file.

Storing the templates in a binary registry provides these advantages:

Quick design-time performance.

The ability to update the defaults in the registry using standard application development tools (such as the Window Formatter). For example, you can modify a procedure template's default window without writing template source code.

The sources for the REGISTRY.TRF are the template code files (.TPL and .TPW) which are installed in the TEMPLATE subdirectory. The Application Generator can read and register .TPL files, adding it to the template registry tree. The .TPW files usually contain additional procedure or code template source, which is processed along with the .TPL file by the #INCLUDE statement in the .TPL file. This allows the template author to logically separate disparate template components.

The default template file for Clarion for Windows is CW.TPL. This file uses the #INCLUDE statement to specify processing the the other .TPW files which appear in the \CW\TEMPLATE directory.


Customizing Default Templates

There are two methods for customizing the templates:

You can edit the template source code in the .TPL and .TPW files.

 It is always a good idea to make a backup copy before making any modifications to the shipping templates.

When directly editing the template source code, you can change the type of source code it generates, or the logic it uses to generate the code. This is how you can make your templates generate source code the way you would write it if you were hand-coding the application.

You can also extend the functionality of the templates by adding your own features. For example, you may want to add prompts to each procedure template that allow you to generate a "comment block" at the beginning of each procedure containing procedure maintenance comments from the programmer maintaining the application.

Adding the following code to the end of any existing template set acccomplishes this modification:

#EXTENSION(CommentBlock,'Add a comment block to the procedure'),PROCEDURE

  #PROMPT('Comment Line',@S70),%MyComment,MULTI('Programmer Comments')

#ATSTART

  #FOR(%MyComment)

  !%MyComment

  #ENDFOR

#ENDAT

This code adds an extension template that is available for any procedure in the application. When you design your procedure, add the CommentBlock extension template to the procedure, then add comments to the Comment Line prompt each time you modify the procedure. At source generation time, each comment line will appear following an exclamation point (!). The block of comments appears in the code  just before the PROCEDURE or FUNCTION statement.

If you want this extension to be used in all the procedures you write, go into the Template Registry and add the extension to all the default procedures for each procedure template. This way, you can make sure it is always used, and you can even place its prompts on the Procedure Properties dialog by checking the Show on Properties box as you add the extension to the procedure template.

Once you make the changes, either choose the Setup · Template Registry menu selection, open an existing application, or create a new application. Make sure the Re-register When Changed box is checked in the Registry Options dialog. The Application Generator automatically pre-processes the templates to update the registry when you have made changes to the template code files.

You can add to or edit the default user interface procedure template elementssuch as the standard window designs and report layouts, or your standard global and local data variablesusing the Template Registry.

When you highlight a procedure template in the Template Registry and press the Properties button, the Procedure Properties dialog appears, without all the custom prompts you would normally see when developing an application. Any button which is not dimmed in the Template Registry is available to you to create the default starting point for the procedure.

You can set up the procedure for the starting point that will get you furthest toward a complete procedure while requiring the least amount of customization from you at application design time. If the procedure allows it, you may use the window and report formatters, or define additional data, by pressing the appropriate buttons.

Once you've customized your template registry, you can also export your customizations to template source code files. This is useful for sharing your customizations with other developers.

To update the template source code with the customizations made in the Template Registry, press the Regenerate button in the Template Properties dialog. This updates the .TPL and .TPW files with the changes made.


Adding New Template Sets

Adding another set of templates, whether from a third-party vendor or templates you have written yourself, is a very simple process. There is only one requirement for the new template set; a #TEMPLATE statement to identify the set for the template registry. Of course, it also needs to have the specific procedure, code, control, and extension templates to add to the template registry.

For example, the following code is completely valid as a template set with nothing else added:

#TEMPLATE(PersonalAddOns,'My personal Template set')

#CODE(ChangeProperty,'Change control property')

  #PROMPT('Control to change',CONTROL),%MyField,REQ

  #PROMPT('Property to change',@S20),%MyProperty,REQ

  #PROMPT('New Value',@S20),%MyValue,REQ

%MyField{%MyProperty} = %'MyValue	#<!Change the %MyProperty of %MyField

When you register this template set, it will appear in the template registry as Class PersonalAddOns containing just the ChangeProperty code template.

Once a template set is registered in the template registry, all its components are completely available to the programmer for their application development, along with all the components of all other registered template sets. This allows the programmer the flexibility to "mix-and-match" their components during development.

For example, the programmer could create a procedure from a procedure template in the standard Clarion template set, populate it with a control template from a third-party vendor, insert a code template into an embed point from another third-party vendor, then add an extension template from their own personally written template set. At source generation time, all these separate components come together to create a fully functional procedure that performs all the tasks required by the programmer (and nothing else). This is the real power behind Clarion's Template-oriented programming!


Chapter 2 - Template Organization
Template Organization

Template Code Sections

#TEMPLATE (begin template set)

#APPLICATION (source generation control section)

#PROGRAM (global area)

#MODULE (module area)

#PROCEDURE (begin a procedure template)

#GROUP (reusable statement group)

#UTILITY (utility execution section)

#CODE (define a code template)

#CONTROL (define a control template)

#EXTENSION (define an extension template)

Embed Points

#EMBED (define embedded source point)

#AT (insert code in an embed point)

#ATSTART (template intialization code)

#ATEND (template reset code)

#EMPTYEMBED (generate empty embed point comments)

#POSTEMBED (generate ending embed point comments)

#PREEMBED (generate beginning embed point comments)

Template Code Section Constraints

#WHERE (define #CODE embed point availability)

#RESTRICT (define section use constraints)

#ACCEPT (section valid for use)

#REJECT (section invalid for use)


Template Code Sections

#TEMPLATE (begin template set)

#APPLICATION (source generation control section)

#PROGRAM (global area)

#MODULE (module area)

#PROCEDURE (begin a procedure template)

#GROUP (reusable statement group)

#UTILITY (utility execution section)

#CODE (define a code template)

#CONTROL (define a control template)

#EXTENSION (define an extension template)


#TEMPLATE (begin template set)

#TEMPLATE( name, description )

#TEMPLATE	Begins the Template set.

name	The name of the Template set which uniquely identifies it for the Template Registry and Template Language statements. This must be a valid Clarion label.

description	A string constant describing the Template set for the Template Registry and Application Generator.

The #TEMPLATE statement marks the beginning of a Template set. This should be the first non-comment statement in the Template file.

The Template Registry allows multiple Template sets to be registered for the Application Generator. Each Template Code Section (#APPLICATION, #PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, and #GROUP) within a Template is uniquely identified by its #TEMPLATE statement's name and the name of the section. This allows different Template sets to contain Template Code Sections with names that duplicate those in other Template sets without ambiguity, and allows the programmer to concurrently use Template sets from multiple sources to generate applications.

Example:

#TEMPLATE(SampleTemplate,'This is a sample Template')

#INCLUDE('FileTwo.TPX')

#INCLUDE('FileThree.TPX')


#APPLICATION (source generation control section)

#APPLICATION( description ) [, HLP( helpid ) ]

#APPLICATION	Begins source generation control section.

description	A string constant describing the application section.

HLP	Specifies on-line help is available.

helpid	A string constant containing the identifier to access the Help system. This may be either a Help keyword or "context string."

The #APPLICATION statement marks the beginning of a source generation control section. The section is terminated by the next Template Code Section (#PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, #UTILITY, or #GROUP) statement. The Template statements contained in this section control the source generation process. Only one #APPLICATION section is allowed in a single Template set. Actual source generation is done by the #GENERATE statement.

Any User-defined symbols defined in the #APPLICATION section are available for use in any Template Code Section that is generated. Any prompts in this section are placed on the Global Properties window and have global scope.

Example:

#APPLICATION('Example Application Section')       #!Generate entire application

#PROMPT('Enable &Shared Files',CHECK),%SharedFiles

#PROMPT('Close Unused &Files',CHECK),%CloseFiles,DEFAULT(1)

#BUTTON('.INI File Settings')

  #PROMPT('Use .INI file',CHECK),%INIActive,DEFAULT(1)

  #ENABLE(%INIActive)

    #PROMPT('.INI File to use',DROP,'Program Name.INI|Other'),%INIFile

    #ENABLE(%INIFile='Other')

      #PROMPT('File Name',@S40),%ININame

    #ENDENABLE

    #PROMPT('Save Window Locations',CHECK),%INISaveWindow,DEFAULT(1)

  #ENDENABLE

#ENDBUTTON

#!

#!Global Template Declarations.

#MESSAGE('Generating ' & %Application,0)	#! Open the Message Box

#DECLARE(%FilesUsed),UNIQUE,MULTI                 #! Label of every file used

#DECLARE(%FilePut,%FilesUsed)                     #! "Yes" for RI PUT used

#DECLARE(%FileDelete,%FilesUsed)                  #! "Yes" for RI DELETE used

#DECLARE(%ModuleFilesUsed,%Module),UNIQUE,MULTI,SAVE  #!Name of file used in module

#DECLARE(%ModuleFilePut,%ModuleFilesUsed),SAVE    #! "Yes" for RI PUT used

#DECLARE(%ModuleFileDelete,%ModuleFilesUsed),SAVE #! "Yes" for RI DELETE used

#DECLARE(%IniFileName)                            #! Used to construct INI file

#DECLARE(%ModuleProcs,%Module),MULTI,SAVE,UNIQUE  #! Program MAP prototype

#DECLARE(%ModulePrototype,%ModuleProcs)           #! Module MAP prototype

#DECLARE(%AccessMode)                             #! File open mode equate

#DECLARE(%BuildFile)                              #! Construction filename

#!

#!Initialization Code for Global User-defined Symbols.

#IF(%SharedFiles)                                 #! IF Shared Files Enabled

  #SET(%AccessMode,'42h')                         #! default access 'shared'

#ELSE                                             #! ELSE (IF NOT Shared Files ..)

  #SET(%AccessMode,'22h')                         #! default access 'open'

#ENDIF                                            #! END (IF Shared Files ...)

#IF(%INIFile = 'Program Name.INI')                #! IF using program.ini

  #SET(%INIFileName, %Application & '.INI')       #! SET the file name

#ELSE                                             #! ELSE (IF NOT using Program.ini)

  #SET(%INIFileName,%ININame)                     #! SET the file name

#ENDIF                                            #! END (IF using program.ini)

#!

#! Main Source Code Generation Loop.

#DECLARE(%GlobalRegenerate)                       #! Flag that controls generation

#IF(~%ConditionalGenerate OR %DictionaryChanged OR %RegistryChanged)

  #SET(%GlobalRegenerate,%True)                   #! Generate Everything

#ELSE                                             #! ELSE (If no global change)

  #SET(%GlobalRegenerate,%False)                  #! Generate changed modules only

#ENDIF                                            #! END (IF Global Change)

#SET(%BuildFile,(%Application & '.TM$'))          #! Make temp program filename

#FOR(%Module), WHERE (%Module <> %Program)        #! For all member modules

  #MESSAGE('Generating Module:    ' & %Module, 1) #! Post generation message

  #IF(%ModuleChanged OR %GlobalRegenerate)        #! IF module to be generated

    #FREE(%ModuleProcs)                           #! Clear module prototypes

    #FREE(%ModuleFilesUsed)                       #! Clear files used

    #CREATE(%BuildFile)                           #! Create temp module file

    #FOR(%ModuleProcedure)                        #! FOR all procs in module

      #FIX(%Procedure,%ModuleProcedure)           #! Fix current procedure

      #MESSAGE('Generating Procedure: ' & %Procedure, 2) #! Post generation message

      #GENERATE(%Procedure)                       #! Generate procedure code

    #ENDFOR                                       #! END (For all procs in module)

    #CLOSE(%BuildFile)                            #! Close last temp file

    #CREATE(%Module)                              #! Create a module file

    #GENERATE(%Module)                            #! Generate module header

    #APPEND(%BuildFile)                           #! Append the temp mod file

    #CLOSE(%Module)                               #! Close the module file

  #ENDIF                                          #! END (If module to be...)

#ENDFOR                                           #! END (For all member modules)

#FIX(%Module,%Program)                            #! FIX to program module

#MESSAGE('Generating Module:    ' & %Module, 1)   #! Post generation message

#FREE(%ModuleProcs)                               #! Clear module prototypes

#FREE(%ModuleFilesUsed)                           #! Clear files used

#CREATE(%BuildFile)                               #! Create temp module file

#FOR(%ModuleProcedure)                            #! For all procs in module

  #FIX(%Procedure,%ModuleProcedure)               #! Fix current procedure

  #MESSAGE('Generating Procedure: ' & %Procedure, 2) #! Post generation message

  #GENERATE(%Procedure)                           #! Generate procedure code

#ENDFOR                                           #! EndFor all procs in module

#CLOSE()                                          #! Close last temp file

See Aslo:

#GENERATE


#PROGRAM (global area)

#PROGRAM( name, description [, target, extension ] ) [, HLP( helpid ) ]

#PROGRAM	Defines the beginning of the main program module.

name	The name of the #PROGRAM which identifies it for the Template Registry and Template Language statements. This must be a valid Clarion label.

description	A string constant describing the #PROGRAM section for the Template Registry and Application Generator.

target	A string constant that specifies the source language the Template generates. If omitted, it defaults to Clarion.

extension	A string constant that specifies the source code file extension for the target. If omitted, it defaults to .CLW.

HLP	Specifies on-line help is available.

helpid	A string constant containing the identifier to access the Help system. This may be either a Help keyword or "context string."

The #PROGRAM statement defines the beginning of the main program module of the Template. The #PROGRAM section is terminated by the next Template Code Section (#MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, or #GROUP) statement encountered, or the end of the file. Only one #PROGRAM section is allowed in a Template set.

#BUTTON, #PROMPT, and #DISPLAY statements are not valid within a #PROGRAM section. Global prompts go in the #APPLICATION section.

Example:

#PROGRAM(CLARION,'Standard Clarion Shipping Template')

PROGRAM   	!PROGRAM statement required

INCLUDE('Keycodes.clw')

 	INCLUDE('Errors.clw')

 	INCLUDE('Equates.clw')


#MODULE (module area)

#MODULE( name, description [, target, extension ] ) [, HLP( helpid ) ] [, EXTERNAL ]

#MODULE	Begins the module section.

name	The name of the Module which identifies it for the Template Registry and Template Language statements. This must be a valid Clarion label.

description	A string constant describing the #MODULE section for the Template Registry and Application Generator.

target	A string constant that specifies the source language the Template generates. The word "EXTERNAL" is convention adopted to indicate an external source or object module. If omitted, it defaults to Clarion.

extension	A string constant that specifies the source code file extension for the target. If omitted, it defaults to .CLW.

HLP	Specifies on-line help is available.

helpid	A string constant containing the identifier to access the Help system. This may be either a Help keyword or "context string."

EXTERNAL	Specifies no source generates into the module.

The #MODULE statement defines the beginning of the section of the template which puts data into each generated source module's data area. The #MODULE Section is terminated by the next Template Code Section (#PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, or #GROUP) statement encountered, or the end of the file. A Template set may contain multiple #MODULE statements.

Code generated by a #MODULE section is (usually) placed at the beginning of a source code file generated by the Application Generator.

#BUTTON, #PROMPT, and #DISPLAY statements are not valid within a #MODULE section.

Example:

#MODULE(ExternalOBJ,'External .OBJ module','EXTERNAL','.OBJ'),EXTERNAL

#MODULE(ExternalLIB,'External .LIB module','EXTERNAL','.LIB'),EXTERNAL

#MODULE(GENERATED,'Clarion MEMBER module')

 	MEMBER('%Program') 	!MEMBER statement is required

%ModuleData    	#!Data declarations local to the Module


#PROCEDURE (begin a procedure template)

#PROCEDURE( name, description [, target ] ) [, REPORT ] [, WINDOW ] [, HLP( helpid ) ]

[, PRIMARY( message [, flag ] ) ]  [, QUICK( wizard ) ]

#PROCEDURE	Begins a procedure template.

name	The label of the procedure template. This must be a valid Clarion label.

description	A string constant describing the procedure Template.

target	A string constant that specifies the source language the template generates. If omitted, it defaults to Clarion.

REPORT	Tells the Application Generator to make the Report Formatter available.

WINDOW	Tells the Application Generator to make the Window Formatter available.

HLP	Specifies on-line help is available.

helpid	A string constant containing the help identifier. This may be either a Help keyword or "context string."

PRIMARY	Specifies at least one file must be placed in the procedure's File Schematic.

message	A string constant containing a message that appears in the File Schematic next to the procedure's Primary file.

flag	If present, contains OPTIONAL (the file is not required), OPTKEY (the key is not required), or NOKEY (the file is not required to have a key).

QUICK	Specifies the procedure has a wizardwizard #UTILITY that runs when the Use Procedure Wizard box is checked.

wizard	The identifier (including template class, if necessary) of the wizard #UTILITY template.

The #PROCEDURE statement begins a Procedure template. A Procedure template contains the Template and target language statements used to generate the source code for a procedure within your application.  A #PROCEDURE section is terminated by the first occurrence of a Template Code Section (#PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, or #GROUP) statement, or the end of the file. Within a Template set you may have multiple #PROCEDURE sections, but they must all have unique name parameters.

Example:

#PROCEDURE(ProcName1,'This is a sample window procedure'),WINDOW

#PROCEDURE(ProcName2,'This is a sample report procedure'),REPORT

#PROCEDURE(ProcName3,'This is a sample anything procedure'),WINDOW,REPORT

#PROCEDURE(Browse,'List with Wizard'),WINDOW,QUICK(BrowseWizard(Wizards))


#GROUP (reusable statement group)

#GROUP( symbol [, [ type ] parameters ] ) [, AUTO ] [, HLP( helpid ) ]

#GROUP	Begins a section of template code that may be inserted into another portion of the template.

symbol	A user-defined symbol used as the #GROUP's identifier.

type	The data type of a passed parameter: LONG, REAL, STRING, or * (asterisk). An asterisk (*) indicates it is a variable-parameter (passed by address), whose value may be changed by the #GROUP. LONG, REAL, and STRING indicates it is a value-parameter (passed by value), whose value is not changed by the #GROUP. If type is omitted, the parameter is a passed as a STRING.

parameters	User-defined symbols by which values passed to the #GROUP are referenced. You may pass multiple parameters, each separated by commas, to a #GROUP. All specified parameters must be passed to the #GROUP; they may not be omitted.

AUTO	Opens a new scope for the group. This means that any #DECLARE statements in the #GROUP would not be available to the #PROCEDURE being generated. Passing parameters to a #GROUP implicitly opens a new scope.

HLP	Specifies on-line help is available.

helpid	A string constant containing the identifier to access the Help system. This may be either a Help keyword or "context string."

#GROUP defines the beginning of a section of code which is generated into the source. A #GROUP section may contain Template and/or target language code. The #GROUP section is terminated by the first occurrence of a Template Code Section (#PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, or #GROUP) statement, or the end of the file. Within a single Template, separate #GROUP sections may not be defined with the same symbol. The parameters passed to a #GROUP fall into two categories: value-parameters and variable-parameters.

Value-parameters are declared as user-defined symbols, with an optional type and are "passed by value" (a copy of the value is passed) Either symbols or expressions may be passed as value-parameters. When a multi-valued symbol is passed as a value-parameter, only the current instance is passed.

Variable-parameters are declared as user-defined symbols with a prepended asterisk (*) (and no type). A variable-parameter is "passed by address" and any change to its value by the #GROUP code changes the value of the passed symbol. Only symbols may be passed to a #GROUP as variable-parameters. When a multi-valued symbol is passed as a variable-parameter, all instances are passed.

The statements contained in the #GROUP section are generated by the #INSERT statement. A #GROUP may contain #EMBED statements to define embedded source code points.

Example:

#GROUP(%GenerateFormulas) #!A #GROUP without parameters

  #FOR(%Formula)

    #IF(%FormulaComputation)

%Formula = %FormulaComputation

    #ELSE

IF(%FormulaCondition)

  %Formula = %FormulaTrue

ELSE

  %Formula = %FormulaFalse

END

    #ENDIF

  #ENDFOR

#GROUP(%ChangeProperty,%MyField,%Property,%Value)

  	#!A #GROUP that receives parameters

%MyField{%Property} = '%Value' #<!Change the %Property of %MyField

#GROUP(%SomeGroup, * %VarParm, LONG %ValParm)

 	#!A #GROUP that receives a variable-parameter and a value-parameter

See Aslo:

#INSERT


 #UTILITY (utility execution section)

#UTILITY( name, description ) [, HLP( helpid ) ] [, WIZARD ]

#UTILITY	Begins a utility generation control.

name	The name of the #UTILITY which identifies it for the Template Registry. This must be a valid Clarion label.

description	A string constant describing the utility section.

HLP	Specifies on-line help is available.

helpid	A string constant containing the identifier to access the Help system. This may be either a Help keyword or "context string."

WIZARD	Specifies the #UTILITY is used as a Wizard to generate a procedure or a complete application.

The #UTILITY statement marks the beginning of a utility execution control section. The section is terminated by the next Template Code Section (#PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, #UTILITY, or #GROUP) statement. The Template statements contained in this section control the utility execution process. Multiple #UTILITY sections are allowed in a single Template set.

The #UTILITY section is very similar to the #APPLICATION section, in that it allows you to produce output from the application. The purpose of #UTILITY is to provide extensible supplemental utilities for such things as program documentation, or a tree diagram of procedure calls. The list of registered utilities appears in the Utilities menu in the Clarion for Windows environment.

#UTILITY with the WIZARD attribute specifies it contains a #SHEET with #TABs that display one tab at a time, guiding the user through the prompts.

Example:

#UTILITY(ProcCallTree, 'Output procedure call tree')

  #CREATE(%Application & '.TRE')

Procedure Call Tree: for %Application

#INSERT(%DisplayTree, %FirstProcedure, '', '  ')

#CLOSE

#!***********************************************************

#GROUP(%DisplayTree, %ThisProc, %Level, %NextIndent)

  #FIX(%Procedure, %ThisProc)

%Level+-%ThisProc (%ProcedureTemplate)

  #FOR(%ProcedureCalled)

    #IF(INSTANCE(%ProcedureCalled) = ITEMS(%ProcedureCalled))

#INSERT(%DisplayTree, %ProcedureCalled, %Level & %NextIndent, '  ')

    #ELSE

#INSERT(%DisplayTree, %ProcedureCalled, %Level & %NextIndent, '| ')

    #ENDIF

  #ENDFOR


 #CODE (define a code template)

#CODE( name,description [,target ] )[, SINGLE][, HLP( helpid )] [, PRIMARY( message [, flag] )]

[, DESCRIPTION( expression ) ] [, ROUTINE ]

[, REQ( addition [,	| BEFORE	| ] ) ] [,	| FIRST	| ]

| AFTER	|	| LAST	|

#CODE	Begins a code template that generates source into an embedded source code point.

name	The label of the code template. This must be a valid Clarion label.

description	A string constant describing the code template. The total number of characters in the #CODE statement must be less than 255. Therefore, the description must not be so long that the entire #CODE statement exceeds this limit.

target	A string constant that specifies the source language the code template generates. If omitted, it defaults to Clarion. This restricts the #CODE to matching target language use, only.

SINGLE	Specifies the #CODE may be used only once in a given procedure (or program, if the embedded source code point is global).

HLP	Specifies on-line help is available.

helpid	A string constant containing the identifier to access the Help system. This may be either a Help keyword or "context string."

PRIMARY	Specifies a primary file for the code template must be placed in the procedure's File Schematic.

message	A string constant containing a message that appears in the File Schematic next to the #CODE's Primary file.

flag	Either OPTIONAL (the file is not required), OPTKEY (the key is not required), or NOKEY (the file is not required to have a key).

DESCRIPTION	Specifies the display description of a #CODE that may be used multiple times in a given application or procedure.

expression	A string constant or expression that contains the description to display.

ROUTINE	Specifies the generated code is not automatically indented from column one.

REQ	Specifies the #CODE requires a previously placed #CODE, #CONTROL, or #EXTENSION before it may be used. It also means all prompts and variables of the required addition are available to it.

addition	The name of the previously placed #CODE, #CONTROL, or #EXTENSION template, from any template set.

BEFORE	Specifies the code is generated before the code is generated for the addition.

AFTER	Specifies the code is generated after the code is generated for the addition.

FIRST	Specifies the code is generated at the beginning of the embedded source code point, before any other code.

LAST	Specifies the code is generated at the end of the embedded source code point, after any other code.

#CODE defines the beginning of a code template which can generate code into embedded source code points. A #CODE section may contain Template and/or target language code. The #CODE section is terminated by the first occurrence of a Template Code Section (#PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, or #GROUP) statement, or the end of the file. Within a single Template set, separate #CODE sections may not be defined with the same name.

#CODE generates its code into a #EMBED embedded source code point. The generated code is automatically indented when placed in ROUTINEs, unless the ROUTINE attribute is present.  A #CODE section may contain #PROMPT statements to prompt for the values needed to generate proper source code. It may also contain #EMBED statements, which become active only if the #CODE section is used.

You can use the #WHERE statement to limit the availability of the #CODE to those embedded source code points where the generated code would be appropriate. A #CODE may contain multiple #WHERE statements to explicitly define all the valid embedded source code points in which it may appear. #RESTRICT can also further restrict the availability of the #CODE based on an expression or Template language statements.

The #AT/#ENDAT structure allows a single #CODE to generate code into multiple embedded source code points to support its functionality.

Example:

#CODE(ChangeProperty,'Change control property')

  #WHERE(%SetupWindow..%ProcedureRoutines) 	#!Appropriate only after window open

  #PROMPT('Control to change',CONTROL),%MyField,REQ

  #PROMPT('Property to change',@S20),%Property,REQ

  #PROMPT('New Value',@S20),%Value,REQ

%MyField{%Property} = '%Value' 	#<!Change the %Property of %MyField

See Also:

#EMBED

#WHERE

#RESTRICT

#AT


#CONTROL (define a control template)

#CONTROL( name, description ) [, MULTI ] [, PRIMARY( message [, flag ] ) ]

[, WINDOW ] [, REPORT]

[, REQ( addition [,	| BEFORE	| ] ) [,	| FIRST	| ] [, DESCRIPTION( expresion ) ] ]

| AFTER	|	| LAST	|

CONTROLS

         control statements [, #REQ ]

END

#CONTROL	Begins a code template that generates a set of controls into a window and the source code required to manipulate them into embedded source code points.

name	The label of the control template. This must be a valid Clarion label.

description	A string constant describing the control template. The total number of characters in the #CONTROL statement must be less than 255. Therefore, the description must not be so long that the entire #CONTROL statement exceeds this limit.

MULTI	Specifies the #CONTROL may be used multiple times in a given window.

PRIMARY	Specifies a primary file for the set of controls must be placed in the procedure's File Schematic.

message	A string constant containing a message that appears in the File Schematic next to the #CONTROL's Primary file.

flag	Either OPTIONAL (the file is not required), OPTKEY (the key is not required), or NOKEY (the file is not required to have a key).

WINDOW	Tells the Application Generator to make the #CONTROL available in the Window Formatter. This is the default setting if both WINDOW and REPORT are omitted.

REPORT	Tells the Application Generator to make the #CONTROL available in the Report Formatter. If omitted, the #CONTROL may not be placed in a REPORT.

REQ	Specifies the #CONTROL requires a previously placed #CODE, #CONTROL, or #EXTENSION before it may be used.

addition	The name of the previously placed #CODE, #CONTROL, or #EXTENSION.

BEFORE	Specifies the code is generated before the code is generated for the addition.

AFTER	Specifies the code is generated after the code is generated for the addition.

FIRST	Specifies the code is generated at the beginning of the embedded source code point, before any other code.

LAST	Specifies the code is generated at the end of the embedded source code point, after any other code.

DESCRIPTION	Specifies the display description of a #CONTROL that may be used multiple times in a given application or procedure.

expression	A string constant or expression that contains the description to display.

CONTROLS	Specifies the controls  for the #CONTROL, and must be terminated with an END statement. This is a "pseudo-Clarion keyword" in that, if you replace the CONTROLS statement with a WINDOW statement, you can use the Text Editor's Window Formatter to create the controls.

controls	Window control declarations that specifiy the control set belonging to the #CONTROL.

#REQ	Specifies the control  is required. If deleted from the window or report, the entire #CONTROL (including all its controls) is deleted.

#CONTROL defines the beginning of a code template containing a "matched set" of controls to populate into a window or report as a group. It also generates the source code required for their correct operation into embedded source code points. A #CONTROL section may contain Template and/or target language code. The #CONTROL section is terminated by the first occurrence of a Template Code Section (#PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, or #GROUP) statement, or the end of the file. Within a single Template set, separate #CONTROL sections may not be defined with the same name.

#CONTROL generates the code to operate its controls into #EMBED embedded source code points using the #AT/#ENDAT structure. #RESTRICT can restrict use of the #CONTROL based on an expression or Template language statements.

A #CONTROL section may contain #PROMPT statements to prompt for the values needed to generate proper source code. These prompts appear on the Actions window in the environment. It may also contain #EMBED statements which become active only if the #CONTROL section is used.

The x and y parameters of the AT attribute of the controls in the #CONTROL set determine the positioning of the control  relative to the last control in the #CONTROL set placed on screen (or relative to the window, if first). If these parameters are omitted, the programmer is prompted for the position to place the control. This makes it simple to populate an entire set of controls without requiring the programmer to place each one individually.

Example:

#CONTROL(BrowseList,'Add Browse List controls')

  #PROMPT('Allow Inserts',CHECK),%InsertAllowed,DEFAULT(1)

  #ENABLE(%InsertAllowed)

      #PROMPT('Insert Hot Key',@s20),%InsertHotKey,DEFAULT('InsertKey')

  #ENDENABLE

  #PROMPT('Allow Changes',CHECK),%ChangeAllowed,DEFAULT(1)

  #ENABLE(%ChangeAllowed)

      #PROMPT('Change Hot Key',@s20),%ChangeHotKey,DEFAULT('CtrlEnter')

  #ENDENABLE

  #PROMPT('Allow Deletes',CHECK),%DeleteAllowed,DEFAULT(1)

  #ENABLE(%DeleteAllowed)

      #PROMPT('Delete Hot Key',@s20),%DeleteHotKey,DEFAULT('DeleteKey')

  #ENDENABLE

  #PROMPT('Update Procedure',PROCEDURE),%UpdateProc

CONTROLS

  LIST,AT(,,270,99),USE(?List),IMM,FROM(Queue:Browse),#REQ

  BUTTON('Insert'),AT(,,40,15),KEY(%InsertHotKey),USE(?Insert),MSG('Add record')

  BUTTON('Change'),AT(,,40,15),KEY(%ChangeHotKey),USE(?Chg),DEFAULT,MSG('Change')

  BUTTON('Delete'),AT(,,40,15),KEY(%DeleteHotKey),USE(?Delete),MSG('Delete record')

END

#!

  #AT(%ControlEvent),WHERE(%ControlOriginal='?Insert' AND %ControlEvent='Accepted')

    #IF(%InsertAllowed)

Action = AddRecord

%UpdateProc

    #ENDIF

  #ENDAT

#!

  #AT(%ControlEvent),WHERE(%ControlOriginal='?Chg' AND %ControlEvent='Accepted')

    #IF(%ChangeAllowed)

Action = ChangeRecord

%UpdateProc

    #ENDIF

  #ENDAT

#!

  #AT(%ControlEvent),WHERE(%ControlOriginal='?Delete' AND %ControlEvent='Accepted')

    #IF(%DeleteAllowed)

Action = DeleteRecord

%UpdateProc

    #ENDIF

  #ENDAT

See Also:

#EMBED

#WHERE

#RESTRICT

#AT


#EXTENSION (define an extension template)

#EXTENSION( name, description [, target ] ) [, MULTI ] [,	| APPLICATION	| ]

| PROCEDURE	|

[, REQ( addition [,	| BEFORE	| ] ) [,	| FIRST	| ] [, DESCRIPTION( expression ) ] ]

| AFTER	|	| LAST	|   [, PRIMARY( message [, flag ] ) ]

#EXTENSION	Begins an extension template that generates code into embedded source code points to add some functionality not associated with specific controls.

name	The label of the extension template. This must be a valid Clarion label.

description	A string constant describing the extension template.

target	A string constant that specifies the source language the extension template generates. If omitted, it defaults to Clarion.

MULTI	Specifies the #EXTENSION may be used multiple times in a given application or procedure.

APPLICATION	Tells the Application Generator to make the #EXTENSION available only at the global level.

PROCEDURE	Tells the Application Generator to make the #EXTENSION available only at the local level.

REQ	Specifies the #EXTENSION requires a previously placed #CODE, #CONTROL, or #EXTENSION before it may be used.

addition	The name of the previously placed #CODE, #CONTROL, or #EXTENSION.

BEFORE	Specifies the code is generated before the code is generated for the addition.

AFTER	Specifies the code is generated after the code is generated for the addition.

FIRST	Specifies the code is generated at the beginning of the embedded source code point, before any other code.

LAST	Specifies the code is generated at the end of the embedded source code point, after any other code.

DESCRIPTION	Specifies the display description of a #EXTENSION that may be used multiple times in a given application or procedure.

expression	A string constant or expression that contains the description to display.

PRIMARY	Specifies a primary file for the extension must be placed in the procedure's File Schematic.

message	A string constant containing a message that appears in the File Schematic next to the #EXTENSION's Primary file.

flag	Either OPTIONAL (the file is not required), OPTKEY (the key is not required), or NOKEY (the file is not required to have a key).

#EXTENSION defines the beginning of an extension template containing code to generate into the application or procedure to provide some functionality not directly associated with any control. A #EXTENSION section may contain Template and/or target language code. The #EXTENSION section is terminated by the first occurrence of a Template Code Section (#PROGRAM, #MODULE, #PROCEDURE, #CONTROL, #CODE, #EXTENSION, or #GROUP) statement, or the end of the file. Within a single Template set, separate #EXTENSION sections may not be defined with the same name.

#EXTENSION can only generate code into #EMBED embedded source code points using the #AT/#ENDAT structure. A #EXTENSION section may contain #PROMPT statements to prompt for the values needed to generate proper source code. These prompts appear when you edit an Extension from the Extensions button in the environment. It may also contain #EMBED statements which become active only if the #EXTENSION section is used.

#RESTRICT can restrict appearance of the #EXTENSION in the list of available extensions based on an expression or Template language statements.

Example:

#EXTENSION(Security,'Add password'),PROCEDURE

  #PROMPT('Password File',FILE),%PasswordFile,REQ

  #PROMPT('Password Key',KEY(%PasswordFile)),%PasswordFileKey,REQ

  #PROMPT('Password Field',COMPONENT(%PasswordFileKey)),%PasswordFileKeyField,REQ

  #AT(%DataSectionBeforeWindow)

LocalPswd 	STRING(10)

SecurityWin WINDOW

   	ENTRY(@s10),USE(LocalPswd),REQ,PASSWORD

BUTTON('Cancel'),KEY(EscKey),USE(?CancelPswd)

 	END

  #ENDAT

  #AT(%ProcedureSetup)

OPEN(SecurityWin)

ACCEPT

  CASE ACCEPTED()

  OF ?LocalPswd

    %PasswordFileKeyField = LocalPswd

    GET(%PasswordFile,%PasswordFileKey)

    IF NOT ERRORCODE()

      LocalPswd = 'OK'

    END

BREAK

  OF ?CancelPswd

CLEAR(LocalPswd)

    BREAK

END

END

CLOSE(SecurityWin)

IF LocalPswd <> 'OK' THEN RETURN.

  #ENDAT

See Also:

#EMBED

#WHERE

#RESTRICT

#AT


Embed Points

#EMBED (define embedded source point)

#AT (insert code in an embed point)

#ATSTART (template intialization code)

#ATEND (template reset code)

#EMPTYEMBED (generate empty embed point comments)

#POSTEMBED (generate ending embed point comments)

#PREEMBED (generate beginning embed point comments)


#EMBED (define embedded source point)

#EMBED( identifier, descriptor ) [, symbol ] [, HLP( helpid ) ] [, DATA ] [, HIDE ]

[, WHERE( expression ) ] [, MAP( symbol, description ) ]

#EMBED	Identifies an explicit position in the Template where the programmer may place their own source code.

identifier	A user-defined template symbol which identifies the embedded source code point for the Application Generator.

descriptor	A string constant containing a description of the embedded source code's position in the Template. This is the string displayed in the list of available embedded source code windows for a procedure Template.

symbol	A built-in multi-valued template symbol. You may have multiple symbols on a single #EMBED statement.

HLP	Specifies on-line help is available for the #EMBED.

helpid	A string constant containing the identifier to access the Help system. This may be either a Help keyword or "context string."

DATA	Specifies the embed point is in a data section, so the Text Editor's Window and Report Formatters can be used.

HIDE	Specifies the source code point does not appear in the tree of available embedded source code points. Therefore, the #EMBED is only available for #CODE, #CONTROL, or #EXTENSION code generation.

WHERE	Specifies the #EMBED is available only for those instances of the symbol where the expression is true.

expression	An expression that specifies the condition.

MAP	Maps the description to the symbol  for display in the embedded source tree. You may have as many MAP attributes as symbols.

description	An expression that specifies the text to display in the embedded source tree.

#EMBED identifies an explicit position in the Template where the programmer may call a procedure, generate code from a code template, or place their own custom embedded source code within the procedure or function. The Application Generator prompts the programmer for the procedure to call, or the code template to use, or calls the Text Editor to allow the programmer to write the embedded source code. #EMBED is also used as the destination of all the source automatically generated by #CODE, #CONTROL, and #EXTENSION template sections. If no code is written in the embedded source code point by the programmer or any code template, control template, or extension template, no code is generated.

In a #PROCEDURE section, the source code is automatically placed in the exact column position at which #EMBED is located within the Template. If #EMBED is directly placed in the data section of a #PROGRAM, #MODULE, or #PROCEDURE, it must be in column one (1) of the Template file (so the embedded code may contain data labels). If the #EMBED statement has the DATA atribute, the Window and Report Formatters in the Text Editor are available for use. In executable code sections, #EMBED may be placed in column one, but that is not required.

#EMBED is valid in a #GROUP section, however, this should be used with care. Since it is possible for a #GROUP to be recursive (call itself), it is possible to create embedded source code that is repeated within each iteration of the recursive #GROUP's generated code. The source code is generated in the same relative column position as the code generated from the #GROUP.

A #EMBED using the symbol attribute is used within a #FOR statement to allow a different piece of embedded source to be inserted for each instance of the symbol. It can also be used within #FOR, #LOOP, and/or recursive #GROUPs for the current instance of the symbol (if it has been #FIXed). The MAP attribute allows you to replace a description for the symbol in the embedded source tree.

Example:

#PROCEDURE(SampleProc,'This is a sample procedure'),WINDOW

#!Template and target language data declarations for the procedure go here

#EMBED(%DataSection,'Data Section Source Code Window'),DATA

     	#!Source code starting in column 1

  CODE     	!Begin executable code

  #EMBED(%SetupProc,'Code Section Source Code Window 1')

  	   	#!Source code starting in column 3

  #!Template and target language executable code for the procedure goes here

  OPEN(Screen)    	!Open window

  ACCEPT     	!Event handler

    CASE SELECTED()    	!Handle field-selection events

    #FOR(%Control)

    OF %Control

      #EMBED(%ScreenFieldSetupEmbed,'Field Selected Embed'),%Control

    #ENDFOR

    END

    CASE ACCEPTED()    	!Handle field-action events

    #FOR(%Control)

    OF %Control

      #EMBED(%ScreenFieldEditEmbed,'Field Accepted Embed'),%Control

    #ENDFOR

.	.

#EMBED(%CustomRoutines,'Code Section Source Code Window 2')

  	 	#!Source code starting in column 1


#AT (insert code in an embed point)

#AT( location [, instances ] ) [, WHERE( expression ) ]

  statements

#ENDAT

#AT	Specifies a location to generate statements.

location	An #EMBED identifier. This may be a #EMBED for the procedure that comes from another template set.

instances	The location parameters that identify the embedded source code point for a multi-valued #EMBED identifier. There may as many instance parameters as are required to explicitly identify the embedded source code point.

WHERE	More closely specifies the #AT location as only those embed points where the expression is true.

expression	An expression that specifies exact placement.

statements	Template and/or target language code.

#ENDAT	Terminates the section.

The #AT structure specifies a location to generate statements. #AT is valid only in a #CONTROL, #CODE, or #EXTENSION templates, and is used to allow them to generate statements into multiple locations. The #AT structure must terminate with #ENDAT.

The WHERE clause allows you to create an expression that can specify a single specific instance of a #EMBED that has a symbol attribute.

Example:

#CONTROL(BrowseList,'Add Browse List controls')

  #AT(%ControlEvent,'?Insert','Accepted')

    #IF(%InsertAllowed)

Action = AddRecord

%UpdateProc

    #ENDIF

  #ENDAT

#!

See Also:

#EMBED

#CODE

#CONTROL

#EXTENSION

#RESTRICT


#ATSTART (template intialization code)

#ATSTART

  statements

#ENDAT

#ATSTART	Specifies template code to execute before the #PROCEDURE, #CODE, #CONTROL, or #EXTENSION generates.

statements	Template language code.

#ENDAT	Terminates the section.

The #ATSTART structure specifies template code to execute before the #PROCEDURE, #CODE, #CONTROL, or #EXTENSION generates its code. Therefore, the statements should normally only contain Template language. #ATSTART is usually used to initialize internal template variables.

Example:

#CONTROL(BrowseList,'Add Browse List controls')

#ATSTART

#DECLARE(%ListQueue)

#ENDAT

See Also:

#PROCEDURE

#CODE

#CONTROL

#EXTENSION


#ATEND (template reset code)

#ATEND

  statements

#ENDAT

#ATEND	Specifies template code to execute after the #PROCEDURE, #CODE, #CONTROL, or #EXTENSION generates.

statements	Template language code.

#ENDAT	Terminates the section.

The #ATEND structure specifies template code to execute after the #PROCEDURE, #CODE, #CONTROL, or #EXTENSION generates its code. Therefore, the statements should only contain Template language. #ATEND is usually used to reset internal template variables.

Example:

#CONTROL(BrowseList,'Add Browse List controls')

#ATEND

#SET(%ListQueue,%NULL)

#ENDAT

See Also:

#PROCEDURE

#CODE

#CONTROL

#EXTENSION


#EMPTYEMBED (generate empty embed point comments)

#EMPTYEMBED( text [, condition ] )

#EMPTYEMBED	Generates comments into empty embed points.

text	A string constant or constant expression containing the text to place in the empty embed point.

condition	An expression that, when true, allows the comments to generate.

The #EMPTYEMBED statement specifies that comments generate into all embed points in which the user has not entered code. This will not generate comments for embed points in which the user has entered code or in which the templates have generated code.

This is valid only in a #PROGRAM or #MODULE section. The output condition is usually the value of a global prompt.

The comment text may use the %EmbedID, %EmbedDescription, and %EmbedParameters built-in symbols to identify the embed point:

%EmbedID	The current embed point's identifying symbol.

%EmbedDescription
The current embed point's description.

%EmbedParameters
The current embed point's current instance, as a comma-delimited list.

Example:

#EXTENSION(EmptyEmbeds,'Empty Embed Comments'),APPLICATION

#PROMPT('Generate Empty EMBED Comments',CHECK),%EmptyEmbeds

#EMPTYEMBED('!Embed: ' & %EmbedDescription & ' ' & %EmbedParameters,%EmptyEmbeds)

See Also:

#PREEMBED

#POSTEMBED


#POSTEMBED (generate ending embed point comments)

#POSTEMBED( text [, condition ] )

#POSTEMBED	Generates comments at the end of embed point code.

text	A string constant or constant expression containing the text to place in the embed point.

condition	An expression that, when true, allows the comments to generate.

The #POSTEMBED statement specifies that comments generate at the end of embed points that contain code.  This is valid only in a #PROGRAM or #MODULE section. The output condition is usually the value of a global prompt.

The comment text may use the %EmbedID, %EmbedDescription, and %EmbedParameters built-in symbols to identify the embed point:

%EmbedID	The current embed point's identifying symbol.

%EmbedDescription
The current embed point's description.

%EmbedParameters
The current embed point's current instance, as a comma-delimited list.

Example:

#POSTEMBED('! After Embed Point: ' & %EmbedID & ' ' & %EmbedDescription & ' ' & |

%EmbedParameters,%GenerateEmbedComments)

See Also:

#PREEMBED

#EMPTYEMBED


#PREEMBED (generate beginning embed point comments)

#PREEMBED( text [, condition ] )

#PREEMBED	Generates comments at the beginning of embed point code.

text	A string constant or constant expression containing the text to place in the embed point.

condition	An expression that, when true, allows the comments to generate.

The #PREEMBED statement specifies that comments generate at the beginning of embed points that contain code.  This is valid only in a #PROGRAM or #MODULE section. The output condition is usually the value of a global prompt.

The comment text may use the %EmbedID, %EmbedDescription, and %EmbedParameters built-in symbols to identify the embed point:

%EmbedID	The current embed point's identifying symbol.

%EmbedDescription
The current embed point's description.

%EmbedParameters
The current embed point's current instance, as a comma-delimited list.

Example:

#PREEMBED('! Before Embed Point: ' & %EmbedID & ' ' & %EmbedDescription & ' ' & |

%EmbedParameters,%GenerateEmbedComments)

See Also:

#POSTEMBED

#EMPTYEMBED


Template Code Section Constraints

#WHERE (define #CODE embed point availability)

#RESTRICT (define section use constraints)

#ACCEPT (section valid for use)

#REJECT (section invalid for use)


#WHERE (define #CODE embed point availability)

#WHERE( embeds )

#WHERE	Limits the availability of a #CODE to only those specific embedded source code points where the generated code would be appropriate.

embeds	A comma-delimited list of #EMBED identifiers that specifies the embedded source code points that may use the #CODE to generate source code.

The #WHERE statement limits the availability of a #CODE to only those #EMBED embedded source code points where the generated code would be appropriate. A single #CODE may contain multiple #WHERE statements to explicitly define all the valid #EMBED embedded source code points. All the #WHERE statements in a #CODE are evaluated to determine which embedded source code points have been specifically enabled.

The embeds list must contain individual #EMBED identifiers delimited by commas. It may also contain ranges of embed points in the form FirstIdentifier..LastIdentifier, also delimited by commas. The embeds list may contain both types in a "mix and match" manner to define all suitable embedded source code points.

Example:

#CODE(ChangeProperty,'Change control property')

  #WHERE(%AfterWindowOpening..%CustomRoutines)

   	#!Appropriate everywhere after window open

  #PROMPT('Control to change',CONTROL),%MyField,REQ

  #PROMPT('Property to change',@S20),%MyProperty,REQ

  #PROMPT('New Value',@S20),%MyValue,REQ

%MyField{%MyProperty} = '%'MyValue

See Also:

#EMBED

#CODE

#RESTRICT


#RESTRICT (define section use constraints)

#RESTRICT [, WHERE( expression ) ]

statements

#ENDRESTRICT

#RESTRICT	Specifies conditions where a Template Code Section (#CODE, #CONTROL, #EXTENSION, #PROCEDURE, #PROGRAM, or #MODULE) can be used.

WHERE	The #RESTRICT statements are excuted only when the expression is true.

expression	A logical expression to limit execution of the #RESTRICT statements.

statements	Template language code to #ACCEPT or #REJECT use of the section which contains the #RESTRICT structure.

#ENDRESTRICT	Terminates the #RESTRICT structure.

The #RESTRICT structure provides a mechanism to limit the availability of a Template Code Section (#CODE, #CONTROL, #EXTENSION, #PROCEDURE, #PROGRAM, or #MODULE) at application design time to only those points where the generated code would be appropriate. Any WHERE clause on the Template Code Section is evaluated first, before #RESTRICT.

The #ACCEPT statement may be used to explicitly declare the section as appropriate for use. An implicit #ACCEPT also occurs if the #RESTRICT statements execute without encountering a #REJECT statement. The #REJECT statement must be used to specifically exclude the section from use. Both the #ACCEPT and #REJECT statements immediately terminate processing of the #RESTRICT code.

Example:

#CODE(ChangeControlSize,'Change control size')

  #RESTRICT

    #CASE(%ControlType)

    #OF('LIST')

    #OROF('BUTTON')

      #REJECT

    #ELSE

      #ACCEPT

    #ENDCASE

  #ENDRESTRICT

  #PROMPT('Control to change',CONTROL),%MyField,REQ

  #PROMPT('New Width',@n04),%NewWidth

  #PROMPT('New Height',@n04),%NewHeight

%MyField{PROP:Width} = %NewWidth

%MyField{PROP:Height} = %NewHeight

See Also:

#ACCEPT

#REJECT


#ACCEPT (section valid for use)

#ACCEPT

The #ACCEPT statement terminates #RESTRICT processing, indicating that the Template Code Section (#CODE, #CONTROL, #EXTENSION, #PROCEDURE, #PROGRAM, or #MODULE) is valid.

The #RESTRICT structure contains Template language statements that evaluate the propriety of generating the section's source code. The #ACCEPT statement may be used to explicitly declare the section as appropriate. An implicit #ACCEPT also occurs if the #RESTRICT statements execute without encountering a #REJECT statement. The #REJECT statement must be used to specifically exclude the section from use. Both the #ACCEPT and #REJECT statements immediately terminate processing of the #RESTRICT code.

Example:

#CODE(ChangeControlSize,'Change control size')

  #WHERE(%EventHandling)

  #RESTRICT

    #CASE(%ControlType)

    #OF 'LIST'

    #OROF 'BUTTON'

      #REJECT

    #ELSE

      #ACCEPT

    #ENDCASE

  #ENDRESTRICT

  #PROMPT('Control to change',CONTROL),%MyField,REQ

  #PROMPT('New Width',@n04),%NewWidth

  #PROMPT('New Height',@n04),%NewHeight

%MyField{PROP:Width} = %NewWidth

%MyField{PROP:Height} = %NewHeight

See Also:

#RESTRICT

#REJECT


#REJECT (section invalid for use)

#REJECT

The #REJECT statement terminates #RESTRICT processing, indicating that the Template Code Section (#CODE, #CONTROL, #EXTENSION, #PROCEDURE, #PROGRAM, or #MODULE) is invalid.

The #RESTRICT structure contains Template language statements that evaluate the propriety of generating the section's source code. The #ACCEPT statement may be used to explicitly declare the section as appropriate. An implicit #ACCEPT also occurs if the #RESTRICT statements execute without encountering a #REJECT statement. The #REJECT statement must be used to specifically exclude the section from use. Both the #ACCEPT and #REJECT statements immediately terminate processing of the #RESTRICT code.

Example:

#CODE(ChangeControlSize,'Change control size')

  #WHERE(%EventHandling)

  #RESTRICT

    #CASE(%ControlType)

    #OF 'LIST'

    #OROF 'BUTTON'

      #REJECT

    #ELSE

      #ACCEPT

    #ENDCASE

  #ENDRESTRICT

  #PROMPT('Control to change',CONTROL),%MyField,REQ

  #PROMPT('New Width',@n04),%NewWidth

  #PROMPT('New Height',@n04),%NewHeight

%MyField{PROP:Width} = %NewWidth

%MyField{PROP:Height} = %NewHeight

See Also:

#RESTRICT

#ACCEPT


Defaults and Template Data

Default Data and Code

#WINDOWS (default window structures)

#REPORTS (default report structures)

#LOCALDATA (default local data declarations)

#GLOBALDATA (default global data declarations)

#DEFAULT(default global data declarations)

Symbol Management Statements

#DECLARE (declare a user-defined symbol)

#ALIAS (access a symbol from another instance)

#ADD (add to multi-valued symbol)

#DELETE (delete a multi-valued symbol instance)

#DELETEALL (delete multiple multi-valued symbol instances)

#PURGE (delete all single or multi-valued symbol instances)

#CLEAR (clear single-valued symbol)

#FREE (free a multi-valued symbol)

#FIX (fix a multi-value symbol)

#FIND (super-fix multi-value symbols)

#SELECT (fix a multi-value symbol)

#SET (assign value to a user-defined symbol)

#UNFIX (unfix a multi-value symbol)

#DECLARE Attributes

UNIQUE (no duplicates allowed)

SAVE (save symbol between generations)


Default Data and Code

#WINDOWS (default window structures)

#REPORTS (default report structures)

#LOCALDATA (default local data declarations)

#GLOBALDATA (default global data declarations)

#DEFAULT(default global data declarations)


#WINDOWS (default window structures)

#WINDOWS

    structures

#ENDWINDOWS

#WINDOWS	Begins a default window data structure section.

structures	Default APPLICATION or WINDOW structures.

#ENDWINDOWS	Terminates the default window section.

The #WINDOWS structure contains default APPLICATION or WINDOW data structures for a procedure Template. The default window structures provide a starting point for the procedure's window design.

The #WINDOWS section may contain multiple structures which may be chosen as the starting point for the procedure's window design. If there is more than one window structure to choose from, the Application Generator displays a list of those structures available the first time the procedure's window is editted. The names of the windows which appear in the Application Generator's list comes from a preceding comment beginning with two exclamations and a right angle bracket (!!>).

If the procedure template contains a #DEFAULT procedure, there is no need for #WINDOWS, since the default window is already in the #DEFAULT. Therefore, the list does not appear when the window is first editted.

Example:

#WINDOWS

!!> Window

Label  WINDOW('Caption'),AT(0,0,100,100)

       END

!!> Window with OK & Cancel

Label  WINDOW('Caption'),AT(0,1,185,92)

         BUTTON('OK'),AT(144,10,35,14),DEFAULT,USE(?Ok)

         BUTTON('Cancel'),AT(144,28,36,14),USE(?Cancel)

       END

#ENDWINDOWS


#REPORTS (default report structures)

#REPORTS

    structures

#ENDREPORTS

#REPORTS	Begins a default report data structure section.

structures	Default REPORT structures.

#ENDREPORTS	Terminates the default report section.

The #REPORTS structure contains default REPORT data structures for a procedure Template. The default report structures provide a starting point for the procedure's report design.

The #REPORTS section may contain multiple structures which may be chosen as the starting point for the procedure's report design. If there is more than one report structure to choose from, the Application Generator displays a list of those structures available the first time the procedure's report is editted. The names of the windows which appear in the Application Generator's list comes from a preceding comment beginning with two exclamations and a right angle bracket (!!>).

If the procedure template contains a #DEFAULT procedure, there is no need for #REPORT, since the default report is already in the #DEFAULT. Therefore, the list does not appear when the report is first editted.

Example:

#REPORTS

!!> Report

Label  REPORT,AT(1000,2500,6000,6000),THOUS

         HEADER,AT(1000,1000,6000,1000)

         END

Detail   DETAIL

         END

         FOOTER,AT(1000,10000,6000,1000)

         END

         FORM,AT(1000,1000,6000,9000)

         END

       END

#ENDREPORTS


#LOCALDATA (default local data declarations)

#LOCALDATA

    declarations

#ENDLOCALDATA

#LOCALDATA	Begins a default local data declaration section.

declarations	Default data declarations.

#ENDLOCALDATA
Terminates the default local data declarations.

The #LOCALDATA structure contains default data declarations local to the procedure generated by the #PROCEDURE procedure Template. #LOCALDATA may only be placed in a #PROCEDURE, #CODE, #CONTROL, or #EXTENSION section of the Template. The declarations will appear in the generated procedure between the keywords PROCEDURE (or FUNCTION) and CODE.

Example:

#LOCALDATA

Action 	BYTE    	!Disk action variable

TempFile 	CTRING(65)   	!Temporary filename variable

#ENDLOCALDATA


#GLOBALDATA (default global data declarations)

#GLOBALDATA

    declarations

#ENDGLOBALDATA

#GLOBALDATA	Begins a default global data declaration section.

declarations	Default data declarations.

#ENDGLOBALDATA
Terminates the default global data declarations.

The #GLOBALDATA structure contains default data declarations global to the program. #GLOBALDATA may be placed in a #PROGRAM, #PROCEDURE, #CODE, #CONTROL, or #EXTENSION section of the Template. The declarations will appear in the global data section of the generated source code.

Example:

#GLOBALDATA

Action 	BYTE    	!Disk action variable

TempFile 	CTRING(65)   	!Temporary filename variable

#ENDGLOBALDATA


#DEFAULT(default global data declarations)

#DEFAULT

    procedure

#ENDDEFAULT

#DEFAULT	Begins a default procedure declaration section.

procedure	Default procedure in .TXA format.

#ENDDEFAULT	Terminates the default procedure declaration.

The #DEFAULT structure contains a single default procedure declaration in .TXA format as generated by the Application generator's Export function. #DEFAULT may only be placed at the end of a  #PROCEDURE section of the Template. You may have multiple #DEFAULT structures for a single #PROCEDURE. #The enclosed procedure section of a .TXA file should contain a procedure of the preceeding #PROCEDURE's type. The  recommened way to create these #DEFAULT structures is to edit the default procedures in the template registry, and then export the template as text.

Example:

#DEFAULT

NAME DefaultForm

[COMMON]

DESCRIPTION 'Default record update'

FROM Clarion Form

[PROMPTS]

%WindowOperationMode STRING  ('Use WINDOW setting')

%INISaveWindow LONG  (1)

[ADDITION]

NAME Clarion SaveButton

[FIELDPROMPT]

[INSTANCE]

INSTANCE 1

PROCPROP

[PROMPTS]

%InsertAllowed LONG  (1)

%InsertMessage @S30  ('Record will be Added')

%ChangeAllowed LONG  (1)

%ChangeMessage @S30  ('Record will be Changed')

%DeleteAllowed LONG  (1)

%DeleteMessage @S30  ('Record will be Deleted')

%MessageHeader LONG  (0)

[ADDITION]

NAME Clarion CancelButton

[FIELDPROMPT]

[INSTANCE]

INSTANCE 2

[PROMPTS]

[WINDOW]

Label WINDOW('Caption'),AT(34,20,289,159),CENTER,STATUS,SYSTEM,GRAY,MDI

       STRING(@s40),AT(123,138,,),USE(ActionMessage),CENTER,#SEQ(1),#ORIG(FileIOButtons),#LINK(?OK)

       BUTTON('OK'),AT(5,133,45,15),USE(?OK),#SEQ(1),#ORIG(?OK),#LINK(?Cancel)

       BUTTON('Cancel'),AT(59,133,45,15),USE(?Cancel),#SEQ(2),#ORIG(?Cancel)

     END

#ENDDEFAULT


Symbol Management Statements

#DECLARE (declare a user-defined symbol)

#ALIAS (access a symbol from another instance)

#ADD (add to multi-valued symbol)

#DELETE (delete a multi-valued symbol instance)

#DELETEALL (delete multiple multi-valued symbol instances)

#PURGE (delete all single or multi-valued symbol instances)

#CLEAR (clear single-valued symbol)

#FREE (free a multi-valued symbol)

#FIX (fix a multi-value symbol)

#FIND (super-fix multi-value symbols)

#SELECT (fix a multi-value symbol)

#SET (assign value to a user-defined symbol)

#UNFIX (unfix a multi-value symbol)


#DECLARE (declare a user-defined symbol)

#DECLARE( symbol [, parentsymbol [,type] ] ) [, MULTI ] [, UNIQUE ] [, SAVE ]

#DECLARE	Explicitly declares a user-defined symbol.

symbol	The name of the symbol being declared. This must meet all the requirements of a user-defined symbol. This must not be a #PROMPT symbol or a variable in the same scope.

parentsymbol	Specifies the parent of the symbol, indicating its value is dependent upon the current value in another symbol. This must be a multi-valued symbol. You may specify more than one parentsymbol if the symbol is dependent upon a set of symbols. This allows implicit multi-dimensional arrays.

type	The data type of the parentsymbol: LONG, REAL, or STRING. If omitted, the data type is STRING.

MULTI	Specifies the symbol may contain multiple values.

UNIQUE	Specifies a multi-valued symbol that cannot contain duplicate values. The values are stored in ascending order. This implicitly declares the symbol as multi-valued, the MULTI attribute is not required.

SAVE	Specifies the value(s) in the symbol are saved between source generation sessions. A symbol with the SAVE attribute may only be declared in the #APPLICATION area.

The #DECLARE statement explicitly declares a user-defined symbol. This may contain a single value or multiple values. All user-defined symbols must be explicitly declared with #DECLARE except those declared on a #PROMPT statement and #GROUP parameters.

The MULTI attribute declares the symbol as multi-valued. This allows the #FIX, #FOR, #ADD, #DELETE, #SELECT, and #FREE statements to operate on the symbol.

A user-defined multi-valued symbol may be treated as an array or a queue. As an array, a single instance of the user-defined multi-valued symbol may be addressed as %symbol[1] in expressions.

The UNIQUE attribute ensures all instances of a multi-valued symbol to be unique and sorted in ascending sequence. When UNIQUE is specified, MULTI is not required. The #ADD statement builds the symbol values in sorted order and only allows a single instance of every value in the symbol when each entry is added.

If the #DECLARE statement contains one or more parentsymbol parameters, the user-defined symbol is dependent on the parentsymbols. This means a separate instance (or instances, if multi-valued) of the symbol is available for each instance of the parentsymbol. If there are no parentsymbol parameters, it is independent.

#DECLARE may be used to create dependent symbols. The parentsymbol must be a multi-valued symbol. Therefore, another symbol may be declared as dependent upon a #DECLAREd dependent symbol only if it has the MULTI attribute.

The SAVE attribute causes a symbol's value(s) to be saved at the end of source generation and restored when the #DECLARE statement is executed at the beginning of the next source generation session. A symbol with the SAVE attribute may only be declared in the #APPLICATION section.

Example:

#APPLICATION('Sample One')

#DECLARE(%UserSymbol),SAVE    	#!Value saved after generation

     	 	#! and restored for next generation

#DECLARE(%ModuleFile,%Module),UNIQUE,MULTI	#!Level-1 dependent symbol

#DECLARE(%ModuleFilePut,%ModuleFile)  	#!Level-2 dependent symbol

#DECLARE(%ModuleFileDelete,%ModuleFile)  	#!Second Level-2 dependent symbol

See Also:

#FIX

#FOR

#ADD

#DELETE

#FREE


#ALIAS (access a symbol from another instance)

#ALIAS( oldsymbol , newsymbol [, instance ] )

#ALIAS	Re-declares a user-defined symbol.

oldsymbol	The name of the symbol being re-declared. This must meet all the requirements of a user-defined symbol. This must not be a #PROMPT symbol or a variable in the same scope.

newsymbol	Specifies the new name of the oldsymbol.

instance	An expression containing the instance of the addition containing the oldsymbol.

The #ALIAS statement re-declares a user-defined oldsymbol declared in a #CODE, #CONTROL, or #EXTENSION template prompt for use in another.

Example:

#EXTENSION(GlobalSecurity,'Global Password Check'),APPLICATION

  #DECLARE(%PasswordFile)

  #DECLARE(%PasswordFileKey)

#EXTENSION(LocalSecurity,'Local Procedure Password Check'),PROCEDURE

  #ALIAS(%PasswordFile,%PswdFile,'GlobalSecurity(Clarion)')

  #ALIAS(%PasswordFileKey,%PswdFileKey,'GlobalSecurity(Clarion)')

See Also:

#CODE

#CONTROL

#EXTENSION


#ADD (add to multi-valued symbol)

#ADD( symbol, expression [, position ] )

#ADD	Adds a new instance to a multi-valued user-defined symbol.

symbol	A multi-valued user-defined symbol.

expression	An expression containing the value to place in the symbol's instance.

position	An integer constant or symbol containing the instance number to add to the symbol. Instance numbering begins with one (1). If the position is greater than the number of previously existing instances plus one, the new instance in appended and no intervening instances are instantiated.

Adds a value to a multi-valued user-defined symbol. An implied #FIX to that symbol's instance occurs. If the symbol is not a multi-valued user-defined symbol then a source generation error is produced.

If the symbol has been declared with the UNIQUE attribute, then the #ADD is a union operation into the existing set of symbol's values. Only one instance of the value being added may exist. Also, the UNIQUE attribute implies the #ADD is a sorted insert into the existing set of symbol's values. After each #ADD, all of the symbol's values will be in sorted order.

If the symbol has been declared without the UNIQUE attribute, duplicate values are allowed. The new value is added to the end of the list and may be a duplicate. If the symbol is a duplicate, then any dependent children instances are inherited.

Example:

#DECLARE(%ProcFilesPrefix),MULTI,UNIQUE 	#!Declare unique multi-valued symbol

#FIX(%File,%Primary)   	#!Build list of all file prefixes in proc

#ADD(%ProcFilesPrefix,%FilePre)  	#!Start with primary file

#FOR(%Secondary)    	#!Then add all secondary files

  #FIX(%File,%Secondary)

  #ADD(%ProcFilesPrefix,%FilePre)

#ENDFOR

See Also:

#DECLARE


#DELETE (delete a multi-valued symbol instance)

#DELETE( symbol [, position ] )

#DELETE	Deletes the value from one instance of a multi-valued user-defined symbol.

symbol	A multi-valued user-defined symbol.

position	An integer constant or symbol containing the instance number in the symbol. Instance numbering begins with one (1). If omitted, the default is the current fixed instance.

The #DELETE statement deletes the value from one instance of a multi-valued user-defined symbol. If there are any symbols dependent upon the symbol, they are also cleared. If this is the last instance in the symbol, the instance is removed. You can get the current instance number to which a symbol is fixed by using the INSTANCE(%symbol) built-in template function.

Example:

#DECLARE(%ProcFilesPrefix),MULTI #!Declare multi-valued symbol

#ADD(%ProcFilesPrefix,'SAV') #!Add a value

#ADD(%ProcFilesPrefix,'BAK') #!Add a value

#ADD(%ProcFilesPrefix,'PRE') #!Add a value

#ADD(%ProcFilesPrefix,'QUE') #!Add a value

 #!%ProcFilesPrefix contains: SAV, BAK, PRE, QUE

#DELETE(%ProcFilesPrefix,1)  #!Delete first value (SAV)

 #!%ProcFilesPrefix contains: BAK, PRE, QUE

#FIX(%ProcFilesPrefix,'PRE') #!Fix to a value

#DELETE(%ProcFilesPrefix)  #!Delete it

 #!%ProcFilesPrefix contains: BAK, QUE

See Also:

#DECLARE

#ADD


#DELETEALL (delete multiple multi-valued symbol instances)

#DELETEALL( symbol, expression )

#DELETEALL	Deletes the values from specified instances of a multi-valued user-defined symbol.

symbol	A multi-valued user-defined symbol.

expression	An expression that defines the instances to delete.

The #DELETEALL statement deletes all values from the symbol that meet the expression.

Example:

#DECLARE(%ProcFilesPrefix),MULTI #!Declare multi-valued symbol

#ADD(%ProcFilesPrefix,'SAV') #!Add a value

#ADD(%ProcFilesPrefix,'BAK') #!Add a value

#ADD(%ProcFilesPrefix,'PRE') #!Add a value

#ADD(%ProcFilesPrefix,'BAK') #!Add a value

#ADD(%ProcFilesPrefix,'QUE') #!Add a value

 #!%ProcFilesPrefix contains: SAV, BAK, PRE, BAK, QUE

#DELETEALL(%ProcFilesPrefix,'BAK') #!Delete all BAK instances

 #!%ProcFilesPrefix now contains: SAV, PRE, QUE

See Also:

#DECLARE

#ADD


#PURGE (delete all single or multi-valued symbol instances)

#PURGE( symbol )

#PURGE	Deletes the values from all instances of a user-defined symbol.

symbol	A user-defined symbol.

The #PURGE statement deletes all values from the symbol. If there are any symbols dependent upon the symbol, they are also cleared. If the symbol is dependent upon a multi-valued symbol, all instances of that dependent symbol are purged for all instances of the symbol upon which it is dependent.

Example:

#DECLARE(%ProcFilesPrefix),MULTI #!Declare multi-valued symbol

#ADD(%ProcFilesPrefix,'SAV') #!Add a value

#ADD(%ProcFilesPrefix,'BAK') #!Add a value

#ADD(%ProcFilesPrefix,'PRE') #!Add a value

#ADD(%ProcFilesPrefix,'BAK') #!Add a value

#ADD(%ProcFilesPrefix,'QUE') #!Add a value

 #!%ProcFilesPrefix contains: SAV, BAK, PRE, BAK, QUE

#PURGE(%ProcFilesPrefix)  #!Delete all instances

See Also:

#DECLARE

#ADD


#CLEAR (clear single-valued symbol)

#CLEAR( symbol )

#CLEAR	Removes the value from a single-valued user-defined symbol.

symbol	A single-valued user-defined symbol.

The #CLEAR statement removes the value from a single-valued user-defined symbol. This statement is approximately the same as using #SET to assign a null value to the symbol, except it is more efficient.

Example:

#DECLARE(%SomeSymbol)  #!Declare symbol

#SET(%SomeSymbol,'Value')  #!Assign a value

 #!%SomeSymbol now contains: 'Value'

#CLEAR(%SomeSymbol)   #!Clear value

 #!%SomeSymbol now contains: ''

See Also:

#DECLARE

#ADD


#FREE (free a multi-valued symbol)

#FREE( symbol )

#FREE	Clears all instances of a multi-valued user-defined symbol.

symbol	A multi-valued user-defined symbol.

The #FREE statement clears all instances of a multi-valued user-defined symbol. If there are any symbols dependent upon the symbol, they are also cleared.

Example:

#DECLARE(%ProcFilesPrefix),MULTI #!Declare multi-valued symbol

#ADD(%ProcFilesPrefix,'SAV') #!Add a value

#ADD(%ProcFilesPrefix,'BAK') #!Add a value

#ADD(%ProcFilesPrefix,'PRE') #!Add a value

#ADD(%ProcFilesPrefix,'BAK') #!Add a value

#ADD(%ProcFilesPrefix,'QUE') #!Add a value

 #!%ProcFilesPrefix contains: SAV, BAK, PRE, BAK, QUE

#DELETEALL(%ProcFilesPrefix,'BAK') #!Delete all BAK instances

 #!%ProcFilesPrefix now contains: SAV, PRE, QUE

#FREE(%ProcFilesPrefix)  #!Free the symbol

 #!%ProcFilesPrefix now contains nothing

See Also:

#DECLARE

#ADD


#FIX (fix a multi-value symbol)

#FIX( symbol, fixsymbol )

#FIX	Fixes a multi-valued symbol to the value of a single instance.

symbol	A multi-valued symbol.

fixsymbol	A  symbol or expression containing the value to fix the symbol to.

The #FIX statement fixes the current value of the multi-valued symbol to the value contained in the fixsymbol. This is done so that one instance of the symbol may be referenced outside a #FOR loop structure, or so you can reference the symbols dependent upon the multi-valued symbol.

The fixsymbol must contain a valid instance of one of the symbol's multiple values. If the fixsymbol does not contain a valid instance, the symbol is cleared and contains no value when referenced. Unless #ADD has been used to add a new value and fix to that instance, #FIX or #SELECT must be used to set the value in a symbol before it contains any value for Template processing outside of a #FOR loop.

#FIX is completely independent of #FOR in that #FOR always loops through every instance of the symbol, whether there is a previous #FIX for that symbol or not. If there is a previous #FIX statement for that symbol before the #FOR loop, that symbol reverts to that previous fixvalue after the #FOR terminates.

If #FIX is used within a #FOR structure, the scope of the #FIX is limited to within the #FOR in which it is used. It does not change the #FOR symbol's iteration value if both the #FOR and #FIX happen to use the same symbol.

Example:

#SET(%OneFile,'HEADER')  #! Put values into two User-defined symbols

#SET(%TwoFile,'DETAIL')

#FIX(%File,%OneFile)  #! %File refers to 'HEADER'

#FOR(%File)    #! %File iteratively refers to all file names

  #FIX(%File,%TwoFile)  #! %File refers to 'DETAIL'

#ENDFOR

#! %File refers to 'HEADER' again

See Also:

#SELECT


#FIND (super-fix multi-value symbols)
#FIND ("super-fix" multi-value symbols)

#FIND( symbol, fixsymbol [, limit ] )

#FIND	Fixes all multi-valued parent symbols to values that point to a single child instance.

symbol	A multi-valued symbol.

fixsymbol	A symbol or expression containing the value to fix the symbol to.

limit	A parent symbol which limits the search scope to the children of the limit symbol.

The #FIND statement finds the first instance of the fixsymbol contained within the symbol then fixes it and all the "parent" symbols on which the symbol is dependent to the values that "point to" the value of the fixsymbol contained in the symbol. This is done so that all the symbol dependencies are aligned and you can reference other symbols dependent on "parent" symbols of the symbol.

For example, assume %ControlUse contains CUS:Name. The  #FIND(%Field,%ControlUse,%Control) statement:

     	Finds the first instance of %Field that matches the current value in %ControlUse (the first instance of CUS:Name in %Field) in the current procedure.

     	Fixes %Field to that value (CUS:Name).

     	Fixes %File to the name of the file containing that field (Customer).

     	This allows the Template code to reference other the symbols dependent upon %File (like %FilePre to get the file's prefix).

The fixsymbol must contain a valid instance of one of the symbol's multiple values. If the fixsymbol does not contain a valid instance, the symbol is cleared and contains no value when referenced.

Example:

#FIND(%Field,%ControlUse)  	#!Fixes %Field and %File to %ControlUse parents

See Also:

#SELECT

#FIX


#SELECT (fix a multi-value symbol)

#SELECT( symbol, instance )

#SELECT	Fixes a multi-valued symbol to a particular instance number.

symbol	A multi-valued symbol.

instance	An expression containing the number of the instance to which to fix.

The #SELECT statement fixes the current value of the multi-valued symbol to a specific instance. The result of #SELECT is exactly the same as #FIX. Each instance in the multi-valued symbol is numbered starting with one (1).

The instance must contain a valid instance number of one of the symbol's multiple values. If the instance is not valid, the symbol is cleared and contains no value when referenced. The INSTANCE built-in template function can return the instance number.

Unless #ADD has been used to add a new value and fix to that instance, #FIX or #SELECT must be used to set the value in a symbol before it contains any value for Template processing outside of a #FOR loop.

Example:

#SELECT(%File,1)  	#!Fix to first %File instance


#SET (assign value to a user-defined symbol)

#SET( symbol,value )

#SET	Assigns a value to a single-valued user-defined symbol.

symbol	A single-valued user-defined symbol. This must have been previously declared with the #DECLARE statement.

value	A built-in or user-defined symbol, string constant, or an expression.

The #SET statement assigns the value to the symbol. If the value parameter contains an expression, you may perform mathematics during source code generation. The expression may use any of the arithmetic, Boolean, and logical operators documented in the Language Reference. If the modulus division operator (%) is used in the expression, it must be followed by at least one blank space (to explicitly differentiate it from the Template symbols). Logical expressions always evaluate to 1 (True) or 0 (False). Clarion language function calls (those supported in EVALUATE()) and built-in template functions are allowed.

Example:

#SET(%NetworkApp,'Network')

#SET(%MySymbol,%Primary)

#FOR(%File)

  #SET(%FilesCounter,%FilesCounter + 1)

%FileStructure

#ENDFOR


#UNFIX (unfix a multi-value symbol)

#UNFIX( symbol )

#UNFIX	Unfixes a multi-valued symbol.

symbol	A multi-valued symbol.

The #UNFIX statement unfixes the current value of the multi-valued symbol. If the unfixed symbol is referenced outside a #FOR loop structure, it has no value and you cannot reference any other symbols dependent upon the multi-valued symbol.

Example:

#SET(%OneFile,'HEADER')  #! Put values into two User-defined symbols

#SET(%TwoFile,'DETAIL')

#FIX(%File,%OneFile)  #! %File refers to 'HEADER'

#FOR(%File)    #! %File iteratively refers to all file names

  #FIX(%File,%TwoFile)  #! %File refers to 'DETAIL'

#ENDFOR

 #! %File refers to 'HEADER' again

#UNFIX(%File)   #! %File refers to no spcific value


#DECLARE Attributes

UNIQUE (no duplicates allowed)

SAVE (save symbol between generations)


UNIQUE (no duplicates allowed)

UNIQUE

The UNIQUE attribute of a #DECLARE statement specifies the multi-valued symbol being declared cannot contain duplicate values. To accomplish this, the #ADD statement always adds instances to the symbol in ascending order.

Example:

#DECLARE(%ProcFilesPrefix),MULTI,UNIQUE #!Declare unique multi-valued symbol

#FIX(%File,%Primary)   #!Build list of all file prefixes in proc

#ADD(%ProcFilesPrefix,%FilePre)  #!Start with primary file

#FOR(%Secondary)    #!Then add all secondary files

  #FIX(%File,%Secondary)

  #ADD(%ProcFilesPrefix,%FilePre)

#ENDFOR

See Also:

#DECLARE


SAVE (save symbol between generations)

SAVE

The SAVE attribute on a #DECLARE statement causes the value(s) of the declared symbol to be saved at the end of source generation and restored at the beginning of the next source generation session. A #DECLARE statement with the SAVE attribute may only appear in the #APPLICATION section.

Example:

#APPLICATION('Sample One')

#DECLARE(%UserSymbol),SAVE    #!Value saved after generation

      #! and restored for next generation

#DECLARE(%ModuleFile,%Module),UNIQUE,MULTI  #!Level-1 dependent symbol

#DECLARE(%ModuleFilePut,%ModuleFile)  #!Level-2 dependent symbol

#DECLARE(%ModuleFileDelete,%ModuleFile)  #!Second Level-2 dependent symbol

See Also:

#DECLARE


Chapter 4 - Programmer Input

Input and Validation Statements

#PROMPT (prompt for programmer input)

#VALIDATE (validate prompt input)

#ENABLE (enable/disable prompts)

#BUTTON (call another page of prompts)

#FIELD (control prompts)

#PREPARE (setup prompt symbols)

#PROMPT Entry Types

CHECK (check box)

COMPONENT (list of KEY fields)

CONTROL (list of window fields)

DROP (droplist of items)

EMBED (enter embedded source)

EMBEDBUTTON (enter embedded source)

FIELD (list of data fields)

FILE (list of files)

FORMAT (call listbox formatter)

FROM (list of symbol values)

KEY (list of keys)

KEYCODE (list of keycodes)

OPTION (display radio buttons)

PICTURE (call picture formatter)

PROCEDURE (add to logical procedure tree)

RADIO (one radio button)

SPIN (spin box)

Display and Formatting Statements

#BOXED (prompt group box)

#DISPLAY (display-only prompt)

#IMAGE (display graphic)

#SHEET (declare a group of #TAB controls)

#TAB (declare a page of a #SHEET control)


Input and Validation Statements

#PROMPT (prompt for programmer input)

#VALIDATE (validate prompt input)

#ENABLE (enable/disable prompts)

#BUTTON (call another page of prompts)

#FIELD (control prompts)

#PREPARE (setup prompt symbols)


#PROMPT (prompt for programmer input)

#PROMPT( string, type ) [, symbol ] [, REQ ] [, DEFAULT( value ) ] [, ICON( file ) ] [, AT( ) ]

[, PROMPTAT( ) ] [, MULTI( description ) ] [, INLINE ] [, SELECTION( description ) ]

#PROMPT	Asks the programmer for input.

string	A string constant containing the text to display as the input prompt. This may contain an ampersand (&) denoting a "hot" key used in conjunction with the ALT key to get to this field on the properties screen.

type	A picture token or prompt keyword.

symbol	A User-defined symbol to receive the input. A #PROMPT with a RADIO or EMBED type cannot have a symbol, all other types must have a symbol.

REQ	Specifies the prompt cannot be left blank or zero.

DEFAULT	Specifies an initial value (which may be overidden).

value	A string constant containing the initial value.

ICON	Specifies an icon for the button face of a #PROMPT with the MULTI attribute.

file	A string constant containing the name of the .ICO file to display on the button face.

AT	Specifies the position of the prompt entry area in the window, relative to the first prompt placed on the window from the Template (excluding the standard prompts on every procedure properties window). This attribute takes the same parameters as the Clarion language AT attribute.

PROMPTAT	Specifies the position of the prompt string in the window, relative to the first prompt placed on the window from the Template (excluding the standard prompts on every procedure properties window). This attribute takes the same parameters as the Clarion language AT attribute.

MULTI	Specifies the programmer may enter multiple values for the #PROMPT. The prompt appears as a button which pops up a list box allowing the programmer to enter multiple values, unless the INLINE attribute is also present.

description	A string constant containing the name to display on the button face and at the top of the list of prompt values.

INLINE	The multiple values the programmer enters for the #PROMPT appears as a list box with update buttons which allow the programmer to enter multiple values. The MULTI attribute must also be present.

SELECTION	Specifies the programmer may select multiple values for the #PROMPT from the list of choices presented by the FROM type. The prompt appears as a button which pops up a list box allowing the programmer to choose multiple values, unless the INLINE attribute is also present.

The #PROMPT statement asks the programmer for input. A #PROMPT statement may be placed in #APPLICATION, #PROCEDURE, #CODE, #CONTROL, #EXTENSION, #UTILITY, or #FIELD sections. It may not be placed in a #PROGRAM, #MODULE, #TEMPLATE, or #GROUP section.

When the #PROMPT is placed in a template section, the prompt string and its associated entry field are placed:

Section Name	Window Name
 #APPLICATION	Global Settings
 #PROCEDURE	Procedure Properties
 #CODE	 	Embeds Dialog
 #CONTROL	 	Control Properties Actions Tab
 #EXTENSION	Extensions Dialog
 #FIELD	Control Properties Actions Tab

The type parameter may contain a picture token to format the programmer's input, or one of the following keywords:

  PROCEDURE	The label of a procedure
  FILE	The label of a data file
  KEY	The label of a key (can be limited to one file)
  COMPONENT	The label of a key component field (can be limited to one key)
  FIELD	The label of a file field (can be limited to one file)
  FORMAT	Calls the listbox formatter.
  PICTURE	Calls the picture token formatter.
  DROP	Creates a droplist of items specified in its parameter
  KEYCODE	A keycode or keycode EQUATE
  OPTION	Creates a radio button structure
  RADIO	Creates a radio button
  CHECK	Creates a check box
  CONTROL	A window control
  FROM	Creates a droplist of items contained in its symbol parameter
  EMBED	Allows the user to edit a specified embedded source code point
  EMBEDBUTTON	Allows the user to edit a specified embedded source code point
  SPIN	Creates a spin control

For all types except RADIO and CHECK (and MULTI attribute prompts), the #PROMPT string is displayed on the screen immediately to the left of its data input area.

A #PROMPT with the REQ attribute cannot be left blank or zero; it is a required input field. The DEFAULT attribute may be used to provide the programmer with an initial value in the #PROMPT, which may be overidden at design time.

A #PROMPT with a RADIO type creates one Radio button for the immediately preceding #PROMPT with an OPTION type. There may be multiple RADIOs for one OPTION. Each RADIO's string, when selected, is placed in the closest preceding OPTION's symbol. The OPTION structure is terminated by the first #PROMPT following it that is not a RADIO.

The MULTI attribute specifies the programmer may enter multiple values for the #PROMPT. A button appears on the Properties window with the description on its face. Alternatively, this can have an ICON attribute to name an .ICO file to display on the button face. This button calls a window containing a list box to display all the multiple values entered for the #PROMPT, along with Insert, Change, and Delete buttons. These three buttons call another window containing the #PROMPT string and its data entry field to allow the programmer to update the entries in the list.

When the programmer has entered a value for the #PROMPT, the input value is assigned to the symbol. The value entered by the programmer may be checked for validity by one or more #VALIDATE statements immediately following the #PROMPT statement.

The value(s) placed in the symbol may be used or evaluated elsewhere within the Template. A symbol defined by a #PROMPT in the #APPLICATION section of the Template is Global, it can be used or evaluated anywhere in the Template. A symbol defined by #PROMPT in a #PROCEDURE section is Local, and is a dependent symbol to %Procedure; it can be used or evaluated only within that #PROCEDURE section. A symbol defined by #PROMPT in a #CODE, #CONTROL, or #EXTENSION section of the Template can be used or evaluated only within that section.

Example:

#PROMPT('Ask for Input',@s20),%InputSymbol  	#!Simple input

#PROMPT('Ask for FileName',FILE),%InputFile,REQ 	#!Required filename

#PROMPT('Pick One',OPTION),%InputChoice  	#!Mutually exclusive options

#PROMPT('Choice One',RADIO)

#PROMPT('Choice Two',RADIO)

#PROMPT('Next Procedure',PROCEDURE),%NextProc 	#!Prompt for procedure name

#PROMPT('Ask for Multiple Input',@s20),%MultiSymbol,MULTI('Input Values...')

      	#!Prompt for multiple input

See Also:

#DISPLAY

#VALIDATE

#GROUP

#BOXED

#ENABLE

#BUTTON


#VALIDATE (validate prompt input)

#VALIDATE( expression,message )

#VALIDATE	Validates the data entered into the immediately preceding #PROMPT field.

expression	The expression to use to validate the entered data.

message	A string constant containing the error message to display if the data is invalid.

The #VALIDATE statement validates the data entered into the #PROMPT field immediately preceding the #VALIDATE. The expression is evaluated when the OK button is pressed on the Procedure Properties window. If the expression is false, the message is displayed to the programmer in a message box, and control is given to the #PROMPT field that immediately precedes the #VALIDATE. There may be multiple #VALIDATE statements following a #PROMPT to validate the entry.

Example:

#PROMPT('Input Value, Even numbers from 100-200',@N3),%Value

#VALIDATE((%Value > 100) AND (%Value < 200),'Value must be between 100 and 200')

#VALIDATE((%Value % 2 = 0),'Value must be an even number')

#PROMPT('Screen Field',WINDOWCONTROL),%SomeField

#VALIDATE(%ScreenFieldType = 'LIST','Must select a list box')

See Also:

#PROMPT


#ENABLE (enable/disable prompts)

#ENABLE( expression ) [, CLEAR ]

    prompts

#ENDENABLE

#ENABLE	Begins a group of prompts which may be enabled or disabled based upon the evaluation of the expression.

expression	The expression which controls the prompt enable/disable.

CLEAR	Specifies the prompts symbol values are cleared when disabled.

prompts	One or more #PROMPT, #BUTTON, #DISPLAY, #ENABLE, and/or #VALIDATE statements.

#ENDENABLE	Terminates the group of prompts.

The #ENABLE structure contains prompts which may be enabled or disabled based upon the evaluation of the expression. If the expression is true, the prompts are enabled, otherwise they are disabled. The prompts appear dimmed when disabled and the programmer may not enter data in them.

Example:

#PROMPT('Pick One',OPTION),%InputChoice  	#!Mutually exclusive options

#PROMPT('Choice One',RADIO)

#PROMPT('Choice Two',R	ADIO)

#ENABLE(%InputChoice = 'Choice Two')

  #PROMPT('Screen Field',WINDOWCONTROL),%SomeField 	#!Enabled only for Choice Two

  #VALIDATE(%ScreenFieldType = 'LIST','Must select a list box')

#ENDENABLE

See Also:

#PROMPT

#GROUP

#BOXED

#BUTTON


#BUTTON (call another page of prompts)

#BUTTON( string [, icon ] ) [, HLP( id ) ] [, AT() ] [, REQ ] [, INLINE ]

[,	| FROM( multisymbol, expression ) [, WHERE( condition ) ]	| ]

| MULTI( fromsymbol, expression )	|

    prompts

#ENDBUTTON

#BUTTON	Creates a command button to call another page of prompts.

string	A string constant containing the text to display on the button's face. This may contain an ampersand (&) to indicate the "hot" letter for the button.

icon	A string constant containing the name of an .ICO file or standard icon to display on the button's face. The string then serves only for "hot" key definition.

HLP	Specifies on-line help is available for the #BUTTON.

id	A string constant containing the identifier to access the Help system. This may be either a Help keyword or "context string."

AT	Specifies the position of the button in the window, relative to the first prompt placed on the window from the Template (excluding the standard prompts on every procedure properties window). This attribute takes the same parameters as the Clarion language AT attribute.

REQ	Specifies the programmer must press the button at least once when the procedure is created.

FROM	Specifies the programmer may enter a set of values for the prompts for each instance of the fromsymbol.

fromsymbol	A built-in multi-valued symbol which pre-defines all instances on which the prompts symbols are dependent. The programmer may not add, change, or delete instances of the fromsymbol.

expression	A string expression to format data display in the multiple value display list box.

WHERE	Specifies the #BUTTON displays only those instances of the fromsymbol where the condition is true.

condition	An expression that specifies the condition for use.

MULTI	Specifies the programmer may enter multiple sets of values for the prompts. This allows multiple related groups of prompts.

multisymbol	A user-defined symbol on which all the prompts symbols are dependent. This symbol is internally assigned a unique value for each set of prompts.

INLINE	The multiple values the programmer enters for the #BUTTON appears as a list box with update buttons which allow the programmer to enter multiple values. The MULTI or FROM attribute must also be present.

prompts	One or more #PROMPT statements. This may also contain #DISPLAY, #VALIDATE, #ENABLE, and #BUTTON statements.

#ENDBUTTON	Terminates the group of prompts which are on the page called by the #BUTTON.

The #BUTTON statement creates a command button displaying either the string or the icon on its face. When the programmer presses the button, a new page of prompts appears for selection and entry.

Each new page of prompts has its own OK, CANCEL, and TEMPLATE HELP buttons as standard fields. All other fields on the page are generated from the prompts within the #BUTTON structure.

Each page's OK button closes the current page of prompts, saving the data the programmer entered in the prompts, then returns to the prior window. The CANCEL button closes the current page of prompts without saving, then returns to the prior window. If the page calls another page with a nested #BUTTON statement and the programmer presses OK on the lowest level page, then CANCEL on the page that called it, the entire transaction is cancelled.

The MULTI attribute specifies the programmer may enter multiple sets of values for the prompts. The button calls a window containing a list box to display all the multiple values entered for the sets of prompts, along with Insert, Change, and Delete buttons. These three buttons call another window containing all the prompts to allow the programmer to update the entries in the list. The expression is used to format the information for display in the list box.

The FROM attribute also specifies the programmer may enter multiple sets of values for the prompts. The button calls a window containing a list box that displays each instance of the fromsymbol, along with an Edit button. This button calls another window containing all the prompts to allow the programmer to update the entries associated with that instance of the fromsymbol. The expression is used to format the information for display in the list box. The WHERE attribute may be used to limit the instances of the fromsymbol to only those that meet the WHERE condition.

Example:

#PROMPT('Name a File',FILE),%FileName  	#!Prompt on the first page

#BUTTON('Page Two')     	#!Button on first page calls

  #PROMPT('Pick One',OPTION),%InputChoice  	#!These prompts on second page

  #PROMPT('Choice One',RADIO)

  #PROMPT('Choice Two',RADIO)

  #ENABLE(%InputChoice = 'Choice Two')

    #PROMPT('Screen Field',WINDOWCONTROL),%SomeField

    #VALIDATE(%ScreenFieldType = 'LIST','Must select a list box')

  #ENDENABLE

#ENDBUTTON      	#!Terminate second page prompts

#PROMPT('Enter some value',@S20),%InputValue1 	#!Another prompt on first page

 	#!Multiple input button:

#BUTTON('Multiple Names'),MULTI(%ButtonSymbol,%ForeName & ' ' & %SurName)

  #PROMPT('First Name',@S20),%ForeName

  #PROMPT('Last Name',@S20),%SurName

#ENDBUTTON      	#!Terminate second page prompts

#PROMPT('Enter another value',@S20),%InputValue2 	#!Another prompt on first page

 #!Multiple input button dependent on %File:

#BUTTON('File Options'),FROM(%File)

  #PROMPT('Open Access Mode',DROP('Open|Share'),%FileOpenMode

#ENDBUTTON      	#!Terminate second page prompts

See Also:

#PROMPT

#VALIDATE

#ENABLE


#FIELD (control prompts)

#FIELD, WHERE( expression )

   prompts

#ENDFIELD

#FIELD	Begins a control prompts section.

WHERE	Specifies the #FIELD is used only for those instances where the expression is true.

expression	An expression that specifies the condition for use.

prompts	Prompt (#PROMPT, #BUTTON, etc.) statements.

#ENDFIELD	Terminates the section.

The #FIELD structure contains prompts for controls that are populated onto a window. These prompts appear in the Actions... dialog.

The list of field prompts appearing in the Actions... dialog is built in the following manner:

 1. #CONTROL prompts.
 2. #PROCEDURE-level #FIELD prompts (also from inserted #GROUPs).
 3. #PROCEDURE-level #FIELD prompts from active #EXTENSION
sections.
 4. #CONTROL-level #FIELD prompts.
 5. #CODE-level #FIELD prompts.

The values the user inputs into the #FIELD prompts are used to generate the source to govern the behavior of the control.

Example:

#FIELD, WHERE(%ControlType = 'BUTTON')

  #PROMPT('Enter procedure call',PROCEDURE),%ButtonProc

#ENDFIELD


#PREPARE (setup prompt symbols)

#PREPARE

   statements

#ENDPREPARE

#PREPARE	Begins a prompts symbol setup section.

statements	Template language statements to fix multi-valued symbols to the values needed to process the #PROMPT or #BUTTON statement following the #PREPARE.

#ENDPREPARE	Terminates the section.

The #PREPARE structure contains Template language statements to fix multi-valued symbols to the values needed to process the #PROMPT or #BUTTON statements preceding the #PREPARE.

Example:

#BUTTON('Customize Colors'),FROM(%ControlField,%ControlField),WHERE(%CntrlHasColor)

#PREPARE

#FIND(%ControlInstance,%ActiveTemplateInstance,%Control)

#ENDPREPARE

#BOXED('Default Colors')

#PROMPT('&Fore Normal:',COLOR),%ControlFieldForeNormal,DEFAULT(-1)

#PROMPT('&Back Normal:',COLOR),%ControlFieldBackNormal,DEFAULT(-1)

#PROMPT('&Fore Selected:',COLOR),%ControlFieldForeSelected,DEFAULT(-1)

#PROMPT('&Back Selected:',COLOR),%ControlFieldBackSelected,DEFAULT(-1)

#ENDBOXED

#BOXED('Conditional Color Assignments')

#BUTTON('Conditional Colors'),MULTI(%ConditionalColors,%ColorCondition),INLINE

#PROMPT('&Condition:',@S255),%ColorCondition

#PROMPT('&Fore Normal:',COLOR),%CondControlFieldForeNormal,DEFAULT(-1)

#PROMPT('&Back Normal:',COLOR),%CondControlFieldBackNormal,DEFAULT(-1)

#PROMPT('&Fore Selected:',COLOR),%CondControlFieldForeSelected,DEFAULT(-1)

#PROMPT('&Back Selected:',COLOR),%CondControlFieldBackSelected,DEFAULT(-1)

#ENDBUTTON

#ENDBOXED

#ENDBUTTON


#PROMPT Entry Types

CHECK (check box)

COMPONENT (list of KEY fields)

CONTROL (list of window fields)

DROP (droplist of items)

EMBED (enter embedded source)

EMBEDBUTTON (enter embedded source)

FIELD (list of data fields)

FILE (list of files)

FORMAT (call listbox formatter)

FROM (list of symbol values)

KEY (list of keys)

KEYCODE (list of keycodes)

OPTION (display radio buttons)

PICTURE (call picture formatter)

PROCEDURE (add to logical procedure tree)

RADIO (one radio button)

SPIN (spin box)

Display and Formatting Statements

#BOXED (prompt group box)

#DISPLAY (display-only prompt)

#IMAGE (display graphic)

#SHEET (declare a group of #TAB controls)

#TAB (declare a page of a #SHEET control)


CHECK (check box)

CHECK

The CHECK type in a #PROMPT statement indicates the prompt's symbol is a toggle switch which is used only for on/off, yes/no, or true/false evaluation.  CHECK puts a check box on screen in the entry area for the #PROMPT. When the Check box is toggled on, the prompt's symbol contains one (1). When the Check box is toggled off, the prompt's symbol contains zero (0).

Example:

#PROMPT('Network Application',CHECK),%NetworkApp


COMPONENT (list of KEY fields)

COMPONENT [ ( scope ) ]

COMPONENT	Displays a list of KEY component fields.

scope	A symbol containing a KEY. If omitted, the list displays all KEY components for all KEYs in all FILEs.

The COMPONENT type in a #PROMPT statement indicates the prompt's symbol must contain the label of one of the component fields of a KEY. A list of available KEY fields pops up when the #PROMPT is encountered on the Properties screen.

The COMPONENT may have a scope parameter that limits the KEY components available in the list. If scope is the label of a KEY, the list displays all KEY components for that KEY.

Example:

#PROMPT('Record Selector',COMPONENT(%Primary)),%RecordSelector


CONTROL (list of window fields)

CONTROL

The CONTROL type in a #PROMPT statement indicates the prompt's symbol must contain the field equate label of a window control. A list of available controls pops up when the #PROMPT is encountered on the Properties screen.

Example:

#PROMPT('Locator Field',CONTROL),%Locator


DROP (droplist of items)

DROP [ ( scope ) ]

DROP	Creates a droplist of items.

scope	A string constant containing the items for the list, delimited by the vertical bar (|) character.

The DROP type in a #PROMPT statement indicates the prompt's symbol must contain one item from the list specified in the scope parameter. The scope must contain all the items for the list. The list of items drops down just like a Clarion language LIST control with the DROP attribute. If no default value is specified, the prompt's symbol defaults to the first value in the scope list.

Example:

#PROMPT('If file not found',DROP('Create the file|Halt Program')),%FileNotFound


EMBED (enter embedded source)

EMBED( identifier [, instance ] )

EMBED	Specifies the prompt directly edits an embedded source code point.

identifier	The user-defined template symbol which identifies the #EMBED embedded source code point to edit.

instance	A string constant or expression containing one of the values in the multi-valued symbol used by the #EMBED. You must have as many instances as are necessary to explicitly identify the single #EMBED point instance to edit.

The EMBED type in a #PROMPT statement indicates the prompt is used to directly edit an embedded source code point. This places an an entry area with an ellipsis (...) button next to the prompt to allow the user access to the embedded source code point. The programmer may enter a procedure call in the entry area, or press the ellipsis (...) button to go into the normal source dialog.

If the #EMBED is associated with a multi-valued symbol, you must identify the specific instance of the #EMBED. If you use a multi-valued symbol as an instance expression, it must be fixed to a single value. Most commonly, this would be used in a #FIELD structure.

Example:

#PROMPT('Embedded Data Declarations',EMBED(%DataSection))

#FIELD, WHERE(%ControlType = 'BUTTON')

  #PROMPT('Action when button is pressed',EMBED(%ControlEvent,%Control,'Accepted'))

#ENDFIELD


EMBEDBUTTON (enter embedded source)

EMBEDBUTTON( identifier [, instance ] )

EMBEDBUTTON	Specifies the prompt directly edits an embedded source code point.

identifier	The user-defined template symbol which identifies the #EMBED embedded source code point to edit.

instance	A string constant or expression containing one of the values in the multi-valued symbol used by the #EMBED. You must have as many instances as are necessary to explicitly identify the single #EMBED point instance to edit.

The EMBEDBUTTON type in a #PROMPT statement indicates the prompt is used to directly edit an embedded source code point. This places a button next to the prompt allow the user access to the embedded source code point. The programmer may press the button to enter the embed dialog.

If the #EMBED is associated with a multi-valued symbol, you must identify the specific instance of the #EMBED. If you use a multi-valued symbol as an instance expression, it must be fixed to a single value. Most commonly, this would be used in a #FIELD structure.

Example:

#PROMPT('Embedded Data Declarations',EMBEDBUTTON(%DataSection))

#FIELD, WHERE(%ControlType = 'BUTTON')

#PROMPT('Action for button press',EMBEDBUTTON(%ControlEvent,%Control,'Accepted'))

#ENDFIELD


FIELD (list of data fields)

FIELD [ ( scope ) ]

FIELD	Displays a list of fields in FILEs.

scope	A symbol containing a FILE label. If omitted, the list displays all fields for all FILEs.

The FIELD type in a #PROMPT statement indicates the prompt's symbol must contain the label of a field in a data file. A list of available fields pops up when the #PROMPT is encountered on the Properties screen.

There may be a scope parameter that limits the fields available in the list. If scope names a FILE, the list displays all fields in the FILE. If there is no scope parameter, the list displays all fields in all FILEs.

Example:

#PROMPT('Locator Field',FIELD(%Primary)),%Locator


FILE (list of files)

FILE

The FILE type in a #PROMPT statement indicates the prompt's symbol must contain the label of a data file. A list of available files from the procedure's File Schematic pops up when the #PROMPT is encountered on the Properties screen.

Example:

#PROMPT('Logout File',FILE),%LogoutFile


FORMAT (call listbox formatter)

FORMAT

The FORMAT type in a #PROMPT statement indicates the prompt's symbol must contain a LIST or COMBO control's FORMAT attribute string, so it calls the listbox formatter to create it.

Example:

#PROMPT('Alternate LIST format',FORMAT),%AlternateFormatString


FROM (list of symbol values)

FROM( symbol [, expression ] [, value ] )

FROM	Specifies a drop-down list of values from the symbol.

symbol	A multi-valued symbol.

expression	An expression which controls which symbol values are displayed. Only symbol values where the expression is true are displayed in the drop list.

value	The symbol containing the values to display for the prompt and assigned mto the symbol.

The FROM type in a #PROMPT statement indicates the user must select one item from the list contained in the symbol. The expression can be used to limit the values displayed, while the value defines the display elements.

Example:

#PROMPT('Select an Event',FROM(%ControlEvent)),%WhichEvent

#PROMPT('Select a Button',FROM(%ControlField,%ControlType = 'BUTTON')),%WhichButton

#PROMPT('Pick a Field',FROM(%Control,%ControlUse <> '',%ControlUse)),%MyButton


KEY (list of keys)

KEY [ ( scope ) ]

KEY	Displays a list of KEYs.

scope	A symbol containing a FILE. If omitted, the list displays all KEYs in all FILEs.

The KEY type in a #PROMPT statement indicates the prompt's symbol must contain the label of a KEY. A list of available keys from the data dictionary pops up when the #PROMPT is encountered on the Properties screen.

There may be a scope parameter that limits the KEYs available in the list. If scope names a FILE, the list displays all KEYs in the FILE. If there is no scope parameter, the list displays all KEYs in all FILEs.

Example:

#PROMPT('Which Key',KEY(%Primary)),%UseKey


KEYCODE (list of keycodes)

KEYCODE

The KEYCODE type in a #PROMPT statement indicates the prompt's symbol must contain a keycode or keycode equate label. A selection list of keycode equate labels from KEYCODES.EQU pops up when the user presses the ellipsis button next to the prompt on the Properties screen.

Example:

#PROMPT('Hot Key',KEYCODE),%ActiveKey


OPTION (display radio buttons)

OPTION

The OPTION type in a #PROMPT statement indicates the prompt's symbol must contain the value of one of the strings in one of the following RADIO #PROMPT statements. Each of the strings displays a radio button on the Properties screen when the #PROMPT is encountered.

Example:

#PROMPT('Ask for Choice',OPTION),%OptionSymbol

#PROMPT('Option One',RADIO)

#PROMPT('Option Two',RADIO)

#PROMPT('Option Three',RADIO)


PICTURE (call picture formatter)

PICTURE

The PICTURE type in a #PROMPT statement calls the picture formatter to create a picture token used to format data for display.

Example:

#PROMPT('Display Format',PICTURE),%DisplayPicture


PROCEDURE (add to logical procedure tree)

PROCEDURE

The PROCEDURE type in a #PROMPT statement indicates the value placed in the symbol is the name of a procedure in your application. This procedure name is added to the Application Generator's logical procedure call tree in the appropriate place.

Example:

#PROMPT('Next Procedure',PROCEDURE),%NextProcedure


RADIO (one radio button)

RADIO

The RADIO type in a #PROMPT statement creates one RADIO button for the closest preceding OPTION prompt. When selected, the RADIO's string is placed in the OPTION's symbol.

Example:

#PROMPT('Ask for Choice',OPTION),%OptionSymbol

#PROMPT('Option One',RADIO)

#PROMPT('Option Two',RADIO)

#PROMPT('Option Three',RADIO)


SPIN (spin box)

SPIN( picture, low, high [, step ] )

SPIN	Creates a spin control.

picture	A data entry picture token.

low	A numeric constant or expression containing the lowest valid value.

high	A numeric constant or expression containing the highest valid value.

step	A numeric constant or expression containing the amount to change each increment between lowest and highest valid values. If omitted, the default is 1.

The SPIN type in a #PROMPT statement creates a spin control for the programmer to select a valid number.

Example:

#PROMPT('How Many?',SPIN(@n2,1,10)),%SpinSymbol


Display and Formatting Statements

Display and Formatting Statements

#BOXED (prompt group box)

#DISPLAY (display-only prompt)

#IMAGE (display graphic)

#SHEET (declare a group of #TAB controls)

#TAB (declare a page of a #SHEET control)


#BOXED (prompt group box)

#BOXED( [ string ] ) [, AT( ) ] [, WHERE( expression ) ] [, CLEAR ] [, HIDE ]

    prompts

#ENDBOXED

#BOXED	Creates a group box of prompts.

string	A string constant containing the text to display as the group box caption.

AT	Specifies the position of the group in the window, relative to the first prompt placed on the window from the Template (excluding the standard prompts on every procedure properties window). This attribute takes the same parameters as the Clarion language AT attribute.

WHERE	Specifies the #BOXED is visible only for those instances where the expression is true.

expression	An expression that specifies the condition for use.

CLEAR	Specifies the prompts symbol values are cleared when disabled.

prompts	One or more #PROMPT statements. This may also contain #DISPLAY, #VALIDATE, #ENABLE, and #BUTTON statements.

HIDE	Specifies the prompts are hidden if the WHERE expression is false when the dialog is first displayed.

#ENDBOXED	Terminates the group box of prompts.

The #BOXED statement creates a group box displaying the string as its caption. If the WHERE attribute is present, the prompts are hidden or visible based upon the evaluation of the expression. If the expression is true, the prompts are visible, otherwise they are hidden.

Example:

#PROMPT('Pick One',OPTION),%InputChoice  	#!These prompts on second page

#PROMPT('Choice One',RADIO)

#PROMPT('Choice Two',RADIO)

#BOXED('Choice Two Options'),WHERE(%InputChoice = 'Choice Two')

    #PROMPT('Screen Field',WINDOWCONTROL),%SomeField

    #VALIDATE(%ScreenFieldType = 'LIST','Must select a list box')

#ENDBOXED

See Also:

#PROMPT

#VALIDATE


#DISPLAY (display-only prompt)

#DISPLAY( [ string ] ) [, AT( ) ]

#DISPLAY	Displays a string constant on a properties window.

string	A string expression containing the text to display.

AT	Specifies the size and position of the string display area in the window, allowing multiple lines of text. This attribute takes the same parameters as the Clarion language AT attribute.

The #DISPLAY statement displays the string on a properties window. If the string is omitted, a blank line is displayed. #DISPLAY is not valid in a #MODULE section.

Example:

#DISPLAY()     	#!Display a blank line

#DISPLAY('Ask programmer to input some') 	#!Display a string

#PROMPT(' specific value',@s20),%InputSymbol

See Also:

#PROMPT

#GROUP

#BOXED

#ENABLE

#BUTTON


#IMAGE (display graphic)

#IMAGE( string ) [, AT( ) ]

#IMAGE	Displays a graphic image on a properties window.

picture	A string expression containing the name of the image file to display.

AT	Specifies the size and position of the picture display area in the window. This attribute takes the same parameters as the Clarion language AT attribute.

The #IMAGE statement displays the picture graphic image on a properties window. #IMAGE is not valid in a #MODULE section.

Example:

#IMAGE('SomePic.BMP') 	#!Display a bitmap


#SHEET (declare a group of #TAB controls)

#SHEET

  tabs

#ENDSHEET

#SHEET	Declares a group of #TAB controls.

tabs	Multiple #TAB control declarations.

#ENDSHEET	Terminates the group box of prompts.

#SHEET declares a group of #TAB controls that offer the user multiple "pages" of prompts for the window. The multiple #TAB controls in the SHEET structure define the "pages" displayed to the user.

Example:

#UTILITY(ApplicationWizard,'Create a New Database Application'),WIZARD

#!

#SHEET

  #TAB('Application Wizard')

    #IMAGE('CMPAPP.BMP')

    #DISPLAY('This wizard will create a new Application.'),AT(90,8,235,24)

    #DISPLAY('To begin creating your new Application, click Next.'),AT(90)

  #ENDTAB

  #TAB('Application Wizard - File Usage'),FINISH(1)

    #IMAGE('WINAPP.BMP')

    #DISPLAY('You can gen procs for all files, or select them'),AT(90,8,235,24)

    #PROMPT('Use all files in DCT',CHECK),%GenAllFiles,AT(90,,180),DEFAULT(1)

  #ENDTAB

  #TAB('Select Files to Use'),WHERE(NOT %GenAllFiles),FINISH(1)

    #IMAGE('WINAPP.BMP')

    #PROMPT('File Select',FROM(%File)),%FileSelect,INLINE,SELECTION('File Select')

  #ENDTAB

  #TAB('Application Wizard - Finally...'),FINISH(1)

    #IMAGE('WINAPP.BMP')

    #DISPLAY('Old procs can be overwritten or new procs suppressed')

    #PROMPT('Overwrite existing procs',CHECK),%OverwriteAll,AT(90,,235),DEFAULT(0)

    #IMAGE('<255,1,4,127>'),AT(90,55)

    #DISPLAY('Your First Procedure is always overwritten!'),AT(125,54,200,20)

  #ENDTAB

#ENDSHEET


#TAB (declare a page of a #SHEET control)

#TAB( text ) [,FINISH( )] [,WHERE( )]

  prompts

#ENDTAB

#TAB	Declares a group of prompts that constitute one of the multiple "pages" within a #SHEET structure.

text	A string constant containing the text to display on the tab, or as the title of the window, if the WIZARD attribute is present on the #UTILITY.

FINISH	Specifies the "Finish" button is present. Valid only in a #UTILITY with the WIZARD attribute.

WHERE	Specifies the #BOXED is visible only for those instances where the expression is true.

expression	An expression that specifies the condition for use.

prompts	One or more #PROMPT statements. This may also contain #DISPLAY, #VALIDATE, #ENABLE, and #BUTTON statements.

#ENDTAB	Terminates the page of prompts.

The #TAB structure declares a group of prompts that constitute one of the multiple "pages" of controls contained within a #SHEET structure. The multiple #TAB controls in the #SHEET structure define the "pages" displayed to the user.

Example:

#UTILITY(ApplicationWizard,'Create a New Database Application'),WIZARD

#!

#SHEET

  #TAB('Application Wizard')

    #IMAGE('CMPAPP.BMP')

    #DISPLAY('This wizard will create a new Application.'),AT(90,8,235,24)

    #DISPLAY('To begin creating your new Application, click Next.'),AT(90)

  #ENDTAB

  #TAB('Application Wizard - File Usage'),FINISH(1)

    #IMAGE('WINAPP.BMP')

    #DISPLAY('You can gen procs for all files, or select them'),AT(90,8,235,24)

    #PROMPT('Use all files in DCT',CHECK),%GenAllFiles,AT(90,,180),DEFAULT(1)

  #ENDTAB

  #TAB('Select Files to Use'),WHERE(NOT %GenAllFiles),FINISH(1)

    #IMAGE('WINAPP.BMP')

    #PROMPT('File Select',FROM(%File)),%FileSelect,INLINE,SELECTION('File Select')

  #ENDTAB

  #TAB('Application Wizard - Finally...'),FINISH(1)

    #IMAGE('WINAPP.BMP')

    #DISPLAY('Old procs can be overwritten or new procs suppressed')

    #PROMPT('Overwrite existing procs',CHECK),%OverwriteAll,AT(90,,235),DEFAULT(0)

    #IMAGE('<255,1,4,127>'),AT(90,55)

    #DISPLAY('Your First Procedure is always overwritten!'),AT(125,54,200,20)

  #ENDTAB

#ENDSHEET


Logic and Source Generation Control

Template Logic Control Statements

#FOR (generate code multiple times)

#IF (conditionally generate code)

#LOOP (iteratively generate code)

#CASE (conditional execution structure)

#INSERT (insert code from a #GROUP)

#BREAK (break out of a loop)

#CYCLE (cycle to top of loop)

#RETURN (return from #GROUP)

#GENERATE (generate source code section)

#ABORT (abort source generation)

File Management Statements

#CREATE (create source file)

#OPEN (open source file)

#CLOSE (close source file)

#READ(read one line of a source file)

#REDIRECT (change source file)

#APPEND (add to source file)

#REMOVE (delete a source file)

#REPLACE (conditionally replace source file)

#PRINT (print a source file)

Conditional Source Generation Statements

#SUSPEND (begin conditional source)

#RELEASE (commit conditional source generation)

#RESUME (delimit conditional source)

#? (conditional source line)


Template Logic Control Statements

#FOR (generate code multiple times)

#IF (conditionally generate code)

#LOOP (iteratively generate code)

#CASE (conditional execution structure)

#INSERT (insert code from a #GROUP)

#BREAK (break out of a loop)

#CYCLE (cycle to top of loop)

#RETURN (return from #GROUP)

#GENERATE (generate source code section)

#ABORT (abort source generation)


#FOR (generate code multiple times)

#FOR( symbol ) [, WHERE( expression ) ] [, REVERSE ]

statements

#ENDFOR

#FOR	Loops through all instances of a multi-valued symbol.

symbol	A multi-valued symbol.

WHERE	Specifies the statements in the #FOR loop are executed only for those instances of the symbol where the expression is true.

expression	An expression that specifies the condition for execution.

REVERSE	Specifies the #FOR loops through the instances of the symbol in reverse order.

statements	Target and/or Template Language statements.

#ENDFOR	Terminates the #FOR structure.

#FOR is a loop structure which generates its statements once for each value contained in its symbol during source code generation. If there are no values in the symbol, no code is generated. #FOR must be terminated by #ENDFOR. If there is no #ENDFOR, an error message is issued during Template file pre-processing. A #FOR loop may be nested within another #FOR loop.

The #FOR loop begins with the first instance of the symbol (or last, if the REVERSE attribute is present) and processes through all instances of the symbol--it is not affected by any #FIX statements. If the WHERE attribute is present, the #FOR statements are executed only for those instances of the symbol where the expression is true. This creates a conditional #FOR loop.

Since #FOR is a loop structure, the #BREAK and #CYCLE statements may be used to control the loop. #BREAK immediately terminates #FOR loop processing and continues with the statement following the #ENDFOR that terminates the #FOR. #CYCLE immediately returns control to the #FOR statement to continue with the next instance of the symbol.

Example:

#FOR(%ScreenField),WHERE(%ScreenFieldType = 'LIST')

  #INSERT(%ListQueueBuild) #!Generate only for LIST controls

#ENDFOR

See Also:

#BREAK

#CYCLE


#IF (conditionally generate code)

#IF( expression )

statements

[ #ELSIF( expression )

statements ]

[ #ELSE

statements ]

#ENDIF

#IF	A conditional execution structure.

expression	Any Template Language expression which can evaluate to false (blank or zero) or true (any other value). The expression may contain Template symbols, constant values, and any of the arithmetic, Boolean, and logical operators documented in the Language Reference. Function calls are allowed. If the modulus division operator (%) is used in the expression, it must be delimited by at least one blank space on each side (to explicitly differentiate it from the Template symbols).

statements	One or more Clarion and/or Template Language statements.

#ELSIF	Provides an alternate expression to evaluate when preceding #IF and #ELSIF expressions are false.

#ELSE	Provides alternate statements to execute when all preceding #IF and #ELSIF expressions are false.

#ENDIF	Terminates the #IF structure.

#IF selectively generates a group of statements depending on the evaluation of the expression(s). The #IF structure consists of a #IF statement and all statements following it until the structure is terminated by #ENDIF. If there is no #ENDIF, an error message is issued during Template file pre-processing. #IF structures may be nested within other #IF structures.

#ELSIF and #ELSE are logical separators which separate the #IF structure into statements groups which are conditionally generated depending upon the evaluation of the expression(s). There may be multiple #ELSIF statements within one #IF structure, but only one #ELSE.

When #IF is encountered during code generation:

     	If the expression evaluates as true, only the statements following #IF are generated, up to the next following #ELSIF, #ELSE, or #ENDIF.

     	If the expression evaluates as false, #ELSIF (if present) is evaluated in the same manner. If the #ELSIF expression is true, only the statements following it are generated, up to the following #ELSIF, #ELSE, or #ENDIF.

     	If all preceding #IF and #ELSIF conditions evaluate false, only the statements following #ELSE (if present) are generated, up to the following #ENDIF. If there is no #ELSE, no code is generated.

Example:

#FOR(%Formula)

  #IF(%FormulaComputation) #!If computed field

    %Formula = %FormulaComputation

  #ELSIF(%FormulaFalse) #!If Conditional with false formula

    IF %FormulaCondition

      %Formula = %FormulaTrue

    ELSE

      %Formula = %FormulaFalse

    END

  #ELSE   #!Else Conditional without false formula

    IF %FormulaCondition

      %Formula = %FormulaTrue

    END

  #ENDIF

#ENDFOR


#LOOP (iteratively generate code)

#LOOP [, 	| UNTIL( expression ) 	| ]

| WHILE( expression ) 	|

| FOR( counter, start, end ) [, BY( step ) ] 	|

    statements

#ENDLOOP

#LOOP	Initiates an iterative statement execution structure.

UNTIL	Evaluates its expression before each iteration of the #LOOP. If its expression evaluates to true, the #LOOP control sequence terminates.

expression	Any Template language expression which can evaluate to false (blank or zero) or true (any other value).

WHILE	Evaluates its expression before each iteration of the #LOOP. If its expression evaluates to false, the #LOOP control sequence terminates.

FOR	Initializes its counter to the start value, and increments it by the step value each time through the loop. When the counter is greater than the end value, the #LOOP control sequence terminates.

counter	A user-defined symbol used as the loop counter.

start	An expression containing the initial value to which to set the loop counter.

end	An expression containing the ending value of the loop counter.

BY	Explicitly defines the increment value for the counter.

step	An expression containing the increment value for the counter. If omitted, the step defaults to one (1).

statements	One or more target and/or Template Language statements.

#ENDLOOP	Terminates the #LOOP structure.

A #LOOP structure repetitively executes the statements within its structure. The #LOOP structure must be terminated by #ENDLOOP. If there is no #ENDLOOP, an error message is issued during Template file pre-processing. A #LOOP structure may be nested within another #LOOP structure.

The #LOOP,UNTIL or #LOOP,WHILE statements create exit conditions for the #LOOP. Their expressions are always evaluated at the top of the #LOOP, before the #LOOP is executed. A #LOOP WHILE structure continuously loops as long as the expression is true. A #LOOP UNTIL structure continuously loops as long as the expression is false. The expression may contain Template symbols, constant values, and any of the arithmetic, Boolean, and logical operators documented in the Language Reference. Function calls are allowed. If the modulus division operator (%) is used in the expression, it must be followed by at least one blank space (to explicitly differentiate it from the Template symbols).

The #LOOP,FOR statement also creates an exit condition for the #LOOP. The #LOOP initializes the counter to the start value on its first iteration. The #LOOP automatically increments the counter by the step value on each subsequent iteration, then evaluates the counter against the end value. When the counter is greater than the end, the #LOOP control sequence terminates.

#LOOP (without WHILE, UNTIL, or FOR) loops continuously, unless a #BREAK or #RETURN statement is executed. #BREAK terminates the #LOOP and continues execution with the statement following the #LOOP structure. All statements within a #LOOP structure are executed unless a #CYCLE statement is executed. #CYCLE immediately gives control back to the top of the #LOOP for the next iteration, without executing any statements following the #CYCLE in the #LOOP.

Example:

#SET(%LoopBreakFlag,'NO')

#LOOP     #!Continuous loop

  #INSERT(%SomeRepeatedCodeGroup)

  #IF(%LoopBreakFlag = 'YES')  #!Check break condition

    #BREAK

  #ENDIF

#ENDLOOP

#SET(%LoopBreakFlag,'NO')

#LOOP,UNTIL(%LoopBreakFlag = 'YES')  #!Loop until condition is true

  #INSERT(%SomeRepeatedCodeGroup)

#ENDLOOP

#SET(%LoopBreakFlag,'NO')

#LOOP,WHILE(%LoopBreakFlag = 'NO')  #!Loop while condition is true

  #INSERT(%SomeRepeatedCodeGroup)

#ENDLOOP

See Also:

#BREAK

#CYCLE


#CASE (conditional execution structure)

#CASE( condition )

#OF( expression )

[ #OROF( expression ) ]

  statements

[ #ELSE

  statements ]

#ENDCASE

#CASE	Initiates a selective execution structure.

condition	Any Template Language expression which returns a value.

#OF	The #OF statements are executed when the #OF expression is equal to the condition of the CASE. There may be many #OF options in a #CASE structure.

expression	Any Template Language expression which returns a value.

#OROF	The #OROF statements are executed when the #OROF expression is equal to the condition of the #CASE. There may be many #OROF options associated with one #OF option.

#ELSE	The #ELSE statements are executed when all preceding #OF and #OROF expressions are not equal to the condition of the #CASE. #ELSE (if used) must be the last option in the #CASE structure.

statements	Any valid executable source code.

#ENDCASE	Terminates the #CASE structure.

A #CASE structure selectively executes statements based on equivalence between the #CASE condition and one of the #OF or #OROF expressions. If there is no exact match, the statements following #ELSE are executed. The #CASE structure must be terminated by #ENDCASE. If there is no #ENDCASE, an error message is issued during Template file pre-processing. #CASE structures may be nested within other #CASE structures.

Example:

  #CASE %ScreenField

  #OF '?Ok'

    #INSERT(%OkButtonGroup)

  #OF '?Cancel'

  #OROF '?Exit'

    #INSERT(%CancelButtonGroup)

  #ELSE

    #INSERT(%OtherControlsGroup)

  #ENDCASE


#INSERT (insert code from a #GROUP)

#INSERT( symbol [ ( set ) ] [, parameters ] )

#INSERT	Inserts code from a #GROUP.

symbol	A symbol that names a #GROUP section.

set	The #TEMPLATE name parameter for the template set to which the #GROUP belongs. If omitted, the #GROUP must be of the same template set name as the #PROCEDURE in which it is used.

parameters	The parameters passed to the #GROUP. Each parameter must be separated by a comma. All parameters defined for the #GROUP must be passed; they may not be omitted.

The #INSERT statement places, at the exact position the #INSERT is located within the Template code, the code from the #GROUP named by the symbol. The set parameter specifies the #TEMPLATE that contains the #GROUP. This allows any Template to use #GROUP code from any other registered Template.

The parameters passed to the #GROUP fall into two categories: value-parameters and variable-parameters. Value-parameters are declared by the #GROUP as a user-defined symbol, while variable-parameters are declared by the #GROUP as a user-defined symbol with a prepended asterisk (*). Either a symbol or an expression may be passed as a value-parameter. Only a symbol may be passed as a variable-parameter.

Example:

#INSERT(%SomeGroup)    #!Ordinary insert

#INSERT(%GenerateFormulas('Clarion')) #!Insert #GROUP from Clarion Template

#INSERT(%FileRecordFilter,%Secondary) #!Insert #GROUP with passed parameter

#INSERT(%FileRecordFilter(Clarion),%Primary,%Secondary)

   #!#GROUP from Clarion Template with two passed parameters

See Also:

#GROUP


#BREAK (break out of a loop)

#BREAK

The #BREAK statement immediately breaks out of the #FOR or #LOOP structure in which it is enclosed. Control passes to the next statement following the #ENDFOR or #ENDLOOP. #BREAK is only valid within a #FOR or #LOOP structure, else an error is generated during Template file pre-processing.

Example:

#SET(%StopFile,'CUSTOMER')

#FOR(%File)

  #IF (UPPER(%File) = %StopFile)

    #BREAK

  #ENDIF

  OPEN(%File)

#ENDFOR


#CYCLE (cycle to top of loop)

#CYCLE

The #CYCLE statement immediately passes control back to the top of the #FOR or #LOOP structure in which it is enclosed to begin the next iteration. #CYCLE is only valid within a #FOR or #LOOP structure, else an error is generated during Template file pre-processing.

Example:

#SET(%StopFile,'CUSTOMER')

#FOR(%File)

  #IF (UPPER(%File) <> %StopFile)

    OPEN(%File)

    #CYCLE

  #ELSE

    #BREAK

  #ENDIF

#ENDFOR


#RETURN (return from #GROUP)

#RETURN

The #RETURN statement immediately returns control to the statement following the #INSERT that called the #GROUP containing the #RETURN statement. #RETURN is only valid in a #GROUP section.

Example:

#GROUP(%ProcessListGroup,%PassedControl)

  #FIX(%ScreenField,%PassedControl)

  #IF (%ScreenFieldType <> 'LIST')

    #UNFIX(%ScreenField)

    #RETURN

  #ENDIF


#GENERATE (generate source code section)

#GENERATE( section )

#GENERATE	Generates a section of the application.

section	One of the following built-in symbols: %Program, %Module, or %Procedure. This symbol indicates the portion of the application to generate.

The #GENERATE statement generates the source code for the specified section of the application by executing the Template Language statements contained within that section. #GENERATE should only be used within the #APPLICATION or a #UTILITY section of the Template.

When section is:

    %Program	The #PROGRAM section of the Template is generated.

    %Module	The appropriate #MODULE section of the Template is generated.

    %Procedure	The appropriate #PROCEDURE section of the Template for the current value of %Procedure is generated.

Example:

#GENERATE(%Program)                            #!Generate program header

#FOR(%Module)                                  #!

  #GENERATE(%Module)                           #!Generate module header

  #FOR(%ModuleProcedure)                       #!For all procs in module

    #FIX(%Procedure,%ModuleProcedure)          #!Fix current procedure

    #GENERATE(%Procedure)                      #!Generate procedure code

  #ENDFOR                                      #!EndFor all procs in module

#ENDFOR                                        #!EndFor all modules


#ABORT (abort source generation)

#ABORT

The #ABORT statement immediately terminates source generation by the previous #GENERATE statement. #ABORT may be placed in any template section.

Example:

#IF(%ValidRangeKey=%Null)

  #ERROR(%Procedure & ' Range Error: The range field is not in the primary key!')

  #ABORT

#ENDIF

See Also:

#GENERATE


File Management Statements

#CREATE (create source file)

#OPEN (open source file)

#CLOSE (close source file)

#READ(read one line of a source file)

#REDIRECT (change source file)

#APPEND (add to source file)

#REMOVE (delete a source file)

#REPLACE (conditionally replace source file)

#PRINT (print a source file)


#CREATE (create source file)

#CREATE( file )

#CREATE	Creates a disk file to receive generated source code.

file	A string constant, template symbol, or expression containing a DOS file specification. This may be a fully qualified DOS pathname.

The #CREATE statement creates a disk file to receive the source code generated by #GENERATE. If the file does not exist, it is created. If the file already exists, it is opened and emptied (truncated to zero length). If the file is already open, a source generation error is produced.

The file is automatically selected as the active source output destination.

Example:

#SET(%NewProgramFile,(%Application & '.$$$'))    #!Temp new program filename

#CREATE(%NewProgramFile)                         #!Create new program file

#GENERATE(%Program)                              #!Generate main program header


#OPEN (open source file)

#OPEN( file ) [, READ ]

#OPEN	Opens a disk file to receive generated source code.

file	A string constant, template symbol, or expression containing a DOS file specification. This may be a fully qualified DOS pathname.

READ	Opens the file as read-only. The file cannot be already open for output.

The #OPEN statement opens a disk file to receive the source code generated by #GENERATE. If the file does not exist, it is created. If the file already exists, it is opened in "append source" mode. If the file is already open, a source generation error is produced.The file is automatically selected as the active source output destination.

If the READ attribute is present, the file is opened in read-only mode so the #READ statement can read it as an ASCII text file. Only one file can be open for input at one time.

Example:

#SET(%ProgramFile,(%Application & '.$$$'))       #!Temp program filename

#OPEN(%ProgramFile)                              #!Open existing program file

#GENERATE(%Program)                              #!Generate main program header

#CLOSE(%ProgramFile)	#!Close output file

#OPEN(%ProgramFile),READ                         #!Open it in read-only mode

#DECLARE(%ASCIIFileRecord)

#LOOP

  #READ(%ASCIIFileRecord)

#! Parse the line and do something with it

#IF(%ASCIIFileRecord = %EOF)

#BREAK

#ENDIF

#ENDLOOP

#CLOSE(%ProgramFile),READ

See Also:

#READ

#CLOSE


#CLOSE (close source file)

#CLOSE( [file] ) [, READ ]

#CLOSE	Closes an open generated source code disk file.

file	A string constant, template symbol, or expression containing a DOS file specification. This may be a fully qualified DOS pathname. If omitted, the current disk file receiving generated source code is closed.

READ	Closes the read-only input file.

The #CLOSE statement closes an open disk file receiving the generated source code. If the file is omitted, the current disk file receiving generated source code is closed. If the file does not exist, or is already closed, a source generation error is produced.

Example:

#SET(%NewProgramFile,(%Application & '.$$$'))    #!Temp new program filename

#CREATE(%NewProgramFile)                         #!Create new program file

#GENERATE(%Program)                              #!Generate main program header

#CLOSE(%NewProgramFile)                          #!Create new program file

#OPEN(%ProgramFile),READ                         #!Open it in read-only mode

#DECLARE(%ASCIIFileRecord)

#LOOP

  #READ(%ASCIIFileRecord)

#! Parse the line and do something with it

#IF(%ASCIIFileRecord = %EOF)

#BREAK

#ENDIF

#ENDLOOP

#CLOSE(%ProgramFile),READ	#!Close the read-only file

See Also:

#OPEN

#READ


#READ(read one line of a source file)

#READ( symbol )

#READ	Reads the next record from the opened read-only file.

symbol	The symbol to receive the text from the file.

The #READ statement reads the next record (up to the next CR/LF encountered) from open read-only file. The symbol receives the text from the file. If the last record has been read, the symbol will contain a value equivalent to the %EOF built-in symbol.

Example:

#OPEN(%ProgramFile),READ                         #!Open it in read-only mode

#DECLARE(%ASCIIFileRecord)

#LOOP

  #READ(%ASCIIFileRecord)

#! Parse the line and do something with it

#IF(%ASCIIFileRecord = %EOF)

#BREAK

#ENDIF

#ENDLOOP

#CLOSE(%ProgramFile),READ	#!Close the read-only file

See Also:

#OPEN

#CLOSE


#REDIRECT (change source file)

#REDIRECT( [file] )

#REDIRECT	Changes the current generated source destination file.

file	A string constant, template symbol, or expression containing a DOS file specification that has already been opened with #OPEN or #CREATE. This may be a fully qualified DOS pathname. If omitted, the source generation destination returns to the previous file that received generated source.

The #REDIRECT statement changes the destination file for generated source code. All source generation output is directed to the specified file until a #OPEN or another #REDIRECT statement is executed. If the file has not been previously opened (or created), or is closed, then a source generation error is produced.

The destination files for generated source are kept as a LIFO (Last In, First Out) "stack" list. When #REDIRECT is issued without a file parameter, the source generation destination reverts to the previous destination file.

Example:

#SET(%NewProgramFile,(%Application & '.CLW'))    #!Temp new program filename

#CREATE(%NewProgramFile)                         #!Create new program file

#FOR(%Module)

  #CREATE(%Module & '.CLW')                      #!Make module files

#ENDFOR

#REDIRECT(%NewProgramFile)                       #!Redirect output to program file

#GENERATE(%Program)                              #!Generate main program header

#CLOSE(%NewProgramFile)                          #!Create new program file

#FOR(%Module)

  #REDIRECT(%Module & '.CLW')                    #!Redirect output to module file

  #GENERATE(%Module)                             #!Generate module header

  #FOR(%ModuleProcedure)                         #!For all procs in module

    #FIX(%Procedure,%ModuleProcedure)            #!Fix current procedure

    #GENERATE(%Procedure)                        #!Generate procedure code

  #ENDFOR                                        #!EndFor all procs in module

#ENDFOR

#!The following code demonstrates the LIFO files list:

#REDIRECT('F1.CLW')  #!List contains:   F1

#REDIRECT('F2.CLW')  #!List contains:   F1,  F2

#REDIRECT('F3.CLW')  #!List contains:   F1,  F2,  F3

#REDIRECT( )         #!List contains:   F1,  F2

#REDIRECT( )         #!List contains:   F1


#APPEND (add to source file)

#APPEND( file )

#APPEND	Adds the file contents to the end of the current source output destination file.

file	A string constant, template symbol, or expression containing a DOS file specification. This may be a fully qualified DOS pathname.

The #APPEND statement adds the complete contents of the file to the end of the current source output destination file. The contents of the file are NOT interpreted for source generation purposes. Therefore, the file should not contain any Template Language code.

If the file does not exist, #APPEND is ignored and source generation continues.

Example:

#FOR(%Module)

  #SET(%TempModuleFile,(%Module & '.$$$'))       #!Set temp module file

  #CREATE(%TempModuleFile)                       #!Create temp module file

  #FOR(%ModuleProcedure)                         #!For all procs in module

    #FIX(%Procedure,%ModuleProcedure)            #!Fix current procedure

    #GENERATE(%Procedure)                        #!Generate procedure code

  #ENDFOR                                        #!EndFor all procs in module

  #SET(%ModuleFile,(%Module & '.CLW'))           #!Set to current module file

  #CREATE(%ModuleFile)                           #!Create module file

  #GENERATE(%Module)                             #!Generate module header

  #APPEND(%TempModuleFile)                       #!Add generated procedures

#ENDFOR


#REMOVE (delete a source file)

#REMOVE( file )

#REMOVE	Deletes a source output file.

file	A string constant, template symbol, or expression containing a DOS file specification. This may be a fully qualified DOS pathname.

The #REMOVE statement deletes the specified source output file. If the file does not exist, #REMOVE is ignored and source generation continues.

Example:

#FOR(%Module)

  #SET(%TempModuleFile,(%Module & '.$$$'))       #!Set temp module file

  #CREATE(%TempModuleFile)                       #!Create temp module file

  #FOR(%ModuleProcedure)                         #!For all procs in module

    #FIX(%Procedure,%ModuleProcedure)            #!Fix current procedure

    #GENERATE(%Procedure)                        #!Generate procedure code

  #ENDFOR                                        #!EndFor all procs in module

  #SET(%ModuleFile,(%Module & '.CLW'))           #!Set to current module file

  #CREATE(%ModuleFile)                           #!Create module file

  #GENERATE(%Module)                             #!Generate module header

  #APPEND(%TempModuleFile)                       #!Add generated procedures

  #REMOVE(%TempModuleFile)                       #!Delete the temporary file

#ENDFOR


#REPLACE (conditionally replace source file)

#REPLACE( oldfile, newfile )

#REPLACE	Performs "intelligent" file replacement.

oldfile	A string constant, template symbol, or expression containing a DOS file specification. This may be a fully qualified DOS pathname.

newfile	A string constant, template symbol, or expression containing a DOS file specification. This may be a fully qualified DOS pathname.

The #REPLACE statement performs a binary comparison between the contents of the oldfile and newfile. If the contents of the oldfile are different from the contents of the newfile (or the oldfile does not exist), then the oldfile is deleted and the newfile is renamed to the oldfile. If the two files are identical, then no action is taken. If the newfile does not exist, #REPLACE is ignored and source generation continues.

Example:

#FOR(%Module)

  #SET(%TempModuleFile,(%Module & '.$$$'))       #!Set temp module file

  #CREATE(%TempModuleFile)                       #!Create temp module file

  #GENERATE(%Module)                             #!Generate module header

  #FOR(%ModuleProcedure)                         #!For all procs in module

    #FIX(%Procedure,%ModuleProcedure)            #!Fix current procedure

    #GENERATE(%Procedure)                        #!Generate procedure code

  #ENDFOR                                        #!EndFor all procs in module

  #SET(%ModuleFile,(%Module & '.CLW'))           #!Set to existing module file

  #REPLACE(%ModuleFile,%TempModuleFile)          #!Replace old with new (if changed)

#ENDFOR


#PRINT (print a source file)

#PRINT( file, title )

#PRINT	Prints a file to the current Windows printer.

file	A string constant, template symbol, or expression containing a DOS file specification. This may be a fully qualified DOS pathname.

title	A string constant, template symbol, or expression containing the title to generate for the file.

The #PRINT statement prints the contents of the file to the Windows default printer.

Example:

#FOR(%Module)

 	#SET(%ModuleFile,(%Module & '.CLW'))           #!Set to existing module file

 	#PRINT(%ModuleFile,"Printout ' & %ModuleFile)

#ENDFOR


Conditional Source Generation Statements

#SUSPEND (begin conditional source)

#RELEASE (commit conditional source generation)

#RESUME (delimit conditional source)

#? (conditional source line)


#SUSPEND (begin conditional source)

#SUSPEND

The #SUSPEND statement marks the start of a section of source that is generated only if a #RELEASE statement is encountered. This allows empty unnecessary "boiler-plate" code to be easily removed from the generated source. The end of the section must be delimited by a matching #RESUME statement.

These #SUSPEND sections may be nested within each other to as many levels as necessary. A #RELEASE encountered in an inner nested section commits source generation for all the outer nested levels in which it is contained, also.

A #EMBED that contains source to generate performs an implied #RELEASE. Any generated source output also performs an implied #RELEASE. Therefore, an explicit #RELEASE statement is not always necessary. The #? statement defines an individual conditional source line that does not preform the implied #RELEASE.

Example:

ACCEPT

#SUSPEND  #!Begin suspended generation

  #?CASE SELECTED()

  #FOR(%ScreenField)

    #SUSPEND

  #?OF %ScreenField

    #EMBED(%ScreenSetups,'Control selected code'),%ScreenField

  #!Implied #RELEASE from the #EMBED of both nested sections

    #RESUME

  END

#RESUME  #!End suspended generation

#SUSPEND  #!Begin suspended generation

  #?CASE EVENT()

  #SUSPEND

  #?OF EVENT:AlertKey

    #SUSPEND

    #?CASE KEYCODE()

      #FOR %HotKey

        #RELEASE #!Explicit #RELEASE

    #?OF %HotKey

      #EMBED(%HotKeyProc,'Hot Key code'),%HotKey

      #ENDFOR

    #?END

    #RESUME

  #?END

#RESUME  #!End suspended generation

END

See Also:

#RELEASE

#RESUME

#?


#RELEASE (commit conditional source generation)

#RELEASE

The #RELEASE enables source generation in a #SUSPEND section. This allows empty unnecessary "boiler-plate" code to be easily removed from the generated source. The code in a #SUSPEND section is generated only when a #RELEASE statement is encountered.

#SUSPEND sections may be nested within each other to as many levels as necessary. A #RELEASE encountered in an inner nested section commits source generation for all the outer nested levels in which it is contained, also.

A #EMBED that contains source to generate performs an implied #RELEASE. Any generated source output also performs an implied #RELEASE. Therefore, an explicit #RELEASE statement is not always necessary. The #? statement defines an individual conditional source line that does not preform the implied #RELEASE.

Example:

ACCEPT

#SUSPEND  #!Begin suspended generation

  #?CASE SELECTED()

  #FOR(%ScreenField)

    #SUSPEND

  #?OF %ScreenField

    #EMBED(%ScreenSetups,'Control selected code'),%ScreenField

  #!Implied #RELEASE from the #EMBED of both nested sections

    #RESUME

  #?END

#RESUME  #!End suspended generation

#SUSPEND  #!Begin suspended generation

  #?CASE EVENT()

  #SUSPEND

  #?OF EVENT:AlertKey

    #SUSPEND

    #?CASE KEYCODE()

      #FOR %HotKey

        #RELEASE #!Explicit #RELEASE

    #?OF %HotKey

      #EMBED(%HotKeyProc,'Hot Key code'),%HotKey

      #ENDFOR

    #?END

    #RESUME

  #?END

#RESUME  #!End suspended generation

END

See Also:

#SUSPEND

#RESUME

#?


#RESUME (delimit conditional source)

#RESUME

The #RESUME statement marks the end of a section of source that is generated only if a #RELEASE statement is encountered. This allows empty unnecessary "boiler-plate" code to be easily removed from the generated source. The beginning of the section must be delimited by a matching #SUSPEND statement.

These #SUSPEND sections may be nested within each other to as many levels as necessary. A #RELEASE encountered in an inner nested section commits source generation for all the outer nested levels in which it is contained, also.

A #EMBED that contains source to generate performs an implied #RELEASE. Any generated source output also performs an implied #RELEASE. Therefore, an explicit #RELEASE statement is not always necessary. The #? statement defines an individual conditional source line that does not preform the implied #RELEASE.

When a #RESUME is executed without the output to the file being released, any conditional lines of code are un-done back to the matching #SUSPEND.

Example:

ACCEPT

#SUSPEND  #!Begin suspended generation

  #?CASE SELECTED()

  #FOR(%ScreenField)

    #SUSPEND

  #?OF %ScreenField

    #EMBED(%ScreenSetups,'Control selected code'),%ScreenField

  #!Implied #RELEASE from the #EMBED of both nested sections

    #RESUME

  #?END

#RESUME  #!End suspended generation

#SUSPEND  #!Begin suspended generation

  #?CASE EVENT()

  #SUSPEND

  #?OF EVENT:AlertKey

    #SUSPEND

    #?CASE KEYCODE()

      #FOR %HotKey

        #RELEASE #!Explicit #RELEASE

    #?OF %HotKey

      #EMBED(%HotKeyProc,'Hot Key code'),%HotKey

      #ENDFOR

    #?END

    #RESUME

  #?END

#RESUME  #!End suspended generation

END

See Also:

#SUSPEND

#RELEASE

#?


#? (conditional source line)

#?statement

#?	Defines a single line of source code generated only if #RELEASE commits the conditional source section.

statement	A single line of target language code. This may contain template symbols.

The #? statement defines a single line of source code that is generated only if a #RELEASE statement is encountered. This allows empty unnecessary "boiler-plate" code to be easily removed from the generated source.

A #EMBED that contains source to generate performs an implied #RELEASE. Any generated source output also performs an implied #RELEASE. Therefore, an explicit #RELEASE statement is not always necessary. The #? statement defines an individual conditional source line that does not preform the implied #RELEASE. When a #RESUME is executed without the output to the file being released, any conditional lines of code are un-done back to the matching #SUSPEND.

Example:

ACCEPT   #!Unconditional source line

#SUSPEND

  #?CASE SELECTED()  #!Conditional source line

  #FOR(%ScreenField)

    #SUSPEND

  #?OF %ScreenField  #!Conditional source line

    #EMBED(%ScreenSetups,'Control selected code'),%ScreenField

    #RESUME

  #?END   #!Conditional source line

#RESUME

#SUSPEND

  #?CASE EVENT()  #!Conditional source line

  #SUSPEND

  #?OF EVENT:AlertKey #!Conditional source line

    #SUSPEND

    #?CASE KEYCODE() #!Conditional source line

      #FOR %HotKey

        #RELEASE

    #?OF %HotKey  #!Conditional source line

      #EMBED(%HotKeyProc,'Hot Key code'),%HotKey

      #ENDFOR

    #?END   #!Conditional source line

    #RESUME

  #?END   #!Conditional source line

#RESUME

END   #!Unconditional source line

See Also:

#SUSPEND

#RELEASE

#RESUME


Chapter 6 - Miscellaneous

Miscellaneous Statements

#! (template code comments)

#< (aligned target language comments)

#CLASS (define a formula class)

#COMMENT (specify comment column)

#ERROR (display source generation error)

#EXPORT (export symbol to text)

#HELP (specify template help file)

#INCLUDE (include a template file)

#IMPORT (import from text script)

#MESSAGE (display source generation message)

#PROTOTYPE (procedure prototype)

#PROJECT (add file to project)

Built-in Template Functions

EXTRACT (return attribute)

EXISTS (return embed point existence)

FILEEXISTS (return file existence)

INLIST (return item exists in list)

INSTANCE (return current instance number)

ITEMS (return multi-valued symbol instances)

QUOTE (replace string special characters)

REPLACE (replace attribute)

SEPARATOR (return attribute string delimiter position)


Miscellaneous Statements

#! (template code comments)

#< (aligned target language comments)

#CLASS (define a formula class)

#COMMENT (specify comment column)

#ERROR (display source generation error)

#EXPORT (export symbol to text)

#HELP (specify template help file)

#INCLUDE (include a template file)

#IMPORT (import from text script)

#MESSAGE (display source generation message)

#PROTOTYPE (procedure prototype)

#PROJECT (add file to project)


#! (template code comments)

#! comments

#!	Initiates Template Language comments.

comments	Any text.

Example:

#! These are Template comments which

#!   will not end up in the generated code


#< (aligned target language comments)

#<comments

#<	Initiates an aligned target language comment.

comments	Any text. This must start with the target language comment initiator.

Example:

#COMMENT(50)

#! This Template file comment will not be in the generated code

#<! This is a Clarion comment which appears in the generated code in column 50

 ! This Clarion comment appears in the generated code in column 2

#<// This is a C++ comment which appears in the generated code beginning in column 50

 // This C++ comment appears in the generated code in column 2

See Also:

#COMMENT


#CLASS (define a formula class)

#CLASS( string, description )

#CLASS	Defines a formula class.

string	A string constant containing the formula class.

description	A string expression containing the description of the formula class to display in the list of those available in the Formula Editor.

Example:

#PROCEDURE(SomeProc,'An Example Template'),WINDOW

#CLASS('START','At beginning of procedure')

#CLASS('LOOP','In process loop')

#CLASS('END','At end of procedure')

%Procedure PROCEDURE

%ScreenStructure

  CODE

  #INSERT(%GenerateFormulas,'START') 	#!Generate START class formulas

  OPEN(%Screen)

  ACCEPT

    #INSERT(%GenerateFormulas,'LOOP') 	#!Generate LOOP class formulas

  END

  #INSERT(%GenerateFormulas,'END')  	#!Generate END class formulas


#COMMENT (specify comment column)

#COMMENT( column )

#COMMENT	Sets the default column number for aligned comments.

column	A numeric constant in the range 1 to 255.

Example:

#COMMENT(50)    #!Set comment column

IF Action = 1  #<!If adding a record

  SomeVariable = InitVariable

END

See Also:

#< (aligned target language comments)


#ERROR (display source generation error)

#ERROR( message )

#ERROR	Displays a source generation error.

message	A string constant, user-defined symbol, or expression containing an error message to display in the Source Generation window.

Example:

#PROCEDURE(SampleProc,'This is a sample procedure')

#PROMPT('Access Key',KEY),%SampleAccessKey

  #IF(%SampleAccessKey = %NULL)  	#!IF the user did not enter a Key

    #SET(%ErrorSymbol,(%Procedure & ' Access Key blank')

    #ERROR(%ErrorSymbol)

    #ERROR('This error is Fatal -- DO NOT CONTINUE')

#ABORT

  #ENDIF


#EXPORT (export symbol to text)

#EXPORT( symbol )

#EXPORT	Creates a .TXA text file from a symbol.

symbol	The template symbol to export.

Example:

#OPEN('MyExp.TXA')

#FOR(%Procedure)

#EXPORT(%Procedure)

#ENDFOR

See Also:

#CREATE

#OPEN

#IMPORT


#HELP (specify template help file)

#HELP( helpfile )

#HELP	Specifies the Template's help file.

helpfile	A string constant containing the name of the template's help file.

Example:

#HELP('Template.HLP')


#INCLUDE (include a template file)

#INCLUDE( filename )

#INCLUDE	Adds a template file to the Template file chain.

filename	A string constant containing the name of the template file to include.

Example:

#TEMPLATE(Clarion,'Clarion Standard Shipping Templates')

#INCLUDE('Clarion1.TPX') 	#!Include a template file

#INCLUDE('Clarion2.TPX') 	#!Include another template file


#IMPORT (import from text script)

#IMPORT( source ) [,	| RENAME	| ]

| REPLACE	|

#IMPORT	Creates an .APP for Clarion for Windows from a .TXA script source file.

source	The name of the .TXA script file from which to create the .APP file.

RENAME	Overrides the Procedure Name Clash prompt dialog and renames all procedures.

REPLACE	Overrides the Procedure Name Clash prompt dialog and replaces all procedures.

Example:

#UTILITY(SomeUtility,'Some Utility Template')

#PROMPT('File to import',@s64),%ImportFile

#IMPORT(%ImportFile)


#MESSAGE (display source generation message)

#MESSAGE( message, line )

#MESSAGE	Displays a source generation message.

message	A string constant, or a user-defined symbol, containing a message to display in the Source Generation dialog.

line	An integer constant or symbol containing the line number on which to display the message. If out of the range 1 through 3, the message is displayed in the title bar as the window caption.

Example:

#MESSAGE('Generating ' & %Application,0) 	#!Display Title bar text

#MESSAGE('Generating ' & %Procedure,2) 	#!Display Progress message on line 2


#PROTOTYPE (procedure prototype)

#PROTOTYPE( parameter list )

#PROTOTYPE	Assigns the parameter list to the Prototype entry field.

parameter list	A string constant containing the procedure's prototype parameter list (the entire procedure prototype without the leading procedure name) for the application's MAP structure (see the discussion of Function and Procedure Prototypes in the Language Reference).

Example:

#PROCEDURE(SomeProc,'Some Procedure Template')

%Procedure PROCEDURE(Parm1,Parm2,Parm3)

  #PROTOTYPE('(STRING,*LONG,<*SHORT>)')

 	#!This procedure expects three parameters:

 	#!  a STRING passed by value

 	#!  a LONG passed by address

 	#!  a SHORT passed by address which may be omitted

#PROCEDURE(SomeFunc,'Some Template Function')

%Procedure FUNCTION(Parm1,Parm2,Parm3)

  #PROTOTYPE('(STRING,*LONG,<*SHORT>),STRING')

 	#!This function expects three parameters:

 	#!  a STRING passed by value

 	#!  a LONG passed by address

 	#!  a SHORT passed by address which may be omitted

 	#!It returns a STRING


#PROJECT (add file to project)

#PROJECT( module )

#PROJECT	Includes a source or object code library, or Project file, in the application's Project file.

module	A string constant which names a source (.CLW, if Clarion is the target language), object (.OBJ), or library (.LIB) file containing procedures and/or functions required by the procedure Template. This may also name a Project (.PRJ) file to be called by the application's Project. The type of file being imported is determined by the file extension.

Example:

#AT(%CustomGlobalDeclarations)

#PROJECT('Party3.LIB')

#ENDAT


Built-in Template Functions

EXTRACT (return attribute)

EXISTS (return embed point existence)

FILEEXISTS (return file existence)

INLIST (return item exists in list)

INSTANCE (return current instance number)

ITEMS (return multi-valued symbol instances)

QUOTE (replace string special characters)

REPLACE (replace attribute)

SEPARATOR (return attribute string delimiter position)


EXTRACT (return attribute)

EXTRACT( string, attribute [, parameter ] )

EXTRACT	Returns the complete form of the specified attribute from the property string symbol.

string	The symbol containing the properties to parse.

attribute	A string constant or symbol containing the name of the property to return.

parameter	An integer constant or symbol containing the number of the property's parameter to return. Zero (0) returns the entire parameter list (without the attribute). If omitted, the attribute and all its parameters are returned.

Return Data Type:	STRING

Example:

#SET(%MySymbol,EXTRACT(%ControlStatement,'DROPID') 	#!Return DROPID attribute

#SET(%MySymbol,EXTRACT(%ControlStatement,'DROPID',0) #!Return all DROPID parameters

See Also:

REPLACE


EXISTS (return embed point existence)

EXISTS( symbol )

EXISTS	Returns TRUE if the embedded source code point is available for use.

symbol	The identifier symbol for a #EMBED embedded source code point.

Return Data Type:  	LONG

Example:

#IF(EXISTS(%CodeTemplateEmbed))

  !Generate some source

#ENDIF


FILEEXISTS (return file existence)

FILEEXISTS( file )

FILEEXISTS	Returns TRUE if the file available on disk.

file	An expression contiaining the DOS filename.

Return Data Type:  	LONG

Example:

#IF(FILEEXISTS(%SomeFile))

  #OPEN(%SomeFile)

  #READ(%SomeFile)

  !some source

#ENDIF


INLIST (return item exists in list)

INLIST( item, symbol )

INLIST	Returns the instance number of the item in the symbol.

item	A string constant or symbol containing the name of the item to return.

symbol	A multi-valued symbol that may contain the item.

Return Data Type:  	LONG

Example:

#IF(INLIST('?MyControl',%Control))

  !Generate some source

#ENDIF


INSTANCE (return current instance number)

INSTANCE( symbol )

INSTANCE	Returns the current instance number to which the symbol is fixed.

symbol	A multi-valued symbol.

Return Data Type:  	LONG

Example:

#DELETE(%Control,INSTANCE(%Control))  	#!Delete current instance


ITEMS (return multi-valued symbol instances)

ITEMS( symbol )

ITEMS	Returns the number of instances contained by the symbol.

symbol	A multi-valued symbol.

Return Data Type:  	LONG

Example:

#DELETE(%Control,ITEMS(%Control))  	#!Delete last instance


QUOTE (replace string special characters)

QUOTE( symbol )

QUOTE	Expands the symbol's string data, "doubling up" single quotes ('), and all un-paired left angle brackets (<) and left curly braces ({) to prevent compiler errors.

symbol	The symbol containing the properties to parse.

Return Data Type:	STRING

Example:

#PROMPT('Filter Expression',@S255),%FilterExpression

#SET(%ValueConstruct,QUOTE(%FilterExpression))	#!Expand single quotes and angle brackets


REPLACE (replace attribute)

REPLACE( string, attribute, new value [, parameter ] )

REPLACE	Finds the complete form of the specified attribute from the property string symbol and replaces it with the new value.

string	The symbol containing the properties to parse.

attribute	A string constant or symbol containing the name of the property to find.

new value	A string constant or symbol containing the replacement value for the attribute.

parameter	An integer constant or symbol containing the number of the property's parameter to affect. Zero (0) affects the entire parameter list (without the attribute). If omitted, the attribute and all its parameters are affected.

Return Data Type:	STRING

Example:

#SET(%ValueConstruct,REPLACE(%ValueConstruct,'MSG',''))	#!Remove MSG attribute

See Also:

EXTRACT


SEPARATOR (return attribute string delimiter position)

SEPARATOR( string, start )

SEPARATOR	Returns the position of the next comma in the attribute string.

string	A string constant or symbol containing a comma delimited list of attributes.

start	An integer constant or symbol containing the starting position from which to seek the next comma.

Return Data Type: 	LONG

Example:

#SET(%MySymbol,SEPARATOR(%ControlStatement,1)

  	#!Return first comma position


Chapter 7 - Template Symbols

Symbol Overview

Expansion Symbols

Symbol Hierarchy Overview

Built-in Symbols

Symbols Dependent on %Application

Symbols Dependent on %File

Symbols Dependent on %ViewFiles

Symbols Dependent on  %Field

Symbols Dependent on %Key

Symbols Dependent on %Relation

Symbols Dependent on %Module

Symbols Dependent on %Procedure

Window Control Symbols

Report Control Symbols

Formula Symbols

File Schematic Symbols

File Driver Symbols

Miscellaneous Symbols


Symbol Overview

Expansion Symbols

Symbol Hierarchy Overview


Expansion Symbols

%%	Expands to a single percent (%) sign. This allows the Application Genetrator to generate the modulus operator without confusion with any symbol.

%#	Expands to a single pound (#) sign. This allows the Application genetrator to generate an implicit LONG variable without confusion with any Template Language statement.

%@picture@symbol
Formats the symbol with the specified picture when source generates. For example, %@D1@MyDate expands the %MyDate symbol, formatted for the @D1 picture.

%[number]symbol	Expands the symbol to fill at least the number of spaces specified. This allows proper comment and data type alignment in the generated source.

%|	Expands the next generated source onto the same line as the last. This is the Template line continuation character.

%'symbol	Expands the symbol's string data, "doubling up" single quotes ('), and all un-paired left angle brackets (<) and left curly braces ({) to prevent compiler errors.

%(expression)	Expands the expression into the generated source.

Example:

%(ALL(' ', %indent))%[20]Field %@d3@Date

#!Generate an indent, expand %Field to occupy at least 20 spaces, then

#! generate the date in mmm dd, yyyy format

%[30]Null	#!Generate 30 spaces

#! %MySymbol contains: Gavin's Holiday

StringVar = '%'MySymbol'	#!Expands as a valid Clarion string constant

#! to 'Gavin''s Holiday"


Symbol Hierarchy Overview

%Application

%DictionaryFile

%File

%Field

%Key

%Relation

%Program

%GlobalData

%Module

%ModuleProcedure

%MapItem

%ModuleData

%Procedure

%Report

%ReportControl

%ReportControlField

%Window

%WindowEvent

%Control

%ControlEvent

%ProcedureCalled

%LocalData

%ActiveTemplate

%ActiveTemplateInstance

%Formula

%FormulaExpression


Built-in Symbols

Symbols Dependent on %Application

Symbols Dependent on %File

Symbols Dependent on %ViewFiles

Symbols Dependent on  %Field

Symbols Dependent on %Key

Symbols Dependent on %Relation

Symbols Dependent on %Module

Symbols Dependent on %Procedure

Window Control Symbols

Report Control Symbols

Formula Symbols

File Schematic Symbols

File Driver Symbols

Miscellaneous Symbols


Symbols Dependent on %Application

%Application	The name of the .APP file. The hierarchy of built-in symbols starts with %Application.

%ApplicationDebug
Contains 1 if the application has debug enabled.

%ApplicationLocalLibrary
Contains 1 if the application is linking in the Clarion runtime library.

%Target32	Contains 1 if the application is producing a 32-bit program.

%DictionaryChanged
Contains 1 if the .DCT file has changed since the last source generation.

%RegistryChanged
Contains 1 if the .REGISTRY.TRF file has changed since the last source generation.

%ProgramDateCreated
The program creation date (a Clarion standard date).

%ProgramDateChanged
The date the program was last changed (a Clarion standard date).

%ProgramTimeCreated
The program creation time (Clarion standard time).

%ProgramTimeChanged
The time the program was last changed (a Clarion standard time).

%FirstProcedure	The label of the applciation's first procedure.

%HelpFile	The name of the application's help file.

%ProgramExtension
Contains EXE, DLL, or LIB.

%DictionaryFile	The name of the .DCT filefor the application.

%File	Contains all file declarations in the .DCT file. Multi-valued. Dependent on %DictionaryFile.

%Program	The name of the PROGRAM file without extension).

%GlobalData	The labels of all global variable declarations made through the Global Data button on the Global Settings window. Multi-valued.

%GlobalDataStatement
The variable's declaration statement (data type and all attributes). Dependent on %GlobalData.

%Module	The names of all source code modules other than the PROGRAM module. Multi-valued.

%QuickProcedure	The name of the procedure type a #UTILITY with the WIZARD attribute is creating.

%Procedure	The names of all procedures and functions in the application. Multi-valued.


Symbols Dependent on %File

%File	Contains all file declarations in the .DCT file. Multi-valued. Dependent on %DictionaryFile.

%FilePrefix    	Contents of the PRE attribute (the file prefix).

%FileDescription     	A short description of the file.

%FileType	Contains FILE, VIEW, or ALIAS.

%FileDriver    	Contents of the DRIVER attribute first parameter.

%FileDriverParameter
Contents of the DRIVER attribute second parameter.

%FileName	Contents of the FILE statement's NAME attribute.

%FileOwner	Contents of the OWNER attribute.

%FileCreate	Contains 1 if the file has the CREATE attribute.

%FileReclaim	Contains 1 if the file has the RECLAIM attribute.

%FileEncrypt	Contains 1 if the file has the ENCRYPT attribute.

%FileBindable	Contains 1 if the file has the BINDABLE attribute.

%FileLongDesc	A long description of the file.

%FileStruct 	The FILE statement (the label and all attributes).

%FileStructEnd	The keyword END.

%FileStructRec	The RECORD statement (including label and any attributes).

%FileStructRecEnd	The keyword END.

%FileStatement	Contains the FILE statement's attributes (only).

%FileThreaded	Contains 1 if the file has the THREAD attribute.

%FileExternal	Contains 1 if the file has the EXTERNAL attribute.

%FileExternalModule
Contents of the file's EXTERNAL attribute parameter.

%FilePrimaryKey	The label of the file's primary key.

%FileQuickOptions	A comma-delimited string containing the choices the user made on the Options tab for the file.

%FileUserOptions	A string containing the entries the user made in the User Options text box on the Options tab for the file.

%ViewFilter	Contents of the FILTER attribute.

%ViewStruct	The VIEW statement (including the label and all attributes).

%ViewStructEnd	The keyword END.

%ViewStatement	The VIEW statement's attributes (only).

%ViewPrimary	The label of the VIEW's primary file.

%ViewPrimaryFields
The labels of all fields in the VIEW from the primary file. Multi-valued.

%ViewPrimaryField
Dependent on %ViewPrimaryFields. Contains the label of a field in the VIEW from the primary file.

%ViewFiles	The labels of all files in the VIEW. Multi-valued.

%AliasFile	The label of the ALIASed file.

%Field	The labels of all fields in the file (including MEMO fields). Multi-valued.

%Key	The labels of all keys and indexes for the file. Multi-valued.

%Relation	The labels of all files that are related to the file. Multi-Valued.


Symbols Dependent on %ViewFiles

%ViewFiles	The labels of all files in the VIEW. Multi-valued. Dependent on %File.

%ViewFileStruct	The JOIN statement for a secondary file in the VIEW.

%ViewFileStructEnd
The keyword END.

%ViewFile	Contains the label of the file.

%ViewJoinedTo 	The label of the file to which the file is JOINed.

%ViewFileFields	The labels of all fields in the file used in the VIEW. Multi-valued.

%ViewFileField	Contains the label of the field in the file used in the VIEW. Dependent on %ViewFileFields.


Symbols Dependent on  %Field

%Field	The labels of all fields in the file (including MEMO fields). Multi-valued.Dependent on %File.

%FieldDescription	A short description of  the field.

%FieldLongDesc  	A long description of the field.

%FieldFile	The label of the file containing the field.

%FieldID 	Label of the field without prefix.

%FieldDisplayPicture
Default display picture.

%FieldRecordPicture
STRING field storage definition picture.

%FieldDimension1  	Maximum value of first array dimension.

%FieldDimension2  	Maximum value of second array dimension.

%FieldDimension3  	Maximum value of third array dimension.

%FieldDimension4  	Maximum value of fourth array dimension.

%FieldHelpID	Contents of the HLP attribute.

%FieldName    	Contents of the field's NAME attribute.

%FieldRangeLow    	The lower range of valid values for the field.

%FieldRangeHigh   	The upper range of valid values for the field.

%FieldType    	Data type of the field.

%FieldPlaces     	Number of decimal places for the field.

%FieldMemoSize	Maximum size of the MEMO.

%FieldMemoImage	Contains 1 if the MEMO has a BINARY attribute.

%FieldInitial	Initial value for the field.

%FieldLookup	File to access to validate this field's value.

%FieldStruct	The field's declaration statement (label , data type, and all attributes).

%FieldStatement	The field's declaration statement (data type and all attributes).

%FieldHeader	The field's default report column header.

%FieldPicture	Default display picture.

%FieldJustType	Contains L, R, C, or D for the field's justification.

%FieldJustIndent	The justification offset amount.

%FieldFormatWidth
The default width for the field's ENTRY control.

%FieldChoices	The choices the user entered for a Must Be In List field. Multi-valued.

%FieldQuickOptions
A comma-delimited string containing the choices the user made on the Options tab for the field.

%FieldUserOptions
A string containing the entries the user made in the User Options text box on the Options tab for the field.


Symbols Dependent on %Key

%Key	The labels of all keys and indexes for the file. Multi-valued.

%KeyDescription	A short description of the key.

%KeyLongDesc	A long description of the key.

%KeyFile	The label of the file to which the key belongs.

%KeyID 	The label of the key (without prefix).

%KeyIndex	Contains KEY, INDEX, or DYNAMIC.

%KeyName	Contents of the key's NAME attribute.

%KeyAuto	Contains the label of the auto-incrementing field.

%KeyDuplicate	Contains 1 if the key has the DUP attribute.

%KeyExcludeNulls	Contains 1 if the key has the OPT attribute.

%KeyNoCase 	Contains 1 if the key has the NOCASE attribute.

%KeyPrimary	Contains 1 if the key is the file's primary key.

%KeyStruct	The key's declaration statement (label and all attributes).

%KeyStatement	The key's attributes (only).

%KeyField	The labels of all component fields of the key. Multi-valued.

%KeyFieldSequence
Contains ASCENDING or DESCENDING. Dependent on %Keyfield.

%KeyQuickOptions	A comma-delimited string containing the choices the user made on the Options tab for the key.

%KeyUserOptions	A string containing the entries the user made in the User Options text box on the Options tab for the key.


Symbols Dependent on %Relation

%Relation	The labels of all files that are related to the file. Multi-Valued.

%RelationPrefix	The prefix of the related file.

%FileRelationType	Contains 1:MANY or MANY:1.

%RelationKey	The label of the related file's linking key.

%FileKey	The label of the file's linking key.

%RelationConstraintDelete
May contain: RESTRICT, CASCADE, or CLEAR.

%RelationConstraintUpdate
May contain: RESTRICT, CASCADE, or CLEAR.

%RelationKeyField	The labels of all linking fields in the related file's key. Multi-valued.

%RelationKeyFieldLink
The label of the linking field in the file's key. Dependent on %RelationKeyField.

%FileKeyField	The labels of all linking fields in the file's key. Multi-valued.

%FileKeyFieldLink
The label of the linking field in the related file's key. Dependent on %FileKeyField.

%RelationQuickOptions
A comma-delimited string containing the choices the user made on the Options tab for the relation.

%RelationUserOptions
A string containing the entries the user made in the User Options text box on the Options tab for the relation.


Symbols Dependent on %Module

%Module	Thes names of all source code modules other than the PROGRAM module. Multi-valued.%ModuleDescription   %Module

%ModuleLanguage	Contains the module target language.

%ModuleTemplate	The name of the Module Template used to generate the module.

%ModuleChanged	Contains 1 if anything in the module  has changed since the last source generation.

%ModuleExternal	Contains 1 if the module is external. (not generated by Clarion for Windows).

%ModuleExtension	The file extension for the module.

%ModuleBase	The name of the module (without extension).

%ModuleInclude	The fiel to INCLUDE in the program MAP containing the module's prototypes.

%ModuleProcedure	The names of all procedures and functions in the module. Multi-valued.

%ModuleData	The labels of all module variable declarations made through the Data button on the Module Properties window. Multi-valued.

%ModuleDataStatement
The variable's declaration statement (data type and all attributes). Dependent on %ModuleData.


Symbols Dependent on %Procedure

%Procedure	Thes names of all procedures and functions in the application. Multi-valued.

%ProcedureType	Contains PROCEDURE or FUNCTION.

%ProcedureReturnType
The data type returned, if the procedure is a FUNCTION.

%ProcedureDateCreated
The procedure creation date (a Clarion standard date).

%ProcedureDateChanged
The date the procedure was last changed (a Clarion standard date).

%ProcedureTimeCreated
The time the procedure was created (a Clarion standard time).

%ProcedureTimeChanged
The time the procedure was last changed (a Clarion standard time).

%Prototype	The procedure's prototype for the MAP structure.

%ProcedureTemplate
The name of the Procedure Template used to generate the procedure.

%ProcedureDescription
A short description of the procedure.

%ProcedureExported
Contains 1 if  the procedure is in a DLL and is callable from outside the DLL.

%ProcedureLongDescription
A long description of the procedure.

%ProcedureLanguage
The target language the procedure template generates.

%ProcedureCalled	The names of all procedures listed by the Procedures button on the Procedure Properties window. Multi-valued.

%LocalData	The labels of all local variable declarations made through the Data button on the Procedure Properties window. Multi-valued.

%LocalDataStatement
The variable's declaration statement (data type and all attributes). Dependent on %LocalData.

%ActiveTemplate	The name of all control templates used in the procedure. Multi-valued.

%ActiveTemplateInstance
The instance numbers of all control templates used in the procedure. Multi-valued. Dependent on %ActiveTemplate.

%ActiveTemplateParentInstance
The instance number of the control template's parent control template. This is the control template that it is "attached" to. Dependent on %ActiveTemplateInstance.

%ActiveTemplatePrimaryInstance
The instance number of the control template's primary control template. This is the first control template in a succession of multiple related control templates. Dependent on %ActiveTemplateInstance.


Window Control Symbols

%Window	The label of the procedure's window. Dependent on %Procedure.

%WindowStatement
The WINDOW or APPLICATION declaration statement (and all attributes). Dependent on %Window.

%MenuBarStatement
The MENUBAR declaration statement (and all attributes). Dependent on %Window.

%ToolbarStatement
The TOOLBAR declaration statement (and all attributes). Dependent on %Window.

%WindowEvent	All field-independent events, as listed in the EQUATES.CLW file (without EVENT: prepended). Multi-valued. Dependent on %Window.

%Control	The field equate labels of all controls in the window. Multi-valued. Dependent on %Window.

%ControlUse	The control's USE variable (not field equate). Dependent on %Control.

%ControlStatement	The control's declaration statement (and all attributes). Dependent on %Control.

%ControlType	The type of control (MENU, ITEM, ENTRY, BUTTON, etc.). Dependent on %Control.

%ControlTemplate	The name of the control template which populated the control onto the window. Dependent on %Control.

%ControlTool 	Contains 1 if the control is in a TOOLBAR. Dependent on %Control.

%ControlMenu	Contains 1 if the control is in a MENUBAR. Dependent on %Control.

%ControlIndent	The control declaration's indentation level in the generated data structure. Dependent on %Control.

%ControlInstance	The instance number of the control template which populated the control onto the window. Dependent on %Control.

%ControlOriginal 	The original field equate label of the control as listed in the control template from which it came. Dependent on %Control.

%ControlFrom	The FROM attribute of a LIST or COMBO control. Dependent on %Control.

%ControlAlert	All ALRT attributes for the control. Multi-valued.  Dependent on %Control.

%ControlEvent	All field-specific events appropriate for the control, as listed in the EQUATES.CLW file (without the EVENT: prepended). Multi-valued. Dependent on %Control.

%ControlField	All fields populated into the LIST, COMBO, or SPIN control. Multi-valued. Dependent on %Control.

%ControlFieldHasIcon
Contains 1 if the field in the LIST or COMBO control is formatted to have an icon. Dependent on %ControlField.

%ControlFieldHasColor
Contains 1 if the field in the LIST or COMBO control is formatted to have colors. Dependent on %ControlField.

%ControlFieldHasTree
Contains 1 if the field in the LIST or COMBO control is formatted to be a tree. Dependent on %ControlField.

%ControlFieldHasLocator
Contains 1 if the field in the LIST or COMBO control is formatted to be a locator. Dependent on %ControlField.


Report Control Symbols

%Report	The label of the procedure's report. Dependent on %Procedure.

%ReportStatement	The REPORT declaration statement (and all attributes). Dependent on %Report.

%ReportControl	The field equate labels of all controls in the report. Multi-valued. Dependent on %Report.

%ReportControlUse
The control's USE variable (not field equate). Dependent on %ReportControl.

%ReportControlStatement
The control's declaration statement (and all attributes). Dependent on %ReportControl.

%ReportControlType
The type of control (MENU, ITEM, ENTRY, BUTTON, etc.). Dependent on %ReportControl.

%ReportControlTemplate
The name of the control template which populated the control onto the report. Dependent on %ReportControl.

%ReportControlIndent
The control declaration's indentation level in the generated data structure. Dependent on %ReportControl.

%ReportControlInstance
The instance number of the control template which populated the control onto the report. Dependent on %ReportControl.

%ReportControlOriginal
The original field equate label of the control as listed in the control template from which it came. Dependent on %ReportControl.

%ReportControlLabel
The label of the report STRING control. Dependent on %ReportControl.

%ReportControlField
All fields populateed into the LIST, COMBO, or SPIN control. Multi-valued. Dependent on %ReportControl.


Formula Symbols

%Formula	The label of the result field for each formula. Multi-valued. Dependent on %Procedure.

%FormulaDescription
A description of the formula.

%FormulaClass	An identifier for the position in generated source to place the formula.

%FormulaInstance	The control template instance number for a formula whose class has been declared in a control template.

%FormulaExpression
The expression to conditionally evaluate or assign to the result field for each formula. Multi-valued. Dependent on %Formula.

%FormulaExpressionType
Contains =, IF, ELSE, CASE, or OF.  Dependent on %FormulaExpression.

%FormulaExpressionTrue
Contains the line number of the true expression in the generated formula.  Dependent on %FormulaExpression.

%FormulaExpressionFalse
Contains the line number of the false expression in the generated formula.  Dependent on %FormulaExpression.

%FormulaExpressionOf
Contains the line number of the OF expression in the generated formula.  Dependent on %FormulaExpression.

%FormulaExpressionCase
Contains the line number of the assignment in the generated formula.  Dependent on %FormulaExpression.


File Schematic Symbols

 %Primary	The label of a Primary file listed in the procedure's File Schematic for the procedure or a control template used in the procedure.

%PrimaryKey	The label of the access key for the primary file. Dependent on %Primary.

%PrimaryInstance	The control template instance number for which the file is primary. Dependent on %Primary.

%Secondary	The labels of all Secondary files listed in the File Schematic for the procedure or a control template used in the procedure.  Multi-valued. Dependent on %Primary.

%SecondaryTo 	The label of the Secondary or Primary file to which the Secondary file is related (thefile"above" it as listed in the procedure's File Schematic). Dependent on %Secondary.

%SecondaryType	Contains 1:MANY or MANY:1. Dependent on %Secondary.

%OtherFiles	The labels of all Other Data files listed for the procedure. Multi-valued.


File Driver Symbols

%Driver	The names of all registered file drivers.

%DriverDLL	The name of  the driver's .DLL file. Dependent on %Driver.

%DriverLIB	The name of  the driver's .LIB file. Dependent on %Driver.

%DriverDescription	A description of the file driver. Dependent on %Driver.

%DriverCreate	Contains 1 if the driver supports the CREATE attribute. Dependent on %Driver.

%DriverOwner	Contains 1 if the driver supports the OWNER attribute. Dependent on %Driver.

%DriverEncrypt	Contains 1 if the driver supports the ENCRYPT attribute. Dependent on %Driver.

%DriverReclaim	Contains 1 if the driver supports the RECLAIM attribute. Dependent on %Driver.

%DriverMaxKeys	The maximum number of keys the driver supports for each data file. Dependent on %Driver.

%DriverUniqueKey	Contains 1 if the driver supports unique (no DUP  attribute) keys. Dependent on %Driver.

%DriverRequired	Contains 1 if the driver supports the RECLAIM attribute. Dependent on %Driver.

%DriverMemo	Contains 1 if the driver supports MEMO fields. Dependent on %Driver.

%DriverBinMemo	Contains 1 if the driver supports the BINARY attribute on MEMO fields. Dependent on %Driver.

%DriverSQL	Contains 1 if the driver is an SQL driver. Dependent on %Driver.

%DriverType	All data types supported bythe driver. Multi-valued. Dependent on %Driver.

%DriverOpcode	All operations supported bythe driver. Multi-valued. Dependent on %Driver.


Miscellaneous Symbols

%ConditionalGenerate
Contains 1 if the Conditional Generation box is checked on the Application Options window.

%Null	Contains nothing. This is used for comparison to detect empty symbols.

%True	Contains 1.

%False	Contains an empty string ('').

%EOF 	Contains the value that flags the end of file when reading a file with #READ.

%BytesOutput 	Contains the number of bytes written to the current output file. This can be used to detect empty embed points (if no bytes were written, it contained nothing).

%EmbedID	Contains the current embed point's identifying symbol.

%EmbedDescription
The current embed point's description.

%EmbedParameters
The current embed point's current instance, as a comma-delimited list.


Chapter 8 - Annotated Examples

Procedure Template: Window

%StandardWindowCode #GROUP

%StandardWindowHandling #GROUP

%StandardAcceptedHandling #GROUP

%StandardControlHandling #GROUP

Code Template: ControlValueValidation

%CodeTPLValidationCode #GROUP

Control Template: DOSFileLookup

Extension Template: DateTimeDisplay

%DateTimeDisplayCode #GROUP


Procedure Template: Window

#PROCEDURE(Window,'Generic Window Handler'),WINDOW,HLP('~TPLProcWindow')

#LOCALDATA

LocalRequest         LONG,AUTO

OriginalRequest      LONG,AUTO

LocalResponse        LONG,AUTO

WindowOpened         LONG

WindowInitialized    LONG

ForceRefresh         LONG,AUTO

#ENDLOCALDATA

#CLASS('Procedure Setup','Upon Entry into the Procedure')

#CLASS('Before Lookups','Refresh Window ROUTINE, before lookups')

#CLASS('After Lookups','Refresh Window ROUTINE, after lookups')

#CLASS('Procedure Exit','Before Leaving the Procedure')

#PROMPT('&Parameters:', @s255), %Parameters

#ENABLE(%ProcedureType='FUNCTION')

  #PROMPT('Return Value:',FIELD),%ReturnValue

#ENDENABLE

#PROMPT('Window Operation Mode:',DROP('Use WINDOW setting|Normal|MDI|Modal')) %|
,%WindowOperationMode

#ENABLE(%INIActive)

  #BOXED('INI File Settings')

    #PROMPT('Save and Restore Window Location',CHECK) %|
,%INISaveWindow,DEFAULT(1),AT(10,,150)

  #ENDBOXED

#ENDENABLE

#AT(%CustomGlobalDeclarations)

  #INSERT(%StandardGlobalSetup)

#ENDAT

#INSERT(%StandardWindowCode)


%StandardWindowCode #GROUP

#GROUP(%StandardWindowCode)

#IF(NOT %Window)

  #ERROR(%Procedure & ' Error: No Window Defined!')

  #RETURN

#ENDIF

#DECLARE(%FirstField)

#DECLARE(%LastField)

#DECLARE(%ProgressWindowRequired)

#INSERT(%FieldTemplateStandardButtonMenuPrompt)

#INSERT(%FieldTemplateStandardEntryPrompt)

#INSERT(%FieldTemplateStandardCheckBoxPrompt)

#EMBED(%GatherSymbols,'Gather Template Symbols'),HIDE

#INSERT(%FileControlInitialize)

%Procedure %ProcedureType%Parameters

#FOR(%LocalData)

%[20]LocalData %LocalDataStatement

#ENDFOR

#INSERT(%StandardWindowGeneration)

#IF(%ProgressWindowRequired)

#INSERT(%StandardProgressWindow)

#ENDIF

  CODE

  #EMBED(%ProcedureInitialize,'Initialize the Procedure')

  LocalRequest = GlobalRequest

  OriginalRequest = GlobalRequest

  LocalResponse = RequestCancelled

  ForceRefresh = False

  CLEAR(GlobalRequest)

  CLEAR(GlobalResponse)

  #EMBED(%ProcedureSetup,'Procedure Setup')

  IF KEYCODE() = MouseRight

    SETKEYCODE(0)

  END

  #INSERT(%StandardFormula,'Procedure Setup')

  #INSERT(%FileControlOpen)

  #INSERT(%StandardWindowOpening)

  #EMBED(%PrepareAlerts,'Preparing Window Alerts')

  #EMBED(%BeforeAccept,'Preparing to Process the Window')

  #MESSAGE('Accept Handling',3)

  ACCEPT

    #EMBED(%AcceptLoopBeforeEventHandling,'Accept Loop, Before CASE EVENT() handling')

    CASE EVENT()

    #EMBED(%EventCaseBeforeGenerated,'CASE EVENT() structure, before generated code')

    #INSERT(%StandardWindowHandling)

    #EMBED(%EventCaseAfterGenerated,'CASE EVENT() structure, after generated code')

    END

    #EMBED(%AcceptLoopAfterEventHandling,'Accept Loop, After CASE EVENT() handling')

    #SUSPEND

    #?CASE ACCEPTED()

    #INSERT(%StandardAcceptedHandling)

    #?END

    #RESUME

    #EMBED(%AcceptLoopBeforeFieldHandling,'Accept Loop, Before CASE FIELD() handling')

    #SUSPEND

    #?CASE FIELD()

    #EMBED(%FieldCaseBeforeGenerated,'CASE FIELD() structure, before generated code')

    #INSERT(%StandardControlHandling)

    #EMBED(%FieldCaseAfterGenerated,'CASE FIELD() structure, after generated code')

    #?END

    #RESUME

  END

  DO ProcedureReturn

!---------------------------------------------------------------------------

ProcedureReturn ROUTINE

  #INSERT(%FileControlClose)

  #INSERT(%StandardWindowClosing)

  #EMBED(%EndOfProcedure,'End of Procedure')

  #INSERT(%StandardFormula,'Procedure Exit')

  IF LocalResponse

    GlobalResponse = LocalResponse

  ELSE

    GlobalResponse = RequestCancelled

  END

  #IF(%ProcedureType='FUNCTION')

  RETURN(%ReturnValue)

  #ELSE

  RETURN

  #ENDIF

!---------------------------------------------------------------------------

InitializeWindow ROUTINE

  #EMBED(%WindowInitializationCode,'Window Initialization Code')

  DO RefreshWindow

!---------------------------------------------------------------------------

RefreshWindow ROUTINE

  IF %Window{Prop:AcceptAll} THEN EXIT.

  #EMBED(%RefreshWindowBeforeLookup,'Refresh Window routine, before lookups')

  #INSERT(%StandardFormula,'Before Lookups')

  #INSERT(%StandardSecondaryLookups)

  #INSERT(%StandardFormula,'After Lookups')

  #EMBED(%RefreshWindowAfterLookup,'Refresh Window routine, after lookups')

  #EMBED(%RefreshWindowBeforeDisplay,'Refresh Window routine, before DISPLAY()')

  DISPLAY()

  ForceRefresh = False

!---------------------------------------------------------------------------

SyncWindow ROUTINE

  #EMBED(%SyncWindowBeforeLookup,'Sync Record routine, before lookups')

  #INSERT(%StandardFormula,'Before Lookups')

  #INSERT(%StandardSecondaryLookups)

  #INSERT(%StandardFormula,'After Lookups')

  #EMBED(%SyncWindowAfterLookup,'Sync Record routine, after lookups')

!---------------------------------------------------------------------------

#EMBED(%ProcedureRoutines,'Procedure Routines')


%StandardWindowHandling #GROUP

#GROUP(%StandardWindowHandling)

#FOR(%WindowEvent)

  #SUSPEND

#?OF EVENT:%WindowEvent

  #EMBED(%WindowEventHandling,'Window Event Handling'),%WindowEvent

  #CASE(%WindowEvent)

  #OF('OpenWindow')

  IF NOT WindowInitialized

    DO InitializeWindow

  END

    #IF(%FirstField)

  SELECT(%FirstField)

    #ENDIF

  #OF('GainFocus')

  ForceRefresh = True

  IF NOT WindowInitialized

    DO InitializeWindow

    WindowInitialized = True

  ELSE

    DO RefreshWindow

  END

  #ENDCASE

  #RESUME

#ENDFOR

#SUSPEND

#?ELSE

  #EMBED(%WindowOtherEventHandling,'Other Window Event Handling')

#RESUME


%StandardAcceptedHandling #GROUP

#GROUP(%StandardAcceptedHandling)

#FOR(%Control),WHERE(%ControlMenu)

  #FIX(%ControlEvent,'Accepted')

  #MESSAGE('Control Handling: ' & %Control,3)

  #SUSPEND

#?OF %Control

  #EMBED(%ControlPreEventHandling,'Control Event Handling, before generated code') %|
 ,%Control,%ControlEvent

  #INSERT(%FieldTemplateStandardHandling)

  #EMBED(%ControlEventHandling,'Internal Control Event Handling')  %|
 ,%Control,%ControlEvent,HIDE

  #EMBED(%ControlPostEventHandling,'Control Event Handling, after generated code') %|
 ,%Control,%ControlEvent

  #RESUME

#ENDFOR


%StandardControlHandling #GROUP

#GROUP(%StandardControlHandling)

#FOR(%Control),WHERE(%Control)

  #MESSAGE('Control Handling: ' & %Control,3)

  #SUSPEND

#?OF %Control

  #EMBED(%ControlPreEventCaseHandling,'Control Handling, before event handling') %|
,%Control

  #?CASE EVENT()

    #IF(NOT %ControlMenu)

      #FOR(%ControlEvent)

        #SUSPEND

  #?OF EVENT:%ControlEvent

    #EMBED(%ControlPreEventHandling,'Control Event Handling, Before Generated %|
Code'),%Control,%ControlEvent

    #INSERT(%FieldTemplateStandardHandling)

    #EMBED(%ControlEventHandling,'Internal Control Event Handling') %|

,%Control,%ControlEvent,HIDE

    #EMBED(%ControlPostEventHandling,'Control Event Handling, After Generated %|

Code'),%Control,%ControlEvent

        #RESUME

      #ENDFOR

    #ELSE

  #?OF EVENT:Accepted

    #ENDIF

    #SUSPEND

  #?ELSE

    #EMBED(%ControlOtherEventHandling,'Other Control Event Handling'),%Control

  #RESUME

  #?END

  #EMBED(%ControlPostEventCaseHandling,'Control Handling, after event handling') %|
,%Control

  #RESUME

#ENDFOR


Code Template: ControlValueValidation

#CODE(ControlValueValidation,'Control Value Validation')

  #RESTRICT

    #CASE(%ControlType)

    #OF('ENTRY')

    #OROF('SPIN')

    #OROF('COMBO')

      #CASE(%ControlEvent)

      #OF('Accepted')

      #OROF('Selected')

        #ACCEPT

      #ELSE

        #REJECT

      #ENDCASE

    #ELSE

      #REJECT

    #ENDCASE

  #ENDRESTRICT

#DISPLAY('This Code Template is used to perform a control value')

#DISPLAY('validation.  This Code Template only works for')

#DISPLAY('the Selected or Accepted Events for an Entry Control.')

#DISPLAY('')

#PROMPT('Lookup Key',KEY),%LookupKey,REQ

#PROMPT('Lookup Field',COMPONENT),%LookupField,REQ

#PROMPT('Lookup Procedure',PROCEDURE),%LookupProcedure

#DISPLAY('')

#DISPLAY('The Lookup Key is the key used to perform the value validation.')

#DISPLAY('If the Lookup Key is a multi-component key, you must insure that')

#DISPLAY('other key elements are primed BEFORE this Code Template is used.')

#DISPLAY('')

#DISPLAY('The Lookup field must be a component of the Lookup Key.  Before')

#DISPLAY('execution of the lookup code, this field will be assigned the value of')

#DISPLAY('the control being validated, and the control will be assigned the value')

#DISPLAY('of the lookup field if the Lookup procedure is successful.')

#DISPLAY('')

#DISPLAY('The Lookup Procedure is called to let the user to select a value. ')

#DISPLAY('Request upon entrance to the Lookup will be set to SelectRecord, and ')

#DISPLAY('successful completion is signalled when Response = RequestCompleted.')

#IF(%ControlEvent='Accepted')

 IF %Control{PROP:Req} = False AND NOT %ControlUse #<! If not required and empty

ELSE

 #INSERT(%CodeTPLValidationCode)

END

#ELSIF(%ControlEvent='Selected')

 #INSERT(%CodeTPLValidationCode)

#ELSE

  #ERROR('This Code Template must be used for Accepted or Selected Events!')

#ENDIF


%CodeTPLValidationCode #GROUP

#GROUP(%CodeTPLValidationCode)

 %LookupField = %ControlUse                        #<! Move value for lookup

#FIND(%Field,%LookupField)                         #! FIX field for lookup

 GET(%File,%LookupKey)                             #<! Get value from file

 IF ERRORCODE()                                    #<! IF record not found

   GlobalRequest = SelectRecord                    #<! Set Action for Lookup

   %LookupProcedure                                #<! Call Lookup Procedure

   LocalResponse = GlobalResponse                  #<! Save Returned Action

   GlobalResponse = RequestCancelled               #<! Clear the Action Value

   IF LocalResponse = RequestCompleted             #<! IF Lookup successful

     %ControlUse = %LookupField                    #<! Move value to control field

#IF(%ControlEvent='Accepted')                      #! IF a Post-Edit Validation

   ELSE                                            #<! ELSE (IF Lookup NOT...)

     SELECT(%Control)                              #<! Select the control

     CYCLE                                         #<! Go back to ACCEPT

#ENDIF                                             #! END (IF a Pre-Edit...)

   END                                             #<! END (IF Lookup successful)

#IF(%ControlEvent='Selected')                      #! IF a Pre-Edit Validation

   SELECT(%Control)                                #<! Select the control

#ENDIF                                             #! END (IF a Pre-Edit...)

 END                                               #<! END (IF record not found)


Control Template: DOSFileLookup

#CONTROL(DOSFileLookup,'Lookup a DOS file name'),WINDOW

CONTROLS

  	BUTTON('...'),AT(,,12,12),USE(?LookupFile)

END

#BOXED('DOS File Lookup Prompts')

  #PROMPT('File Dialog Header:',@S60),%DOSFileDialogHeader,REQ,DEFAULT('Choose a File')

  #PROMPT('DOS FileName Variable:',FIELD),%DOSFileField,REQ

  #PROMPT('Default Directory:',@S80),%DOSInitialDirectory

  #PROMPT('Variable File Mask',CHECK),%DOSVariableMask

  #ENABLE(%DOSVariableMask)

    #PROMPT('Variable Mask Value:',FIELD),%DOSVariableMaskValue

  #ENDENABLE

  #ENABLE(NOT %DOSVariableMask)

    #PROMPT('File Mask Description:',@S40),%DOSMaskDesc,REQ,DEFAULT('All Files')

    #PROMPT('File Mask',@S50),%DOSMask,REQ,DEFAULT('*.*')

    #BUTTON('More File Masks'),MULTI(%DOSMoreMasks,%DOSMoreMaskDesc & ' - ' & %|
%DOSMoreMask)

      #PROMPT('File Mask Description:',@S40),%DOSMoreMaskDesc,REQ

      #PROMPT('File Mask',@S50),%DOSMoreMask,REQ

    #ENDBUTTON

  #ENDENABLE

#ENDBOXED

#LOCALDATA

DOSDialogHeader      CSTRING(40)

DOSExtParameter      CSTRING(250)

DOSTargetVariable    CSTRING(80)

#ENDLOCALDATA

#ATSTART

  #DECLARE(%DOSExtensionParameter)

  #DECLARE(%DOSLookupControl)

  #FOR(%Control),WHERE(%ControlInstance = %ActiveTemplateInstance)

    #SET(%DOSLookupControl,%Control)

  #ENDFOR

  #IF(%DOSVariableMask)

    #SET(%DOSExtensionParameter,%DOSVariableMask)

  #ELSE

    #SET(%DOSExtensionParameter,%DOSMaskDesc & '|' & %DOSMask)

    #FOR(%DOSMoreMasks)

      #SET(%DOSExtensionParameter,%DOSExtensionParameter & '|' & %DOSMoreMaskDesc %|
& '|' & %DOSMoreMask)

    #ENDFOR

  #END

#ENDAT

#AT(%ControlEventHandling,%DOSLookupControl,'Accepted')

IF NOT %DOSFileField

  #INSERT(%StandardValueAssignment,'DOSTargetVariable',%DOSInitialDirectory)

ELSE

  DOSTargetVariable = %DOSFileField

END

#INSERT(%StandardValueAssignment,'DOSDialogHeader',%DOSFileDialogHeader)

#INSERT(%StandardValueAssignment,'DOSExtParameter',%DOSExtensionParameter)

IF FILEDIALOG(DOSDialogHeader,DOSTargetVariable,DOSExtParameter,0)

  %DOSFileField = DOSTargetVariable

  DO RefreshWindow

END

#ENDAT


Extension Template: DateTimeDisplay

#EXTENSION(DateTimeDisplay,'Display the date and/or time in the current window') %|
,HLP('~TPLExtensionDateTimeDisplay'),PROCEDURE

#BUTTON('Date and Time Display'),AT(10,,180)

  #BOXED('Date Display...')

    #PROMPT('Display the current day/date in the window',CHECK) %|
,%DisplayDate,DEFAULT(0),AT(10,,150)

    #ENABLE(%DisplayDate)

      #PROMPT('Date Picture:',DROP('October 31, 1959|OCT 31,1959|10/31/59| %|
10/31/1959|31 OCT 59|31 OCT 1959|31/10/59| %|
31/10/1959|Other')),%DatePicture %|
,DEFAULT('October 31, 1959')

      #ENABLE(%DatePicture = 'Other')

        #PROMPT('Other Date Picture:',@S20),%OtherDatePicture,REQ

      #ENDENABLE

      #PROMPT('Show the day of the week before the date',CHECK),%ShowDayOfWeek %|
,DEFAULT(1),AT(10,,150)

      #PROMPT('&Location of Date Display:',DROP('Control|Status Bar')) %|
,%DateDisplayLocation

      #ENABLE(%DateDisplayLocation='Status Bar')

        #PROMPT('Status Bar Section:',@n1),%DateStatusSection,REQ,DEFAULT(1)

      #ENDENABLE

      #ENABLE(%DateDisplayLocation='Control')

        #PROMPT('Date Display Control:',CONTROL),%DateControl,REQ

      #ENDENABLE

    #ENDENABLE

  #ENDBOXED

  #BOXED('Time Display...')

    #PROMPT('Display the current time in the window',CHECK),%DisplayTime %|
,DEFAULT(0),AT(10,,150)

    #ENABLE(%DisplayTime)

      #PROMPT('Time Picture:',DROP('5:30PM|5:30:00PM|17:30|17:30:00| %|
1730|173000|Other')),%TimePicture %|
,DEFAULT('5:30PM')

      #ENABLE(%TimePicture = 'Other')

        #PROMPT('Other Time Picture:',@S20),%OtherTimePicture,REQ

      #ENDENABLE

      #PROMPT('&Location of Time Display:',DROP('Control|Status Bar')) %|
,%TimeDisplayLocation

      #ENABLE(%TimeDisplayLocation='Status Bar')

        #PROMPT('Status Bar Section:',@n1),%TimeStatusSection,REQ,DEFAULT(2)

      #ENDENABLE

      #ENABLE(%TimeDisplayLocation='Control')

        #PROMPT('Time Display Control:',CONTROL),%TimeControl,REQ

      #ENDENABLE

    #ENDENABLE

  #ENDBOXED

#ENDBUTTON

#ATSTART

  #DECLARE(%TimerEventGenerated)

  #IF(%DisplayDate)

    #DECLARE(%DateUsePicture)

    #CASE(%DatePicture)

    #OF('10/31/59')

      #SET(%DateUsePicture,'@D1')

    #OF('10/31/1959')

      #SET(%DateUsePicture,'@D2')

    #OF('OCT 31,1959')

      #SET(%DateUsePicture,'@D3')

    #OF('October 31, 1959')

      #SET(%DateUsePicture,'@D4')

    #OF('31/10/59')

      #SET(%DateUsePicture,'@D5')

    #OF('31/10/1959')

      #SET(%DateUsePicture,'@D6')

    #OF('31 OCT 59')

      #SET(%DateUsePicture,'@D7')

    #OF('31 OCT 1959')

      #SET(%DateUsePicture,'@D8')

    #OF('Other')

      #SET(%DateUsePicture,%OtherDatePicture)

    #ENDCASE

  #ENDIF

  #IF(%DisplayTime)

    #DECLARE(%TimeUsePicture)

    #CASE(%TimePicture)

    #OF('17:30')

      #SET(%TimeUsePicture,'@T1')

    #OF('1730')

      #SET(%TimeUsePicture,'@T2')

    #OF('5:30PM')

      #SET(%TimeUsePicture,'@T3')

    #OF('17:30:00')

      #SET(%TimeUsePicture,'@T4')

    #OF('173000')

      #SET(%TimeUsePicture,'@T5')

    #OF('5:30:00PM')

      #SET(%TimeUsePicture,'@T6')

    #OF('Other')

      #SET(%TimeUsePicture,%OtherTimePicture)

    #ENDCASE

  #ENDIF

#ENDAT

#AT(%DataSectionBeforeWindow)

  #IF(%DisplayDate AND %ShowDayOfWeek)

DisplayDayString STRING('Sunday   Monday   Tuesday  WednesdayThursday %|
 Friday   Saturday ')

DisplayDayText   STRING(9),DIM(7),OVER(DisplayDayString)

  #ENDIF

#ENDAT

#AT(%BeforeAccept)

  #IF(%DisplayTime OR %DisplayDate)

IF NOT INRANGE(%Window{Prop:Timer},1,100)

  %Window{Prop:Timer} = 100

END

#INSERT(%DateTimeDisplayCode)

  #ENDIF

#ENDAT

#AT(%WindowEventHandling,'Timer')

  #SET(%TimerEventGenerated,%True)

  #IF(%DisplayDate OR %DisplayTime)

#INSERT(%DateTimeDisplayCode)

  #ENDIF

#ENDAT

#AT(%WindowOtherEventHandling)

  #IF(%DisplayDate OR %DisplayTime)

    #IF(NOT %TimerEventGenerated)

IF EVENT() = EVENT:Timer

  #INSERT(%DateTimeDisplayCode)

END

    #ENDIF

  #ENDIF

#ENDAT


%DateTimeDisplayCode #GROUP

#GROUP(%DateTimeDisplayCode)

    #IF(%DisplayDate)

      #IF(%ShowDayOfWeek)

        #CASE(%DateDisplayLocation)

        #OF('Control')

  %DateControl{Prop:Text} = CLIP(DisplayDayText[(TODAY()%%7)+1]) & ', ' &  %|
FORMAT(TODAY(),%DateUsePicture)

  DISPLAY(%DateControl)

        #ELSE

  %Window{Prop:StatusText,%DateStatusSection} = CLIP(DisplayDayText[(  %|
TODAY()%%7)+1]) & ', ' & FORMAT(TODAY(),%DateUsePicture)

        #ENDCASE

      #ELSE

        #CASE(%DateDisplayLocation)

        #OF('Control')

  %DateControl{Prop:Text} = FORMAT(TODAY(),%DateUsePicture)

  DISPLAY(%DateControl)

        #ELSE

  %Window{Prop:StatusText,%DateStatusSection} = FORMAT(TODAY(),%DateUsePicture)

        #ENDCASE

      #ENDIF

    #ENDIF

    #IF(%DisplayTime)

      #CASE(%TimeDisplayLocation)

      #OF('Control')

  %TimeControl{Prop:Text} = FORMAT(CLOCK(),%TimeUsePicture)

  DISPLAY(%DateControl)

      #ELSE

  %Window{Prop:StatusText,%TimeStatusSection} = FORMAT(CLOCK(),%TimeUsePicture)

      #ENDCASE

    #ENDIF