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 070

Review: REALbasic 4.5 (Part 4)

This week we finish up our look at REALbasic 4.5 by looking at a couple more major improvements as well as some smaller fixes.

Major New Features

Virtual Files

One of the most exciting new features of REALbasic 4.5 is the new Virtual Volume function. However, it's rather buried in the middle of so much other stuff and it's never explained especially well, so you may not know it's there or what to do with it.

Before I explain about it, let's take a moment to look at a question posed to me by Dan. He sent this to me a while back and I wrote a program that solves his problem: however, Virtual Volumes solves this more elegantly. I'll show you both solutions.

First, here's the original problem:

Hello again Marc.

I always enjoy your excellent column. The effort you put into it, especially how you've managed to keep it up week after week is astounding. Well done!

I asked you a question about using resource forks for storing program data (eg. for games) in which you advised me to use binary files because resources are on there way out. However, I have been puzzled by this. How do you store pictures and sounds in a binary file? Can't it just store text and numbers? The only way I can think of to do it would be to store an image as a long string of integers, representing the RGB value of each pixel - very inefficient and slow.

What am I missing?

Dan

Actually, Dan's on the right track: binary files can store anything, and they're quite efficient. Say we wanted to store more than one picture in the same file. How could we do that? Well, all we need is the picture's binary data and we save that in a binary file. If there's more than one picture, we do the same for it. We need a little bit of header info in the file to tell us where one picture starts and ends and the other picture starts and ends, and then we can save and retrieve the two pictures from one file.

The problem in this case isn't limitations of the binary file: it's limitations of REALbasic. REALbasic doesn't give us an easy way to access the binary info of a picture. For a styled editField, for instance, we can access the textStyleData property: that's where all the formatting for the text is saved. But there is no such property for pictures. So what do we do?

In my sample program save2binary.rb, I came up with a workaround. It's a little complicated, so follow along.

First, remember that REALbasic gives us standard .OpenAsPicture and .SaveAsPicture methods. That's how we usually open or save a picture. However, that won't work in this case, since we want to store multiple pictures in a binary file.

But the picture files as they exist on disk, are binary files. If only there was a way to read in that data as binary data, not as a picture... hold on a second. Why couldn't we just read the picture file in as a binary file (part of a binaryStream object)?

That's exactly what we do: we read in the file as binary data and save it in our binary save routine. Here are the steps we take to save two pictures into one file:

  1. create a new binary file for our picture
  2. save picture 1 on disk in a temporary file
  3. read in the temp file as binary data
  4. save the binary file in our special binary file
  5. save picture 2 on disk in a temporary file
  6. read in the temp file as binary data
  7. append that data to our special binary file

To open our special binary file, we reverse the process:

  1. open the binary file as binary
  2. read in the info for the first picture
  3. save that data back to disk as a temporary binary file
  4. open that binary file as a picture (using the .OpenAsPicture method)
  5. read in the info for the second picture
  6. save that data back to disk as a temporary binary file
  7. open that binary file as a picture (using the .OpenAsPicture method)

That's it! For simplicity's sake, I just did this to support two pictures in one file, but the same system could be extended to support as many pictures as you like. If you made the header info saved within our custom binary file more detailed, you could even specify different kinds of files and store sounds, pictures, text, etc. all in one file. All that's important is that you have some kind of a system in place to indicate to your program what kind of data is coming next and how long it is: that way you know how much data to read for the next object and what it is (sound, graphic, etc.).

If you want to try my program, you can download it here. It comes with a sample two-graphic binary file you can open with the program.

Of course my system is a kludge -- since we don't have access to the raw binary details of data within REALbasic's object system we have to write them out disk before we can access them. That means every object is being read and written to disk multiple times during the save. That's not very efficient.

REALbasic 4.5, however, has obsoleted my system. Virtual Volumes give us the power to store multiple files in a single file: that's just like we can do with a resource fork, but since the file is a simple binary file, it's cross-platform (resource forks only work on Macintosh).

Best of all, Virtual Volumes do this in an incredibly simple manner, one that we all know and love: folderItems.

