[ Go to September 1997 Table of Contents ]|
Make Directories Fit to Print
Windows 95 makes it easier than ever to see the contents of directories and drives. You can use Explorer or just double-click on the Desktop's My Computer icon. Whichever method you choose, you'll see a tidy, informative graphical display chock-full of useful information.
But what if you want Windows to print this information? Unfortunately, you're just about out of luck. Sure, you can do it through elaborate tricks, such as copying lists of filenames to the clipboard, pasting them into Notepad, then formatting them by hand. But isn't that too much trouble? I think it is, so I wrote the WinMag Directory Printer.
Based on the WinMag Disk Scanner (see Power Windows, December 1996), this program prints an entire directory tree. If the root of the tree is the root directory of a drive, the entire drive's contents will print. Or you can select any subdirectory as the root and prune as much of the listing as you wish. Besides the names of each directory and file, the program prints the size and date of modification of each file in the tree.
This often-requested utility also gives us a good opportunity to examine how Windows programs print.
Desktop lasers and ink jets are page printers. They print an entire page at a time, making printing faster, more reliable and cheaper than earlier printers that sent one character or line to the page at a time. The page printer dramatically changed the way programmers think. Before page printers, documents were thought of as streams of characters. Documents were created in the same order they would later be read, from left to right and from top to bottom.
Now, programmers think of documents as 2D surfaces. Like a painter with a canvas, a programmer can "paint" any portion of the page at any time. Printers can receive information in any order. For example, information that will appear at the bottom of a page can be sent first, followed by information to be printed at the top.
Thanks to the miracle of modern drivers, almost any printer can appear to be a page printer. If the printer lacks a buffer large enough to store a full page of data, the driver will buffer the print commands in the computer's RAM. If the printer requires information in a particular order, the driver will rearrange data before sending it. With the right Windows driver, all printers are created equal (at least as far as programs are concerned)
Windows does a good job of hiding printer details from programs and programmers. Most programs use Windows' GDI (Graphics Device Interface) to control a printer. This portion of Windows communicates directly with a printer's driver. Visual Basic (VB), the language used to write the WinMag Directory Printer, takes device-independent printing another step. It hides Windows' printer support inside an object named Printer.
As we've seen before, an object is just a special bit of software. Like all software, objects consist of procedures (blocks of instructions) and variables (places where data is stored). Objects usually contain many private procedures and variables. But there are also procedures or variables available for use by other programs. These public procedures are called methods, while public variables are called properties.
VB's Printer object provides nine methods and over two dozen properties to make printing easy. Many properties, like FontBold, FontItalic and FontUnderline, can be set to simple True/False values to determine whether the text about to be printed will be bold, italic or underlined. You can store strings or numbers in other properties. For example, you can control the font to be used when printing by storing the font's name in the Printer object's FontName property. You can set the FontSize property to the size of the desired font, in points. Once set, any future printing will occur in the selected font and size until you change one or both properties.
Calling the Printer object's EndDoc method tells Windows when an entire document (possibly containing several pages) has been printed. This allows Windows to schedule the document for printing via Windows' printer spooler. Another popular method, Circle, can draw a circle or ellipse anywhere on the page. Parameters passed to Circle specify a drawing's size, location on the page and outline color.
The sidebar "Page Printer" shows some of the Printer object's other methods and properties in use. The PrintNewPage subroutine is a simplified version of the subroutine the WinMag Directory Printer calls each time it begins printing on a new page.
The subroutine starts by declaring a string variable named Title. This variable will be used to temporarily store text information prior to printing. Line 3 is where our subroutine gets down to business, by calling the Printer object's NewPage method. This method prevents any further changes to the page already printing and provides a "blank sheet" as the starting point for our next page.
Line 4 temporarily stores the caption text of our program's main window in the variable Title. This text will become our page's header, printed at the top of every page. Storing it in Title is the first step in a process that measures the text's width so it can be centered over the page.
The actual centering takes place in line 5, where our subroutine calls the Printer object's methods TextWidth and ScaleWidth. TextWidth returns the width of the text passed to it (in our case, the text stored in the variable Title), while ScaleWidth returns the width of the page's printable area.
Once the widths are determined, line 5 subtracts one width from the other, then divides the result by two. This trick computes the distance across the page where our string
Title must start in order to be centered.
This horizontal distance is then stored in the Printer object property named CurrentX. Together with the property CurrentY, CurrentX determines where the next printed text will appear. CurrentX controls the starting point's horizontal distance from the left edge of the printable portion of the page, while CurrentY determines the starting point's vertical distance from the top of the page's printable region. Both properties are reset to zero when the method NewPage is called.
By the way, all Printer object methods and properties are measured in TWIPs (twentieth of a point). A typesetter's point is 1/72nd of an inch, so a TWIP is actually 1/1,440th of an inch. You can change the measurement unit to pixels, inches, points or centimeters by calling the Printer object's ScaleMode method.
Back to our subroutine: We're now ready to actually print something. That's accomplished in line 6, where we call the Printer object's Print method. Like VB's Print statement, this method accepts one or more string variables or text as parameters. If more than one parameter is passed to Print, you must place commas or semicolons between each. If commas are used, each parameter's text prints on a separate line. If semicolons are used, each parameter's text prints immediately after the text of its predecessor on the same line. In addition to printing text, the Print method adjusts the value stored in CurrentX to reflect the width of the text it prints and adjusts CurrentY if a new line of text begins.
Finally, line 7 calls the Printer object's Line method to print a horizontal line across the page. The parameters passed to Line indicate the line's starting point (0,0) and ending point (Printer.ScaleWidth, 0). The first number in each pair of parentheses indicates the horizontal coordinate of the point (or x-coordinate, for you geometry types), while the second number indicates the point's vertical (or y-) coordinate.
The VB keyword Step tells the Line method that the x- and y-coordinates are relative to the values of CurrentX and CurrentY. So, the point's x- and y-coordinates will be added to CurrentX and CurrentY to determine the point's location. Without the Step keyword, a point's coordinates are absolute, representing distances from the left and top edges of the page's printable region.
If you'd like to see the entire source code of the WinMag Directory Printer or just take it for a test-drive, you can download it from the WinMag Web site. The file-name is PWDIRPRN.ZIP. You'll find 16-bit VB 3.0 and 32-bit VB 4.0 versions. The 32-bit version supports long filenames.
Karen Kenworthy is the author of Visual Basic for Applications, Revealed! (Prima Publishing, 1994), a nonprogrammer's introduction to VBA. She is also a contributing editor to WINDOWS Magazine and manager of WINDOWS Magazine Online on America Online and CompuServe. Reach Karen care of the editor at the addresses on page 20.