ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ PMail v3.0 Programmable Forms ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ To PMail v3.0, a form is simply a resource file containing certain required statements and an arbitrary number of control statements. The format is quite complex, but I make no apology for this - the resulting forms architecture is extremely powerful and rewards the effort taken to create the form. It is possible to use the forms manager in PMail to recreate PMail's own standard editing window, as well as almost any single-screen data entry form imaginable. The forms manager provides access to all the most important PMail features, including address books, user lists, distribution lists and more. Forms are prepared using a text editor such as Brief, DTE or (shudder) DOS EDIT, and are then compiled using the PMail resource compiler, ResCom. Forms are made available to users via the PM-MENU.RSC external interface mechanism in PMail v3.0 - examine the sample PM-MENU.R source file supplied with the PMail archive for more information on this structure. Resources in the file number from 0 and can take the form of several different data structures: a thorough understanding of the data types the forms manager uses is the essential key to being able to use the forms manager effectively. Resource file data structures ----------------------------- The data structures used in forms fall into two general categories - built-in, and user-defined. The built-in data types are special hooks into internal mechanisms used by PMail's underlying user interface code and take a very strict, occasionally abstruse form. Some of the fields in the built-in data types will seem obscure, irrelevant or will simply never be used in the context of the forms manager, a hang-over from their use outside the realm for which they were originally intended. The built-in data types recognized by ResCom are: String, Text, Data, Menu, Block, Dstring, Window, Integer, Struct The other class of data type is the user-defined group. The ResCom resource compiler supports a special type definition mechanism called a typedef which allows arbitrary data structures to be declared and used in resource files. Several user-defined data structures have been developed for use with the Forms manager - these are declared in the file FORMS.RH, which accordingly must be included in every form file's source code using the INCLUDE instruction before the first time any of the data structures are used. The major user-defined structures used in Forms management are: Formtable, popup_menu, line, box, editor, log The co-ordinate scheme ---------------------- Many of the data structures used in forms design refer to a position on the screen: PMail's co-ordinate scheme runs from the top left of the window (at 1,1) to the bottom right. Data types and operators ------------------------ Pegasus Mail is written in the C programming language, and the Resource compiler makes a number of assumptions based on this fact. It also uses a certain number of terms and operators derived loosely from the C language (such as the struct data type, the typedef keyword and the bitwise operators). The resource compiler makes the following assumptions in particular: * Integers are 16-bit signed entities in the range -32768 to 32767. * Strings are arbitrary arrays of ASCII characters terminated with a single ASCII NUL (0) character. The Resource compiler supports extremely simple integer arithmetic expressions evaluated strictly from left to right with no parenthesis operator. It is important to remember this if you use expressions, since what you are used to from C and Pascal will NOT hold true in a resource definition - to the resource compiler, 3 + 4 * 6 = 42. The following arithmetic operators are supported: + - * / - Plus, Minus (binary and unary), Multiply, Divide | - Bitwise OR operator (7 | 7 = 7); & - Bitwise AND operator (128 & 127 = 0) ^ - Bitwise XOR operator (8 ^ 15 = 7) The very first resource in the file (resource 0) must be a STRING resource containing the title of the form. The built-in data structures ---------------------------- String ------ The String data type declares an arbitrary string of ASCII characters of any length. Strings are usually used for single-line text resources such as window titles and default records. Strings can contain any ASCII value except the value zero which is used as a terminator (ResCom supplies the terminator automatically). Strings must be enclosed within quotes (") in the resource source file. Text ---- A text resource is essentially a scaled-up version of a string, intended to be multi-line. Text resources are used for large amounts of textual data such as help screens and formatting records for messages. Text resources can contain any ASCII character except zero, and ResCom will recognize certain "escapes" within strings: \r - replaced with a single carriage return character (13) \n - replaced with a single newline character (10). A newline is all that is required to indicate end of line for those routines in the forms manager which display blocks of text on the display \e - Replaced with the Escape character (27) \t - Replaced with the Tab character (9) \" - Replaced with a single quote character \\ - Replaced with a single virgule ('\') character Data ---- A data resource defines a single data entry point on the screen into which the user can type information. The data record has the following structure: 1: (Integer) X (Horizontal) position of field on screen 2: (Integer) Y (Vertical) position of field on screen 3: (Integer) Maximum width ON SCREEN of the field 4: (Integer) Maximum length of the variable (may be longer than the on-screen width) 5: (Integer) Colour for an active field 6: (Integer) Colour for a non-active field 7: (Integer) Help, or arbitrary ID field for the entry 8: (Integer) The data type of the field. Use the GT_* constants in defines.rh - eg, GT_INTEGER 9: (Integer) Control flags for the entry: OR together the G* constants in defines.rh - eg GEND, GSECRET Values 5, 6 and 9 are sensibly defaulted if 0. All other fields should have non-zero values, and have no defaults. The help value is always ignored by the forms manager and should be zero, since it is replaced by the help value defined in the formtabl record for the form. Menu ---- The menu data structure defines a menu with scrolling lightbar and keystroke selection. In terms of the forms manager a menu record is always used in association with the popup_menu user-defined data type and a menu cannot appear on its own. The menu type consists of a header followed by an array of menu records. The header has up to five integer values: 1: The total number of entries in the menu (must be < 24) 2: The menu mode (any of the M* constants in defines.rh ORed) 3: The offset of the default choice in the menu (starting from 0) 4: The colour of a normal entry 5: The colour of a selected entry All the header values except 1 are sensibly defaulted A menu record describes on entry in the menu: it is built as follows: 1: (Integer) The X (horizontal) position of the item 2: (Integer) The Y (vertical) position of the item 3: (Integer) An optional help or ID value for the item 4: (Char) The keystroke which selects this item 5: (Integer) The value to return if this item is selected 6: (String) The text to display for the choice No item in a menu record is defaulted. Within the structure of the forms manager the Y and help values are always ignored. Block ----- A block is a set of strings displayed at the same X position on the screen, with the Y position incrementing with each string. Block definitions are as follows: 1: (Integer) X (horizontal) position for block 2: (Integer) Initial Y (vertical) position for block 3: (Integer) Colour/mode word. OR together colours from defines.rh, and optionally OR position modifiers (such as wcentre, wadjacent). 4...n: The strings to display. To define a colour for a block you will usually combine a foreground colour and a background colour using the Resource compiler's OR operator ('|') - so for example, to create a block of text which is presented as white on blue you would use "WHITE | BBLUE". If you give only a foreground colour, the default background colour of the window will be used for the text. Text can be centred within the window by combining the "wcentre" attribute with the colour integer using the OR operator. So, to display a block of text in Yellow on Light Grey centred in the current window, you would use the expression "YELLOW | BLIGHTGREY | wcentre". American users: please notice the English spelling of "Grey" and "Centre" - you may wish to change these in DEFINES.RH if you are more comfortable with the US spelling. Colour changes within strings: you can change between bright and normal video in mid-string by embedding Ctrl-A (ASCII 001) characters in the string. Each time a Ctrl-A is encountered the brightness mode is toggled. Embedding Ctrl-B characters toggles between normal and reverse video. Dstring ------- A dstring is a single-string version of a block. The X, Y and Attribute integers are identical but only one string may be provided. Dstrings load and display faster than blocks. Window ------ The Window is the basic screen unit in PMail. Windows have local co-ordinate schemes starting at 1,1 for the top-left corner and preserve the screen beneath them, restoring it when they close. All forms in PMail must appear in a window: a form with no F_WINDOW resource is regarded by the forms manager as a template record for a standard editing screen. The Window data structure looks like this: 1: (Integer) X (Horizontal) position of window on screen 2: (Integer) Y (Vertical) position of window on screen 3: (Integer) Width of the window 4: (Integer) Depth of the window 5: (Integer) Colour and characteristics of window frame - OR with colour and w* constants in defines.rh, for example "wzip | BBLUE | WHITE". 6: (Integer) Default text colour/attribute in window 7: (Integer) Default fill character for window 8: (Integer) Linestyle for window frame - use the B* constants in defines.rh - eg, BSINGLE, BDOUBLE 9: (String) Title for the window (maximum 40 characters) Values 5, 6, 7 and 8 are sensibly defaulted if 0. Integer ------- Almost never used in forms, this data type declares a single integer value expressed in decimal form. Struct ------ Almost never used in forms, this data type allows you to agglomerate completely arbitrary data with no predefined format. Its use is not described in this document. The user-defined data types --------------------------- The forms manager uses the following data types defined in FORMS.RH to create the data structures necessary to present a form. Formtable --------- The most important single data type in a form, the formtable defines the order of data entry in the form and gives the forms manager the means to associate individual resources in the form with the various components of the message the form generates. The formtable resource must ALWAYS be the very last resource in the resource file, and is an array of an arbitrary number of structures consisting of six integers arranged as follows: 1: Resource number of the entry associated with this item. Since the resource compiler expects resources to be named, you can use the name you gave the resource in this field. It is possible to use a resource ID of 0, usually when you want to initialize a field in the message without any associated user intervention. 2: Correlation (see below) 3: Resource number of the help for this entry; must be text type. 4: Validation: for future use - not used in this release. 5: Text resource containing the item's status line text (0 for none) 6: Default: for booleans, 1/0; for ints/strings; resource ID The correlation value is used to tell the forms manager what the item represents in e-mail terms, and must be selected from the following list: F_TO Message's To: field F_SUBJECT Message's Subject: field F_CC Message's CC: field F_BCC Message's BCC: field F_REPLY_TO Message's Reply-to: field F_READING Message's Reading confirmation flag F_DELIVER Message's delivery confirmation flag F_NOSIG Message's "omit signature" flag F_ENCRYPT Message's encrypt flag F_KEY Message's encryption key F_COPYSELF Message's copy-self flag F_MESSAGE Message's text (usually an editor data type) F_ATTACH Message's attachment list F_URGENT Message's "urgent" flag F_STRING User-defined string field (max length 200 chars) F_INTEGER User-defined integer field F_BOOLEAN User-defined boolean (Y/N) field F_SMTP_TEMPLATE Formatting template to produce the output message F_WINDOW The window for the form F_LOG A logging resource F_SERIAL Serial number resource F_STATUS A status area (always a Box data type) A correlation value of 0 is only legal for inert screen drawing elements such as lines, boxes and dstrings; defining a correlation of zero for any other form element will almost certainly result in PMail crashing when you attempt to run the form. The help field in the formtable represents the resource ID of the resource which should be invoked in response to a request for context-sensitive help while this field is active. The validation field will in future versions of PMail allow you to define a set of validation rules which should be applied to the data the user enters. In this release it is unimplemented and should be set to zero. The status field refers to the resource ID of a block data type which should be displayed in the status area of the form when this field is active. Any user-interaction item can have status text, which is enabled by created a resource of type Box in the file and correlating it in the formtable to the F_STATUS correlation value. The Box type defines the bounding area of the status text area. For an example of defining and using status text, see the sample telephone message form provided with PMail 3.0, tphone.r. The default field is the ID of a resource which should be loaded as a default value for the field. For fields where the data type is a Boolean value (yes or no) the default field is either 0 or 1 depending on the yes or no value of the field. For Integer and String data types the field refers to a resource which must be of string type. While it may seem odd to have a string as a default for an Integer field, this allows environment values such as the date or time to be used as defaults for Integer fields using form substitution (see below). The order in which entries appear in the formtable defines the "tab order" of the form, or the order in which the Forms Manager will process the form's fields. The Forms Manager paints inert screen drawing elements such as lines and boxes in the order they appear in the formtable, which allows you to overlay text and graphic elements by ordering them carefully. Data entry elements such as data fields and popup menus are also processed in the order in which they appear in the formtable. Popup_Menu ---------- The Popup_Menu data type is used to create a popup menu in the form. When the user enters a popup menu field, an arrow will blink next to the field indicating that a menu is available by pressing . If the user presses , the menu will popup and the user will be able to choose from it. The "return value" of the menu, or the value which can be substituted into the message, is the text selected from the menu itself. The Popup_Menu data structure is defined as seven integers arranged as follows: 1: Resource ID of menu (use the name you gave the menu) 2: X-coord. on the screen of the top left of the popup window 3: Y-coord. on the screen of the top left of the popup window 4: X-coord. on the screen where the menu result should display 5: Y-coord. on the screen where the menu result should display 6: Attribute word for the popup menu (colours etc) 7: Attribute word for the menu result display text Line ---- A line resource simply allows you to draw a line on the screen. It consists of five integers and a character arranged as follows: 1: X position of start of line 2: Y position of start of line 3: If non-zero, the width of the line (horizontal) 4: If non-zero, the height of the line (vertical) 5: The colour attributes of the line 6: The character to use to draw the line. The line can be drawn with IBM extended ASCII characters; the ASCII values 196 and 205 draw single and double horizontal lines respectively, while the ASCII values 179 and 186 draw single and double vertical lines respectively. You can, of course, use any character you wish to draw a line except an ASCII NUL (0). Box --- The Box resource draws an unfilled box on the screen using one of several line styles. The resource consists of six integer values organized as follows: 1: X position of top left corner of box 2: Y position of top left corner of box 3: Width (across the screen) of the box in characters 4: Height (down the screen) of the box in characters 5: Line style - select one of the following values BSINGLE - single lines all around BDOUBLE - double lines all around BMIXED - single vertical and double horizontal lines BSOLID - thick lines all around BDOTS - dotted lines all around 6: Attribute word - colours etc. Editor ------ The editor data type allows you to create a rectangular text editor in the form, usually for editing the text of the message. The editor type is defined as eight integers laid out as follows: 1: X co-ordinate of top left corner of editor rectangle 2: Y co-ordinate of top left corner of editor rectangle 3: Width of editor rectangle on screen 4: Depth of editor rectangle on screen 5: Maximum line length in editor (may be wider than width (3) 6: Maximum number of lines of text the editor can accept 7: Maximum number of characters the editor will accept 8: Colour attributes for editor area. Note that the line length may be wider than the width of the editor on screen - if it is, the editor will scroll horizontally when it reaches the right hand edge of the screen rectangle. The maximum size of the text an editor record can accept is 32000 bytes. An editor is almost always associated with the F_MESSAGE correlation in the form table since this is the only correlation which allows more than 200 characters of data. Logfile ------- A log record is a special optional resource which can appear in the form to allow the message to be logged. After the message has been successfully sent, the last thing the Forms Manager does before tidying up and returning control to PMail is to scan the formtable for entries with the correlation set to F_LOG. For each F_LOG entry it finds it expects to find a logfile resource laid out as follows: 1: (string, max 64 characters) the name of the log file 2: (integer) Resource ID of the text logging resource. The filename is the name of the file to which the log information should be appended. If it does not exist, the Forms Manager will create it. In order for this facility to be useful, the logfile must clearly be in a location where the user has write access. The resource ID must refer to a Text resource in the resource file which should be used to format the logging record added to the log file. The same substitution mechanisms used to format the outgoing message (see below) can be used to substitute values from the form into the logging record. Formatting the message for transmission --------------------------------------- Getting the data from the user is only half the work of the Forms Manager - the other half is creating the outgoing message based on that data. When the user has accepted the data in the form by pressing Ctrl-Enter or by "dropping through the bottom" of the form, the Forms Manager scans the formtable for an entry where the correlation is set to F_SMTP_TEMPLATE (the name is an anachronism - the same template is used for all message transports). If it does not find one, the entry in the table with the F_MESSAGE correlation is sent unaltered as the body of the message. If an F_SMTP_TEMPLATE correlation is found, however, the Forms Manager expects it to be a text resource which contains the format of the outgoing message body. The formatting template consists of lines of text ending in the \n text escape; embedded in the text lines there will usually be special substitution strings which are replaced by fields from the form or which perform special formatting functions. Anything in the text resource which is not a substitution string is printed literally to the message. Substitution strings are always enclosed in curly brackets ('{' and '}') in the formatting record - so in the line "This is a sample string printed on {rfc-date}\n" there is a stream of regular text which will be printed to the message unaltered, and a single substitution called "rfc-date" which will be replaced by the current date and time in RFC-822 format. Substitution strings are considered to be zero characters wide for formatting purposes, so a formatting string which results in an empty string will introduce no text into the message at all. The following substitution strings can be used in templates, both for logging and for messages: {to} The message's TO: address field {subject} The message's SUBJECT: field {cc} The message's CC: field {bcc} The message's BCC: field {reply-to} The message's REPLY-TO: field {reading} The message's reading confirmation flag (Y or N) {delivery} The message's delivery confirmation flag (Y or N) {no-signature} The message's no-signature flag (Y or N) {encrypt} The message's encryption flag (Y or N) {key} The encryption key for the message {copyself} The message's copy-to-self flag (Y or N) {message} The message's text (the F_MESSAGE correlation) {urgent} The message's urgent flag (Y or N) {field x} The value of item number X in the formtable {rfc-date} The time and date in full RFC-822 format {day} The name of the current day {nday} The number in the month of the current day {month} The name of the current month {nmonth} The number of the current month {year_2} The current year expressed in two digits {year_4} The current year expressing as a full four digits {username} The name of the current user {servername} The name of the server into which the user is logged. {tab x} Pad with spaces to column X across the message {hour} The hour component of the current time {minute} The minute component of the current time {serial file} Serial number resource - see below {domain} The server's Internet name, defined in PCONFIG The {message} substitution is column-sensitive: if it appears at a position indented from the left-hand edge of the template, the entire message text will print starting at that column. This allows you to set a kind of "indented left margin" for the message. The {Serial} substitution allows you to define an automatically incrementing number stored in a writable file on the network. The file parameter to the substitution consists simply of a fully- qualified path in DOS or NetWare format to the file containing the serial number value. The file should contain the serial number as a simple ASCII string on a single line ending with a CR-LF pair - you can create this file using any standard text editor. Note that to be useful the file must be writable by anyone able to use the form; as well, the serial number is read and incremented the moment the Forms Manager encounters the {Serial} substitution, so take care if you use it to initialize a string in the form. There is no provision for "winding back" a serial number if the user aborts the form or if delivery fails. Substitution widths: all substitutions can be given a width in the message by ending them with ":x", where X is the width of the field in which the substituted text should appear. As an example, if you want the current value of item 7 in the formtable to be printed in a field 50 wide, you would use the substitution "{field 7:50}". Items are always left-justified in fields.