Sandbox

From CometWiki

(Difference between revisions)
Jump to: navigation, search
(testing)
 
(3 intermediate revisions not shown)
Line 1: Line 1:
-
C:\My Documents\ABS\EnhPrint.htm
 
-
'''Enhanced Printing Reference'''
 
-
+
XAP Gateway Internals
-
'''Introduction to concepts and terms'''
+
-
'''UNIT OF MEASURE - TWIPS:'''
+
There are 2 major parts to the XAP technology. The first part is what we call the CGI server and the second is what we call the XAP Gateway.
-
Regardless of the nature of the printer being addressed, the pixel resolution used by the windows printer driver is in TWIPS.  1 TWIP is equal to 1/20th of a printer's POINT. 1 POINT is equal to 1/72nd of an inch. Therefore there are 1440 TWIPS per inch or 567 TWIPS per centimeter.  Unless otherwise stated, ALL functions contained herein use TWIPS as the unit of measure.
+
The CGI Server
 +
The CGI server listens on the port configured for it. It expects to receive connections using the http protocol. It then performs the following steps:
 +
    It receives and assembles a whole browser request.
 +
    It parses the individual parts of this request, splitting out the following components:
-
'''PAGE SIZES:'''
+
    The CGI Environment variables.
 +
    Any Cookies that the browser may have sent.
 +
    Any query strings that the browser may have sent.
-
When calculating the dimensions of a printer page, keep in mind that in many cases the entire page is not always printable (HP Laser printers have a 1/4" unprintable area on all four sides).  Therefore, it may be necessary to inquire as to not just the page size, but also the offset from the physical page boundary to the printable page boundary.  See GetPageInfo for additional info.
+
    It then writes these items into a Keyed File* (called the XAP environment file), so that a user program can access them quickly.
 +
        CGI environment variables are written to the keyed file such that the key name is the environment variable name with dots instead of underlines separating words of the name, ie HTTP_USER_AGENT would become HTTP.USER.AGENT.
 +
        Cookie names are preceded with a "C." so that a cookie by the name of "my cookie" would be written as "C.MY COOKIE".
 +
        Likewise, query strings are preceded with a "Q." so that a query string by the name of "credit card number" would be written as "Q.CREDIT CARD NUMBER".
 +
    If an appropriate cookie was present in the request, the CGI server establishes the context data for the connection.
 +
    It then launches the Internet Basic program designated by the SCRIPT.NAME environment variable. The program inherits a connection to the browser through the XAP gateway, any context items established in step 4 above, and the keyed file produced in step 3 above.
-
'''FONTS:'''
+
Note: Any mention of "files" in this document does not necessarily mean "disk files". Files may reside in memory or disk depending on performance/sharing issues.
-
 
+
-
Font sizes are requested in tenth's of a point.  This does not guarantee that the font created is exactly the requested size. It is important to inquire AFTER selecting a font as to the actual size the font mapper created.  Also, when printing text there is usually some additional space (external leading) added between lines. This space is specified by the font designer and should be combined with the font height to determine the height of a line.  See GetFontInfo for additional information.
+
   
   
-
'''MNEMONICS:'''
+
The XAP Gateway
-
Commands are issued to a Windows printer using IB mnemonics.  These commands can be issued directly in the form of a PRINT (list) statement or through a PRINT (format) statement. If the PRINT (list) method is used a (TR) mnemonic must precede all commands in the list.  For example:
+
The XAP Gateway acts in response to commands included in the Internet Basic program launched by the CGI Server. The interface is very easy to learn because it contains relatively few basic commands:
-
 
+
-
+
-
            Using the PRINT (list) method
+
-
                        PRINT (Lun) (TR);(Move To = X1, Y1);(Line To = X2, Y2)
+
-
 
+
-
+
-
            Using a Format statement
+
    Write – the program may write data to the browser through the gateway.
-
                        FmtLineAt: Format (Move To = X1, Y1) ;(Line To = X2, Y2)
+
-
          .
+
-
            .
+
-
            .
+
-
            PRINT (Lun, FmtLineAt)
+
    If no previous data has been written to the XAP Gateway, the XAP Gateway will generate a standard HTML header before sending the data to the browser. The program is free to modify this behavior through a control explained below. Otherwise, the data will be sent directly to the browser. All data is buffered for best performance.
 +
    Control – the program may send various controls that cause the gateway to perform actions meaningful to the program. These will be described below.
 +
    Status – the program can get various pieces of information from the gateway by the use of a simple status function.
 +
    Close – When the LUN pointing to the XAP Gateway is closed, all buffered data is sent to the browser, Context data is filed away for future connections, and the connection to the browser is gracefully closed.
 +
    The XAP environment file is also used as part of the interface between the program and the XAP gateway. The program can read browser request data from this file as explained above. It may also write information that will eventually be written to the browser as explained below.
   
   
-
'''USE FILES:'''
+
XAP Gateway Controls
-
            The following files are normally stored in the WDL directory. They are Hyperlinked here for ease of understanding.
+
Most of the power of the XAP Gateway is embedded in the various Controls that the program may send to it. The Control statement looks like a standard function in the language:
 +
Syntax:
 +
Result-string = CONTROL(LUN,Control.String [,EXCP=exception.routine])
-
* COSUTLD.INC          Constants and variables commonly used by other USE files and applications for parameter passing (TRUE, FALSE, NULL, etc).
+
The CONTROL statement sends the specified control-string to the specified logical unit number. In the case of the XAP Gateway, the Logical Unit Number or "LUN" is always 0 (zero).
-
* PTRCTLD.INC          Printer driver function constants (paper sizes, bins, etc.)
+
-
* LOGFNT.IBS            Functions used to manipulate fonts
+
-
* LOGFNT.INC Constants and variables used by #LOGFNT
+
-
* FILFND.IBS              Contains routine for finding DOS filenames for files living in Comet directories
+
-
* FILFND.INC              Constants and variables used by #FILFND
+
-
* DESERVE.INC        Declaratives for Driver Event Server programs
+
 +
The CONTROL statement also reads the result field from the input buffer and places it in the result-string. A plus sign (+) in the first byte of the result-string indicates that the control function was performed successfully. A minus sign (-) in the first byte indicates that the control was not performed successfully. The remaining bytes of the result-string contain text describing the success or failure of the control function.
-
Hyperlinks to detailed explanation of Enhanced Printing Functions
+
The CONTROL statement performs the same function as the following statements:
 +
FILE (LUN) CTL=control-string
-
'''(Draw Bitmap)'''
+
INPUT (LUN) result-string
-
+
-
Draws the bitmap contained in the file (.BMP/.JPG) specified in <FileName> in the rectangle specified by  <Left>, <Top>, <Right>, <Bottom> using the format codes contained in <Flags>.  Scaling factors can be specified in  <ScaleX>, <ScaleY>.
+
-
'''(DrawText)'''
+
Here are the controls that may be sent to the XAP gateway. Where string constants are used in the examples, string expressions may also be used.
-
+
-
Prints the specified text <Printable Text> into the rectangle specified by the coordinates <Left>, <Top>, <Right>, <Bottom> using the format codes specified in <Flags>.
+
-
'''
+
-
(Ellipse)'''
+
-
+
-
Draws an ellipse bound by the rectangle specified by <Left>, <Top>, <Right>, <Bottom> using the currently selected pen and brush.
+
-
'''(GetBkColor)'''
+
    TYPE – sets a MIME type to the browser. As explained above if no TYPE control is sent, the type is assumed to be HTML and the appropriate header is sent to the browser..
-
+
-
Returns the current background color.
+
    Result-string = CONTROL (0,"TYPE 0") notifies the XAP gateway that the program will subsequently write its own MIME type header.
 +
    result-string = CONTROL(0,"TYPE 1") tells the XAP Gateway to set the mime type to "text/html"
 +
    result-string = CONTROL(0,"TYPE 2") tells the XAP Gateway to set the mime type to "text/plain"
 +
    Result-string = CONTROL (0,"TYPE 3") tells the XAP Gateway to set the mime type to "text/plain" and supply automatic carriage return line feeds following every write.
-
'''(GetBkMode)'''
+
    COOKIE – sends a cookie to the browser. This control must be sent before any other data is sent to the browser because the cookie information is part of the header.
-
+
-
Returns the current background mode.
+
    The syntax is as follows:
-
'''(GetFontInfo''' )
+
    A$ = CONTROL (0,'COOKIE cookie-name=cookie-value,time-period')
-
+
-
Returns the font information specified by <ItemCode>.
+
    Where time-period is the specified length of time for the cookie to be stored in the browser.
-
'''(GetFuncResult)'''
+
    The format for time period is:
-
+
-
Request the 4 byte result of the last printer function.
+
    +nM = n minutes into the future
-
'''(GetPageInfo)'''
+
    +nH = n hours into the future
-
+
-
Returns the information specified in <ItemCode> Exactly what information is entered in <ItemCode> and in what format is a mystery.
+
    +nD = n days into the future
-
'''(GetROP2)'''
+
    For example, to make the CUSTOMERNUMBER=123456789 cookie stay in the browser system for 25 days, you would use the following statement:
-
+
-
Returns the current foreground mix mode.
+
    A$ = CONTROL(0,'COOKIE CUSTOMERNUMBER=123456789,+25D')
 +
    REDIRECT – Sends the appropriate commands to the browser so that it will automatically connect to the URL contained in the REDIRECT control. This control must be sent before any other data is sent to the browser because the redirect information is part of the header.