If you've used REALbasic for any time at all, you've had a chance to use the powerful folderItem class. A folderItem is a REALbasic object that represents a file on disk. There are methods and properties for doing all sorts of things to the file: renaming it, moving it, duplicating it, deleting it, opening it, saving it, etc. Almost anything you want to do to a file you can do to a folderItem.

REALbasic 4.5 has simply provided a new kind of folderItem: a Virtual Volume folderItem. With a Virtual Volume folderItem, you're free to do all the things you normally do with files and folders. You can create new folders, save items inside those folders, add files, delete files, rename files. Yet, because this is a Virtual Volume, the entire structure -- dozens of files and folders -- is saved as a single binary file.

Think about that. You already know how to use the built-in folderItem methods to open and save pictures, right? Well, with a Virtual Volume you'd just do the same thing except to files inside another file! Simple. Brilliantly simple.

Except that it's not. Well, it should be, but the Virtual Volume feature, in my opinion, isn't finished.

We should be able to write a save routine like this:

  
dim vv as virtualVolume
dim f, f2 as folderItem

f = getFolderItem("").child("test vvolume")
if f <> nil then
vv = f.CreateVirtualVolume
if vv <> nil then
f2 = vv.root.child("picture1")
f2.saveAsPicture canvas1.backdrop

f2 = vv.root.child("picture2")
f2.saveAsPicture canvas2.backdrop

f2 = vv.root.child("text1")
f2.saveStyledEditField editField1

msgBox "saved"
else
msgBox "vv nil"
end if // vv = nil
else
msgBox "f nil"
end if // f = nil

This creates a new Virtual Volume and saves two pictures and a styled editfield into it. Because a Virtual Volume is a subclass of the folderItem object, our vv object has methods such as saveAsPicture and saveStyledEditField.

Unfortunately, while those methods seem to be there and the program compiles and runs, those methods do nothing!

It took me a little while to figure this out as the minimal documentation about Virtual Volumes didn't explain this limitation. I finally found a brief explanation in some mailing list postings. It turns out that at least for now, Virtual Volumes only support the binaryStream and textInputStream and textOutputStream objects. That's why saveAsPicture and saveStyledEditField don't work.

This rather sucks as it's an incomplete metaphor, but I hope the problem is just temporary and REAL Software will soon finish what started out as a useful feature. As Virtual Volumes exist right now, they aren't much better than my old program. In a rewrite of my binary save routine to work with Virtual Volumes, you'd still have do the temporary file trick to access the binary info of a picture, which takes extra time, so the only thing you'd save is not having to worry about the file headers -- keeping track of which virtual file is which and how long they are. In a simple program like the above demo, that's not much extra work. In a more complex program with several data types to save it could be, but you could write your own wrapper class to handle that dirty work transparently.

Contrast the above routine with this one, rewritten to take advantage of Virtual Volumes, but using the binaryStream class instead of saveAsPicture and saveStyledEditField:

  
dim vv as virtualVolume
dim f, f2, f3 as folderItem
dim tout as textOutputStream
dim bs, bout as binaryStream


f = getFolderItem("").child("test vvolume")
f2 = getTempFolderitem
if f <> nil or f2 <> nil then
vv = f.CreateVirtualVolume
if vv <> nil then

// Save the first picture
// Generate bout virtual file within f (our vv object)
f= vv.root.child("picture1")
if f <> nil then
bout = f.CreateBinaryFile("myBinary")
if bout <> nil then
// Save temp picture
f2.saveAsPicture canvas1.backdrop
// Read temp picture back in
// and save into bout (our virtual binarystream)
bs = f2.OpenAsBinaryFile(false)
if bs <> nil then
bout.write bs.read(bs.length)
bs.close
end if
bout.close
end if // bout
end if // f = nil

