Separate Data, Code
Volume 8
Number 4
Column Title: Getting Started
Related Info: Resource Manager Window Manager Picture Utilities
Separating Data from Code
Using those little pockets of data called resources
By Dave Mark, MacTutor Regular Contributing Author
Note: Source code files accompanying article are located on MacTech CD-ROM or
source code disks.
Last month’s column focused on QuickDraw, the Macintosh drawing environment.
The TextBoxer program showed you how to use QuickDraw in combination with the
Window Manager to draw text and graphics in a window. This month we’ll learn about
resources, the Mac’s mechanism for separating data from code.
Resources
Resources are little pockets of data, designed to pull descriptive data out of your
program’s source code. For example, a WIND resource describes the size, location, and
characteristics of a Macintosh window. In last month’s column, we used the Window
Manager call NewWindow() to create a new window:
/* 1 */
WindowPtr window;
Rect windowRect;
SetRect( & windowRect, 20, 40, 260, 74 );
window = NewWindow( nil, & windowRect, "\pBox o' Text",
kVisible, documentProc, kMoveToFront,
kNoGoAway, kNilRefCon );
The parameters passed to NewWindow() completely describe the window. The
trouble is, the description is inexorably bound into the source code. To change the size
or position of the window, you’ve got to recompile your program. The WIND resource
gives you an alternative to this strategy. Here’s how it works...
Basic Resource Strategy
At the heart of any resource strategy is a resource editor. Though there are
others, for my money [e specially since it is free - Ed.] ResEdit can’t be beat. ResEdit
allows you to edit resources using a graphic resource editor designed for that resource
type. For example, Figure 1 shows ResEdit’s WIND editing window.
This window gives you all the tools you’ll need to completely describe a window.
At the top is a row of icons that let you select the type of window you’d like to create. At
bottom-left is a series of fields you can use to describe the size and location of the
window. In the center is a miniature version of your screen, showing how your window
will look once it’s created.
Figure 1. ResEdit’s WIND editing window.
Once you design your resources, you load them into your program using a set of
Toolbox routines designed to work with resources. As an example, the routine
GetNewWindow() loads a WIND resource and creates the same kind of WindowRecord as
the Window Manager routine NewWindow():
/* 2 */
window = GetNewWindow( kBaseResID, nil, kMoveToFront );
If you use NewWindow() to create a window, the data that describes the window
is embedded in the source code in the form of NewWindow() parameters. If you use
GetNewWindow(), the data that describes the window resides outside of your program’s
code, in the WIND resource. The WIND resource acts as a template for creating a
window.
As you spend more time programming the Macintosh, you’ll learn more and more
about the enormous potential of resources. For now, we’ll start slowly, introducing a
few basic resources in this column, and adding to our list each month.
Resource Management Specifics
Resources are identified by a resource type and a resource ID. The resource type
is a four-byte value, typically made up of readable ASCII characters. The resource type
defines the data described by the resource. For example, a WIND resource always
follows the same format and always describes a Macintosh window. There are lots of
different resource types.
A program can contain more than one resource of a given type. The resource ID
serves to differentiate one resource of a given type from another. Typically, resource
IDs start at 128 and move upwards from there. If your program used three WIND
resources, you’d number them 128, 129, and 130.
This month’s sample program, PICTWindow, makes use of two resources, a PICT
and a WIND. The PICT resource contains a Macintosh picture. PICTWindow uses the
WIND resource to create a new window, loads the PICT resource into memory, then
draws the PICT in the window.
Let’s get to work...
Creating the PICTWindow Resources
If you don’t already have a copy of ResEdit, go out and get one. You can download
ResEdit from most of the big bulletin boards, and you can purchase ResEdit from APDA.
In my latest APDA catalog, there were three entries for ResEdit version 2.1.1.
$29.95 gets you the manual and disk, $14.95 is the manual only, and $15.00 for the
disk only. You can reach APDA by phone at (800) 282-2732 in the United States,
(800) 637-0029 in Canada, and (408) 562-3910 internationally.
You might also consider ordering the book ResEdit Complete, a fine book written
by Peter Alley and Carolyn Strange ($29.95 from APDA).
Once you’ve copied your copy of ResEdit to your hard drive, create a folder for
all the PICTWindow files inside your development folder. I called my folder (logically
enough) PICTWindow.
Next, use your favorite graphics package to create a pleasing picture. Copy the
picture, then paste it into the Scrapbook. Feel free to use color, text, and whatever else
pleases your eye in your picture. PICTWindow can handle anything you can paste into
the Scrapbook.
Now you’re ready to create some resources. Double-click on the ResEdit icon to
start-up ResEdit. When the bouncing Jack-in-the-box appears, click the mouse
button. You’ll be prompted for a file to open (if your version of ResEdit doesn’t prompt
you, it’s OK, just ignore the rest of this paragraph). Click the Cancel button.
We’re going to create a new resource file. Select New... from the File menu. The
dialog box shown in Figure 2 will appear, asking you to name the new resource file.
Using the standard techniques, navigate over and in to the PICTWindow folder you
created earlier. In the text field at the bottom of the dialog box, type the file name
PICTWindow.π.rsrc exactly as it appears in Figure 2. To type the π character, hold
down the option key and press the p key. Be sure to type the name exactly as shown.
Don’t add anything. Don’t leave anything out. You’ll see why later in the column.
Figure 2. Naming your new resource file.
Once the name is typed in, click on the New button. ResEdit will create the new
resource file and display a window showing the resources in this file. So far, there are
none. We’ll fix that right now.
Select Create New Resource from the Resource menu. A scrolling list of resource
types will appear (Figure 3). Scroll to the bottom of the list and select WIND (if you
prefer, you can type WIND in the text field). Once WIND is selected (or typed) click the
OK button. A WIND icon will be added to the PICTWindow.π.rsrc main window, showing
you that a WIND resource exists. A WIND picker window will appear, listing all the
WIND resources in this file. Finally, on top of the other two, a WIND editing window will
appear, allowing you to edit your new WIND.
Figure 3. Creating a new WIND resource.
By default, your new WIND resource is given the resource ID 128. That’s
convenient, since that’s the number we wanted it to have. Use the settings shown in
Figure 4 to modify your WIND resource. Click the second icon from the left (at the top
of the window) and type in the four numbers shown in the lower left corner.
Figure 4. The WIND editing window from WIND 128.
Next, select Set 'WIND' Characteristics... from the WIND menu that appeared
along with the WIND editor. Type in an appropriate window title (don’t change any of
the other fields) and click the OK button. Congratulations! You’ve just created your
first Macintosh resource. Close the WIND editing window and the WIND picker window,
leaving the main window for the resource file. A WIND icon should appear in this
window.
Let’s add the second resource needed by our program, the PICT resource. Go to
the Scrapbook and Copy the picture you pasted in there earlier (if you prefer, Copy one
of the pictures that come with the Scrapbook - Don’t copy plain text. Plain text won’t
do what we want).
Once your picture is copied, bring the PICTWindow.π.rsrc window back to the
front and select Paste from ResEdit’s Edit menu. A new resource will be created and a
PICT icon will appear in the main window verifying this fact. The PICT resource will
automatically be given the resource ID 128. Now would be an excellent time to select
Save from the File menu. You are done creating resources.
Quit ResEdit by selecting Quit from the File menu.
Creating the PICTWindow Project
Startup THINK C and create a new project in the PICTWindow folder. Name the
new project PICTWindow.π (be sure to spell it exactly this way). When you run a
project, THINK C automatically tacks on the five characters “.rsrc” to the end of the
project name and looks for a resource file with that name. If a resource file with that
name is found, the resources in that file are automatically made available to your
program. PICTWindow.π is the name of your project file and PICTWindow.π.rsrc is the
name of your resource file.
Once the project is created, go into the Mac Libraries folder and add MacTraps to
the project. Next, select New from the File menu to create a new source code file. Type
in this source code:
/* 3 */
#define kBaseResID 128
#define kMoveToFront (WindowPtr)-1L
/***************/
/* Functions */
/***************/
void ToolBoxInit( void );
void WindowInit( void );
void DrawMyPicture( void );
/****************** main ***************************/
void main( void )
{
ToolBoxInit();
WindowInit();
DrawMyPicture();
while ( !Button() ) ;
}
/****************** ToolBoxInit *********************/
void ToolBoxInit( void )
{
InitGraf( &thePort );
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs( nil );
InitCursor();
}
/****************** WindowInit ***********************/
void WindowInit( void )
{
WindowPtr window;
window = GetNewWindow( kBaseResID, nil, kMoveToFront );
if ( window == nil )
{
SysBeep( 10 ); /* Couldn't load the WIND resource!!! */
ExitToShell();
}
ShowWindow( window );
SetPort( window );
}
/****************** DrawMyPicture ********************/
void DrawMyPicture( void )
{
Rect pictureRect;
PicHandle picture;
picture = GetPicture( kBaseResID );
if ( picture == nil )
{
SysBeep( 10 ); /* Couldn't load the PICT resource!!! */
ExitToShell();
}
pictureRect = (**picture).picFrame;
OffsetRect( &pictureRect, - pictureRect.left,
- pictureRect.top );
DrawPicture( picture, &pictureRect );
FrameRect( &pictureRect );
}
Once your source code is typed in, select Save from the File menu. Save the file
under the name “PICTWindow.c”. Next, add the source file to the project by select Add
(not Add...) from the Source menu. Your project window should look like the one shown
in Figure 5.
Figure 5. The project window for PICTWindow.π.
Running the Program
Now you’re ready to run your program. Select Run from the Project menu. If you
encounter any errors, check your source code for typos and make sure your project
window has the two files shown in Figure 5. Once your program runs, you should see a
window similar to the one shown in Figure 6.
Notice that the picture is drawn in the upper left corner of the window. The
upper left corner of the picture is at (0,0) in the window’s local coordinate system.
Figure 6. The PICTWindow window!
Key Lines of Code
Most of the program should make sense to you if you read through last month’s
TextBoxer example. Rather than repeat last weeks explanations, I’d like to point out
three key segments of code. The first is the code that loads the WIND resource and
creates a new window:
/* 4 */
window = GetNewWindow( kBaseResID, nil, kMoveToFront );
As mentioned earlier, this line of code accomplishes the same thing as
NewWindow(), except that GetNewWindow() gets its information from the WIND
resource, instead of its parameter list. GetNewWindow() is described in Volume I of
Inside Macintosh, on page 283.
The second key line of code is the line that loads the PICT resource:
/* 5 */
picture = GetPicture( kBaseResID );
This line of code loads the PICT resource with an ID matching kBaseResID. Match
this line of code up with the following:
/* 6 */
DrawPicture( picture, &pictureRect );
and you can really see the power of resources. Two lines of code and you’ve drawn
a complex graphic in a window!!! By the way, GetPicture() is on page 475 of Volume I
of Inside Macintosh and DrawPicture() is on page 190 of Volume I.
Till Next Month
Take some time to play around with ResEdit. Use ResEdit to modify your WIND
resource, changing the type of window (click on the icons on the top row of the WIND
editor) and the window’s location. Notice that the picture is drawn in the upper left of
the window, no matter where the window is drawn on the screen. Look up OffsetRect()
in Inside Macintosh and try to figure out why the picture is drawn where it is.
Finally, try to write a routine that centers the picture in the window. For a little
help with this last exercise, you can check out the ShowPICT program in Volume I of the
Mac Primer.
Sorry to cut this column short, but the next time I speak with you all, I should
be a proud new poppa! Stay tuned...