-
'''(GetTextAlign)'''
+
    For example, if you wanted your program to redirect the browser to www.signature.net, you would use the following statement:
-
+
-
Returns the current text alignment mode.
+
    A$ = CONTROL(0,'REDIR http://www.signature.net')
 +
    OPEN – performs a "test open" of the file contained in the control to validate whether it is present. This file may be a template file, html file, image file or any file. The named file is opened, and the handle is saved for further operations using that file.
-
'''(GetTextColor)'''
+
    For example, if you wanted your program to send the image contained in the file "c:\images\logo.jpg" to the browser, you would use the following command:
-
+
-
Returns the current text color.
+
    A$ = CONTROL (0,'OPEN C:\IMAGES\LOGO.JPG')
-
'''(GetTextExtent)'''
+
    After the execution of this control, the result string A$ would contain "+OK" if the file was successfully opened, or "-ERR error opening path" if the file could not be found.
-
+
    SEND – Sends the file referred to in the control to the browser. The file is sent to the browser in the fastest way possible. The SEND control may specify a path pointing to the file to be sent --
-
Measures the size (width and height) of the specified <Printable Text>.
+
    A$ = CONTROL (0,'SEND C:\IMAGES\LOGO.JPG')
-
'''(LineTo)'''
+
-
+
-
Draws a line using the currently selected pen from the current location pointer to the location specified by <X, Y>.
+
    or optionally, if no path is specified --
-
'''(MoveTo)'''
+
    A$ = CONTROL (0,'SEND')
-
+
-
Moves the current location pointer to the location specified by <X> and <Y>.
+
    the XAP gateway will send a file previously opened by the OPEN control as specified above.
 +
    PUSH – Flushes the output buffer contained in the XAP gateway to the browser for debugging purposes or to implement "server push" actions.
 +
    MERGE – Merges data from a template file named in the control with data contained in the CGI Environment file, Then sends the resultant merged data stream to the browser. Merge is the most powerful of all of the controls. It merges selected data from the CGI environment file with a template file (or a section of a template file) and sends the resulting web page to the browser.
-
'''(Rectangle)'''
+
The syntax for the MERGE control may take several forms. The general description of the merge command is:
-
+
-
Draws a the rectangle specified by <Left>, <Top>, <Right>, <Bottom> using the currently selected pen and brush.
+
A$ = CONTROL (LUN,’MERGE Path-name |"." [,SECTION Section-name])
-
'''(RoundRect)'''
+
As you can see, the MERGE command takes an optional path name and an optional section name. Here is how Comet processes a MERGE command.
-
+
-
Draws a rectangle with corners rounded using the ellipse specified by  <CornerWidth> and <CornerHeight> at the location specified by <Left>, <Top>, <Right>, <Bottom> using the currently selected pen and brush.
+
        Comet first determines if there is a path name specified, or a dot, meaning use the last file either opened from a previous MERGE command or an OPEN command. If a Path name was supplied, that file is opened.
 +
        Comet then determines whether a SECTION name was supplied. If a Section name was specified, Comet searches the file for a string of characters such as:
-
'''(SelectFont)'''
+
        <!—BEGIN Section-nameà
-
+
-
Selects the font specified by the <LogFont> structure.
+
        If found, the file pointer is set just beyond this string, causing Comet to read data from this point on. If no such string was found, Comet starts reading the e file from the first byte.
 +
        If a section was specified in the control statement, Comet then searches the file for an end-of-section string. This string is of the form:
-
'''(SelectHatchBrush)'''
+
        <!—END Section-nameà
-
+
-
Selects the hatched brush described <Style> and <Red>, <Green>, <Blue>.
+
        If such a string is found, a pointer is set to the character just prior to the opening character of this string. This pointer marks the last character sent from the file on this Merge command. If no such string is found, the ending pointer is set to the last character of the file.
-
'''
+
        Comet then searches the file starting at the current file pointer for an indicator marking data to be inserted. At the current time, this marker is a pair of stars (**).
-
(SelectPen)'''
+
        If such a marker is found, all data is streamed from the file to the Browser up to this marker.
-
+
        Comet then searches the file for an ending indicator. At the current time this is also a pair of stars (**). If such a marker is found, all characters between the beginning and ending markers (including the **’s) is assembled into a Key to be used in a keyed read on LUN 1. If the read is successful, the data record resulting from this keyed read is streamed to the browser.
 +
        If the keyed read was unsuccessful, the first * of the beginning marker is sent to the browser and the process is repeated from step d. above.
 +
        Once the entire file or section has been streamed to the browser, the control command is completed.
-
Selects the pen described by <Style>, <Width> and <Red>, <Green>, <Blue>.
+
It should be noted that the syntax used for the begin and end indicators denotes HTML comments. Thus the markers would not be visible in the html page if the browser displayed them.
-
'''(SelectSolidBrush)'''
+
It should also be noted that even though the operations above look like operations on a file, the data is really read into memory and streamed from there for performance reasons.
-
+
-
Selects the solid brush described <Red>, <Green>, <Blue>.
+
Following are two lessons from a tutorial which deal with the MERGE command:
-
'''(SelectSysFont)'''
+
This lesson and the next one are the most important lessons in the eComet tutorial. In this lesson, you will learn how to merge live Comet data into stored HTML documents.
-
+
-
Selects the SYSTEM font specified by <FontNumber>.
+
Let us repeat that last part (for emphasis): you can merge live Comet data into a stored HTML document in order to make a dynamic return page.
-
 
+
-
'''(SetBkColor)'''
+
-
+
-
 
+
-
Sets the current background color as specified by <Red>, <Green>, <Blue>.
+
-
 
+
-
'''(SetBkMode )'''
+
-
+
-
 
+
-
Sets the background mode specified by <Mode>.
+
-
 
+
-
'''(SetOrientation)'''
+
-
+
-
 
+
-
Sets the paper orientation contained in <Mode>.
+
-
 
+
-
'''(SetROP2 )'''
+
-
+
-
 
+
-
Sets the current foreground mix mode.
+
-
 
+
-
'''(SetTextAlign)'''
+
-
+
-
 
+
-
Sets the text alignment mode to that specified by <Flags>.
+
-
 
+
-
'''(SetTextColor)'''
+
-
+
-
 
+
-
Sets the current text color as specified by <Red>, <Green>, <Blue>.
+
-
 
+
-
'''(TextOut)'''
+
-
+
-
 
+
-
Prints the specified <Printable Text> at the location specified by <X> and <Y>.
+
-
 
+
-
'''LineSpacing'''
+
-
+
-
 
+
-
Adjusts the line spacing for the current font to <LinesPerInch>.  Due to differences in font design, when you select a font you may get the desired font but not the desired spacing (external leading may have been applied). This function provides a line spacing override that will adjust the font to fit your page requirements.
+
-
 
+
-
'''PopFont'''
+
-
+
-
 
+
-
Restores a font previously saved with a PushFont. (See PushFont).
+
-
 
+
-
'''PushFont'''
+
-
+
-
 
+
-
Saves the current font on a stack so it can be restored with a corresponding PopFont.  This feature allows a programmer to modify the printer font for a specific purpose and then restore the previous font without knowing how it was selected.
+
   
   
-
+
Here's how it works:
-
'''SelectFont'''
+
-
(SelectFont);<LogFontData>
+
First, create an XAP-ready HTML document. In the locations where you want to include a merge field, surround the field name with double asterisks.
-
            Selects the font specified by the <LogFont> structure.
+
Here's a sample HTML file. We've included one merge field named **TODAY**.
-
+
<HTML>
-
Typically, a user will call GDI.InitLogFont first to set all font fields to their default values, and then modify whichever field needs changing.
+
<HEAD>
-
+
-
Because the font structure consists of MTB strings, the INTEL/INTELD functions must be used to effect any modifications. For an example see the GDI.InitLogFont function in the USE file #LOGFNT.
+
<TITLE>
-
+
Sample merge document
-
Some commonly modified fields are:
+
</TITLE>
-
'''lfHeight$'''        Font size in 10th's of a point (inch/72). The font mapper looks for the largest font that does not exceed the requested size; if there is no such font, it looks for the smallest font available.
+
</HEAD>
-
+
<BODY>
-
'''lfWidth$'''          Specifies the average width, in logical units, of characters in the font.(/lr) If lfWidth is zero, the aspect ratio of the device is matched against the digitization aspect ratio of the available fonts to find the closest match, determined by the absolute value of the difference.
+
This is a sample document.
-
'''lfEscapement$'''  Specifies the angle, in tenths of degrees, of each line
+
Today's date is **TODAY**.
-
of text written in the font (relative to the bottom of the page).
+
</BODY>
-
lfWeight$        Darkness (or lightness) of the characters
+
</HTML>
-
lfItalic$            Specifies an italic font if set to TRUE.
+
For the sake of this example, let's suppose we saved this file on drive C: and named the file TODAY.HTM.
-
lfUnderline$    Specifies an underlined font if set to TRUE.
+
Next, write an Internet Basic program that does two things:
-
lfStrikeOut$    Specifies a strikeout font if set to TRUE.
+
1.Writes the merge field(s) to the CGI Environment File, using the double-asterisk field name as the key
-
lfFaceName$    Desired font face ("Arial", "Courier New", etc.)
+
2.Merges the HTML document with the CGI Environment File via the MERGE command
-
+
-
SelectSysFont
+
-
(SelectSysFont = <FontNumber>)
+
Here's some sample code to show you how this works:
-
            Selects the SYSTEM font specified by <FontNumber>.