// Save the second picture
// Generate bout virtual file within f (our vv object)
f = vv.root.child("picture2")
if f <> nil then
bout = f.CreateBinaryFile("myBinary")
if bout <> nil then
// Save temp picture
f2.saveAsPicture canvas2.backdrop
// Read temp picture back in
// and save into bout (our virtual binarystream)
bs = f2.OpenAsBinaryFile(false)
if bs <> nil then
bout.write bs.read(bs.length)
bs.close
end if
bout.close
end if // bout
end if // f = nil


// Now we handle styled editField
// Since we have binary data for it, we don't need
// to bother with temp files

// Generate bout virtual file within f (our vv object)
f = vv.root.child("text1")
if f <> nil then
bout = f.CreateBinaryFile("myBinary")
if bout <> nil then
// First we write the text length and text data
bout.writeLong len(editField1.text)
bout.write editField1.text

// then we write style data length and style data
bout.writeLong len(editField1.textStyleData)
bout.write editField1.textStyleData

// Remove temporary file & save
f2.delete
bout.close
end if // bout
end if // f = nil

msgBox "saved"
else
msgBox "vv nil"
end if // vv = nil
else
msgBox "f nil"
end if // f = nil

Wow, that's a lot more complicated, isn't it! That why, though I love the concept of Virtual Volumes, in their current half-finished state they're rather useless.

They do work, however. Here's what the program looks like when you run it and open the included demo file:

As you can see, it not only restored the two pictures successfully, but it also restored the styled text in the editField properly.

Working with Virtual Volumes can be confusing, so I recommend you download Will Leshner's free VV Browser utility (written in REALbasic, of course). It lets you open and examine the structure of a Virtual Volume. The one I created for this example looks like this:

I'm going to make public both Virtual Volume versions of this demo project: the first is simpler, but doesn't work right now -- hopefully it will in the future. It's called save2vvolume_future.rb. The other works right now in RB 4.5, but has to use the temporary binary file trick and is therefore complex. It's called save2vvolume.rb.

QuickTime

Another major improvement to REALbasic 4.5 is better QuickTime support. Unfortunately, I'm not well versed in using QuickTime, so I can't tell you what the improvements are. However, the new features sound impressive:

  • Track level editing
  • New soundtrack class
  • New 3dAudio class
  • Movie-level editing
  • Movieplayer editing
  • QTVR navigation

If there's interest, perhaps I'll try to do an RBU project using QuickTime in the future. It's just not something I have any experience with right now.

PagePanel Object

REALbasic 4.5 adds a new object to the controls palette: the pagePanel. A pagePanel is similar to a tabPanel except that it has no visual indication of the current page (or tab). It's basically a generic multi-page object that allows you to set up whatever kind of interface you'd like (to create "wizards" or preference panels).

For instance, you could use it in combination with a listBox to set up a preference window similar to Internet Explorer's:

Or you could do the new icon-style preference pane like in Jaguar's Mail program:

Both of these can be created with the pagePanel object. It looks like this in the IDE:

Not particularly attractive, but remember, this is only seen in the IDE. If you run this project you'll see nothing at all in the running program. Clicking on the middle control (between the left/right arrows) brings up a menu that lets you add or delete pages.

Since the pagePanel has no interface, you must add that yourself, in the form of a popupMenu, buttons, icons, or something the user can click on to switch between the various pages of controls. Here's a pathetic demo that shows this in action: pagepaneldemo.rb.

Miscellaneous Features and Bug Fixes

There are tons of other things added or fixed with RB 4.5. These include:

  • Automate common code editing tasks with the Scriptable Code Editor
  • Resume debugging by saving breakpoints and clearing them when finished
  • RbScript can now communicate with the rest of your application
  • Integrate REALbasic with standard source and version control systems with Export modules and classes as XML
  • Expanded AppleEvent types

Many bugs have also been fixed. My favorite is that now you can programmatically (dynamically) assign menu shortcuts that use modifier keys (such as "Shift-I"). You've been able to do that within the IDE for a long time, but when you tried to do it dynamically, it didn't work.

Next Week

Marc will explore two interesting aspects of REALbasic we haven't touched on yet: supporting Apple Events and RbScript.

Letters

No letters section this time since I answered one in the column.


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