Tech Note 22: Printing using PalmPrint/SCSPrint

September 17 2003

© NSB Corporation. All rights reserved.

Contributed by Michael J. Verive, author of NS BASIC Programming for Palm OS

Printing in NS Basic using PalmPrint/SCSPrint

Storing information in your Palm device is great, and HotSync allows you to transfer this data to your desktop computer, where you’re likely to do most of your printing.  However, you may need to print directly from your Palm device, either through the serial port or to an IR-enabled printer.  NS Basic doesn’t have any built-in print routines, so currently the only way to print from NS Basic is to do so using the serial I/O functions, or through the use of third-party applications such as SCSPrint or PalmPrint (available from Stevens Creek Software at www.stevenscreek.com).  Printing through PalmPrint in NS Basic is somewhat different from how you may be used to printing in other dialects of Basic (printing using SCSPrint is handled using the same code as PalmPrint, so I’ll just refer to PalmPrint for either PalmPrint or SCSPrint). 

The easiest way to print to PalmPrint in NS Basic is through the use of the AppLaunch statement.  Since it’s not always easy to remember the syntax of this statement or the launch code used, you can use this subroutine in a code module for your applications :

Sub PalmPrint(PrintString as String)
    Dim CardNo as Integer
    Dim LaunchCode as Integer
    Dim result as Integer
    CardNo=0
    LaunchCode=32768
    result=AppLaunch(CardNo,"PalmPrint",LaunchCode,PrintString)
    If result<>0 Then
        result=alert("PalmPrint","Error printing to PalmPrint",3,"OK")
    End If
End Sub

If you load this code module into your application, when you need to print to PalmPrint from any of your forms or objects, all you need to provide is the name of the subroutine and the string to be printed:

PalmPrint "This is the print string"

or

Call PalmPrint("This is the print string")

This is fine if all you want to do is print a single line of text.  Most of the time, however, you’ll need to print multiple lines (or pages) of information.  Using the PalmPrint statement with each individual line will work, but with an undesirable side effect – each line will be printed on a separate page!  The PalmPrint subroutine runs PalmPrint as a separate "print job" each time it’s called, so PalmPrint faithfully ejects the page after each job. 

To print multiple lines on the same page, you’ll need to modify your string so that it contains all of the lines to be printed PLUS the necessary codes to tell the printer to move to the next line as needed (or, use line-by-line printing, discussed later).  If you are concatenating lines to create a single "print string", you're in luck; the code for moving to the next line when printing is the same as the code for moving to a new line in a field – the Chr(10), or "line feed" character:

Dim PrintString as string
PrintString="This is the first line."
PrintString=PrintString+chr(10)+"This is the next line."
PrintString=PrintString+chr(10)+"and so on…"
PalmPrint PrintString

PalmPrint allows you to determine whether you want a line feed, a "carriage return" (the ASCII code Chr(13)), or both at the end of a line (even if your lines end with the line feed alone, as above).  Most printers will print properly if the line feed and carriage return pair is used (but you may have to experiment with your printer).  PalmPrint also allows you to select from a wide variety of printers, and knows which codes to send to tell the printer to print using different fonts, point sizes, and other settings.

Printing with PalmPrint is easy with supported IR-enabled printers, and printing through the serial port is only slightly more complicated.  Your application won’t need to handle printing any differently, but you’ll need to make sure that PalmPrint and your printer are set to use the same baud rate and other serial parameters.  You may also need to use a "null modem" cable or adapter, depending on your printer, if you are printing through the Palm serial port connected directly to a printer.

Advanced Printing – Formatting with Control Codes

For most purposes, PalmPrint works well "out of the box", since it knows internally how to print to many different printers.  In fact, PalmPrint was written to be "printer independent", so that if you have something that you print on one type of printer, then switch to another type of printer, you’ll still get the same (or very similar) output. However, there may be times that you’ll want to "spice up" your output with bold, double-wide, condensed, or other print formatting.  PalmPrint makes this easy by allowing you to embed special "escape" codes to tell your printer what formatting you’d like to use.  Not all of the special formatting codes work the same with all printers, however, so you end up trading printer independence for this added formatting power.

Formatting codes are inserted in strings sent to PalmPrint as one to three digit numeric values surrounded by the "double-less-than" and "double-greater-than" ("<<" and ">>") characters.  Note that these refer to ASCII 171 and 187, NOT merely two less-than or two greater-than signs together, but the characters found in the lower right corner of the "Int'l" portion of the popup keyboard on the Palm (normal and shifted). 

Many of the formatting codes use the "ESC" (ASCII 27) character to tell the printer that formatting commands follow, so only the value 27 needs to be in the "<<>>" string.  For example, "ESC"W1 turns on a special "double-wide" mode on a Canon printer, and "ESC"W0 turns it off.  So, the following code will print with a special "double wide" string (27 is the numeric value of the ESC character), followed by normal text:

Dim EscStart as byte
Dim EscEnd as byte
EscStart=chr(171)
EscEnd=chr(187)
Msg=EscStart+"27"+EscEnd+"W1This is double-wide"
Msg=msg+chr(10)+EscStart+"27"+EscEnd+"W0And this is back to normal"
PalmPrint Msg

