REALbasic University Resources:

RBU: Glossary Defines common REALbasic programming terms
  Archives Previously published columns
Translations: Dutch Courtesy of Floris van Sandwijk
  Japanese Courtesy of Kazuo Ishizuka
  Chinese Courtesy of Dong Li
  RBU Translation Guide Information on Translating RBU into other languages
Books: Matt's Book (2nd Edition!) Ideal for experienced programmers
  Erick's Book Best for beginning programmers
Websites: Mother Ship The publisher of REALbasic
  RB Webring Links to hundreds of REALbasic websites
  RESExcellence Another REALbasic programming column
  REALbasic Developer Magazine The premiere source for REALbasic instruction.

REALbasic University is Sponsored by

Make your Mac do what YOU want it to. Create games, utilities, cool Mac OS X tricks. Download REALbasic now and create your own software.


Print This Article

REALbasic University: Column 064

FontPrinter: Part Three

We've built most of the foundation for FontPrinter, our utility to print out a table of special key sequences for typing special characters in various fonts, so in this lesson we're going to learn how to actually print.

Adding Printing Methods

Printing in REALbasic isn't especially difficult, once you get the hang of it. Basic printing isn't too difficult, but working with multiple page documents, handling various sizes of paper, and other issues, can really complicate matters.

The basic steps you take for handling printing are these:

  1. Get or restore the user's Page Setup settings
  2. Display the standard Print dialog
  3. Draw to the printer's graphics object, using standard REALbasic graphics commands

The first of these may seem imposing, but it's actually quite simple. The standard Page Setup dialog allows the user to choose various settings for their printer, including paper size, page orientation, reduction or enlargement, etc. Some settings are unique for a particular printer.

Here's the tricky part: you cannot access these settings directly. That's because there's a layer of abstraction between you (inside REALbasic) and the actual Mac OS routines that get and set this information. That translation layer is needed, because different printers might have completely different settings.

Fortunately, REALbasic gives you an easy way to access the important parts of the Page Setup information. It also gives you a way to save and restore this info. REALbasic has an object (a class) called printerSetup which contains important properties such as the current printer's resolution, paper size, margins, etc. Some settings, such as the paper's orientation, aren't accessible -- which is fine, because you wouldn't know what to do with that info anyway. At any rate, whatever settings are set within the Page Setup dialog are simply passed on to the printer driver, which takes care of actually doing whatever the user indicated.

Let's open Window1 and add a new method (Edit menu, "New Method"). Call it pageSetup. Now put in this code:

  
dim pageSetup as printerSetup

pageSetup = new PrinterSetup
if gThePrintSettings <> "" then
pageSetup.SetupString = gThePrintSettings
end if

if pageSetup.pageSetupDialog then
gThePrintSettings = pageSetup.SetupString
end if

As you can see, there isn't much to this. First, we define a variable, pageSetup, of type printerSetup. Since pageSetup is an object, we must create a new instance of it.

The page setup data is stored in a string, and in our last lesson we added some global properties, including a string variable called gThePrintSettings. That's where we'll save whatever settings a user makes in the Page Setup dialog.

So our next step is to check and see if gThePrintSettings has anything in it: if it does, we pass that data to the Page Setup dialog via the .SetupString property. If gThePrintSettings is empty, then the default settings are used.

The final if-then statement is what displays the dialog: the pageSetup.pageSetupDialog method displays the standard Page Setup dialog and returns true if the user clicked Okay and false if the user hit Cancel. That's all we're concerned with initially.

If true, then we save the settings, whatever they are, into gThePrintSettings. (REALbasic puts the new settings into the .SetupString property.) If the dialog returns false, we do nothing.

That's it!

You see, you don't even need to know anything about the format of the Page Setup information: REALbasic puts that data into a string for you to easily save and retrieve as you like, but you don't have to actually do anything more than that. Once you've created a printerSetup object, you can feed it saved settings -- the line pageSetup.SetupString = gThePrintSettings does this.

