---------------------------------------------------------
The Liberty Basic Newsletter - Issue #63 - JAN 2000
       2000, Cliff Bros and Alyce Watson
             All Rights Reserved

Brosco and Alyce have written a Book for Liberty BASIC,
which is available in electronic form on a CDROM.
For details:  http://alyce.50megs.com/sss/cd.htm
---------------------------------------------------------
In this issue:

	Printing with native Liberty BASIC commands
	Printing with Notepad - Open Source Editor part 6
	Printing with Deanslib.dll
	Printing with vbprint.dll
	Printing with straight api calls

In future issues:
	Copyright and licensing considerations
	A new way to use the filedialog
	Playing wavs
	Using ascii characters in commands
	the FILES command
	Writing and using an ini file
	Writing output 'code'
	Installers
---------------------------------------------------------
PRINTING WITH NATIVE LIBERTY BASIC COMMANDS

TEXT:
It is very easy to send text to be printed using Liberty
BASIC commands.  There are only two to remember:

Lprint text$

This will send the character string contained in the
variable text$ to the default printer for a hard-copy
printout.  You may also use this format:

Lprint "Hello World!"

Your text will be printed -- eventually!  If you want to
force the job to print immediately, just issue this command:

DUMP

Easy?  YES!  Problems?  Unfortunately, yes.  Using Lprint
will only allow printing in the printer's Default Font.
On many printers, the lower half of the last line on a page
may not print.  Any lines longer than 80 characters will
simply be cut off -- there is no line-wrapping in Lprint.
If you want to make sure you don't lose any text, you must
write a line-wrap routine yourself, or copy one of the 
routines available on LB websites.

PRINTING GRAPHICS WITH LIBERTY BASIC COMMANDS:

Graphics from a graphicbox or a graphics window can be printed
on the printer -- in color, if the printer supports color printing.
The command is simply:
print #graphics, "print"

Note that you must put the pen down before drawing graphics, or
they will not show in the window or on the printed page.  You
must also flush the graphics or they will not print.  Try the
little program here and see what you get:

open "test" for graphics as #1
print #1, "down; color green;backcolor green"
print #1, "place 100 100; circlefilled 80"
print #1, "flush; print"
close #1
end

The graphics print command simply sends pixels to the printer
as dots.  If you have a printer whose resolution is 75 dots
per inch in the width and height, you will get a decent printout.
If your printer, like mine has a resolution of 300 dots per inch
width and height, the printout will be quite small.  Depending
upon your printer resolution, the printout can be very tiny!
Also, some printers have different numbers of dots per inch in
the width and height, so your printout might also be incorrectly
proportioned.  It is possible to print a correctly scaled copy
of a graphic window on the printer, but it requires quite a lot
of complex api calls.  See the last part of the newsletter for
more information.
---------------------------------------------------------
PRINTING WITH NOTEPAD	

We can ask Notepad to print text for us.  The text must be in 
a disk file, so if the text is not contained in a file, we
must write one.  Let us assume that the text we want to
print is in the character string, text$.  We'll write it
to a temporary file, which MUST have an extension of .txt:

	open "temp.txt" for output as #t
	print #t, text$
	close #t

We'll need to give a full path for the api call, so
we'll use the DefaultDir$ value as the directory parameter.
The path and name of the file will then be:

    lpFile$ = "temp.txt" + chr$(0)
    lpDirectory$ = DefaultDir$ + chr$(0)

The call to ShellExecute that we will use requires
that we specify the operation "print", and a flag
for program display.  We can hide Notepad from
the user by using _SW_HIDE.  This function will print
the temp.txt file with Notepad, or with the program the user
has set to be the default application for TXT files.
That is why it is important that the name of the file to print
ends with the .txt extension.  ShellExecute looks at the
extension to determine which application to run!
After printing, Notepad closes automatically.

    lpOperation$ = "print" + chr$(0)
    lpParameters$ = "" + chr$(0) 'not needed here
    nShowCmd = _SW_HIDE

    open "shell.dll" for dll as #shell
    calldll #shell, "ShellExecute", _
        h as word, _                'program window handle
        lpOperation$ as ptr, _
        lpFile$ as ptr, _
        lpParameters$ as ptr, _
        lpDirectory$ as ptr, _
        nShowCmd as short, _
        result as word
    close #shell

