Liberty Basic is develeopped by Carl Gundel Original Newsletter compiled by Alyce Watson and Brosco Translation to HTML: Raymond Roumeas
In this issue:
Hard copy printing in Liberty BASIC with lbprnt01.dll
In future issues:
- Copyright and licensing considerations
- the FILES command
- Writing and using an ini file
- Writing output 'code'
- Choosing fonts
- RGB color choices
- Changing the runtime icon
- Launching the default web browser and email client
- Installers
In Newsletter #63, we discussed several ways to achieve hard copy printouts using Liberty BASIC. We can use Liberty BASIC's own LPRINT function for text and the graphics PRINT function for graphicboxes and graphics windows. We can ask Notepad, or other default text editor to print text for us. We can use Dean Hodgson's excellent library, Deanslib.dll. We can also "do it all" with api function calls.
We discussed the vbprint.dll at length, and it is a great tool. If only it offered a few more functions...
I've had it in mind to write a printing dll for Liberty BASIC for some time, and all of this printing discussion has prompted me to give it a try. The result is not perfect, but it does offer some useful functions.
BY ALYCE WATSON
awatso-@wctc.net
© Alyce Watson, 2000
ALL RIGHTS RESERVED
LBprnt01.dll is being released as shareware. It is not crippled or time limited, and it contains no nags. The released version is the only version there is. Registration will be on the honor system. For use in commercial applications, the one-time registration fee is $15.00. For all other uses, the registration fee is determined by the individual user, with a suggested value of $1.00. This will help defray the cost of the many ink cartridges reams of printer paper that were consumed in writing and testing this. Note that anyone who has purchased the CDROM, Windows Programming for Everybody with Liberty BASIC need not register the DLL, except for commercial use. Send registration fee to:
Alyce Watson
3030 Buchberger Road
Wisconsin Rapids, WI 54494 USA
- Carl Courtney mailto:carlcour-@aol.com
- Eldron Gill mailto:egil-@eritter.net
- Bill Jennings mailto:bbje-@tir.com
- Brian Pugh mailto:bdpug-@hipperholme19.freeserve.co.uk
- Dean Hodgson mailto:dhodgso-@nexus.edu.au
Without their help, this DLL would never have seen the light of day.
Thank you, friends.
You must first open the DLL, of course!
Open "lbprnt01.dll" for dll as #lb
To begin a print job, you must call either PrinterInit or PrinterDialog. All other printing functions should be placed after one of these calls. When the job is ready to be sent to the printer, you must call EndPrint. You may initialize the printer, print, then call EndPrint as many times as you need within a program. When you are finished with all printing jobs, close the DLL:
close #lb
You may use either of the following calls to initialize the printer. Use PrinterDialog if you want to give the user a chance to cancel the operation, to choose the printer to use, or to choose the number of copies to print. The window handle is the first parameter in the call. It is best to use your program window's handle for this parameter, but it may be set to zero. The return from the PrinterDialog function is the device context of the printer.
CallDll #lb, "PrinterDialog",_ 'must call this to start a documenth as short,_ 'handle of program window pDC as short 'nozero if successful = printer DC
PrinterInit does not give the user a chance to cancel the operation, or to choose number of copies or printer. It also requires the window handle as the first parameter and it returns the printer device context. In this case, it will be the user's default printer.
CallDll #lb, "PrinterInit",_ 'init with no print dialogh as short,_ 'window handle pDC as short 'nonzero if successful = printer DC
You cannot print anything if the initialization call fails, so be sure to trap that possiblity in your code. If pDC = 0, then you do not need to call EndPrint. Here is one way:
IF pDC = 0 THEN
notice "Print job cancelled!"
goto [loop]
END IF
When all items to be printed have been added to the document, then
call EndPrint to send the job to the printer. The EndPrint call will
release the DC of the printer and eject the final printed page.
After issuing this call, you will need to initialize the printer
again for a new print job.
CallDll #lb, "EndPrint",_ 'ends document, ejects final page
h as short,_ 'window handle
r as short 'nonzero if successful
If you have initialized with PrinterDialog, you can retrieve
the number of copies requested by the user with the GetNumberCopies
function. You cannot get other information, such as page selections
if the user chooses to print only part of the job, or print quality.
This function does not retrieve the number of pages in each job, but
the number of printouts requested by the user.
CallDll #lb, "GetNumberCopies",_ 'only works with PrinterDialog call
h as short,_ 'window handle
numbercopies as short 'number of copies chosen by user
IMPORTANT NOTICE
PrinterDialog and PrinterInit both return the device context of
the printer, and call StartDoc and StartPage. If you are familiar
with printer function calls to GDI.DLL, you may place your
own calls in amongst calls to the lbprnt01.dll. Calling
EndPrint calls EndPage and EndDoc and releases the printer DC.
---------------------------------------------------------
CREATE FONTS
All text will be printed using the font Courier New - 10pt, unless
you choose to create a font of your own. You do not need to create
a font, but you may do so. There are three ways to create a font
with this dll. The easiest way requires only the name of the font
face desired, and the fontheight in hundredths of an inch. A
fontheight of 25, for instance, would result in a font that is one
quarter of an inch high = 25/100 inch. Note that the height includes
the blank space between lines, which is called the "External Leading"
space. The actual font will be slightly smaller than the height you
specify. This simple font creation function is called EasyFont.
In Liberty BASIC, when we specify font names, we must replace any blanks
in the name with an underscore character. "Courier New" becomes
"Courier_New" in Liberty BASIC syntax. DON'T DO THAT HERE!! Please
leave blank spaces blank for these font creation functions. You must
terminate the string containing the font name with a null character,
which is chr$(0) Here is the correct syntax for specifying a font
name and height in this dll:
pfontname$="Courier New" + chr$(0) 'must be null terminated
height=24 'in hundredths of inch
The call to EasyFont requires the window handle, height parameter as
short, and the fontname parameter as a pointer. The function
returns the handle of the created font. If the return is 0, the
function was unable to create a font.
CallDll #lb, "EasyFont",_ 'easy create font
h as short,_ 'window handle
height as short,_ 'height in hundedths of inch
pfontname$ as ptr,_ 'null terminated, no LB underscores
hfont as short 'returns handle of font
You can create a font with additional attributes, with a call to
PrinterFont. It has a few more parameters; bold, italic, underline,
and strikeout. If any of these parameters is set to 1, that attribute
will be set. They can be used in any combination, so a font can be
both bold and underlined, for instance. If an attribute's parameter is
set to 0, that attribute will not be used in the font. The other
parameters are exactly the same as for the EasyFont call:
pfontname$="Courier New" + chr$(0) 'must be null terminated
'no underscores between words
height=30 'in hundredths of inch
bold=0 'do not make it bold
italic=1 'make it italic
underline=1 'make it underlined
strikeout=0 'do not make it strikeout
CallDll #lb, "PrinterFont",_ 'create a font with many attributes
h as short,_ 'window handle
height as short,_ 'height in hundredths of inch
bold as short,_ '0=normal 1=bold
italic as short,_ '0=normal 1=italic
underline as short,_ '0=normal 1=underline
strikeout as short,_ '0=normal 1=strikeout
pfontname$ as ptr,_ 'null terminated, no LB underscores
hfont as short 'returns handle of font
For the purists, there is another font creation function that allows you
to create fonts in point sizes, rather than in hundredths of an inch. There
are approximately 72 points in an inch. When you use a word processor such
as WordPad, the fonts are sized in points. All parameters are the same as
in the call to PrinterFont, except that the size attribute for the call,
PointSizeFont is in points instead of hundredths of an inch:
CallDll #lb, "PointSizeFont",_ 'create a font with many attributes
h as short,_ 'window handle
height as short,_ 'height in points - 72 pts per inch
bold as short,_ '0=normal 1=bold
italic as short,_ '0=normal 1=italic
underline as short,_ '0=normal 1=underline
strikeout as short,_ '0=normal 1=strikeout
pfontname$ as ptr,_ 'null terminated, no LB underscores
hfont as short 'returns handle of font
SET TEXT COLOR
You may choose an RGB color for text printing. It requires a struct
containing the color information. Color values are for red, green,
and blue, and each should be between 0 and 255. 0 means none of a
color, so rgb of 0,0,0 results in black. 255 is total saturation of
a color, so rgb of 255,255,255 is white. If you wanted pure red, you
would set that value to 255, and the others to 0. Here's an example:
struct col,_ 'holds info for text color
red as short,_ 'red value = 0-255
green as short,_ 'green value = 0-255
blue as short 'blue value = 0-255
col.red.struct = 255 '0-255
col.green.struct = 0 '0-255
col.blue.struct = 0 '0-255
CallDll #lb, "ChooseTextRGB",_
h as short,_ 'handle of window
col as struct,_ 'struct of color info
r as long 'nonzero if successful
If the user does not have a color printer, text will be printed
in black, no matter what color you set. This would be true
of a dot matrix printer, for instance.
---------------------------------------------------------
PRINTING TEXT
There are two functions that print text in this dll. Both
will print one line of text in the default font, or in the
most recently created font, and in the color from
ChooseTextRGB, if that function has been called. It is not
necessary to create a font or to set a text color. In that
case, defaults will be used.
**************************************************
********IMPORTANT NOTE ABOUT TEXT PRINTING********
**************************************************
There are two ways to print a line of text with this DLL.
Using PrintTextLocate allows the programmer complete control
over text location on the printed page. Starting new pages
is the responsibility of the programmer.
Using PrintTextLine lets the DLL print one line after another
at the proper line spacing. The DLL controls the location
of text on the printed page, starting new pages when needed.
Although these functions may both be used in the same print
job, it is best to use one or the other, and not both, to
preclude the possibility of one function overwriting text that
has been placed on the page by the other function.
**************************************************
********IMPORTANT NOTE ABOUT TEXT PRINTING********
**************************************************
PrintTextLocate
The first text print function allows the programmer complete
freedom over text location on the page. X location and Y
location are set in hundredths of an inch. Setting xloc to
200 would cause the start of the text to be two inches from
the left margin. Keep in mind that most printers allow a
printable width of about eight inches, and a printable height
of about ten and a half inches. Some newer printers will allow
nearly the full 8 1/2 inch width and 11 inch height.
You must use a null terminator on each line of text, as you
did for the fontname discussed earlier:
text$="Some words."+chr$(0)
You also need to determine the length of the text line to
print. Do NOT include the null terminator in this length,
so if you have added chr$(0) before determining the length,
remember to subtract 1.
length=len(text$)-1
xloc=100:yloc=200
CallDll #lb, "PrintTextLocate",_ 'print one line of text
h as short,_ 'window handle
text$ as ptr,_ 'text string to print
xloc as short,_ 'x location in hundredths of inch
yloc as short,_ 'y location in hundredths of inch
length as short,_ 'length of text string
r as short 'nonzero if successful
You can determine the maximum number of characters that will
fit across the width of the printer page, in the current
font, with a call to GetMaxCharsTotalWidth. This will tell
you how many characters will fit in a line of text if it
begins at the very left edge of the paper, and continues all
of the way to the right edge. You can use this value to
determine the maximum length of a line to print with
PrintTextLocate:
CallDll #lb, "GetMaxCharsTotalWidth",_ 'total characters from edge to edge
h as short,_ 'window handle
totalmax as short 'total number of chars that will
fit,
'if text starts at left edge
PrintTextLine
Using the previous function to print text requires the programmer
to keep track of the location of all text on the page. You
can eliminate this need by calling PrintTextLine. Calls to
this function will print a line of text in the current font and
color, and within the current margins. Each subsequent call will
advance the Y cursor the proper amount for the font size in use.
It doesn't matter if you change fonts for each line, the next line
will print at the proper distance from the previously printed line.
The parameters are similar to the PrintTextLocate call, but no
X and Y location are needed:
text$="Some words."+chr$(0)
length=len(text$)-1
CallDll #lb, "PrintTextLine",_ 'prints line, moves down automatically
each line
h as short,_ 'window handle
text$ as ptr,_ 'text string to print
length as short,_ 'length of text string
r as short 'nonzero if successful
If you need to advance the text printing location down the page more than
one line's height, then make a call to PrintBlankLine. This call can
be made as many times as needed to create the space desired.
CallDll #lb, "PrintBlankLine",_ 'move cursor down page the height of
one line
h as short,_ 'window handle
r as void 'no return
When calling PrintTextLine and PrintBlankLine, you do not need
to concern yourself with the location of the bottom of the page.
When the bottom of the page is reached, the page will automatically
be ejected, and a new page will begin. This takes the current margins
into account for all four sides of the page.
If you do need to know the location of the Y cursor, which is the Y
location to print the NEXT line with PrintTextLine, you may use
the function GetLineYPos, which returns the location of the Y cursor
in hundredths of an inch.
CallDll #lb, "GetLineYPos",_ 'cursor position for PrintTextLine
h as short,_ 'window handle
linepos as short 'position of y cursor in hundredths
Remember that the Y cursor is only used by PrintTextLine. In
PrintTextLocate, the programmer has complete control over the
location of the text on the page. If you are not careful, a call
to PrintTextLocate could overwrite lines printed with PrintTextLine.
Calling GetLineYPos will help you determine the lower extent of text
printed with PrintTextLine.
You may retrieve the current line height, as determined by the current
font, with GetTextLineHeight. This function retrieves the height of
a font, including the space between the previous line of text, and the
top of the font, which is called the External Leading space. This
line height value is used by the DLL in PrintTextLine to determine
the y position of each succeeding line of text. You may retrieve this
value for use in PrintTextLocate, for proper line spacing when you locate
text on the page. The line height is returned in hundredths of an inch.
CallDll #lb, "GetTextLineHeight",_ 'height for lines in current font
h as short,_ 'window handle
lineheight as short 'height in hundredths of text line
Notice that for both PrintTextLocate and PrintTextLine, only one
line of text at a time may be printed. For PrintTextLine, you
can make a call to GetMaxChars to determine the maximum number
of characters that can be printed across the width of the page,
considering the current page margins:
CallDll #lb, "GetMaxChars",_ 'max for PrintTextLine, current margins
h as short,_ 'window handle
maxchar as short 'total number of characters that will fit
'in a line within current page margins
You may eject a page and start a new page yourself whenever you
would like, by calling NewPage:
CallDll #lb, "NewPage",_ 'ejects page, starts new one
h as short,_ 'window handle
r as short 'nonzero if sucessful
You may retrieve the values for the maximum possible width
of a character in the current font, and the value for
the average width of a character, with the following two
functions. Maximum width and average width will be the same,
or very close to the same for a fixed width font. They might
vary greatly for a variable width font. In a fixed width font,
all characters occupy the same space, as on an old-fashioned
typewriter. In a variable width font, large characters, such as
an upper case letter "M" will take much more space than small
characters such as a lower case "i", a comma, a space, etc.
CallDll #lb, "GetMaxCharWidth",_ 'maximum width of char in current font
h as short,_ 'window handle
maxwidth as short 'max char width in printer dots
CallDll #lb, "GetAveCharWidth",_ 'average width of char in current font
h as short,_ 'window handle
avewidth as short 'ave char width in printer dots
---------------------------------------------------------
MARGINS for PrintTextLine
Margins are only significant when using the PrintTextLine
function. The default margins are one inch on all sides.
If you are using PrintTextLocate, you are not restricted,
and you may print right up to all edges of the paper. You
may change the margins that will be used by PrintTextLine
with the following four functions that allow you to change
only the margins desired. Remember, the default margins
are all one inch, and needn't be changed unless you desire
to do so. Margins are set in hundredths of an inch.
Choosing a margin of 50 would result in a half inch
margin: 50/100 = one half inch.
top=100 'top margin in hundredths of inch
CallDll #lb, "SetTopMargin",_
h as short,_ 'window handle
top as short,_ 'top margin in hundredths of inch
r as short 'nonzero if successful
right=80 'right margin in hundredths of inch
CallDll #lb, "SetRightMargin",_ 'OPTIONAL
h as short,_ 'window handle
right as short,_ 'right margin in hundredths of inch
r as short 'nonzero if successful
bottom=100 'bottom margin in hundredths of inch
CallDll #lb, "SetBottomMargin",_
h as short,_ 'window handle
bottom as short,_ 'bottom margin in hundredths of inch
r as short 'nonzero if successful
left=150 'left margin in hundredths of inch
CallDll #lb, "SetLeftMargin",_
h as short,_ 'window handle
left as short,_ 'left margin in hundredths of inch
r as short 'nonzero if successful
---------------------------------------------------------
PRINTER INFORMATION
There are four functions in the DLL that will tell you
information about the printer resolution. GetDotsInchWidth
will tell you how many printer dots are in one inch of
page width. My printer has 300 dots per inch. My previous
printer had 360 dots per inch width. My old dot matrix
printer has only 75 dots per inch width. You may also
find out the dots per inch height with a call to
GetDotsInchHeight. Why do we need both? Aren't they the
same? No! On some printers there are more dots in one
direction than in the other.
CallDll #lb, "GetDotsInchWidth",_
h as short,_ 'window handle
dpix as short 'dots per inch in width
CallDll #lb, "GetDotsInchHeight",_
h as short,_ 'window handle
dpiy as short 'dots per inch in height
The other measurements of printer resolution in the dll are
for total dots per width and height of the paper. In
general, the total dots per width will be equal to the
dots per inch width multiplied by 8 -- the number of inches
that may be printed by most printers. My printer has
300 dots per inch width, and 2400 total dots per page width.
In the same way, the total dots in the height will be equal
to the number of dots per inch in height multiplied by 10 1/2.
Here are the calls to get total dots:
CallDll #lb, "GetDotsTotalWidth",_
h as short,_ 'window handle
dotswide as short 'total dots in width
CallDll #lb, "GetDotsTotalHeight",_
h as short,_ 'window handle
dotshigh as short 'total dots in height
If you want to know the width of a page in printable inches,
then divide the Total Dots Width by the Dots per Inch Width.
inchesWide=dotswide/dpix
The same is true for height in inches:
inchesHigh=dotshigh/dpiy
---------------------------------------------------------
GRAPHICS
LINE
There are four graphics entities that can be printed with
the dll. The first is PrintLine. The parameters x1 and y1
specify the starting point of the line, in hundredths of an
inch, on the printed page. The parameters x2 and y2 specify
the ending points of the line. You may draw as many lines
as you would like.
CallDll #lb, "PrintLine",_
h as short,_ 'window handle
x1 as short,_ 'x origin in hundredths of inch
y1 as short,_ 'y origin in hundredths of inch
x2 as short,_ 'x end in hundredths of inch
y2 as short,_ 'y end in hundredths of inch
r as short 'nonzero if successful
RECTANGLE
Printing a rectangle is quite similar to printing a line. The
parameters x1 and y1 specify the coordinates for the starting
corner of the rectangle -- usually the upper left corner is used.
The parameters x2 and y2 specify the coordinates for the corner
opposite the starting corner. If the upper left corner was determined
by the x1, y1 parameters, then the x2, y2 parameters would specify
the coordinates for the lower right corner of the rectangle. All
coordinates are in hundredths of an inch locations on the printed
page.
CallDll #lb, "PrintRectangle",_ 'measure in hundredths of inch
h as short,_ 'window handle
x1 as short,_ 'x origin corner
y1 as short,_ 'y origin corner
x2 as short,_ 'x end opposite corner
y2 as short,_ 'y end oppposite corner
r as short 'nonzero if successful
ELLIPSE
The call to print an ellipse is very similar to the PrintRectangle call.
This is because the parameters also specify a rectangular shape, in
just the same way as they did in the PrintRectangle call. This
rectangle will not be visible, but it will be the bounding rectangle
for the ellipse. The ellipse will be drawn so that its edges intersect
the bounding rectangle on all four sides.
CallDll #lb, "PrintEllipse",_ 'measure in hundredths of inch
h as short,_ 'window handle
x1 as short,_ 'x origin corner - bounding rectangle
y1 as short,_ 'y origin corner - bounding rectangle
x2 as short,_ 'x end opposite corner - bounding rectangle
y2 as short,_ 'y end oppposite corner - bounding rectangle
r as short 'nonzero if successful
ROUND RECTANGLE
The call to PrintRoundRectangle is indentical to the PrintRectangle call
except that it contains two more parameters. The x3 parameter specifies
the width of a small ellipse that will be used to round the corners of
the rectangle. The y3 parameter specifies the height of the small
ellipse that will be used to round the corners. The larger these
numbers in relation to the size of the Round Rectangle, the more rounded
the corners will be. A small relative size of the x3 and y3 parameters
will create sharper curves on the corners of the round rectangle.
CallDll #lb, "PrintRoundRectangle",_ 'measure in hundredths of inch
h as short,_ 'window handle
x1 as short,_ 'x origin corner
y1 as short,_ 'y origin corner
x2 as short,_ 'x end opposite corner
y2 as short,_ 'y end oppposite corner
x3 as short,_ 'corner ellipse width
y3 as short,_ 'corner ellipse height
r as short 'nonzero if successful
---------------------------------------------------------
COLOR IN GRAPHICS
PRINTER PEN
Objects are drawn with black lines unless changed by programmer. The
drawing pen can be altered in width, style and color, by calling the
PrinterPen function. You may set the color for any pen style. As
in the ChooseTextRGB function, the values for red, green, and blue may
be between 0-255, with 0, 0, 0 being black. You may set the size of
the pen for the pen style _PS_SOLID. This size will be in logical
units, which in this case are printer dots. You may call the function
GetDotsInchWidth to determine the best number of dots for the pen size,
if this is important in your graphics. For instance, with a dots per
inch of 300, a size of 75 would give a one quarter inch thick pen.
You may set the style of the pen also. All styles other than a solid
pen default to size 1. Here are the possible styles:
'0 = _PS_SOLID PS = PEN STYLE
'1 = _PS_DASH
'2 = _PS_DOT;
'3 = _PS_DASHDOT
'4 = _PS_DASHDOTDOT
'> 4 THEN default is _PS_SOLID
'NOTE if style > 0 then size reverts to 1 pixel
The PrinterPen function returns the handle of the created pen,
if successful.
CallDll #lb, "PrinterPen",_ 'shapes outlined with pen
h as short,_ 'window handle
size as short,_ 'size in dots
style as short,_ 'pen style
pred as short,_ 'red value 0-255
pgreen as short,_ 'green 0-255
pblue as short,_ 'blue 0-255
hPen as short 'returns handle of pen
PRINTER BRUSH
Objects are filled with hollow brush unless changed by programmer.
Unless you specify a brush, your drawn objects will just be
outlines. You must again specify the rgb color values for the
brush, just as for the PrinterPen and ChooseTextRGB functions.
You must also choose a brush style. To fill shapes with a solid
color, choose a style value of 6. The other style patterns are
as follows:
'0 = _HS_HORIZONTAL HS = HATCH STYLE
'1 = _HS_VERTICAL
'2 = _HS_FDIAGONAL
'3 = _HS_BDIAGONAL
'4 = _HS_CROSS
'5 = _HS_DIAGCROSS
'6 will give a solid fill = no pattern
The PrinterBrush function returns the handle of the created brush,
if successful.
CallDll #lb, "PrinterBrush",_ 'fills graphics entities
h as short,_ 'window handle
style as short,_ '6=solid, 0-5 are hatch styles
pred as short,_ 'red value 0-255
pgreen as short,_ 'green 0-255
pblue as short,_ 'blue 0-255
hBrush as short 'returns handle of brush
If you have created a PrinterBrush, then have a need to
return to a hollow brush to draw outline figures only,
then call PrinterNullBrush.
The PrinterNullBrush function returns the handle of the created
brush, if successful.
CallDll #lb, "PrinterNullBrush",_ 'allows you to return to default
hollow figure
h as short,_ 'window handle
hBrush as short 'returns handle of brush
---------------------------------------------------------
SCREEN PRINT
*************** WARNING ************************
IN TESTS, THIS FUNCTION SOMETIMES RESULTED IN
A GRAYSCALE PRINTOUT, RATHER THAN A COLOR PRINTOUT.
WHEN IT PRINTS IN COLOR, IT MAY NOT APPEAR THE
SAME AS THE SCREEN DISPLAY VERSION.
*************** WARNING ************************
As we've discussed in a previous newsletter, the graphics
printing capabilities of Liberty BASIC have some limitations.
The PrintWindowArea function will allow some graphics printing
flexibility. The first parameter required is the window's
handle. YOU MUST USE THE HANDLE OF THE GRAPHICS WINDOW OR
GRAPHICBOX - you may not use 0 for this parameter in this
function. After the window handle parameter, there are four
parameters that specify the location and size of the screen
image to capture. You need not take the entire image. The xorg
and yorg are the coordinates of the upper left corner of the
desired area, in PIXELS! Remember that pixels are the logical
units of the display, so the measurements for the screen are in
pixels. The width and height parameters tell the function how much
of the screen to copy to the printer, in pixels. If you wanted to
capture the image from x = 10, y = 33, and take an area that is
100 pixels by 227 pixels:
xorg=10
yorg=33
width=100
height= 227
The next four parameters are the ones that tell the printer where
to locate the screen image on the page, and how large to make it.
These values are all given in hundredths of an inch. The params,
pxorg and pyorg will define the location of the upper left corner
of the screen image on the printed page, in hundredths of an inch.
If you wanted the image to begin 2 1/2 inches from the left side
of the page, you would have pxorg = 250.
The next two parameters tell the printer how wide and high you
want to make the image -- again in hundredths of an inch. If
you wanted the image to be four inches wide, then pwidth = 400.
CallDll #lb, "PrintWindowArea",_
h as short,_ 'valid window handle NOT = 0 !
xorg as short,_ 'starting x pixel for print
yorg as short,_ 'starting y pixel for print
width as short,_ 'pixel width from screen
height as short,_ 'pixel height from screen
pxorg as short,_ 'x loc on page in hundredths of inch
pyorg as short,_ 'y loc on page in hundredths of inch
pwidth as short,_ 'width of image on page in hundredths of inch
pheight as short,_ 'height of image on page in hundredths of inch
r as short 'nonzero if successful
There have been some reports that this function results in a
grayscale printout on some systems. Please take this into
consideration when using this function.
---------------------------------------------------------
BITMAP PRINT
You may print a hard copy of any bitmap that is loaded
into memory. The bitmap may be loaded with Liberty BASIC's
LOADBMP function, or it may be an image loaded from a third-
party DLL. You must have the handle of the bitmap to pass
into the call. If the image was loaded with an add-on DLL,
you will likely get the handle of the bitmap as the return from
the loading function. In Liberty BASIC, we get the handle
of a bitmap with the HBMP function. The syntax would be:
loadbmp "party","party.bmp"
hbitmap = hbmp("party")
After the window handle and the bitmap handle, you must specify
the coordinates for the location and size to print the bitmap
on the paper. These values are in hundredths of an inch.
The point x1, y1 will determine the upper left corner for
bitmap placement on the page, in hundredths of an inch. If
you wanted to print the bitmap 3 1/4 inches from the top, then
y1 = 325.
You must also set a width and height to print the bitmap, in
hundredths of an inch. If you want the bitmap to be 4 inches
wide, then pwidth = 400. The function returns nonzero if
successful.
CallDll #lb, "PrintBitmap",_
h as short,_ 'window handle
hbitmap as short,_ 'bitmap handle
x1 as short,_ 'org x on page in hundredths
y1 as short,_ 'org y on page in hundredths
pwidth as short,_ 'hundredths of inch wide to print
pheight as short,_ 'hundredths of inch high to print
r as short 'nonzero if successful
To aid in sizing and proportion when printing a bitmap, there
are functions that return the bitmap's dimensions. You may
use these for scaling/sizing purposes. To retrieve the
width of a loaded bitmap, pass the handle of the bitmap into
the function BitmapWidth, and the function returns the width
of the bitmap in pixels. The BitmapHeight function will
return the height of the bitmap in pixels. You can use these
values to set the width and height of the printed copy of the
bitmap. If you multiply the bitmap width and bitmap height
by the same factor, then the proportions will remain the
same. It is not necessary to keep the proportions the same,
so you may use different scaling factors if you wish.
CallDll #lb, "BitmapWidth",_
h as short,_ 'window handle
hbitmap as short,_ 'bitmap handle
bmpwidth as short 'bitmap width
CallDll #lb, "BitmapHeight",_
h as short,_ 'window handle
hbitmap as short,_ 'bitmap handle
bmpheight as short 'bitmap height
If you wanted the bitmap to be twice as large (in hundredths
of an inch) on the printed page as its width on the screen,
then you would set the width and height like so:
pwidth = 2 * bmpwidth
pheight = 2 * bmpheight
If you wanted the bitmap to be out of proportion, you might
have something like this:
pwidth = 3 * bmpwidth
pheight = int(2.3 * bmpheight)
Note that you should use the INT function if there is a chance
of a fractional value, because Liberty BASIC will crash
if you try to use a fraction as a parameter in an api call.
---------------------------------------------------------
DEMOS
There are several demonstration programs included with this
newsletter that use many of the functions in the dll.
There are demos using the following line-wrap routine.
There is also a great demo by Bill Jennings, with a better
line-wrap routine, so thanks AGAIN, Bill!
It would be very, very nice if people would post code that
uses this DLL, so that others can benefit, and so that the
author of the DLL knows if this tool has been useful.
---------------------------------------------------------
LINE WRAP
This DLL will print one line of text. It will not automatically
wrap lines that are too long to fit on the width of the page.
Please consider whether the VBprint.dll we discussed in an
earlier newsletter would be better for your needs, if your
program needs to print large blocks of text easily.
The function GetMaxCharsTotalWidth will tell you the approximate
number of characters that will fit on a line, if the line is
to begin at the left printable edge of the page, and continue
to the right printable edge. You can use this value to
determine the length to make lines to insure that they will not
be truncated when using PrintTextLocate. This formula uses the
average character width to calculate the maximum number of
characters, so it will only be approximate.
The function GetMaxChars will tell you the approximate number
of characters that will fit on a line using PrintTextLine
with the current margins. You can use this value to determine
the length to make lines, so that they will not be truncated.
This formula also uses the average character width to calculate
the maximum number of characters, so it will only be
approximate.
If you would like to send a large block of text to the printer,
without concerning yourself with line-wrapping, the following
subroutine is provided for your convenience. You will need
to place the text string into a variable called TextBlock$
and then call GOSUB [print.text.block]. Be sure to paste
the routine below, unchanged, into your code. The beginning
and end of the routine are clearly marked. The block of
text can be obtained from an opened file, like this:
open "readme.txt" for input as #rm
TextBlock$ = input$(#rm, lof(#rm))
close #rm
gosub [print.text.block]
The contents of a text editor may be retrieved and printed
using this subroutine, like this:
print #1.texted, "!contents?";
input #1.texted, TextBlock$
gosub [print.text.block]
You may also hard-code the text into your program like this:
TextBlock$="Here is some text to print. It can be as long as you like."
gosub [print.text.block]
SUBROUTINE FOR PRINTING WITH LINE-WRAP FOLLOWS:
---------------------------------------------------------
'-----------------------------------------------
'-----------------------------------------------
' BEGIN LINE-WRAP ROUTINE
' DO NOT CHANGE THE CODE BELOW!
'
' LBPRNT01.DLL MUST BE OPENED
' AS #lb
'
' PRINTER MUST BE INITIALIZED WITH
' PrinterDialog
' OR
' PrinterInit
'
' SEND IN A BLOCK OF TEXT IN
' A STRING CALLED TextBlock$
' CALL GOSUB [print.text.block]
'-----------------------------------------------
'-----------------------------------------------
[print.text.block]
gosub [get.max.chars.in.line] 'returns max.char
gosub [print.wrap] 'wraps and places in temp file tf.tmp
Open "tf.tmp" for input as #5
While eof(#5)=0
Line input #5, temp.line$ 'send one line of text to printer
[fix.tab.stops]'removes chr$(9) and replaces with blank spaces
if instr(temp.line$,chr$(9))>0 then
blank=instr(temp.line$,chr$(9))
blank=instr(temp.line$,chr$(9))
temp.line$=left$(temp.line$,blank-1)+space$(4)+Mid$(temp.line$,blank+1)
if instr(temp.line$,chr$(9))>0 then goto [fix.tab.stops]
end if
line.length=len(temp.line$)
temp.line$=temp.line$+chr$(0)
gosub [print.text.line.from.block]
wend
close #5
kill "tf.tmp"
return
[print.text.line.from.block]
CallDll #lb, "PrintTextLine",_
h as short,_ 'window handle
temp.line$ as ptr,_ 'text string to print
line.length as short,_ 'length of text string
r as short 'nonzero if successful
RETURN
[get.max.chars.in.line]
CallDll #lb, "GetMaxChars",_
h as short,_ 'window handle
max.char as short 'returns maximum chars in line
RETURN
[print.wrap] 'word wrap for printing based on max.char formula
newL$=""
CrLf$=chr$(13)
ist = 1
while ist < len(TextBlock$)
nst = instr(TextBlock$, CrLf$, ist)
if nst = 0 then
line$ = mid$(TextBlock$, ist)
ist = len(TextBlock$)
else
line$ = mid$(TextBlock$, ist, nst-ist)
ist = nst + 2
if line$ = "" then newL$ = newL$ + CrLf$
end if
while line$ <> ""
if len(line$) <= max.char then
newL$ = newL$ + line$ + CrLf$
line$ = ""
else
if instr(line$, " ") < 1 then
newL$ = newL$ + left$(line$, max.char) + CrLf$
line$ = mid$(line$, max.char+1)
else
char$ = ""
index = max.char + 1
while char$ <> " "
char$ = mid$(line$, index, 1)
index = index - 1
wend
newL$ = newL$ + left$(line$, index+1) + CrLf$
line$ = mid$(line$, index+2)
end if
end if
wend
wend
open "tf.tmp" for output as #5
print #5, newL$
close #5
cursor normal
return
'-----------------------------------------------
'-----------------------------------------------
' END LINE-WRAP ROUTINE
' DO NOT CHANGE THE CODE ABOVE!
'-----------------------------------------------
'-----------------------------------------------
which is available in electronic form on a CDROM.
For details: http://alyce.50megs.com/sss/cd.htm
Newsletter compiled and edited by: Brosco and Alyce. Comments, requests or corrections: Hit 'REPLY' now! mailto:brosc-@orac.net.au or mailto:awatso-@wctc.net