+
LENGTH 10 & LOCAL TODAY$
-
+
CGIDATA: FORMAT TODAY$
-
Where:
+
TODAY$ = '06/08/2000'
-
            <FontNumber>          A Number from 0 to 2, corresponding to an entry
+
WRITE (1,CGIDATA) KEY='**TODAY**' ! Write merge field
-
                                                in the COSW.INI [Printer Fonts] section.
+
A$ = CONTROL(0,'MERGE C:\TODAY.HTM') ! Merge the HTML file
-
+
The WRITE statement writes a record to the CGI Environment file (remember, this file is automatically opened on Logical Unit Number 1 when the XAP program is started). The key is the same as the merge field name in the HTML document (i.e.,**TODAY**).
-
Provides a system dependent method for assuring compatible printer output
+
The MERGE command merges the HTML document (C:\TODAY.HTM) with any merge field(s) contained in the CGI Environment File. In this example, there's only one merge field.
-
by allowing the user to choose the system fonts according to what is available on her system.
+
The result is a web page that contains "06/08/2000" in the exact location where "**TODAY**" was contained in the stored document.
-
+
Here are some important notes:
-
Font numbers are defined as follows:
+
The MERGE command is very similar to the SEND command (i.e., it sends a stored document from the eComet system to the browser.
-
+
The merge field(s) can appear anywhere in the stored document. This means that you can merge Comet data into places where you want data to appear, and you can also merge HTML commands into a stored document (to change the appearance of a web page for a particular user, for example).
-
0                    Used for normal printing
+
Here's another example. Remember the program (from Lesson 2) that displayed several Comet system variables? Well, we've rewritten that example using the MERGE command.
-
1                    Used for compact (compressed) printing
+
First, we created an HTML document and included several merge fields. The "raw" document is named systvar.htm. Take a look at the HTML source code and notice the merge fields (**PARTITION** and the others).
-
2                    Used for wide (expanded) printing
+
Next, we created an Internet Basic program that writes the desired merge records to the CGI Environment File. Look at the following source code and notice the WRITE statements.
-
+
-
<Back to Top>
+
-
+
!---------------------------------------------------------------------
-
GetFontInfo
+
-
(GetFontInfo = <ItemCode>)
+
!
-
            Returns the font information specified by <ItemCode>.
+
! *** Main program
-
+
!
-
Where <ItemCode> is:
+
A$ = DSTAT('CL1') ! Refresh TIME$
-
PTR.FONT.HEIGHT - Specifies the height (ascent + descent) of characters
+
!
-
+
OPEN (10) '#CGICTRL' ! Open CGI control file
-
PTR.FONT.EXTLEADING - Specifies the amount of extra leading (space) that
+
READ (10,HTMLPATH) KEY='**HTMLPATH**' ! Get HTML path
-
the application adds between rows. Since this area
+
HTMLPATH$ = STRIP(HTMLPATH$) ! Strip blanks
-
is outside the font, it contains no marks and is
+
CLOSE (10)
-
not altered by text output calls in either OPAQUE
+
!
-
or TRANSPARENT mode. May be 0.
+
! *** Write merge fields to CGI file
-
+
!
-
PTR.FONT.AVECHARWIDTH - Specifies the average width of characters in the
+
OUTPUT$ = PARTITION$ ! Partition #
-
font (generally defined as the width of the letter x). This value
+
WRITE (1,OUTPUT) KEY='**PARTITION**' ! Write record
-
does not include the overhang required for bold or italic characters.
+
!
-
+
OUTPUT$ = TIME$ ! System time
-
PTR.FONT.MAXCHARWIDTH - Specifies the width of the widest character in the font.
+
WRITE (1,OUTPUT) KEY='**TIME**' ! Write record
-
+
!
-
PTR.FONT.WEIGHT - Specifies the weight of the font.
+
OUTPUT$ = DATE$ ! System date
-
+
-
<Back to Top>
+
-
+
-
Color
+
-
+
WRITE (1,OUTPUT) KEY='**DATE**' ! Write record
-
(SetTextColor = <Red>, <Green>, <Blue>)
+
!
-
            Sets the current text color as specified by <Red>, <Green>, <Blue>.
+
OUTPUT$ = LONGYEAR$ ! 4-digit year
-
+
WRITE (1,OUTPUT) KEY='**LONGYEAR**' ! Write record
-
(SetBkColor = <Red>, <Green>, <Blue>)
+
!
-
            Sets the current background color as specified by <Red>, <Green>, <Blue>.
+
OUTPUT$ = VERSION$ ! Version #
-
Colors are represented by 3 (Red, Green, Blue) color intensity values, each
+
WRITE (1,OUTPUT) KEY='**VERSION**' ! Write record
-
ranging in value from 0 (no color - black) to 255 (max color - white).
+
!
-
+
! *** Merge the CGI file with the HTML file, and send the results
-
<Red>            ! Specifies the amount of RED
+
!
-
<Green>        ! Specifies the amount of GREEN
+
MERGESTRING$ = 'MERGE '+HTMLPATH$ + 'systvar.htm' ! Build MERGE string
-
<Blue>            ! Specifies the amount of BLUE
+
A$ = CONTROL(0,MERGESTRING$) ! Merge
-
+
!
-
(GetTextColor)
+
KILL PARTITION$
-
            Returns the current text color.
+
Note
-
+
The MERGE command may also be executed via the FILE statement, as shown here:
-
(GetBkColor)
+
FILE (0) CTL='MERGE ______________'
-
            Returns the current background color.
+
HTML file name
-
The return value for this function is obtained by requesting the result of the previous
 
-
 
-
operation with (GetFuncResult) and then performing an input of the 4 byte return value
 
   
   
-
<Back to Top>
 
-
+
In Lesson 3, we showed you how to send multiple stored documents to the web browser with the SEND command. The MERGE command can be used to do the same thing.
-
BKMode
+
-
+
-
(SetBkMode = <Mode>)
+
-
            Sets the background mode specified by <Mode>.
+
For example, here's a program segment that sends 3 stored documents via the MERGE command:
-
The background mode defines whether the system removes existing background colors on the drawing surface before drawing text, hatched brushes, or any pen style that is not a solid line.
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3x.htm')
-
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3y.htm')
-
Where <Mode> is:
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3z.htm')
-
BKM.OPAQUE        Background is filled with the current background color before the text, hatched brush, or pen is drawn. This is the default background mode.
+
Please note these differences between SEND and MERGE:
-
+
The MERGE command invokes the merge feature, while the SEND command does not
-
BKM.TRANSPARENT Background is not changed before drawing.
+
There's another very important difference between SEND and MERGE. The MERGE command can send sections of an HTML document. The sections are user-defined portions of the HTML file.
-
+
These sections are defined via the HTML comment tag and some XAP-specific keywords within each comment. Here's an example:
-
(GetBkMode)
+
<!--BEGIN ABC123-->
-
            Returns the current background mode.
+
This is a section of HTML code. This
-
+
section includes text as well as HTML
-
The return value for this function is obtained by requesting the result of the previous
+
<font color="ff0000">commands</font>.
-
operation with (GetFuncResult) and then performing an input of the 4 byte return value
+
<p>
-
+
This whole section is defined by the
-
+
-
<Back to Top>
+
-
+
BEGIN and END statements, which are
-
Printing Text
+
-
+
contained within HTML comments.
-
(SetTextAlign = <Flags>)
+
<!--END ABC123-->
-
            Sets the text alignment mode to that specified by <Flags >.
+
The browser ignores the BEGIN and END statements, since they're contained within HTML comments. However, the MERGE command uses the BEGIN and END commands to defined a section of the file. This section is called ABC123.
-
+
Assume that you saved the above HTML file as:
-
The TextOut function uses these flags when positioning a string of text on a display or device. The flags specify the relationship between a specific point and a rectangle that bounds the text. The coordinates of this point are passed as parameters to the TextOut member function. The rectangle that bounds the text is formed by the adjacent character cells in the text string.
+
c:\ecomet\html\test.htm
-
+
Here's how you would send this section of the HTML file via the MERGE command:
-
The flags specify the relationship between a point and a rectangle that bounds the text. The point may be either the current position or the coordinates specified by a text-output function. The rectangle that bounds the text is defined by the adjacent character cells in the text string. The <Flags> parameter can be one or more flags from the following three categories. Choose only one flag from each category.
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\test.htm SECTION ABC123')
-
+
Some important notes:
-
The first category affects text alignment in the x-direction:
+
    There is no limit to the number of sections you may define
-
+
    The first section in an HTML document does not require a <!--BEGIN--> statement
-
TA.CENTER              Aligns the point with the horizontal center of the bounding rectangle.
+
    The final section does not require an <!--END--> statement.  
-
+
    No blank spaces are allowed at the beginning of these commands (i.e., inside of the "<!--BEGIN" string and the "<!--END" string)
 +
    Each section must have an alphanumeric section label (currently a maximum of 28 characters per label)
 +
    When using sections in an HTML document, make sure all of your HTML code and text is between a <!--BEGIN--> statement and an <!--END--> statement. Content outside of those boundaries will not be sent to the browser.
-
TA.LEFT                    Aligns the point with the left side of the bounding rectangle.
+
The next example is based on the sample program you saw in Lesson 4. In this case, we will be merging data from a Comet data file, the DLRS file, into a stored HTML document.
-
This is the default setting.
+
The HTML document will be divided into 3 sections, named TOP, MIDDLE, and BOTTOM.
-
TA.RIGHT                  Aligns the point with the right side of the bounding rectangle.
+
The TOP section will contain the initial HTML commands and text for the top portion of the web page. Since this is the first section, we don't need a <!--BEGIN--> statement.
-
+
<HTML>
-
The second category affects text alignment in the y-direction:
+
<HEAD>
-
+
<TITLE>
-
TA.BASELINE          Aligns the point with the base line of the chosen font.
+
Comet Dealers
-
TA.BOTTOM              Aligns the point with the bottom of the bounding rectangle.
+
</TITLE>
-
TA.TOP                      Aligns the point with the top of the bounding rectangle. (default)
+
</HEAD>
-
+
<BODY BGCOLOR="FFFFFF">
-
The third category determines whether the current position is updated when text is written:
+
<CENTER>
-
+
<H1>
-
TA.NOUPDATECP  Does not update the current position after each call to a text-output function. This is the default setting.
+
Comet Dealers
-
+
</H1>
-
TA.UPDATECP        Updates the current x-position after each call to a text-output function.
+
</CENTER>
-
The new position is at the right side of the bounding rectangle for the text. When this flag is set, the coordinates specified in calls to the TextOut member function are ignored.
+
<HR>
-
+
-
<Back to Top>
+
-
+
Here is a list of Comet dealers.
-
(GetTextAlign)
+
This data is contained in a
-
            Returns the current text alignment Flags.  The resulting flags are  returned in <LoWord>.
+
Comet keyed file named <B>DLRS</B>.
-
+
The DEMO11B program reads records
-
(GetTextExtent);<Printable Text>
+
from that file and displays the
-
            Measures the size (width and height) of the specified <Printable Text>.
+
complete list of names.
-
The resulting width and height are returned in <LoWord> and <HiWord> (respecively).
+
<P>
-
The return value for this function is obtained by requesting the result of the previous
+
<!--END TOP-->
-
operation with (GetFuncResult) and then performing an input of the 4 byte return value
+
The MIDDLE section will be very short. In this section, we will include a merge field named **DEALER**, followed by a line break tag (<BR>):
-
+
<!--BEGIN MIDDLE-->
-
(TextOut = <X>, <Y>); <Printable Text>
+
**DEALER**
-
            Prints the specified <Printable Text> at the location specified by <X> and <Y>.
+
<BR>
-
Character origins are at the upper-left corner of the character cell. By
+
<!--END MIDDLE-->
-
default, the current position is not used or updated by the function.
+
By itself, the MIDDLE section does not look very impressive. Just wait until you see the way we use Internet Basic to merge data into this section!
-
+
The BOTTOM section will contain the final HTML commands for our sample web page:
-
If an application needs to update the current position when it calls TextOut,
+
<!--BEGIN BOTTOM-->
-
the application can call the SetTextAlign member function with Flags set to
+
</BODY>
-
TA.UPDATECP. When this flag is set, Windows ignores the x and y parameters on
+
</HTML>
-
subsequent calls to TextOut, using the current position instead.
+
<!--END BOTTOM-->
-
+
We'll save the above file and name it:
-
+
-
<Back to Top>
+
-
+
c:\ecomet\html\dealers.htm
-
(DrawText = <Left>, <Top>, <Right>, <Bottom>, <Flags>);<Printable Text>
+
-
Prints the specified text <Printable Text> into the rectangle specified by the    coordinates <Left>, <Top>, <Right>, <Bottom> using the format codes specified in <Flags>.
+
Now all we have to do is write an Internet Basic program that sends the 3 sections (and merged data) to the web browser. The first MERGE command will send SECTION TOP:
-
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\dealers.htm SECTION TOP')
-
This function is used to format text inside the specified rectangle. It formats text by expanding tabs into appropriate spaces, aligning text to the left, right, or center of the rectangle, and breaking text into lines that fit within the rectangle. The type of formatting is specified by <Flags>. The formatting codes can be combined and are specified in <Flags>.
+
The next part of the Internet Basic program will READ data from the DLRS file, WRITE a key to the CGI Environment File, and MERGE SECTION MIDDLE. These steps will be repeated for all of the records in the DLRS file:
-
+
OPEN (10) 'DLRS'
-
DT.TOP                      Specifies top-justified text (single line only).
+
ReadMore:
-
DT.LEFT                    Aligns text flush-left.
+
READ (10,DEALERINFO) EXCP=AllDone
-
DT.CENTER              Centers text horizontally.
+
WRITE (1,DEALERINFO) KEY='**DEALER**'
-
DT.RIGHT                  Aligns text flush-right.
+
A$ = CONTROL(0,'MERGE . SECTION MIDDLE')
-
DT.VCENTER          Specifies vertically centered text (single line only).
+
GOTO ReadMore
-
DT.BOTTOM            Specifies bottom-justified text. This value must be combined with DT.SINGLELINE.
+
Notice that the key value (**DEALER**) matches the merge field in the HTML file.
-
DT.WORDBREAK    Specifies word-breaking. Lines are automatically
+
Also notice that the MERGE command contains a different format than before. If you are merging more than one section of an HTML file, you only have to specify the file name once (on the first MERGE command). After that, you can use the period (.) to represent the HTML file name.
-
broken between words if a word would extend past the edge of the rectangle specified by <Left>, <Top>, <Right>, <Bottom>. A carriage return-line feed sequence will also break the line.
+
The period is both a coding shortcut and a way to get faster performance from the MERGE command. Once an HTML file has been opened and read into memory, there's no need to re-open and re-read it. Thus, the period refers to a document that is already in memory.
-
DT.SINGLELINE      Specifies single line only. Carriage returns and linefeeds do not break the line.
+
The final section the program closes the data file and sends the BOTTOM section of the HTML file:
-
DT.EXPANDTABS  Expands tab characters. The default number of characters per tab is eight.
+
AllDone:
-
DT.TABSTOP          Sets tab stops. The high-order byte of <PtrFlags> is the number of characters for each tab. The default number of characters per tab is eight.
+
CLOSE (10)
-
DT.NOCLIP              Draws without clipping. DrawText is somewhat faster when DT.NOCLIP is used.
+
A$ = CONTROL(0,'MERGE . SECTION BOTTOM')
-
DT.EXTERNALLEADING    Includes the font's external leading in the line height. Normally, external leading is not included in the height of a line of text.
+
KILL PARTITION$
-
DT.CALCRECT        returns the height of the formatted text, but does not draw the text.
+
Here's something to Think About
-
DT.NOPREFIX          Turns off processing of prefix characters. Normally, DrawText interprets the ampersand (&) mnemonic-prefix character as a directive to underscore the character that follows, and the two-ampersand (&&) mnemonic-prefix characters as a directive to print a single
+
As we mentioned above, merge fields can appear anywhere in an HTML file, including HTML commands and parameters. For example, you could include a merge field where you would normally include a hard-coded parameter, as in the BACKGROUND portion of the BODY tag:
-
ampersand. By specifying DT.NOPREFIX, this processing is turned off.
+
<BODY BACKGROUND="**PICTURE**">
-
DT.INTERNAL          Uses the system font to calculate text metrics.
+
Then, from within an Internet Basic program, you could define a specific background graphic simply by writing the **PICTURE** key to the CGI Environment File and merging it with your HTML file.
-
DT.EDITCONTROL Duplicates the text-displaying characteristics of a
+
PICTURE: FORMAT PICTURE$
-
multiline edit control. Specifically, the average
+
.
-
character width is calculated in the same manner as
+
PICTURE$ = "SAMPLE.GIF"
-
for an edit control, and the function does not
+
WRITE (1,PICTURE) KEY="**PICTURE**"
-
display a partially visible last line.
+
A$ = CONTROL(0,'MERGE HTML-document SECTION section-name')
-
DT.PATH.ELLIPSIS See DT.END.ELLIPSIS Below
+
You could use this technique to good effect, for example, by displaying a unique background graphic for each customer who uses your web site. You could determine who's who by reading a persistent cookie (assuming you had already sent one to the browser), getting unique data from that cookie (a customer number, let's say), and using that data to read a GIF or JPG file name from a keyed file. Then you could write that file name to the CGI Environment File and merge it into an HTML file, as shown in the code segment above. This would result in a very personalized web site for each of your customers.
-
 