Since we have put a constraint on the Newsletter version
of the open source editor to avoid extra files, let's use 
this method to improve our print routine.  We have been
using Lprint and Dump, but as we've explained earlier, there
are some problems with this method that can be solved by
asking the default text editor (often Notepad) to print
for us.  Here is the routine as it is added to our editor.
For full code, see the attached open06.bas.
---------------------------------------------------------
OPEN SOURCE PRINT ROUTINE:

[print]
    cursor hourglass
    print #1.t, "!origin?";
    input #1.t, rowVar,columnVar
    print #1.t, "!contents?";
    input #1.t, saveit$ 

'** NEW **
    open "tempedit.txt" for output as #tprint
        print #tprint, saveit$
    close #tprint

    printFile$ = "tempedit.txt"+chr$(0)

    open "shell.dll" for dll as #shell
    calldll #shell, "ShellExecute", _
        h as word, _
        "print" as ptr, _
        printFile$ as ptr, _
        "" as ptr, _
        DefaultDir$ as ptr, _
        _SW_HIDE as short, _
        result as word
    close #shell

    print #1.t, "!origin ";rowVar;" ";columnVar;"";
    cursor normal
    goto [loop]

---------------------------------------------------------
PRINTING WITH DEANSLIB.DLL

Hard-copy printing with fonts and graphics has been 
available to us for years, courtesy of Dean Hodgson.  His
latest DLL, written expressly for use with Liberty BASIC
is a necessity for any LB programmer.  For your convenience,
it is attached to this newsletter.

Deanslib.dll allows you to create custom controls, manipulate
files in many ways, and more....  

Deanslib.dll allows you to get a real printer dialog, print
text and graphics anywhere on the printed page that you
would like, and print with the font face and size of your
choice -- including bold, underline and italic.  Dean
writes the best documentation around, so please refer to 
the attached documentation, Deanslib.doc.  Also see the
attached sample code, dlprnt.bas for a working example.

mailto:dhodgson@nexus.edu.au    E-mail Dean Hodgson

---------------------------------------------------------
LIMITATIONS OF DEANSLIB PRINTING

Deanslib makes printing easy and fun, but we must still
keep track of the current position on the page, and increment
it for each new line of text to print.  We may only print
text one line at a time, and lines that are too long to
fit on the page will be truncated unless we write a line-wrap
routine ourselves.  We must also keep track of the printing
position on the page so that we can eject a page when we
reach the bottom.  We must also get the Dots Per Inch of the 
printer, so that we can set the sizes and placement of text 
and graphics properly.  
---------------------------------------------------------
PRINTING WITH VBPRPINT.DLL

A huge thanks to David Szafranski for bringing this DLL
to our attention!

Did you ever wish there were an easy way to print a hard copy
on the printer in your choice of font face, size and attributes?
Did you also wish that one simple function would automatically
line-wrap the text at the proper spots, and page feed at the
bottom of each page?  Your wish has been answered.  In the
following few lines, you will find a complete program that
allows you to open a text file, and print it as described.


'COMPLETE PROGRAM FOR VBPRINT.DLL:
    print "Please wait..."
[initialize]
    open "vbprint.dll" for dll as #vb
    CallDll #vb, "InitializePrinter",0 as short, r as short
