This lesson describes how you can integrate the printer into Visual Basic applications that
you write. Visual Basic communicates with the Windows printer driver so that you can send text and even graphics to the printer.
Unlike most of Visual Basic's features, however, sending output to the printer can be a tedious process.
Surprisingly, one of Visual Basic's weaknesses is also its strength: Printing requires that you send a fairly long list of instructions to your
printer that describes exactly the way the output is to look. As easily as Visual Basic allows you to add and
manage controls, one would have thought that the printing could be made easier. Nevertheless, despite the tedium sometimes associated with the
printer, you'll see that you can control every aspect of printing, including the font of individual characters
that your application sends to the printer. Therefore, the tedious control needed for the printer provides pinpoint accuracy that allows you to
control all printing details.
Concept: The Visual Basic Primer system that comes with this book doesn't support the use of the Print command on the File menu. You'll still
be able to print reports from your applications, however.
If you attempt to select Print from the File menu, the Visual Basic Primer system displays the error message box shown in Figure 21.1. This book's version of Visual Basic doesn't support
the print commands that you would normally find on Visual Basic's
File menu.
Figure 21.1. The File Print command is unavailable.
In case you upgrade to a different version of Visual Basic, you should
know that the File menu's Print command usually allows you to produce printed copies of the code within an application. In addition, you would normally be able to print an
application's forms graphically as well as produce printed descriptions of forms.
Such output could provide documentation that you could file away and use as a starting point if you modify the application at a later date.
Review: If you attempt to select the Print command from the
File menu, the Visual Basic Primer system produces a message box explaining that the feature is unavailable. Although you can't print form and code
documentation, you will be able to produce text and graphic reports from the Visual Basic applications that
you write by applying the properties and methods discussed in the rest of this unit.
Concept: When your application sends output to the printer, Windows intercepts those printer commands. Rather than send output directly to the printer attached to your computer, Visual Basic actually sends
printed
output to the Windows Print Manager.
Definition: The Windows Print Manager controls all printed output in Windows.
The Windows Print Manager determines how all printed output from all Windows programs eventually appears. Therefore, when your Visual Basic application attempts to send printed output directly to the printer, the Windows Print Manager intercepts those
commands, and might change the output before the printer ever sees the output.
The Windows Print Manager knows how to communicate with any printer supported by Windows. There are hundreds of different kinds of printers now recognized by Windows,
and most of these printers require specialized commands. If every program that you
bought had to provide support for every kind of printer that you or your users might own, programs would require even more disk space than they already do. In addition,
programs would cost more because each software developer would have to spend the time
writing the program to produce output on every kind of printer available.
Rather than require that every software developer support all printers, the Windows
Print Manager requires that every software developer support only one kind of printed output: the kind required by the Windows Print Manager. If the applications
that you write need to produce printed output, Visual Basic produces that output in a
form required by the Windows Print Manager. Figure 21.2 shows that Visual Basic applications send output directly to the Windows Print Manager. The Windows Print Manager
then converts that output into the individual commands needed by whatever
printer is attached to the system.
Figure 21.2. The Windows Print Manager collects all program output and manages individual printers.
Suppose that you had both a laser printer and a dot matrix
printer attached to your computer. Without the Windows Print Manager, you would need to provide two sets of printer commands for every Visual Basic application you write. With the Windows Print
Manager, you'll need to provide only one generic set of
printed output commands. Before running the application, you can use commands available in the Windows Print Manager to select one of your two printers. When you run the program, Windows will convert
the Visual Basic output into commands needed by
whatever printer is selected.
Review: The Windows Print Manager simplifies communication with all the various printers. Your Visual Basic application needs only to send output to the Windows Print
Manager no matter what kind of printer that
output will eventually be directed to. The Windows Print Manager knows how to communicate with all Windows-supported printers, and converts your Visual Basic application's output to the chosen printer's required
format.
Concept: Users could be caught unaware if
your application begins printing without first warning the user that the printer must be ready.
Definition: Online means the printer is ready for printing.
Always remind the user to turn on the printer, make sure that the printer has paper, and ensure that the printer is online. If the user's printer is not first turned on and ready with an ample paper supply, the
user will receive a Windows Print Manager
error message similar to the one shown in Figure 21.3.
Figure 21.3. The Windows Print Manager senses that something isn't right.
Stop and Type: The function procedure in Listing 21.1 provides you with a useful MsgBox() call that you might want to incorporate into your own programs before printing.
Review:
Warn the user that printing is about to take place to make sure that the user puts paper in the printer and turns the printer online.
Listing 21.1. Warns the user before printing.
1: Function PrReady() 2: ' Make sure the user is ready to print 3: Dim IsReady As Integer 4: IsReady = MsgBox("Make sure the printer is ready", 1, "Printer Check") 5: If (IsReady = 2) Then 6: PrReady = 0 ' A Cancel press returns a False value 7: End If 8: PrReady = 1 ' User pressed OK so return True 9: End Function
Output: Figure 21.4 shows the message box presented by Listing 21.1.
Figure 21.4. The user now knows to prepare the printer for printing.
Analysis: After the user reads the message and responds to the message box in line 4, the procedure's
return value determines whether the user wants to see the output (assume that the user has properly prepared
the printer for printing) or cancel the printing. The return value of zero (meaning false) or one (meaning true) can be checked as follows from
another procedure that prints based on the user's response:
If PrReady() Then ' If function is true Call PrintRoutine End If
Concept: Visual Basic applications send all printed output to a special Visual
Basic object called the Printer object. The Printer object supports several property values and methods with which you determine
the look of the printed output.
The keyword Printer specifies the printer object to which your applications will
direct all output. There is no Printer control on the Toolbox window. All access to Printer must take place using Visual Basic code.
Note: The commands that your application sends to the Printer object are generic Windows printer commands. The Windows Print Manager converts those generic commands to a specific printer's commands. You, therefore, worry about what you want printed and let the Windows Print Manager worry about how the output gets produced.
Throughout this book, when you learned a new object, such as the command button control, you learned about the properties that relate to that object. Before using the
Printer object, you should see the properties available for the Printer object so that
you'll know what kinds of things you can do with printed output from within Visual Basic. All of the Printer object's properties are listed in Table 21.1.
Definition: A pixel is the smallest addressable point on the screen or printer.
Property | Description |
CurrentX | Holds the horizontal print column, from the upper-left corner of the page, measured either in twips or the scale defined by the Scale properties. |
CurrentY | Holds the vertical print row, from the upper-left corner of the page, measured either in twips or the scale defined by Scale properties. |
DrawMode | Determines the appearance of graphics that you draw on the printer. |
DrawStyle | Specifies the style of any graphical lines that your application draws. |
DrawWidth | Specifies the width of lines drawn, from 1 (the default) to 32767 pixels. |
FillColor | Specifies the color of printed shapes. Determines the shading density for noncolor printed output. |
FillStyle | Contains the style pattern of printed shapes. |
FontBold | Contains either True or False to determine whether subsequent printed output will be boldfaced. |
FontCount | Specifies the current printer's number of installed fonts. |
FontItalic | Holds either True or False to determine whether subsequent output will be italicized. |
FontName | Holds the name of the current font being used for output. |
Fonts | Contains a table of values that act as if they were stored in a control array. Fonts(0) to Fonts(FontCount - 1) holds the names of all installed fonts on the target computer. |
FontSize | Holds the size, in points, of the current font. |
FontStrikeThru | Holds either True or False to determine whether subsequent output will be printed with a strikethru line. |
FontTransparent | Holds either True or False to determine whether subsequent output will be transparent. |
FontUnderline | Holds either True or False to determine whether subsequent output will be underlined. |
ForeColor | Specifies the foreground color of printed text and graphics. (The paper determines the background color.) |
hDC | A Windows device context handle for advanced Windows procedure calls. |
Height | Holds the height, in twips, of the current printed page. |
Page | Contains the page number currently being printed and updated automatically by Visual Basic. |
ScaleHeight | Specifies how many ScaleMode units high that each graphic will be upon output. |
ScaleLeft | Specifies how many ScaleMode units from the left of the page where subsequent printed output appears. |
ScaleMode | Sets the unit of measurement for all subsequent printed output that appears. |
ScaleTop | Specifies how many ScaleMode units from the top of the page where all subsequent printed output appears. |
ScaleWidth | Specifies how many ScaleMode units wide that each graphic will consist of upon printed output. |
TwipsPerPixelX | Specifies the number of screen twips that each printer's dot (called a pixel) height consumes. |
TwipsPerPixelY | Specifies the number of screen twips that each printer's dot, or pixel, width consumes. |
Width | Holds the size of the page width (measured in twips). |
There are lots of Printer properties, as shown in Table 21.1. Luckily, you'll use only a few of the properties for most of your printing needs. The font-related Printer properties take care of
just about almost all of your printing jobs that are
textual in nature.
Note: The graphics-related Printer properties and methods aren't covered in this unit. Once you master graphics in the next unit, you'll be more prepared to understand the graphics-related Printer properties. Most of the Printer's properties are reserved for controlling extremely advanced graphics output. For typical applications, you'll rarely bother to specify any properties because the default values work well for normal reporting requirements.
Unlike most of Visual Basic's control objects, the Printer object's methods are much more
important than the property values. Table 21.2 contains a complete list of the methods supported by Visual Basic's Printer object.
Method | Description |
Circle | Draws a circle, ellipse, or arc on the printer |
EndDoc | Releases the current document, in full, to the Print Manager for output |
Line | Draws lines and boxes on the page |
NewPage | Sends a page break to the printed output so that subsequent output appears on the next page |
Prints numeric and text data on the printer | |
PSet | Draws a graphical point on the printed output |
Scale | Determines the scale used for measuring output |
TextHeight | Determines the full height of text given in the scale set with Scale |
TextWidth | Determines the full width of text given in the scale set with Scale |
Tip: By far the most widely used Printer methods are the Print, EndDoc, and NewPage methods. Once you master these three methods, you'll rarely need to use any other methods.
Review: There are several properties and methods available for the Printer object. Unless you
need to send graphics to the printer using advanced graphics capabilities, you'll need only two or three of the
properties and methods to fulfill all your printing needs.
Concept: The Printer object's Print method handles almost all printed output. Print supports
several different formats. With Print, you can print messages, variables, constants, and expressions on the printer.
The Print method is, by far, the most commonly used printing method in Visual Basic. By mastering the Print method, you will have
mastered the single most important printing method that you can master.
Note: Remember that a method is nothing more than a command that you apply to a particular object. For example, the AddItem method is a method that you've seen used throughout this book to add items to list and combo box controls.
Here is the format of the Print method:
[Printer.]Print [Spc(n) | Tab(n)] Expression [; | ,]
The format makes Print look a lot more confusing that it really is, but the portion of the Print method that appears to the right of Print takes some
explanation. The next several sections explain the various options available for the Print method.
The
Print method easily prints string and numeric constants. To print a string or numeric constant, place the constant to the right of the Print method. The following methods send the numbers 1, 2, and 3 to the printed output:
printer.Print 1 Printer.Print 2 Printer.Print 3
When execution hits these three lines of code, Visual Basic sends 1, 2, and 3 to the Printer object with each number appearing on subsequent lines. Every Print method sends
a carriage return and line feed sequence to the printer. A lone Print method on
a line by itself such as this one:
printer.Print
sends a blank line to the printer.
Note: Visual Basic always adds a space before all positive numeric values printed on the page. The space is where an invisible plus sign appears.
The following Print method sends two lines of text to the Printer object:
printer.Print "Visual Basic makes writing programs" Printer.Print "for Windows easy."
When the Windows Print Manager gets these two lines of output, the following appears on the printer's paper:
Visual Basic makes writing programs for Windows easy.
In addition to constants, the Print method prints the contents of variables and controls. The following
initializes a string and integer variable and then prints the contents of the variables on the printer:
FirstName = "Charley" Age = 24 Printer.Print FirstName Printer.Print Age
Here is the
output produced by these Print methods:
Charley 24
Note: Remember that Visual Basic won't send anything to the Printer object until the code that contains Print executes. You would insert Print methods at appropriate places in the code's procedures where printed output is required. For example, if there is a command button labeled Print Report, that command button's Click procedure would contain Print methods.
If you could print only
individual strings, numeric constants, and variables, Print would be extremely limiting. Of course, Print is not that limited. You can combine constants, variables, and expressions to the right of Print methods to produce more
complex printed output. The
following Print method prints 31:
printer.Print 25 + (3 * 2)
The expression can contain both variables, controls, and constants, like this:
printer.Print Factor * lblWeight.Caption + 10
If you want to send special characters to the printer, you can do that by using the Chr$() function. The following expression produces a message that includes embedded quotation marks inside the printed
string:
printer.Print "She said, " & Chr$(34) & "I do." & Chr$(34)
When execution reaches the former Print method, this is what the Print Manager sends to the
printer:
She said, "I do."
Note: You wouldn't be able to print the quotation marks without the Chr$() function. Usually, Visual Basic suppresses quotation marks when printing string constants.
Definition: A print zone occurs every 14 columns on the page.
When you need to
print several values on one line, you can do so by separating those values with semicolons and commas. The semicolon forces subsequent values to appear right next to each other in the output. The comma forces values to appear in the
next print zone.
The following two messages print on different lines:
printer.Print "The sales were " Printer.Print 4345.67
By using the semicolon, you can force these values to print next to each other:
printer.Print "The sales were "; 4345.67
The semicolon also acts to keep automatic carriage return and line feeds from taking place. The following Print method ends with a trailing
semicolon:
printer.Print "The company name is ";
The trailing semicolon keeps the printer's print head at the end of the message for subsequent output. Therefore, the subsequent Print
statement shown next, no matter how much later in the code the Print appears, would print its output right next to the
previous Print's output:
printer.Print lblComName.Caption ' Complete the line
The semicolon is nice for printing multiple values of different data types of the same line. The following Print prints all of its data on the same line of output:
printer.Print "Sales:"; totSales; "Region:"; RegNum
The comma is still sometimes used to force subsequent values to print in the next print zone. The following Print prints names every 14 spaces on the printed line:
printer.Print DivName1, DivName2, DivName3, DivName4
No matter how long or short each division name is, the next division name will print in the next print zone. The previous Print might produce output similar to the
following:
North NorthWest South SouthWest
Tip: When you print lists of numbers or short strings, the comma allows you to easily align each column.
Most Windows-compatible printers
support a variety of fonts. The font-related properties are often useful for printing titles and other special output messages in special font sizes and styles.
You can add special effects to your printed text by setting the font modifying
properties from Table 21.1. For example, the following code first puts the printer in a boldfaced, italicized, 72-point font (a print size of one full inch), and then prints
a message:
printer.FontBold = True Printer.FontItalic = True Printer.FontSize = 72 Printer.Print "I'm learning Visual Basic!"
Note: The font properties affect subsequent output. Therefore, if you print several lines of text and then change the font size, the text that you've already printed remains unaffected. Visual Basic prints only the subsequent output with the new font.
The Print
method supports the use of the embedded Spc() and Tab() functions to give you additional control over your program's output. Spc() produces a variable number of spaces in the output as determined by the argument to Spc(). The following Print
prints a
total of ten spaces between the first name and the last:
printer.Print FirstName; Spc(10); LastName
The argument that you send to the embedded Tab() function determines in which column the next
printed character appears. In the following Print, the date appears in the 50th column on the page:
printer.Print Spc(50); DateGenerated
As these examples show, if you print values before or after
the Spc() and Tab() functions, you separate the functions from the surrounding printed values using the semicolon.
Tip: Spc() and Tab() give you more control over spacing than the comma and semicolon allow.
Stop and Type: Listing 21.2 contains some code that computes and prints two housing pricing and taxation values.
Review: Use Spc() and Tab() to control the printer's output spacing.
Listing 21.2. Using Spc() and Tab().
1: Tax1 = TaxRate * HouseVal1 2: Tax2 = TaxRate * HouseVal2 3: 4: TotalVal = HouseVal1 + HouseVal2 5: TotTaxes = TaxRate * TotalVal 6: 7: Printer.Print "House Value"; Tab(20); "Tax" 8: Printer.Print Format$(HouseVal1, "Currency"); 9: Printer.Print Tab(20); Format$(Tax1, "Currency") 10: Printer.Print Format$(HouseVal2, "Currency"); 11: Printer.Print Tab(20); Format$(Tax2, "Currency") 12: 13: Printer.Print ' Prints a blank line 14: 15: Printer.Print "Total tax:"; Spc(5); Format$(TotTaxes, "Currency")
Output: Here is a sample of what you may see on the paper after Listing 21.2
executes:
House Value Tax $76,578.23 $9,189.39 $102,123.67 $12,254.81 Total tax: $21,444.20
Analysis: The Tab(20) function calls in lines 7, 9, and 11 ensure
that the second column that contains the tax information is aligned. Also, notice that the trailing semicolons on lines 8 and 10 allow you to
continue the Print methods on subsequent lines without squeezing long Print method values onto the same line.
Line 13 prints a blank line. Line 15 uses the Spc() function to insert five spaces between the title and the total amount of tax.
Concept: The physical printing doesn't begin until all output is released to the Print Manager, or until your application issues an EndDoc method.
As you send
Print methods to the Print Manager via the Printer object, the Print Manager builds the page or pages of output but doesn't release that output until you issue an EndDoc method. EndDoc tells the Print Manager, "I'm done sending output
to you, you can
print now."
Without EndDoc, Windows would collect all of an application's output and not print any of the output until the application terminates. If you were to write an application that the user runs throughout the day and that prints
invoices as customers make
purchases, you would need to issue an EndDoc method at the end of each invoice-printing procedure if you wanted each invoice to print at that time.
Stop and Type: Listing 21.3
prints a message on the printer and then signals to the Print Manager that the output is ready to go to paper. Without the EndDoc, the Print Manager would hold the output until the
application containing the code terminates.
Review: The EndDoc method tells the Print Manager to release all printed output.
Listing 21.3. The EndDoc tells the Print Manager to release the output.
1: Printer.Print "Invoice #"; invNum 2: Printer.Print "Customer:"; cust(CCnt); Tab(20); "Final Sales" 3: Printer.Print "Amount of sale:"; Tab(20); Format$(SaleAmt, "Currency") 4: Printer.Print "Tax:"; Tab(20); Format$(tax, "Currency") 5: Printer.Print 6: Printer.Print "Total:"; Tab(20); Format$(TotalSale, "Currency") 7: 8: ' Release the job for actual printing 9: Printer.EndDoc
Analysis: The program containing Listing 21.3's code might continue to run and process other sets of data. The EndDoc method triggered by line 9 ensures that the output built in
the preceding Print methods all
gets sent to the physical printer immediately. If other Print methods appear later in the program, the Print Manager will begin building the output all over again, releasing that subsequent output only for an EndDoc
procedure or when the application ends.
Concept: When printing to
the printer, you must be careful to print at the top of a new page when you want the output to advance one page. The NewPage method forces the printer to eject the current page and
begin subsequent output on the next new page.
The Windows Print
Manager ensures that each printed page properly breaks at the end of a physical page. Therefore, if the printer's page length is 66 lines and you print 67 lines, the 67th line will appear at the top of the second page of output.
There are times,
however, when you need to print less than a full page on the printer. You can release that incomplete page for printing using the NewPage method (from Table 21.1). To use NewPage, simple apply the NewPage method to the Printer object
like this:
printer.NewPage
Note: Remember that you actually print to the Windows Print Manager and that your application's output methods don't directly control a physical printer. Therefore, NewPage tells the Print Manager to go the a new page when the Print Manager gets to that location in the output.
You've got to remember that you're
working with printers that support many fonts and font sizes. You can always determine, in advance, how many lines of output will fit on a single page as long as you first check the value of the following formula:
numLinesPerPage = Printer.Height / Printer.TextHeight("X")
As explained in Table 21.1, the Height property determines the height, in twips, of the page. The TextHeight property determines the full height of a
printed character (including leading, which is the area directly above and below characters).
TextHeight measures the height in twips if you haven't changed the scale using the ScaleMode property.
For printed reports, you'll rarely use
the ScaleMode method. If you have the need to change the scale of measurement, however, you'll have to change the scale back to twips before calculating the number of output lines per page, like this:
printer.ScaleMode = TWIPS
The ScaleMode accepts values defined in Table 21.3. As long as you add the CONSTANT.TXT file to your application's Property window, you can use the named constants in place of the numeric values if
you want to change the scale measurement.
Value | Named Constant | Description |
0 | USER | A user-defined value |
1 | TWIPS | Measured in twips (the default) |
2 | POINTS | Measured in points |
3 | PIXELS | Measured in pixels (the smallest unit addressable by your printer) |
4 | CHARACTERS | Measured in characters (120 by 240 twips) |
5 | INCHES | Measured in inches |
6 | MILLIMETERS | Measured in millimeters |
7 | CENTIMETERS | Measured in centimeters |
Stop and Type:
Listing 21.4 contains code that prints two messages, one per page of printed output.
Review: At any point during your application's printing, you can issue an NewPage method to force the
printer to eject the current page and begin printing at the top of the next page.
Listing 21.4. The NewPage forces the printer to eject the current page.
1: Printer.Print "The Report begins on the next page..." 2: Printer.NewPage ' Go to top of new page 3: Printer.Print "The Campaign Platform"
Analysis: Line 2 ejects the printer
even if the printer has not yet printed a full page.
Write a program that prints the ASCII characters (print only the values from ASCII 32 to 255) on a piece of paper when the user presses a command button.