+
-
DT.END.ELLIPSIS  Replaces part of the given string with ellipses, if necessary,
+
-
 
+
-
so that the result fits in the specified rectangle. The given
+
-
 
+
-
string is not modified unless the DT.MODIFYSTRING flag
+
-
 
+
-
is specified.
+
   
   
-
You can specify DT.END.ELLIPSIS to replace characters
+
*Keyed Files
-
at the end of the string, or DT.PATH.ELLIPSIS to replace
+
Keyed files provide direct access to the data records.
-
characters in the middle of the string. If the string contains
+
Comet stores data for keyed files in two DOS disk files. One DOS file stores the data records in their entered order, and a "key tree" file stores the record keys in ascending ASCII order.
-
backslash (\) characters, DT.PATH.ELLIPSIS preserves as
+
An individual record may be retrieved using this identifier using the KEY= parameter of the READ (or associated input) statement.
-
much as possible of the text after the last backslash.
+
A keyed file may also be read in key-sequential order; records are retrieved in ascending sorted key order.
-
+
The index for a keyed file is a string field from 1 to 64 characters long. When the file is created, the key length is specified. So is the record length; this value ranges from 1 to 1,024 bytes, and is fixed for each record in the file. Because of the ease of use and advantages of direct access, keyed files are the most common types of data files used in Internet Basic applications.
-
DT.MODIFYSTRING Modifies the given string to match the displayed text.
+
When an Internet Basic program opens a keyed file, the Comet operating system assigns a unique file pointer to the file. Each user opening the file is assigned a unique pointer, allowing multiple users to access data from the same file at the same time. To avoid data integrity problems when more than one user is accessing a file, Internet Basic provides a record locking mechanism. The EXTRACT statement is used to read and lock individual data records.
-
This flag has no effect unless the DT_END_ELLIPSIS or
+
As a user accesses records in a keyed file, the file pointer keeps track of the current location. When the file is opened, the pointer is located at the record associated with the first key. If the records are retrieved without an index, the pointer moves along in ascending ASCII order of the key values (i.e., in key-sequential order).
-
DT_PATH_ELLIPSIS flag is specified.
+
When a record is accessed directly using an index, the pointer is moved to the associated position. If no record is found matching the specified index, an exception occurs, but the pointer is located at the index following the requested index value. From this point, the program could retrieve records in sequence (without an index), or retrieve another record from the file using another index value.
-
+
Keyed files may also be accessed with a numeric index. In this case, the index value is used to specify the record number in the file in record number sequence (rather than in key sequence).
-
DT.RTLREADING    Layout in right to left reading order for bi-directional text when
+
Application notes:
-
the font selected into the hdc is a Hebrew or Arabic font.
+
    Since Key trees are built using "Balanced B Tree" structures, access to specific records is very fast. Depending on key length, access to a single record in a file of several million records may only take 3 or 4 reads from the underlying file system.