[printHeadline]
	    filedialog "Open Text File","*.txt", file$
    open file$ for input as #f
    Headline$=input$(#f, lof(#f))
    close #f
	    FontName$="Times New Roman"+chr$(0)
	    FontSize=12 : Style=0
    CallDll #vb, "PrintHeadline",_
        Headline$ as ptr,_
        FontName$ as ptr,_
        FontSize as short,_
        Style as short,_
        r as short
[endPrint]
    CallDll #vb, "DonePrinting",r as short
    close #vb
    print "Job has been sent to printer!"
END

Now you are probably saying that this is all very good, but
it would sure be nice if you could set page margins, print
lines and other shapes, and hey... what about columns?
With vbprint.dll, you can do all of these things!  Read
on for complete instructions.
---------------------------------------------------------
SETUP VALUES:

Vbprint.dll provides a really easy way to print hard copies
of both text and primitive graphics.  Text can be printed
in your choice of face and size, and with several different
style attributes, including bold, italic and bordered.  If
you do not define font attributes, but leave the value for
STYLE at 0, you will get a normal font.  If you want other
attributes, then you will need to define some values for 
font style flags:

    NORMAL.FONT      =         0
    BOLD.FONT        = hexdec("0x0001")
    ITALIC.FONT      = hexdec("0x0002")
    TOP.BORDER       = hexdec("0x0004")
    LEFT.BORDER      = hexdec("0x0008")
    RIGHT.BORDER     = hexdec("0x0010")
    BOTTOM.BORDER    = hexdec("0x0020")
    CHECK.BOX        = hexdec("0x0100")

The above values can be put together with a bitwise OR
operation.  See newsletter #57 for more about bitwise
operations and constants in api calls.

NORMAL.FONT -- will give a normal typeface.
BOLD.FONT -- will make a bold font.  
ITALIC.FONT -- this one will create an italic font.  Remember
	that you can have multiple style flags, so a font can be
	both bold and italic, for instance.
TOP.BORDER -- this flag will cause a line to be drawn above all
	text printed.  The line will match the style of font.  
	If the font is bold, the line will be bold.
LEFT.BORDER -- this flag will cause a line to be drawn along the
	left side of the printed text.
RIGHT.BORDER -- this one will cause a line to be drawn along the
	right side of the printed text.
BOTTOM.BORDER -- as you might guess, this flag causes a line to be
	drawn under the printed text.
CHECK.BOX -- this flag will cause a small checkbox to appear to
	the left of the printed text.

Remember that multiple styles can be used.

Style=BOLD.FONT OR LEFT.BORDER OR RIGHT.BORDER OR BOTTOM.BORDER OR TOP.BORDER

The style above would create a bold font that is bounded on all
sides by bordering lines.  After these values are initialized, you 
may use them in your printing routines.

INITIALIZE PRINTER
You will need to get the handle of the program's window, open the
vbprint.dll and make the call to initialize it before you make
any other calls to vbprint.dll.  You may use 0 for the window handle,
because 0 is the handle of the desktop window, but it it better to
use the program window handle:

    h=hwnd(#w)
    open "vbprint.dll" for dll as #vb
    CallDll #vb, "InitializePrinter",_
	h as short,_   'handle of window
	r as short     


PAGE SETUP
The DLL automatically sets default margins, but you have the ability
to set these yourself if you wish to do so.  Do this AFTER initializing
the DLL!  The measurements are in hundredths of an inch, so 100 will 
give a one inch margin, and 25 will give a quarter inch margin.  Please 
notice the order to list these params in the call:  top, right, bottom,
left.  This call is only valid once per job.  You must call DonePrinting,
then InitializePrinter to start a new print job before making this call again.

    top=100     'in hundredths of an inch
    right=50
    bottom=100
    left=50

    CallDll #vb, "PageLayoutSetup",_
        top as short,_
        right as short,_
        bottom as short,_
        left as short,_
        r as short

IMPORTANT LIMITATION!  The maximum value for margins is 200, which sets
margins at two inches.  Setting margins at 0 may result in a loss of
text.

You can retrieve the X, Y position of the upper left corner in TWIPS
as determined by the PageLayoutSetup on the printed page.  There are
1440 TWIPS in once inch.  If you haven't made a call to 
PageLayoutSetup, this will return the default margins - 1440 X and 1440 Y.  
The calls are PagePosX and PagePosY:

    CallDll #vb, "PagePosX",_
		xpos as short   'left margin size in TWIPS

    CallDll #vb, "PagePosY",_
		ypos as short   'top margin size in TWIPS

    notice "X margin is ";str$(xpos);" and Y margin is ";str$(ypos)


PRINTING TEXT

This DLL uses some misleading terminology.  The easiest way to print 
a block of text of ANY size, is with a call to PrintHeadline!
Look at that tiny printing program at the start of this section.
Did you copy it into Liberty BASIC and run it?  If you did, you
saw that it printed the entire text file of your choice, just
using PrintHeadline!  The PrintHeadline call requires the
text string you want to print, the font name you prefer, the
font size you choose, and the style attribute.  Here is an
example call:

    Headline$="Liberty BASIC Printing"+chr$(0)
    FontName$="Arial"+chr$(0)
    FontSize=30
    Style=BOTTOM.BORDER or BOLD.FONT
    CallDll #vb, "PrintHeadline",_
        Headline$ as ptr,_
        FontName$ as ptr,_
        FontSize as short,_
        Style as short,_
        r as short

VERY IMPORTANT NOTE ! ! ! ! !
KEEP THE SIZE OF THE TEXT STRING UNDER 32 KB, WHICH IS 32000
CHARACTERS.  BREAK TEXT THAT IS LONGER THAN THIS INTO
MULTIPLE PARTS FOR PRINTING.

Now, let's talk about the call for ParagraphText.  NOTE:  if
you read the documentation accompanying the dll, you will find 
that it is inconsistent, and in some places it lists this call
as PrintParagraphText.  Don't try to use this name, or you will
crash your program!

The only real difference between PrintHeadline and ParagraphText
is that the PrintHeadline call requires the attributes for the
font to be listed within the call, and the ParagraphText call
requires these attributes to be given in a separate call,
StartParagraph.  Before you can print with ParagraphText,
make this call:

    CallDll #vb, "StartParagraph",_
        FontName$ as ptr,_
        FontSize as short,_
        Style as short,_
        r as short

Then, you can make the call to ParagraphText.  Both PrintHeadline
and ParagraphText will wrap long lines for you at spaces between
words, and will determine when you have reached the bottom of
the page, giving the printer an automatic page feed message.
Here is the call to make after you have called StartParagraph:

    CallDll #vb, "ParagraphText",_
        Text$ as ptr,_
        r as short

You may call this function and add text as many times as you would
like.  It would better be called BlockTextPrint, because it will
print as many paragraphs, and even pages, as you need in this one
call to ParagraphText.  When you have finished printing the block
of text, then call FinishParagraph:

    CallDll #vb, "FinishParagraph",r as short

If you want to print more text after this, you will need to call
StartParagraph again.  Paragraphs here are actually blocks of text,
separated by spaces.  You need to do nothing to accept the default
spacing between paragraph blocks.  If you would like to change the
spacing, call SetParagraphSpacing.  The documentation errs in telling
you the number of params for this call.  It actually requires two
space params, one that sets the space before a paragraph block, and
another that determines the space after a paragraph block.  The default
spacing is 18 pts, which is one quarter inch.  This call uses points as
the measurement.  Our friend Brian Pugh, who is the computer guru for
his newspaper, tells us that there are 72 pts in one inch.

    beforespace=6  
    afterspace=24
    CallDll #vb, "SetParagraphSpacing",_
        beforespace as short,_
        afterspace as short,_
        r as short


PRINT COLUMN HEADERS

The function, PrintColumnHeaders will print text in columns that
you have set up.  It will print one row of text.  For each row
of text that you want to place into columns, you must make the
call again.

To set up the columns, you need a struct that contains params for
the number of columns you will use.  Each param will contain an
integer value that sets the size of that column in hundredths of
an inch.  Let's set up a struct that has 3 columns:

    ncolumn=3    'number of columns
    struct column,_
        cone as short,_   'width of first column
        ctwo as short,_   'width of second column
        cthree as short   'width of third column

Now, let's make each column 2 inches wide.  That means each param
of the struct will be set equal to 200:

    column.cone.struct=200
    column.ctwo.struct=200
    column.cthree.struct=200

The function PrintColumnHeaders will also require the font name, 
font size and style:

    Style=BOLD.FONT
    FontName$="Arial"+chr$(0)
    FontSize=20

Now, we'll need to set up a text string that holds the text to
be printed in the columns.  If you need to place numbers into
the columns, you must do it as a string representation of the
number, rather than as a numeric variable or literal.  The
entries for columns are separated by the tab character, which is
chr$(9).  Let's make our typing go faster and set a variable 
equal to the tab character:

    t$=chr$(9) 'tab character separates column entries

Here is the form our row of text will take for the call to
PrintColumnHeaders.  Each entry is separated by a chr$(9) and
the end is marked with a null termination -- chr$(0):

    Text$="Header One"+t$+"Header Two"+t$+"Header Three"+chr$(0)

NOTE:  If we did not want to place an entry in a column, we would
simply omit it, placing two tab characters together with nothing
between.  If, for instance, we did not have an entry for column 2,
our text string would be:

    Text$ = "Header One" +t$ +t$ + "Header Three" + chr$(0)

IMPORTANT NOTE!!  Make sure that the text to print contains the same
number of column entries that you have set up in the struct.  Place
tab characters as above to delimit text for each column.  You may 
also place an empty string as a placeholder:

    Text$ = "Header One" +t$ + "Header Two" + t$ + "" + chr$(0)


And here is the sample call:

    CallDll #vb, "PrintColumnHeaders",_
        Text$ as ptr,_         'row of items to print
        ncolumn as short,_     'number of columns
        column as struct,_     'struct containing columns
        FontName$ as ptr,_     'name of desired font
        FontSize as short,_    'font size
        Style as short,_       'font style attributes
        r as short

After all column text has been printed, call the function to
EndColumnPrinting:

    CallDll #vb, "EndColumnPrinting",r as short


PRINTING COLUMNS

You may do all of your column printing with PrintColumnHeaders.
If you would prefer, you can use PrintColumnText instead.  The
PrintColumnText call requires a call to SetUpColumns before it can
be used, just as the ParagraphText call required a setup call.
It may be that setting up the attributes in a separate call, which
is done only once for each change in setup, will run faster than
the calls which require params for all attributes to be passed
each time the call is made.

NOTE!!!  There is a limit of eight columns!

Setting up columns requires the same type of struct as the
PrintColumnHeader call.  You must have struct members for each 
column that you want to print, and each will contain the width 
in hundredths of an inch for the corresponding column.  Here is
another example of the struct in action.  This one has seven
columns, each of which is 1.1 inches wide.  Of course, you
can make each column a different width if you choose to do so.

    ncolumn=7
    struct column,_
        cone as short,_
        ctwo as short,_
        cthree as short,_
        cfour as short,_
        cfive as short,_
        csix as short,_
        cseven as short

    column.cone.struct=110
    column.ctwo.struct=110
    column.cthree.struct=110
    column.cfour.struct=110
    column.cfive.struct=110
    column.csix.struct=110
    column.cseven.struct=110

In addition to the struct, the SetUpColumns call requires the
font attributes as parameters:

    FontName$="Times New Roman"+chr$(0)
    Style=NORMAL.FONT
    FontSize=12

    CallDll #vb, "SetUpColumns",_
        ncolumn as short,_     'number of columns
        column as struct,_     'struct of column size info
        FontName$ as ptr,_     'font name
        FontSize as short,_    'font size
        Style as short,_       'font style attributes
        r as short

As before, the row of text is delimited by the tab character,
chr$(9) and finished with the null chr$(0).  Two tabs in a row 
will make an empty column entry.

   t$=chr$(9) 'a tab character separates column entries

    Text$="Apple"+t$+"Banana"+t$
    Text$=Text$+"Melon"+t$+"Orange"+t$
    Text$=Text$+"Peach"+t$+"Grape"+t$
    Text$=Text$+"Kiwi"+t$+"Pear"+chr$(0)

Now, the call to print the row of text into columns is made 
very simply:

    CallDll #vb, "PrintColumnText",_
        Text$ as ptr,_   'text string to print
        r as short

After all column text has been printed, call the function to
EndColumnPrinting:

    CallDll #vb, "EndColumnPrinting",r as short


JUSTIFIED NUMBERS IN COLUMNS:

For consistent results, it appears to be necessary to make the
call to PrintColumnHeaders rather than PrintColumnText if you
want to assure that your numbers are right justified.  There
is no magic in printing a column of justified numbers, it just
requires the Liberty BASIC USING function.  USING returns a string
that takes a numeric value and sets up the spacing of the
numerals according to the template you supply.  The template will
look like this:  "####.#####"  You must place a # character into
the template string for each number place you want to show, with
a dot to indicate where the decimal will appear.  Here is an example
that will print three rows of justified numbers:

    num1$=using("##########.##",67.89)
    num2$=using("##########.##",123.45)
    num3$=using("##########.##",12345.67)

    Text$=num2$+t$+num1$+t$+num3$+chr$(0)
    gosub [printColumnHeaders]

    Text$=num1$+t$+num3$+t$+num2$+chr$(0)
    gosub [printColumnHeaders]

    Text$=num3$+t$+num2$+t$+num1$+chr$(0)
    gosub [printColumnHeaders]

After all column text has been printed, call the function to
EndColumnPrinting:

    CallDll #vb, "EndColumnPrinting",r as short

This is the subroutine to call for each new row of text:

[printColumnHeaders]   
    CallDll #vb, "PrintColumnHeaders",_
        Text$ as ptr,_
        ncolumn as short,_
        column as struct,_
        FontName$ as ptr,_
        FontSize as short,_
        Style as short,_
        r as short
    RETURN


GRAPHICS WITH VBPRINT:

We can print some graphics primitives with vbprint:  a line,
a rectangle, a round rectangle and an ellipse.  Some units of
measurement in the vbprint.dll are in hundredths of an inch,
some are in pts (72 pts = 1 inch) and now we have another unit!
This one is twips.  An inch is made up of 1440 twips.  Using
twips allows us very fine control over graphics printing.  If
we want to position a figure at one and a half inches from the
left, the left x value would equal int(1.5 * 1440), which is the
way to express 1.5 inches in twips.

The simplest graphic entity to print is a line.  The call is to
DrawLine, and it requires only four parameters:  the x and y 
coordinates of one end point, then the x and y coordinates of 
the other end point.  PRINTABLE PAGE DIMENSIONS FOR MOST
PRINTERS ARE 8 INCHES WIDTH, AND 11 INCHES HEIGHT.

    ulx=1*1440   'x value for first end point
    uly=6*1440   'y value for first end point
    lrx=7*1440   'x value for second end point
    lry=10*1440  'y value for second end point

    CallDll #vb, "DrawLine",_
        ulx as short, uly as short,_
        lrx as short, lry as short, r as short

We can easily print a rectangle with DrawRectangle.  This call also
requires only four parameters.  The first two are the x,y coordinates
of one corner of the rectangle.  The second two params are the x, y
coordinates of the opposite corner of the rectangle.

    ulx=2*1440   'x value for upper left corner
    uly=8*1440   'y value for upper left corner
    lrx=3*1440   'x value for lower right corner (opposite first corner)
    lry=10*1440  'y value for lower right corner (opposite first corner)

    CallDll #vb, "DrawRectangle",_
        ulx as short, uly as short,_
        lrx as short, lry as short, r as short

We can also draw a rectangle with rounded corners with a call
to DrawRndRectangle.  It has six parameters.  The first four are 
identical to the ones in the DrawRectangle call.  The rounded corners 
have an elliptical shape determined by the height and width in the
5th and 6th parameter passed into the call.

    ulx=4*1440   'x value for upper left corner
    uly=8*1440   'y value for upper left corner
    lrx=6*1440   'x value for lower right corner (opposite first corner)
    lry=10*1440  'y value for lower right corner (opposite first corner)
    elx=1*1440   'width of ellipse for corner shaping
    ely=int(.75 * 1440) 'height of ellipse for corner shaping

    CallDll #vb, "DrawRndRectangle",_
        ulx as short, uly as short,_
        lrx as short, lry as short,_
        elx as short, ely as short, r as short

Finally, we can print an ellipse with a call to DrawEllipse.  This
will produce an ellipse (oval) that fits between the bounding 
rectangle determined by the four parameters in the call.  Imagine
taking the rectangle produced in a DrawRectangle call and fitting
an ellipse within its borders which just touched the sides of the
rectangle at its midpoints.

    ulx=1*1440   'x value for upper left corner of bounding rectangle
    uly=7*1440   'y value for upper left corner of bounding rectangle
    lrx=7*1440   'x value for lower right corner of bounding rectangle
    lry=int(10.5*1440)   'y value for lower right corner of bounding rectangle

    CallDll #vb, "DrawEllipse",_
        ulx as short, uly as short,_
        lrx as short, lry as short, r as short
 
THE LOOK OF GRAPHICS:

The look of the graphics is actually determined by the most recent
font used.  A large bold font produces a large bold line in
subsequent graphics.  If you want to influence the look of the
graphics in this way, first call the function StartParagraph and
use the font style corresponding to the line style you want in
the printed graphics. 

NOTE:  If you print the rectangle, the round rectangle or the
ellipse, they may appear to be outlines only.  This is not
the case, however.  You must think of them as being filled with
a white brush, not as hollow.  Try this experiment:  print a
block of text, coding a DrawRectangle function call so that
it places the rectangle in the same spot as the text, after the
text is printed.  You will find that the only text that prints 
is outside of the borders of the rectangle.


VERY IMPORTANT NOTE!!!

When the entire print job has been coded, you MUST make a call to
end the printing.  This tells the printer that you are finished.
If you do not do this, you will get error messages, and perhaps
a program crash.  Be sure to close the dll also:

    CallDll #vb, "DonePrinting",r as short
    close #vb


MANAGEMENT CALLS

If you find a need to abort printing for any reason, the
call to make is to KillJob:

    CallDll #vb, "KillJob",r as short

The vbprint.dll will automatically issue a page feed command
to the printer when the bottom of the page is reached, or when
you call DonePrinting.  If you want to eject a page yourself
during the print job, call EjectPage:

    CallDll #vb, "EjectPage",r as short

Position for printing is determined in two ways.  When you issue
graphics print commands, you specify exactly where you want
the entity to appear on the page.  When you are printing any
text, the dll automatically advances the Y cursor down the page
as more lines are printed, paying attention to the values for
paragraph spacing that we mentioned earlier.  If you want to
advance the cursor down the page yourself, to leave a gap
between printed lines, the call is MoveYPos, and the units
in the call are in hundredths of an inch.  To move the Y cursor
2 inches, pass the parameter as 200:

    distY = 200  '2 inches
    CallDll #vb, "MoveYPos",_
        distY as short, r as short


INFORMATIONAL FUNCTIONS:

We can discover information about our printer, and about the
DLL also.  


PRINTER PORT:
To retrieve the name of the printer port, call PrinterPort.  
You must set up a string buffer to receive the information.  
It MUST be zero terminated, or the DLL will not be able to 
place the information into the buffer.

    Port$=space$(256)+chr$(0)

    CallDll #vb, "PrinterPort",Port$as ptr, r as short

After making the call, the name of the printer port will be in
the variable Port$.  It might be "LPT1"


PRINTER NAME:
We can find out the printer name in much the same way:

    pName$=space$(256)+chr$(0)

    CallDll #vb, "PrinterName",pName$ as ptr, r as short

After making the call, the name of the printer will be in the
variable pName$.  It might be "Acme Color DeskJet #33"


PRINTABLE PAGE SIZE:
We can also get the size (in twips) of the printable width 
and height of the page with PageSizeX and PageSizeY.  These
two functions need no parameters, and they return the values
as called.  Divide the results by 1440 to ascertain the values
in inches:

    CallDll #vb, "PageSizeY", pageheight as short
    CallDll #vb, "PageSizeX", pagewidth as short

pageXinches = pagewidth/1440
pageYinches = pageheight/1440


PAGE CONDITION:
You can find out if anything has previously been printed on 
a page with a call to IsPageDirty.

    CallDll #vb, "IsPageDirty",_
		dirty as short  'returns nonzero if answer is yes

    if dirty > 0 then dirty$ = "YES" else dirty$ = "NO"
    notice "Is Page Dirty?  "+dirty$


DLL VERSION:
You will probably never need this one, but you can retrieve
the version number of the vbprint.dll with the call to
PrintDLLVersion.
    CallDll #vb, "PrintDLLVersion",version as short

The major version number is in the low byte of the result
and the minor version number is in the high byte of the 
result.  Retrieve them like this:

        minor=int(version/256)
        major=version - (major*256)

---------------------------------------------------------
There are many source code samples that demonstrate the
functions in this dll, along with the dll in the file
attached to this newsletter.
---------------------------------------------------------
PRINTING WITH STRAIGHT API CALLS

You can print anything you want with straight API function
calls to GDI.dll.  You can create fonts with any attributes
of your choice, including upside-down and sideways.  You
can print text and graphics in the colors of your choice.
You can print many more graphic figures, such as pie shapes
and polygons.  You can fill these shapes with pattern brushes
in your choice of colors.  You can also print bitmapped 
images.  You can print a hard copy of anything you can draw
on the screen.  

Printing is one of the most complex parts of API functions.
It should only be attempted when you feel that you have a
good grasp of Liberty BASIC, and of calling on the API.
For an example that prints a two-fold greeting card, with
text and images in different orientations, check out the
cardmaker at Side by Side Software, in the programs section:

http://alyce.50megs.com/sss/

A chapter of the electronic book we have written deals with
printing issues, giving full explanations for these functions.
It is available on CDROM:

http://alyce.50megs.com/sss/cd.htm
---------------------------------------------------------
Newsletter compiled and edited by: Brosco and Alyce.
Comments, requests or corrections: Hit 'REPLY' now!
mailto:brosco@orac.net.au or mailto:awatson@wctc.net
---------------------------------------------------------