To access properties of the printerSetup object, just use the same "dot" syntax you always do. Using the pageSetup object we defined above, here are some sample properties:

pageSetup.pageHeight -- returns the height of the paper in pixels (792 for standard U.S. 11" tall paper)
pageSetup.pageWidth -- returns the width of the paper in pixels (612 for standard U.S. 8.5" wide paper)
pageSetup.pageLeft -- the left margin, in pixels (72 would be one inch)
pageSetup.pageTop -- the top margin, in pixels (72 would be one inch)
etc.

You could retrieve these to make sure what you print will, for example, fit on the paper the user is using. (In FontPrinter, we assume the user is using 8.5" x 11" -- more on that later.)

In Detail

Note that you don't even have to display the Page Setup dialog: once you've loaded your printerSetup object with some data, it's ready to print. I do this with my Z-Write word processor, saving the Page Setup setting info within the user's document so they don't have to go back to the Page Setup dialog every time they print. (Of course, they can manually choose the Page Setup menu command if they need to change a setting, but they aren't forced to do a Page Setup if they don't need to.)

But what about printing the document? We're getting there. It's important to understand the Page Setup stuff because that is required to happen first. You see, when you open the Print dialog, you must send it a printerSetup object (presumably loaded with the appropriate setting info).

Add another method called printIt and put in this code:

  
dim g as graphics
dim thePrinter as printerSetup

if gThePrintSettings = "" then
pageSetup
end if

if gThePrintSettings = "" then
return
end if

thePrinter = new PrinterSetup
thePrinter.setupString = gThePrintSettings

gPrintOkay = false

// do a print preview?
if checkPreview.value then
p = newPicture(thePrinter.pageWidth, thePrinter.pageHeight, 8)
if p <> nil then
// Draw it into the picture
drawIt(p.graphics)

// Preview the printing
printPreview.showModal
else // p = nil = error
beep
msgBox "Sorry, there's not enough memory for print preview."
gPrintOkay = true
end if
else
gPrintOkay = true
end if

if gPrintOkay then
g = OpenPrinterDialog(thePrinter)
if g <> nil then
drawIt(g)
end if // g = nil
end if // gPrintOkay = true

Okay, this looks complicated, but it's really not. The first thing we do is define our variables, and then we check to see if gThePrintSettings is empty or not. If it is, we know the user hasn't go to the Page Setup dialog yet: we make them do that first. If it's still empty after that, it means they hit cancel, so we end the method with a return command, since they obviously don't want to print (they're canceling things).

Once we've got a valid gThePrintSettings, we initialize a new thePrinter (our printerSetup object), and assign it the contents of gThePrintSettings. Now we're ready to print. Sort of.

One of the features of FontPrinter is a print preview window: it's not that necessary under Mac OS X, since that operating system already has one built-in (via its print-to-PDF feature), but it's still a nice thing to have. Why? Because it makes it easier for the you, the programmer, to test your printing routines without wasting a lot of paper!

We have a checkPreview checkBox which, if it's checked, means the user wants to preview the print job before printing it. If it's not checked, we simply set gPrintOkay to true and skip to the final if-then statement which actually does the printing.

To handle the print preview, we need to create a temporary picture to hold the stuff we're printing. We already have a global picture property called p, so we just need to newPicture it (reserve the appropriate amount of memory for it).

After we do that, we double-check to make sure p isn't nil -- that would mean there isn't enough memory to create p and so we give the user an appropriate error message. Note that when we do this, we set gPrintOkay to true so that the user can print without previewing if they want (they can always cancel the Print dialog if they don't want to print).

The middle part of the code -- the part after if p <> nil then -- is the main print preview stuff. First, we tell our drawIt method to draw stuff into the graphics property of p. Next, we display the printPreview window.

Say what? You're curious about where those two things are? You are correct the program won't run until we create them, so let's do that next.

First, add a new method called drawIt. Give it parameters of g as graphics. For now, just leave it blank.

Next, add a window (File menu, "New Window"). Give it these settings:

Good. Now FontPrinter will compile and run, but it still doesn't do much. Go to the filePageSetup menu handler and put in this:

 pageSetup 

That way the program will at least do something: you can bring up the Page Setup dialog and mess with that!

Unfortunately, the print preview stuff is a little complicated, so we'll have to save that for next time.

If you would like the complete REALbasic project file for this week's tutorial (including resources), you may download it here.

Next Week

We finish adding the Print Preview feature to FontPrinter.

News

2002 Cubie Award Winners Announced

Every year REAL Software gives out "Cubie" awards, sort of like Oscars for REALbasic programs. Anyone can enter to nominate themselves or someone else. There are some terrific programs here, so I encourage you to check them out (if nothing else, they serve as excellent examples of the quality of programs you can create with REALbasic).

Here are this year's winners:

Advocate of the Year: Erick Tejkowski
Finally, there's a special category for the REALbasic advocate of the year, that person who has done the most for the community, and helped make REALbasic known everywhere as the truly great tool that it is.

Business: Barcode Producer by Intelli Innovations, Inc.
The best tool for conducting some sort of commercial activity, whether it is a traditional business application or a tool for creating stuff that makes money for the user.

Cross-platform: Quick Pallet Maker 2 by SCA Mecanica
The best example of an application that embraces Macintosh, Mac OS X, and Windows.

REALbasic development aid: UniHelp by Electric Butterfly
This includes plug-ins, classes, modules, frameworks, pre- and post-processors, anything that helps some REALbasic developer get the job done.

Education: A-OK! The Wings of Mercury by You Are Go!
Software for learning (something useful, ideally).

Enterprise: Visual 3270 by Trizen Systems
Enterprise software. Big iron, mainframes, legacy systems -- crucial tools for getting big business done.

Internet: AthenaIRC by ChiperSoft Systems
Best tool for the Internet. This could be anything useful in that rather large arena, from a server tool, to a decoder, player, testing tool. If it uses IP (or its cousins) or some known protocol or format, it's in!

Mac OS X: MediaEdit by Mien Software
The best application for Mac OS X. It need not fall into any particular category, and can also support the classic Mac OS (and heck, Windows too).

Multimedia: Baytex Party! by Baytex
That best application for the audio, visual, wave of the future.

Utility: PrefsOverload 4.1.2 by Zik's Software and Passenger by MacinMind Software
The best application that does something useful. This too is intentionally broad! All it has to do is crank out the utiles, and we will be all over it.

Final Chance to Get the Premier Issue of REALbasic Developer

In other news, this is just a quick reminder that if you've been putting off ordering your subscription to the new REALbasic Developer magazine, hurry up and subscribe today.

Subscribers who order a print subscription in August will be mailed the premiere issue (the August/September issue) in September. People who subscribe in September will be sent the October/November issue as their first issue. So if you don't want to miss an issue, order your subscription today!

Letters

Here's a letter from Len, wondering if the latest version of REALbasic is stable. (He sent this to me when RB4 was current; now, of course, RB4.5 is out.)

I have been trying to find out how stable RB4 is because I am considering upgrading from 3.5.2. The forums seem to steer away from this topic, but I am not sure "no news is good news" in this case. I heard something about problems with editfield performance when version 4 came out and was wondering if this issue had been solved and your bounce on RB4 in general.

Thanks in advance.

Whether upgrading is worth it for you depends on what you are doing with REALbasic, Len. If 3.52 does everything you need, the plug-ins you need still work, and the programs it creates still function the way you want, upgrading might not be necessary.

While I'm sure REAL Software would love it everyone upgraded for every release, the reality is that for people using REALbasic only occasionally, or just learning, an upgrade every six months can be too much. (For professional users, it's the ideal release schedule.)

However, every new version of REALbasic fixes bugs and adds new features you might want. For instance, recent versions of RB have added the dictionary class, regular expressions, improved support for Mac OS X, and made the interface of the IDE better.

Unfortunately, the newer versions sometimes work differently than the old ones (that's the price of progress), so you might find yourself having to slightly modify old programs to get them to work with the latest version. (REAL Software in general does a great job of keeping things backward compatible. Much better than Apple and CodeWarrior, in my opinion.) For instance, I often find I included a complicated workaround for an RB bug in my program, and the new version of RB fixes that bug, so I'm free to clean up that ugly workaround code.

Also, sometimes REAL Software makes improvements that backfire. For instance, starting with RB4, they rewrote the editField control to work better with Mac OS X. This fixed visual problems the old editField was having, but as a side effect, the new editField can be sluggish when typing long paragraphs. REAL Software says this is due to a bug in Mac OS X and Apple must fix it, but it's still a pain if your program depends on editFields.

As to stability, I'm not sure what you are referring too: the IDE crashing or the programs you create. I don't have complaints about either one, though I'll admit the IDE tends to "unexpectedly quit" on me quite often. I'm using Mac OS X full-time, however, so the IDE quiting isn't a big deal as it doesn't effect other applications.

I've started using the new REALbasic 4.5 and I'll have a mini-review in a week or so, covering some of the new features so you can decide if it's worth upgrading.


About the Column
REALbasic University is a weekly instructional column on programming with REALbasic and is brought to you by REALbasic Developer, the magazine for REALbasic programmers.

Each week we answer select reader questions, and we're always open to ideas for future columns. Send your questions to . (Keep your questions simple and specific. General queries like "How do I write my own web browser?" will be neglected.) Your question won't be answered immediately, but will be answered in a future column. (If you don't want your correspondence published, just be sure to indicate that when you write. Otherwise it's fair game.)

About the Author
is an author, philosopher, graphic designer, photographer, film director, soccer fanatic, and programmer (among other things). He writes for MacOpinion, runs his own software company, Stone Table Software, which sells the revolutionary Z-Write word processor, and is Publisher and Editor of REALbasic Developer. He lives in Northern California with his cats, Mischief and Mayhem, and is rapidly running out of free time.

See the REALbasic University Archives


REALbasic University contents ©2001-2004 by Marc Zeedar and REALbasic Developer. All Rights Reserved.

Email This Article - Comment On This Article

.

Reader Specials

Server Racks Online:
Apple Xserve CompatibleServer Racks and Universal Network Racks
42U KVM Switch Solutions:
High-End Mac and Multi-Platform KVM Matrix switching solutions!
Digital Camera Online:
Great prices on Digital Cameras and accessories!
KVM Switches Online:
Great prices on Mac KVM Switches from the leading manufacturers!
LCD Monitors Online:
Great prices on LCD Monitors from the leading manufacturers!
LCD Projectors Online:
Shop online for LCD Projectors from the leading manufacturers!
USB 2.0 Online:
Great prices on USB 2.0 products from the leading manufacturers

Serious Business Software:
Accounting, Sales, Inventory, CRM, Shipping, Payroll & more!

KVM Switch solutions for MACs:
DAXTEN is a KVM switch, KVM extender and monitor splitter specialist for PC, SUN and MAC applications from name brand manufacturers - offices worldwide.

The "Think Different Store: The iPod Accessories Store - iPod cases, iPod mini, iPod photo, speakers, itrip, inMotion, Soundstage and all other iPod accessories

Earn Cash with the ThinkDifferent Store Affiliates Program

Need A Web Site?
Applelinks Web Hosting Starting at 19.95 a Month

iTunes_RGB_9mm

.

iTunes_RGB_9mm

Cool Mac Gear


iPod 1G-2G
iPod 3G
iPod 4G
iPod Mini
PowerBook-iBook
Keyboard Skins
Garageband