-
 
+
     A keyed file provides the most convenient way to randomly access a file. Therefore, most Internet Basic programs use keyed files to store data records.
-
The default reading order for all text is left to right.
+
    When a record is deleted from a keyed file, the vacated space is automatically reused by the file to store subsequent records. This advantage is another reason why keyed files are predominant in Internet Basic applications.
-
 
+
-
+
-
 
+
-
DT.WORD.ELLIPSIS Truncates text that does not fit in the rectangle and adds ellipses.
+
-
 
+
-
NOTE: The values DT.CALCRECT, DT.EXTERNALLEADING, DT.INTERNAL, DT.NOCLIP, and
+
-
 
+
-
DT.NOPREFIX cannot be used with the DT.TABSTOP value.
+
-
+
-
<Back to Top>
+
-
 
+
-
+
-
SelectPen
+
-
 
+
-
+
-
 
+
-
(SelectPen = <Style>, <Width>, <Red>, <Green>, <Blue>)
+
-
 
+
-
            Selects the pen described by <Style>, <Width> and <Red>, <Green>, <Blue>.
+
-
 
+
-
Available pen styles <Style> are:
+
-
 
+
-
PS.SOLID                  Creates a solid pen.
+
-
 
+
-
+
-
 
+
-
PS.DASH                  Creates a dashed pen. Valid only when the pen width is 1 or less, in device units.
+
-
 
+
-
PS.DOT                    Creates a dotted pen. Valid only when the pen width is 1 or less, in device units.
+
-
 
+
-
PS.DASHDOT          Creates a pen with alternating dashes and dots. Valid only when the pen width is 1 or less, in device units.
+
-
 
+
-
PS.DASHDOTDOT  Creates a pen with alternating dashes and double dots. Valid
+
-
 
+
-
only when the pen width is 1 or less, in device units.
+
-
 
+
-
PS.NULL                    Creates a null pen.
+
-
 
+
-
PS.INSIDEFRAME  Creates a pen that draws a line inside the frame of closed
+
-
 
+
-
shapes produced by the Windows GDI output functions that
+
-
 
+
-
specify a bounding rectangle (for example, the Ellipse,
+
-
 
+
-
Rectangle, RoundRect, Pie, and Chord member functions).
+
-
 
+
-
When this style is used with Windows GDI output functions
+
-
 
+
-
that do not specify a bounding rectangle (for example, the
+
-
 
+
-
LineTo member function), the drawing area of the pen is not
+
-
 
+
-
limited by a frame.
+
-
 
+
-
+
-
 
+
-
If the width of the pen <PtrWidth> is 0, the width in device units is always 1 pixel, regardless of the mapping mode.
+
-
 
+
-
+
-
 
+
-
NOTE: See SetTextColor for color parameter information.
+
-
 
+
-
+
-
SelectBrush
+
-
 
+
-
+
-
 
+
-
(SelectSolidBrush = <Red>, <Green>, <Blue>)
+
-
 
+
-
            Selects the solid brush described <Red>, <Green>, <Blue>.
+
-
 
+
-
NOTE: See SetTextColor for color parameter information.
+
-
 
+
-
+
-
 
+
-
(SelectHatchBrush = <Style>, <Red>, <Green>, <Blue>)
+
-
 
+
-
            Selects the hatched brush described <Style> and <Red>, <Green>, <Blue>.
+
-
 
+
-
+
-
 
+
-
Where <Style> can be one of the following values:
+
-
 
+
-
HS.HORIZONTAL     Horizontal hatch
+
-
 
+
-
HS.VERTICAL          Vertical hatch
+
-
 
+
-
HS.FDIAGONAL      Upward hatch (left to right) at 45 degrees
+
-
 
+
-
HS.BDIAGONAL      Downward hatch (left to right) at 45 degrees
+
-
 
+
-
HS.CROSS              Horizontal and vertical crosshatch
+
-
 
+
-
HS.DIAGCROSS      Crosshatch at 45 degrees
+
-
 
+
-
NOTE: See SetTextColor for color parameter information.
+
-
 
+
-
+
-
<Back to Top>
+
-
 
+
-
+
-
MoveTo / LineTo
+
-
 
+
-
+
-
 
+
-
(MoveTo = <X>, <Y>)
+
-
 
+
-
Moves the current location pointer to the location specified by <X>, <Y>. Returns: The X and Y coordinates of the previous position in <LoResult> and  <HiResult> (respectively).
+
-
 
+
-
+
-
 
+
-
(LineTo = <X>, <Y>)
+
-
 
+
-
Draws a line using the currently selected pen from the current location pointer up to but not including the location specified by <X>, <Y>. The current position is set to <X>, <Y>.
+
-
 
+
-
+
-
<Back to Top>
+
-
 
+
-
+
-
Set / Get ROP2
+
-
 
+
-
+
-
 
+
-
(SetROP2 = <Mode>)
+
-
 
+
-
Sets the current foreground mix mode. GDI uses the foreground mix mode to combine pens and interiors of filled objects with the colors already on the screen. The foreground mix mode defines how colors from the brush or pen and the colors in the existing image are to be combined.
+
-
 
+
-
+
-
 
+
-
Where <Mode> can be any of the following values:
+
-
 
+
-
+
-
 
+
-
Mix mode
+
-
+
-
 
+
-
Description
+
-
 
+
-
R2.BLACK
+
-
+
-
 
+
-
Pixel is always 0.
+
-
 
+
-
R2.COPYPEN
+
-
+
-
 
+
-
Pixel is the pen color.
+
-
 
+
-
R2.MASKNOTPEN
+
-
+
-
 
+
-
Pixel is a combination of the colors common to both the screen and the inverse of the pen.
+
-
 
+
-
R2.MASKPEN
+
-
+
-
 
+
-
Pixel is a combination of the colors common to both the pen and the screen.
+
-
 
+
-
R2.MASKPENNOT
+
-
+
-
 
+
-
Pixel is a combination of the colors common to both the pen and the inverse of the screen.
+
-
 
+
-
R2.MERGENOTPEN
+
-
+
-
 
+
-
Pixel is a combination of the screen color and the inverse of the pen color.
+
-
 
+
-
R2.MERGEPEN
+
-
+
-
 
+
-
Pixel is a combination of the pen color and the screen color.
+
-
 
+
-
R2.MERGEPENNOT
+
-
+
-
 
+
-
Pixel is a combination of the pen color and the inverse of the screen color.
+
-
 
+
-
R2.NOP
+
-
+
-
 
+
-
Pixel remains unchanged.
+
-
 
+
-
R2.NOT
+
-
+
-
 
+
-
Pixel is the inverse of the screen color.
+
-
 
+
-
R2.NOTCOPYPEN
+
-
+
-
 
+
-
Pixel is the inverse of the pen color.
+
-
 
+
-
R2.NOTMASKPEN
+
-
+
-
 
+
-
Pixel is the inverse of the R2_MASKPEN color.
+
-
 
+
-
R2.NOTMERGEPEN
+
-
+
-
 
+
-
Pixel is the inverse of the R2_MERGEPEN color.
+
-
 
+
-
R2.NOTXORPEN
+
-
+
-
 
+
-
Pixel is the inverse of the R2_XORPEN color.
+
-
 
+
-
R2.WHITE
+
-
+
-
 