As an added "bonus", PalmPrint expects only numeric values between the "<<>>" characters, so non-numeric strings are ignored, and can be used to embed comments in the string:

Msg="<<This text is double-wide>>"+EscStart+"27"+EscEnd+"W1 Profits 2nd Quarter"
Msg=msg+chr(10)+"<<Back to normal>>"+EscStart+"27"+EscEnd+"W0Region: Northwest"
PalmPrint Msg

For some printers, you may need to enter the ESC character without the "<<>>" delimiters:

Dim EscChar as string
EscChar=chr(27)
Msg=EscChar +"W1 Profits 2nd Quarter"
Msg=msg+chr(10)+EscChar +"W0Region: Northwest"
PalmPrint Msg

Remember that these "escape sequences" are printer-dependent, although many printers have "Epson-compatible" or "HP-compatible" modes, allowing you to use standard Epson or Hewlett-Packard codes.  Consult your printer manual for the specific codes to use.  The following table gives common escape sequences and their functions for most Epson (and Epson-compatible) printers:

Epson Printer Control Codes (Esc=chr(27)).

Code String

Effect

Esc ©

Reset Printer

Esc -1

Turns underlining on

Esc -0

Turns underlining off

Esc E

Turns emphasized (bold) on

Esc F

Cancels emphasized mode

Esc G

Starts double-strike mode

Esc H

Cancels double-strike mode

Esc P

10 character per inch (CPI) mode (pica)

Esc M

12 CPI mode (elite)

chr(15)

Condensed print

Esc S0

Starts superscript mode (S0)

Esc S1

Starts subscript mode (S1)

Esc T

Cancels subscript/superscript modes

Esc W1

Starts double-wide mode

Esc W0

Cancels double-wide mode

Advanced Printing - using AppLaunch and Launch Codes

Starting with version 2.0, PalmPrint provides yet another way to control print formatting, and this method maintains printer-independence.  It’s a little more involved, and sacrifices a little printer control (e.g., you don’t have the ability to select printer-specific fonts), but it may work better for routine formatting when you don’t have control over which printer will be used.

The secret to this method of formatting is the fact that PalmPrint can accept various different launch codes in the AppLaunch statement (like the 32768 used to tell PalmPrint to print the string passed to it):

result=AppLaunch(CardNo,"PalmPrint",32768,PrintString)

The following table gives the Launch codes that are available from within NS Basic (there are other codes available, but require pointers not available using the AppLaunch statement in NSBasic):

PalmPrint Launch Codes available using NS Basic

Launch Code

Description

32768

Print string, then eject page when finished

32770

Marks the start of a series of print commands ("print job")

32774

Marks the end of a series of print commands

32771

Marks the start of a series of transmit commands

32775

Marks the end of a series of transmit commands

32772

Sends a string of characters to the printer (without ending the "print job" like code 32768)

32773

Transmits a string of characters

32800

Sends a form feed to the printer (ejects the page)

32802

Sets plain printing

32804

Sets bold printing

32828

Sets printer into portrait mode (PCL and Postscript only)

32830

Sets printer into landscape mode (PCL and Postscript only)

As seen in the above table, you can tell PalmPrint to start a "print job" (series of print commands), send the necessary formatting commands, use 32772 instead of 32768 to print your text, then tell PalmPrint to end the print job.  Here’s an example of printing the same report as in the previous example, but using the different launch codes rather than escape sequences:

result=AppLaunch(CardNo,"PalmPrint",32770,"") ' start print job
result=AppLaunch(CardNo,"PalmPrint",32804,"") ' set bold
result=AppLaunch(CardNo,"PalmPrint",32772,"Profits 2nd Quarter")
result=AppLaunch(CardNo,"PalmPrint",32802,"") ' set default print
result=AppLaunch(CardNo,"PalmPrint",32772," Region: Northwest")
result=AppLaunch(CardNo,"PalmPrint",32774,"") ' end print job

You’ll also notice in the table above that there are launch codes for controlling character transmission.  PalmPrint allows you to send output to terminal programs like HyperTerm, as well as to printers.  By using codes 32771 (start transmission), 32773 (transmit line), and 32775 (end transmission) you can send your output to a serial program for capture, rather than a printer.  You will most likely need a null-modem adapter, and will also need to make sure that PalmPrint and your receiving application are set to the same baud rate (PalmPrint’s other serial parameters: 8 data bits, 1 stop bit, no parity, hardware flow control).  If you are using PalmPrint for this feature, consult its documentation for more specifics.

One last point about printing using PalmPrint.  You may have certain applications that require you to send a null (chr(0)) as a character embedded in the print string.  However, the Palm OS uses the null character to mark the end of a string, so using the actual null character will cause the output to be cut off past the null.  If you need to use the null character, use chr(255) instead – PalmPrint will translate it into the null character for output (however, this means that you won’t be able to send a chr(255) to your printer).

PalmPrint is a very flexible application, so study its documentation thoroughly, and check at www.stevenscreek.com to see if your specific printer is supported.  PalmPrint may work with printers not specifically mentioned, but you risk causing compatibility problems that might be difficult to debug.

Using Non-IRDA printers wirelessly

Photologic sells a black box that lets you receive IRDA signals to drive most standard printers. Get details here.