## Visual Basic in 12 Easy Lessons vel21.htm

- What You'll Learn
- A Word of Warning
- Printing With Windows
- Tell the User You Will Print
- Introducing the Printer Object
- The Print Method
  - Printing Constants
  - Printing Variables and Controls
  - Printing Expressions
  - Printing Multiple Values
  - Utilize the Fonts
  - Better Spacing with Spc() and Tab()
- Initiating the Print
- Page Breaks
- Homework
  - General Knowledge
  - Find the Bug
  - What's the Output?
  - Write Code That...
  - Extra Credit

#
Lesson 11, Unit 21

##
Using the Printer

###
What You'll Learn

- A word of warning
- Printing with Windows
- Telling the user you will print
- Introducing the Printer object
- The Print method
- Initiating the print
- Page breaks

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.

###
A Word of Warning

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.

###
Printing With Windows

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.

###
Tell the User You Will Print

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

###
Introducing the Printer Object

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.

Table 21.1. The Printer object's properties.

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.

Table 21.2. The Printer object's methods.

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
Print | 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.

###
The Print Method

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.

####
Printing Constants

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.

####
Printing Variables and Controls

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.

####
Printing Expressions

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.

####
Printing Multiple Values

> > 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.

####
Utilize the Fonts

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.

####
Better Spacing with Spc() and Tab()

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.

###
Initiating the Print

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.

###
Page Breaks

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.

Table 21.3. The ScaleMode values.

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.

###
Homework

####
General Knowledge

1. What File command does the Visual Basic Primer system not support?
2. What job does the Windows Print Manager play in printing your application's output?
3. Why doesn't your program need to understand every printer's individual command?
4. What does online mean?
5. How can you ensure that the user prepares the printer before you print reports from a Visual Basic application?
6. What is the Printer object?
7. True or false: The Printer object supports properties and methods just as many of the controls do.
8. What is a pixel?
9. What is the most commonly used Printer method?
10. True or false: You can print variables and constants but not expressions with Print.
11. True or false: There is no difference between using several embedded Tab(14) functions and using commas to separate columns of output in a Print method.
12. Printing three strings separated by commas causes the strings to appear in columns 1, 15, and 29. Why do you think that printing three positive numbers, separated by commas, causes the numbers to print in columns 2, 16, and 30?
13. What is a print zone?
14. True or false: A Print that isn't terminated with a trailing semicolon always prints a carriage return and line feed on the printer.
15. How can you print quotation marks onto paper?
16. True or false: If the last thing an application does before terminating is print a report, there is no need to specify the EndDoc method at the end of the printing.
17. What is meant by leading?

####
Find the Bug

1. Poor Caroline isn't having luck getting a report to print properly. Caroline learned in her early days of computing that a printed page has 66 lines of text. Now that Caroline has upgraded to Windows and is practicing to become a top-notch Visual Basic programmer, Caroline's 66-line per printed page doesn't seem to be true all of the time. Explain to Caroline what she must do to fix her problem.
2. Mike is working on two programs. For some reason, Mike can't figure out why these two different output lines don't produce exactly the same output. Help Mike solve this dilemma.
   Printer.Print Tab(10); "Visual Basic"
   Printer.Print Spc(10); "Visual Basic"

####
What's the Output?

1. What's the output from the following two Print methods?
   Printer.Print "Line 1";
   Printer.Print "Line 2"
2. What does the following Print method produce on the printer when the Print Manager releases the line to be printed?
   Printer.Print "The Spanish N is "; Chr$(164)

####
Write Code That...

1. Write a line of Visual Basic code that prints the word America in column 57.

####
Extra Credit

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.