+
-
Pixel is always 1.
+
-
 
+
-
R2.XORPEN
+
-
+
-
 
+
-
Pixel is a combination of the colors in the pen and in the screen, but not in both.
+
-
 
+
-
+
-
 
+
-
(GetROP2)
+
-
 
+
-
Retrieves the foreground mix mode of the specified device context. The mix mode specifies how the pen or interior color and the color already on the screen are combined to yield a new color.  The resulting mode is returned in <LoWord>.
+
-
 
+
-
+
-
<Back to Top>
+
-
+
-
 
+
-
+
-
Ellipse, Rectangle & RoundRect
+
-
 
+
-
+
-
 
+
-
+
-
 
+
-
(Ellipse = <Left>, <Top>, <Right>, <Bottom>)
+
-
 
+
-
Draws an ellipse. The center of the ellipse is the center of the bounding rectangle specified by <Left>, <Top>, <Right>, <Bottom>. The ellipse is drawn with the current pen, and its interior is filled with the current brush. The figure drawn by this function extends up to, but does not include, the right and bottom coordinates. This means that the height of the figure is <Bottom> - <Top> and the width of the figure is <Right> - <Left>.
+
-
 
+
-
+
-
 
+
-
If either the width or the height of the bounding rectangle is 0, no ellipse is drawn.
+
-
 
+
-
+
-
 
+
-
+
-
 
+
-
(Rectangle = <Left>, <Top>, <Right>, <Bottom>)
+
-
 
+
-
Draws a rectangle specified by <Left>, <Top>, <Right>, <Bottom> using the current pen. The interior of the rectangle is filled using the current brush. The rectangle extends up to, but does not include, the right and bottom coordinates. This means that the height of the rectangle is<Bottom> - <Top> and the width of the rectangle is <Right> - <Left>. Both the width and the height of a rectangle must be greater than 2 units and less than 32,767 units.
+
-
 
+
-
+
-
 
+
-
+
-
 
+
-
(RoundRect = <Left>, <Top>, <Right>, <Bottom>, <CornerWidth>, <CornerHeight>)
+
-
 
+
-
Draws a rectangle with corners rounded using the ellipse specified by  <CornerWidth> and <CornerHeight> at the location specified by <Left>, <Top>, <Right>, <Bottom> using the currently selected pen. The interior of the rectangle is filled using the current brush.
+
-
 
+
-
See Rectangle above.
+
-
+
-
<Back to Top>
+
-
+
-
DrawBitmap
+
-
 
+
-
+
-
 
+
-
(DrawBitmap =  <Left>,<Top>,<Right>,<Bottom>,<ScaleX>,<ScaleY>,<Flags>);<FileName>
+
-
 
+
-
Draws the bitmap contained in the file (.BMP/.JPG) specified in <FileName> in the rectangle specified by <Left>, <Top>, <Right>, <Bottom> using the format codes contained in <Flags>.  Scaling factors can be specified in <ScaleX>, <ScaleY>.
+
-
 
+
-
+
-
 
+
-
FileName is a string containing the full path name of the bit map file. No trailing @00@ is needed or expected.
+
-
 
+
-
+
-
 
+
-
Valid flag  are:
+
-
 
+
-
BMR.FIT.TO.RECT              Stretch (or shrink) bitmap to fit rectangle.
+
-
 
+
-
Cannot be used with any other codes
+
-
 
+
-
or
+
-
 
+
-
+
-
 
+
-
BMR.CENTER.HZ.RECT    Center the bitmap horizontally in rectangle
+
-
 
+
-
BMR.CENTER.VT.RECT    Center the bitmap vertically in rectangle
+
-
 
+
-
BMR.SCALE                        Multiply dimensions by scaling factors below
+
-
 
+
-
+
-
 
+
-
When scaling, values contained in <ScaleX> and <ScaleY> are converted to floating point, divided by 100, and then multiplied
+
-
 
+
-
by their respective axis to providing scaling by as little as 1 percent.
+
-
 
+
-
+
-
 
+
-
Scaling example:
+
-
 
+
-
+
-
 
+
-
To double only the horizontal size of a bitmap:
+
-
 
+
-
<ScaleX> = 200    ! * 2
+
-
 
+
-
<ScaleY> = 100    ! * 1
+
-
 
+
-
+
-
 
+
-
To halve a bitmap
+
-
 
+
-
<ScaleX> = 50          ! * .5
+
-
 
+
-
<ScaleY> = 50          ! * .5
+
-
 
+
-
+
-
 
+
-
To convert bitmap pixels to .01 inch:
+
-
 
+
-
<ScaleX> = 1440  ! * 14.40 (TWIPS/inch)
+
-
 
+
-
<ScaleY> = 1440  ! * 14.40 (TWIPS/inch)
+
-
 
+
-
+
-
<Back to Top>
+
-
+
-
Orientation & PageInfo
+
-
 
+
-
+
-
 
+
-
(SetOrientation = <Mode>)
+
-
 
+
-
Sets the paper orientation contained in <Mode>.
+
-
 
+
-
+
-
 
+
-
Valid values for <Mode> are:
+
-
 
+
-
DMORIENT.PORTRAIT                  Vertical paper alignment
+
-
 
+
-
DMORIENT.LANDSCAPE              Horizontal paper alignment
+
-
 
+
-
+
-
 
+
-
(GetPageInfo = <ItemCode>)
+
-
 
+
-
Returns the information specified in <ItemCode>
+
-
 
+
-
+
-
 
+
-
Valid <ItemCode> Values:
+
-
 
+
-
PTR.PAGEINFO.PRINTABLESIZE            Dimensions of printable area (Width, Height)
+
-
 
+
-
PTR.PAGEINFO.PHYSICALSIZE              Physical page size (Width, Height)
+
-
 
+
-
PTR.PAGEINFO.PHYSICALOFFSET      Offset to start of printable area (Left, Top)
+
-
 
+
-
PTR.PAGEINFO.LOGPIXELS                    Number of pixels per inch (Width, Height)
+
-
 
+
-
+
-
 
+
-
The return value for this function is obtained by requesting the result of the previous operation with (GetFuncResult) and then performing an input of the 4 byte return value The paired values are returned in <LoResult> and <HiResult> respectively.
+
-
 
+
-
+
-
<Back to Top>
+
-
+
-
GetFuncResult
+
-
 
+
-
+
-
 
+
-
(GetFuncResult)
+
-
 
+
-
Requests the 32 bit (4 byte) result of the last printer function.  This function must be followed immediately by an INPUT statement to receive the value into the MTB program.
+
-
 
+
-
+
-
 
+
-
Example:
+
-
 
+
-
+
-
 
+
-
      ! Variables for GetFuncResult
+
-
 
+
-
Length      2 & Local Word$                    ! Temporary 2 byte word holder
+
-
 
+
-
Length      4 & Local Result$                  ! 4 byte string result
+
-
 
+
-
Length  5.0 & Local LoResult, HiResult              ! Lower/upper 16 bit value
+
-
 
+
-
Length 10.0 & Local BigResult                  ! 32 bit value
+
-
 
+
-
+
-
 
+
-
! Variables for GetPageSize
+
-
 
+
-
Length  5.0 & Local PageWidth, PageHeight            ! Printable page size
+
-
 
+
-
+
-
 
+
-
+
-
 
+
-
! Program segment
+
-
 
+
-
.
+
-
 
+
-
.
+
-
 
+
-
Gosub GetPageSize                        ! Define printer page size
+
-
 
+
-
.
+
-
 
+
-
.
+
-
 
+
-
.
+
-
 
+
-
GetPageSize:
+
-
 
+
-
    Print (LUN) (GetPageInfo = PTR.PAGEINFO.PRINTABLESIZE)
+
-
 
+
-
    Gosub GetFuncResult                        ! Get low and high 16 bit results
+
-
 
+
-
    PageWidth = LoResult                              ! Store resulting page width
+
-
 
+
-
    PageHeight = HiResult                            ! Store resulting page height
+
-
 
+
-
Return
+
-
 
+
-
+
-
 
+
-
GetFuncResult:
+
-
 
+
-
    Print (LUN) (GetFuncResult)                      ! Request result
+
-
 
+
-
    Input (LUN) Result$                        ! Input result
+
-
 
+
-
    Word$  = SUB(Result$,2,1)+ Result$        ! Get and reverse 1st 2 bytes
+
-
 
+
-
    LoResult      = HEXDEC(Word$)                    ! Convert to MTB numeric
+
-
 
+
-
    Word$  = SUB(Result$,4,1)+SUB(Result$,3,1) ! Get and reverse 2nd 2 bytes
+
-
 
+
-
    HiResult      = HEXDEC(Word$)                    ! Convert to MTB numeric
+
-
 
+
-
    BigResult    = HiResult*65536+LoResult          ! Combined 32 bit numeric value Return
+
-
 
+
-
+
-
<Back to Top>
+

Latest revision as of 14:55, 12 February 2014

XAP Gateway Internals

There are 2 major parts to the XAP technology. The first part is what we call the CGI server and the second is what we call the XAP Gateway.

The CGI Server

The CGI server listens on the port configured for it. It expects to receive connections using the http protocol. It then performs the following steps:

   It receives and assembles a whole browser request.
   It parses the individual parts of this request, splitting out the following components:
   The CGI Environment variables.
   Any Cookies that the browser may have sent.
   Any query strings that the browser may have sent.
   It then writes these items into a Keyed File* (called the XAP environment file), so that a user program can access them quickly.
       CGI environment variables are written to the keyed file such that the key name is the environment variable name with dots instead of underlines separating words of the name, ie HTTP_USER_AGENT would become HTTP.USER.AGENT.
       Cookie names are preceded with a "C." so that a cookie by the name of "my cookie" would be written as "C.MY COOKIE".
       Likewise, query strings are preceded with a "Q." so that a query string by the name of "credit card number" would be written as "Q.CREDIT CARD NUMBER".
   If an appropriate cookie was present in the request, the CGI server establishes the context data for the connection.
   It then launches the Internet Basic program designated by the SCRIPT.NAME environment variable. The program inherits a connection to the browser through the XAP gateway, any context items established in step 4 above, and the keyed file produced in step 3 above.

Note: Any mention of "files" in this document does not necessarily mean "disk files". Files may reside in memory or disk depending on performance/sharing issues.


The XAP Gateway

The XAP Gateway acts in response to commands included in the Internet Basic program launched by the CGI Server. The interface is very easy to learn because it contains relatively few basic commands:

   Write – the program may write data to the browser through the gateway.
   If no previous data has been written to the XAP Gateway, the XAP Gateway will generate a standard HTML header before sending the data to the browser. The program is free to modify this behavior through a control explained below. Otherwise, the data will be sent directly to the browser. All data is buffered for best performance.
   Control – the program may send various controls that cause the gateway to perform actions meaningful to the program. These will be described below.
   Status – the program can get various pieces of information from the gateway by the use of a simple status function.
   Close – When the LUN pointing to the XAP Gateway is closed, all buffered data is sent to the browser, Context data is filed away for future connections, and the connection to the browser is gracefully closed.
   The XAP environment file is also used as part of the interface between the program and the XAP gateway. The program can read browser request data from this file as explained above. It may also write information that will eventually be written to the browser as explained below.


XAP Gateway Controls

Most of the power of the XAP Gateway is embedded in the various Controls that the program may send to it. The Control statement looks like a standard function in the language:

Syntax:

Result-string = CONTROL(LUN,Control.String [,EXCP=exception.routine])

The CONTROL statement sends the specified control-string to the specified logical unit number. In the case of the XAP Gateway, the Logical Unit Number or "LUN" is always 0 (zero).

The CONTROL statement also reads the result field from the input buffer and places it in the result-string. A plus sign (+) in the first byte of the result-string indicates that the control function was performed successfully. A minus sign (-) in the first byte indicates that the control was not performed successfully. The remaining bytes of the result-string contain text describing the success or failure of the control function.

The CONTROL statement performs the same function as the following statements:

FILE (LUN) CTL=control-string

INPUT (LUN) result-string

Here are the controls that may be sent to the XAP gateway. Where string constants are used in the examples, string expressions may also be used.

   TYPE – sets a MIME type to the browser. As explained above if no TYPE control is sent, the type is assumed to be HTML and the appropriate header is sent to the browser..
   Result-string = CONTROL (0,"TYPE 0") notifies the XAP gateway that the program will subsequently write its own MIME type header.
   result-string = CONTROL(0,"TYPE 1") tells the XAP Gateway to set the mime type to "text/html"
   result-string = CONTROL(0,"TYPE 2") tells the XAP Gateway to set the mime type to "text/plain"
   Result-string = CONTROL (0,"TYPE 3") tells the XAP Gateway to set the mime type to "text/plain" and supply automatic carriage return line feeds following every write.
   COOKIE – sends a cookie to the browser. This control must be sent before any other data is sent to the browser because the cookie information is part of the header.
   The syntax is as follows:
   A$ = CONTROL (0,'COOKIE cookie-name=cookie-value,time-period')
   Where time-period is the specified length of time for the cookie to be stored in the browser.
   The format for time period is:
   +nM = n minutes into the future
   +nH = n hours into the future
   +nD = n days into the future
   For example, to make the CUSTOMERNUMBER=123456789 cookie stay in the browser system for 25 days, you would use the following statement:
   A$ = CONTROL(0,'COOKIE CUSTOMERNUMBER=123456789,+25D')
   REDIRECT – Sends the appropriate commands to the browser so that it will automatically connect to the URL contained in the REDIRECT control. This control must be sent before any other data is sent to the browser because the redirect information is part of the header.
   For example, if you wanted your program to redirect the browser to www.signature.net, you would use the following statement:
   A$ = CONTROL(0,'REDIR http://www.signature.net')
   OPEN – performs a "test open" of the file contained in the control to validate whether it is present. This file may be a template file, html file, image file or any file. The named file is opened, and the handle is saved for further operations using that file.
   For example, if you wanted your program to send the image contained in the file "c:\images\logo.jpg" to the browser, you would use the following command:
   A$ = CONTROL (0,'OPEN C:\IMAGES\LOGO.JPG')
   After the execution of this control, the result string A$ would contain "+OK" if the file was successfully opened, or "-ERR error opening path" if the file could not be found.
   SEND – Sends the file referred to in the control to the browser. The file is sent to the browser in the fastest way possible. The SEND control may specify a path pointing to the file to be sent --
   A$ = CONTROL (0,'SEND C:\IMAGES\LOGO.JPG')
   or optionally, if no path is specified --
   A$ = CONTROL (0,'SEND')
   the XAP gateway will send a file previously opened by the OPEN control as specified above.
   PUSH – Flushes the output buffer contained in the XAP gateway to the browser for debugging purposes or to implement "server push" actions.
   MERGE – Merges data from a template file named in the control with data contained in the CGI Environment file, Then sends the resultant merged data stream to the browser. Merge is the most powerful of all of the controls. It merges selected data from the CGI environment file with a template file (or a section of a template file) and sends the resulting web page to the browser.

The syntax for the MERGE control may take several forms. The general description of the merge command is:

A$ = CONTROL (LUN,’MERGE Path-name |"." [,SECTION Section-name])

As you can see, the MERGE command takes an optional path name and an optional section name. Here is how Comet processes a MERGE command.

       Comet first determines if there is a path name specified, or a dot, meaning use the last file either opened from a previous MERGE command or an OPEN command. If a Path name was supplied, that file is opened.
       Comet then determines whether a SECTION name was supplied. If a Section name was specified, Comet searches the file for a string of characters such as:
       <!—BEGIN Section-nameà
       If found, the file pointer is set just beyond this string, causing Comet to read data from this point on. If no such string was found, Comet starts reading the e file from the first byte.
       If a section was specified in the control statement, Comet then searches the file for an end-of-section string. This string is of the form:
       <!—END Section-nameà
       If such a string is found, a pointer is set to the character just prior to the opening character of this string. This pointer marks the last character sent from the file on this Merge command. If no such string is found, the ending pointer is set to the last character of the file.
       Comet then searches the file starting at the current file pointer for an indicator marking data to be inserted. At the current time, this marker is a pair of stars (**).
       If such a marker is found, all data is streamed from the file to the Browser up to this marker.
       Comet then searches the file for an ending indicator. At the current time this is also a pair of stars (**). If such a marker is found, all characters between the beginning and ending markers (including the **’s) is assembled into a Key to be used in a keyed read on LUN 1. If the read is successful, the data record resulting from this keyed read is streamed to the browser.
       If the keyed read was unsuccessful, the first * of the beginning marker is sent to the browser and the process is repeated from step d. above.
       Once the entire file or section has been streamed to the browser, the control command is completed.

It should be noted that the syntax used for the begin and end indicators denotes HTML comments. Thus the markers would not be visible in the html page if the browser displayed them.

It should also be noted that even though the operations above look like operations on a file, the data is really read into memory and streamed from there for performance reasons.

Following are two lessons from a tutorial which deal with the MERGE command:

This lesson and the next one are the most important lessons in the eComet tutorial. In this lesson, you will learn how to merge live Comet data into stored HTML documents.

Let us repeat that last part (for emphasis): you can merge live Comet data into a stored HTML document in order to make a dynamic return page.


Here's how it works:

First, create an XAP-ready HTML document. In the locations where you want to include a merge field, surround the field name with double asterisks.

Here's a sample HTML file. We've included one merge field named **TODAY**.

<HTML>

<HEAD>

<TITLE>

Sample merge document

</TITLE>

</HEAD>

<BODY>

This is a sample document.

Today's date is **TODAY**.

</BODY>

</HTML>

For the sake of this example, let's suppose we saved this file on drive C: and named the file TODAY.HTM.

Next, write an Internet Basic program that does two things:

1.Writes the merge field(s) to the CGI Environment File, using the double-asterisk field name as the key

2.Merges the HTML document with the CGI Environment File via the MERGE command

Here's some sample code to show you how this works:

LENGTH 10 & LOCAL TODAY$

CGIDATA: FORMAT TODAY$

TODAY$ = '06/08/2000'

WRITE (1,CGIDATA) KEY='**TODAY**' ! Write merge field

A$ = CONTROL(0,'MERGE C:\TODAY.HTM') ! Merge the HTML file

The WRITE statement writes a record to the CGI Environment file (remember, this file is automatically opened on Logical Unit Number 1 when the XAP program is started). The key is the same as the merge field name in the HTML document (i.e.,**TODAY**).

The MERGE command merges the HTML document (C:\TODAY.HTM) with any merge field(s) contained in the CGI Environment File. In this example, there's only one merge field.

The result is a web page that contains "06/08/2000" in the exact location where "**TODAY**" was contained in the stored document.

Here are some important notes:

The MERGE command is very similar to the SEND command (i.e., it sends a stored document from the eComet system to the browser.

The merge field(s) can appear anywhere in the stored document. This means that you can merge Comet data into places where you want data to appear, and you can also merge HTML commands into a stored document (to change the appearance of a web page for a particular user, for example).

Here's another example. Remember the program (from Lesson 2) that displayed several Comet system variables? Well, we've rewritten that example using the MERGE command.

First, we created an HTML document and included several merge fields. The "raw" document is named systvar.htm. Take a look at the HTML source code and notice the merge fields (**PARTITION** and the others).

Next, we created an Internet Basic program that writes the desired merge records to the CGI Environment File. Look at the following source code and notice the WRITE statements.

!---------------------------------------------------------------------

!

! *** Main program

!

A$ = DSTAT('CL1') ! Refresh TIME$

!

OPEN (10) '#CGICTRL' ! Open CGI control file

READ (10,HTMLPATH) KEY='**HTMLPATH**' ! Get HTML path

HTMLPATH$ = STRIP(HTMLPATH$) ! Strip blanks

CLOSE (10)

!

! *** Write merge fields to CGI file

!

OUTPUT$ = PARTITION$ ! Partition #

WRITE (1,OUTPUT) KEY='**PARTITION**' ! Write record

!

OUTPUT$ = TIME$ ! System time

WRITE (1,OUTPUT) KEY='**TIME**' ! Write record

!

OUTPUT$ = DATE$ ! System date

WRITE (1,OUTPUT) KEY='**DATE**' ! Write record

!

OUTPUT$ = LONGYEAR$ ! 4-digit year

WRITE (1,OUTPUT) KEY='**LONGYEAR**' ! Write record

!

OUTPUT$ = VERSION$ ! Version #

WRITE (1,OUTPUT) KEY='**VERSION**' ! Write record

!

! *** Merge the CGI file with the HTML file, and send the results

!

MERGESTRING$ = 'MERGE '+HTMLPATH$ + 'systvar.htm' ! Build MERGE string

A$ = CONTROL(0,MERGESTRING$) ! Merge

!

KILL PARTITION$

Note

The MERGE command may also be executed via the FILE statement, as shown here:

FILE (0) CTL='MERGE ______________'

HTML file name


In Lesson 3, we showed you how to send multiple stored documents to the web browser with the SEND command. The MERGE command can be used to do the same thing.

For example, here's a program segment that sends 3 stored documents via the MERGE command:

A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3x.htm')

A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3y.htm')

A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3z.htm')

Please note these differences between SEND and MERGE:

The MERGE command invokes the merge feature, while the SEND command does not

There's another very important difference between SEND and MERGE. The MERGE command can send sections of an HTML document. The sections are user-defined portions of the HTML file.

These sections are defined via the HTML comment tag and some XAP-specific keywords within each comment. Here's an example:


This is a section of HTML code. This

section includes text as well as HTML

commands.

This whole section is defined by the BEGIN and END statements, which are contained within HTML comments. The browser ignores the BEGIN and END statements, since they're contained within HTML comments. However, the MERGE command uses the BEGIN and END commands to defined a section of the file. This section is called ABC123. Assume that you saved the above HTML file as: c:\ecomet\html\test.htm Here's how you would send this section of the HTML file via the MERGE command: A$ = CONTROL(0,'MERGE c:\ecomet\html\test.htm SECTION ABC123') Some important notes: There is no limit to the number of sections you may define The first section in an HTML document does not require a statement The final section does not require an statement. No blank spaces are allowed at the beginning of these commands (i.e., inside of the " statement and an statement. Content outside of those boundaries will not be sent to the browser. The next example is based on the sample program you saw in Lesson 4. In this case, we will be merging data from a Comet data file, the DLRS file, into a stored HTML document. The HTML document will be divided into 3 sections, named TOP, MIDDLE, and BOTTOM. The TOP section will contain the initial HTML commands and text for the top portion of the web page. Since this is the first section, we don't need a statement. <HTML> <HEAD> <TITLE> Comet Dealers </TITLE> </HEAD> <BODY BGCOLOR="FFFFFF">

Comet Dealers


Here is a list of Comet dealers.

This data is contained in a

Comet keyed file named DLRS.

The DEMO11B program reads records

from that file and displays the

complete list of names.

The MIDDLE section will be very short. In this section, we will include a merge field named **DEALER**, followed by a line break tag (
):

    • DEALER**

By itself, the MIDDLE section does not look very impressive. Just wait until you see the way we use Internet Basic to merge data into this section! The BOTTOM section will contain the final HTML commands for our sample web page: </BODY> </HTML> We'll save the above file and name it: c:\ecomet\html\dealers.htm Now all we have to do is write an Internet Basic program that sends the 3 sections (and merged data) to the web browser. The first MERGE command will send SECTION TOP: A$ = CONTROL(0,'MERGE c:\ecomet\html\dealers.htm SECTION TOP') The next part of the Internet Basic program will READ data from the DLRS file, WRITE a key to the CGI Environment File, and MERGE SECTION MIDDLE. These steps will be repeated for all of the records in the DLRS file: OPEN (10) 'DLRS' ReadMore: READ (10,DEALERINFO) EXCP=AllDone WRITE (1,DEALERINFO) KEY='**DEALER**' A$ = CONTROL(0,'MERGE . SECTION MIDDLE') GOTO ReadMore Notice that the key value (**DEALER**) matches the merge field in the HTML file. Also notice that the MERGE command contains a different format than before. If you are merging more than one section of an HTML file, you only have to specify the file name once (on the first MERGE command). After that, you can use the period (.) to represent the HTML file name. The period is both a coding shortcut and a way to get faster performance from the MERGE command. Once an HTML file has been opened and read into memory, there's no need to re-open and re-read it. Thus, the period refers to a document that is already in memory. The final section the program closes the data file and sends the BOTTOM section of the HTML file: AllDone: CLOSE (10) A$ = CONTROL(0,'MERGE . SECTION BOTTOM') KILL PARTITION$ Here's something to Think About As we mentioned above, merge fields can appear anywhere in an HTML file, including HTML commands and parameters. For example, you could include a merge field where you would normally include a hard-coded parameter, as in the BACKGROUND portion of the BODY tag: <BODY BACKGROUND="**PICTURE**"> Then, from within an Internet Basic program, you could define a specific background graphic simply by writing the **PICTURE** key to the CGI Environment File and merging it with your HTML file. PICTURE: FORMAT PICTURE$ . PICTURE$ = "SAMPLE.GIF" WRITE (1,PICTURE) KEY="**PICTURE**" A$ = CONTROL(0,'MERGE HTML-document SECTION section-name') You could use this technique to good effect, for example, by displaying a unique background graphic for each customer who uses your web site. You could determine who's who by reading a persistent cookie (assuming you had already sent one to the browser), getting unique data from that cookie (a customer number, let's say), and using that data to read a GIF or JPG file name from a keyed file. Then you could write that file name to the CGI Environment File and merge it into an HTML file, as shown in the code segment above. This would result in a very personalized web site for each of your customers.
  • Keyed Files
Keyed files provide direct access to the data records. Comet stores data for keyed files in two DOS disk files. One DOS file stores the data records in their entered order, and a "key tree" file stores the record keys in ascending ASCII order. An individual record may be retrieved using this identifier using the KEY= parameter of the READ (or associated input) statement. A keyed file may also be read in key-sequential order; records are retrieved in ascending sorted key order. The index for a keyed file is a string field from 1 to 64 characters long. When the file is created, the key length is specified. So is the record length; this value ranges from 1 to 1,024 bytes, and is fixed for each record in the file. Because of the ease of use and advantages of direct access, keyed files are the most common types of data files used in Internet Basic applications. When an Internet Basic program opens a keyed file, the Comet operating system assigns a unique file pointer to the file. Each user opening the file is assigned a unique pointer, allowing multiple users to access data from the same file at the same time. To avoid data integrity problems when more than one user is accessing a file, Internet Basic provides a record locking mechanism. The EXTRACT statement is used to read and lock individual data records. As a user accesses records in a keyed file, the file pointer keeps track of the current location. When the file is opened, the pointer is located at the record associated with the first key. If the records are retrieved without an index, the pointer moves along in ascending ASCII order of the key values (i.e., in key-sequential order). When a record is accessed directly using an index, the pointer is moved to the associated position. If no record is found matching the specified index, an exception occurs, but the pointer is located at the index following the requested index value. From this point, the program could retrieve records in sequence (without an index), or retrieve another record from the file using another index value. Keyed files may also be accessed with a numeric index. In this case, the index value is used to specify the record number in the file in record number sequence (rather than in key sequence). Application notes: Since Key trees are built using "Balanced B Tree" structures, access to specific records is very fast. Depending on key length, access to a single record in a file of several million records may only take 3 or 4 reads from the underlying file system. A keyed file provides the most convenient way to randomly access a file. Therefore, most Internet Basic programs use keyed files to store data records. When a record is deleted from a keyed file, the vacated space is automatically reused by the file to store subsequent records. This advantage is another reason why keyed files are predominant in Internet Basic applications.
Personal tools