TweetFollow Us on Twitter

MACINTOSH C
MACINTOSH C: A Hobbyist's Guide To Programming the Mac OS in C
Version 2.3

© 2000 K. J. Bricknell

Go to Contents

(Chapter 17)

MORE ON RESOURCES

A link to the associated demonstration program listing is at the bottom of this page



Introduction

Chapter 1 - System Software, Memory, and Resources covered the basics of creating standard resources for an application's resource file and with reading in standard resources from application files and the System file. In addition, the demonstration programs in preceding chapters have all involved the reading in of standard resources from those files.

This chapter is concerned with aspects of resources not covered at Chapter 1, including search paths, detaching and copying resources, creating, opening, and closing resource files, and reading from and writing to resource files. In addition, the accompanying demonstration program demonstrates the creation of custom resources, together with reading such resources from, and writing them to, the resource forks of files other than application and System files.

Search Path for Resources

Preamble

When your application uses a Resource Manager function to read, or perform an operation on, a resource, the Resource Manager follows a defined search path to find the resource. The different files whose resource forks may constitute the search path are therefore of some relevance. The following summarises the typical locations of resources used by an application:

Resource Fork of: Typical Resources Therein Comments
System file Sounds, icons, cursors, and other elements available for use by all applications.

Code resources which manage user interface elements such as menus, controls and windows.

On startup, the system software calls InitResources to initialise the Resource Manager, which creates a special heap zone within the system heap and builds a resource map which points to system-resident resources. The Resource Manager then opens the resource fork of the System file and reads its resource map into memory.
Application file Descriptions of menus, windows, controls, icons, and other elements.

Static data such as text used in dialog boxes or help balloons.

When a user opens an application, system software automatically opens the application's resource fork.
Application's preferences file Data which encodes the user's global preferences for the application. An application should typically open the preferences file at application launch, and leave it open.
Application's document file Data which defines characteristics specific only to this document, such as its window's last size and location. When an application opens a document file, it should typically opens the file's resource fork as well as its data fork.

Current Resource File

The first file whose resource fork is searched is called the current resource file. Whenever your application opens the resource fork of a file, that file becomes the current resource file. Thus the current resource file usually corresponds to the file whose resource fork was opened most recently.

The resource fork of a file is also called the resource file because, in some respects, you can treat it as if it were a separate file.

Most Resource Manager functions assume that the current resource file is the file on which they should operate or, in the case of a search, the file in which to begin the search.

Default Search Order

During its search for a resource, if the Resource Manager cannot find the resource in the current resource file, it continues searching until it either finds the resource or has searched all files in the search path.

Specifically, when the Resource Manager searches for a resource, it normally looks first in the resource map in memory of the last resource fork your application opened. If the Resource Manager does not find the resource there, it continues to search the resource maps of each resource open to your application in reverse order of opening. After looking in the resource maps of the resource files your application has opened, the Resource Manager searches your application's resource map. If it does not find the resource there, it searches the System file's resource map.

Implications of the Default Search Order

The implications of this search order are that it allows your application to:

  • Access resources defined in the System file.

  • Override resources defined in the System file.

  • Override application-defined resources with document-specific resources.

  • Share a single resource amongst several files by storing it in the application's resource fork.

Setting the Current Resource File To Dictate the Search Order

Although you can take advantage of the Resource Manager's search order to find a particular resource, your application should generally set the current resource file to the file containing the desired resource before reading and writing resource data. This ensures that that file will be searched first, thus possibly obviating unnecessary searches of other files.

UseResFile is used to set the current resource file. Note that UseResFile takes as its single parameter a file reference number, which is a unique number identifying an access path to the resource fork. The Resource Manager assigns a resource file a file reference number when it opens that file. (Your application should keep track of the file reference numbers of all resource files it opens.) CurResFile may be used to get the file reference number of the current resource file.

Restricting the Search to the Current Resource File

The search path may be restricted to the current resource file by using Resource Manager functions (such as Get1Resource) which look only in the current resource file's resource map when searching for a specific resource.

Detaching and Copying Resources

When you have finished using a resource, you typically call ReleaseResource, which releases the memory associated with that resource and sets the handle's master pointer to NULL, thus making your application's handle to the resource invalid. If the application needs the resource later, it must get a valid handle to the resource by reading the resource into memory again using a function such as GetResource.

Your application can use DetachResource to replace a resource's handle in the resource map with NULL without releasing the associated memory. DetachResource may thus be used when you want your application to access the resource's data directly, without the aid of the Resource Manager, or when you need to pass the handle to a function which does not accept a resource handle. For example, the AddResource function, which makes arbitrary data in memory into a resource, requires a handle to data, not a handle to a resource.

DetachResource is useful when you want to copy a resource. The procedure is to read in the resource using GetResource, detach the resource to disassociate it from its resource file, and then copy the resource to a destination file using AddResource.

Creating, Opening and Closing Resource Forks

Opening an Application's Resource Fork

The system software automatically opens your application's resource fork at application launch. Your application should simply call CurResFile early in its initialisation function to save the file reference number for the application's resource fork.

Creating and Opening a Resource Fork

Creating a Resource Fork

To save resources to the resource fork of a file, you must first create the resource fork (if it does not already exist) and obtain a file reference number for it. You use FSpCreateResFile to create a resource fork. FSpCreateResFile requires four parameters: a file system specification structure, the signature of the application creating the file, the file type, and the script code for the file. The effect of FSpCreateResFile varies as follows:

  • If the file specified by the file system specification structure does not already exist (that is, the file has neither a data fork nor a resource fork), FSpCreateResFile:

    • Creates a file with an empty resource fork and resource map.

    • Sets the creator, type, and script code fields of the file's catalog information structure to the specified values.

  • If the data fork of the file specified by the file system specification structure already exists but the file has a zero-length resource fork, FSpCreateResFile:

    • Creates an empty resource fork and resource map.

    • Changes the creator, type, and script code fields of the catalog information structure of the file to the specified values.

  • If the file specified by the file system specification structure already exists and includes a resource fork with a resource map, FSpCreateResFile does nothing, and ResError returns an appropriate result code.

Opening a Resource Fork

After creating a resource fork, and before attempting to write to it, you must open it using FSpOpenResFile. FSpOpenResFile returns a file reference number which, as previously stated, may be used to change or limit the Resource Manager's search order.

Note that, although the file reference number for the data fork and the resource fork usually match, you should not assume that this is always the case.

When you open a resource fork, the Resource Manager resets the search path so that the file whose resource fork you just opened becomes the current resource file.

After opening a resource fork, you can use Resource Manager functions to write resources to it.

It is possible to write to the resource fork using File Manager functions. However, in general, you should always use Resource Manager functions.

Closing a Resource Fork

When you are finished using a resource fork that your application explicitly opened, you should close it using CloseResFile. Note that the Resource Manager automatically closes any resource forks opened by your application that are still open when your application calls ExitToShell.

Reading and Manipulating Resources

The Resource Manager provides a number of functions which read resources from a resource fork. Depending on which function is used, you specify the resource to be read by either its resource type and resource ID or its resource type and resource name.

Reading From the Resource Map Without Loading the Resource

Those Resource Manager functions which return handles to resources normally read the resource data into memory if it is not already there. Sometimes, however, you may want to read, say, resource types and attributes from the resource map without reading the resource data into memory. Calling SetResLoad with the load parameter set to false causes subsequent calls to those functions which return handles to resources to not load the resource data to memory. (To read the resource data into memory after a call to SetResLoad with the load parameter set to false, call LoadResource.)

If you call SetResLoad with the load parameter set to false, be sure to call it again with the parameter set to true as soon as possible. Other parts of the system software that call the Resource Manager rely on the default setting (that is, the load parameter set to true), and some functions will not work properly if resources are not loaded automatically.

Indexing Through Resources

The Resource Manager provides functions which let you index through all resources of a given type (for example, using CountResources and GetIndResource). This can be useful when you want to read all resources of a given type.

Writing Resources

After opening a resource fork, you can write resources to it. You can write resources only to the current resource file.

To specify the data for a new resource, you usually use AddResource, which creates a new entry for the resource in the resource map in memory (but not on the disk) and sets the entry's location to refer to the resource's data. UpdateResFile or WriteResFile may then be used to write the resource to disk. Note that AddResource always adds the resource to the resource map in memory which corresponds to the current resource file. For this reason, you usually need to set the current resource file to the desired file before calling AddResource.

If you change a resource that is referenced through the resource map in memory, you use ChangedResource to set the resChanged attribute of that resource's resource map entry. ChangedResource reserves enough disk space to contain the changed resource. Immediately after calling ChangedResource, you should call UpdateResFile or WriteResFile to write the changed resource data to disk. The difference between UpdateResFile and WriteResFile is as follows:

  • UpdateResFile writes those resources which have been added or changed to disk. It also writes the entire resource map to disk, overwriting its previous contents.

  • WriteResFile writes only the resource data of a single resource to disk and does not update the resource's entry in the resource map on disk.

Care with Purgeable Resources

Most applications do not make resources purgeable. However, if you are changing purgeable resources, you should use the Memory Manager function HNoPurge to ensure that the Resource Manager does not purge the resource while your application is in the process of changing it.

Partial Resources

Some resources, such as 'snd ' and 'sfnt' resources, can be too large to fit into available memory. ReadPartialResource and WritePartialResource allow you to read a portion of the resource into memory or to alter a section of the resource while it is still on disk.

Preferences Files

Many applications allow the user to alter various settings to control the operation or configuration of the application. You can create a preferences file in which to record user preferences, and your application can retrieve the information in that file when the application is launched. Preferences information should be saved as a custom resource to the resource fork of the preferences file.

In deciding how to structure your preferences file, it is important to distinguish document-specific settings from application-specific settings. Some user-specifiable settings affect only a particular document and should, therefore, be saved to the document file's resource fork. Other settings are not specific to a particular document. You could store such settings in the application's resource fork, but it is generally better to store them in a separate preferences file, the main reason being to avoid problems which can arise if the application is located on a server volume.

The Operating System provides a special folder in the System Folder, called Preferences, where you can store the preferences file.



Main Resource Manager Constants, Data Types and Functions

Constants

Resource Attributes

resSysHeap    = 64  System or application heap?
resPurgeable  = 32  Purgeable resource?
resLocked     = 16  Load it in locked?
resProtected  = 8  Protected?
resPreload    = 4  Load in on OpenResFile?
resChanged    = 2  Resource changed?

Data Types

typedef unsigned long  FourCharCode;
typedef FourCharCode  ResType;

Functions

Initialising the Resource Manager

short  InitResources(void);

Checking for Errors

short  ResError(void);

Creating an Empty Resource Fork

void  FSpCreateResFile(const FSSpec *spec,OSType creator,OSType fileType,ScriptCode
      scriptTag);

Opening Resource Forks

short  FSpOpenResFile(const FSSpec *spec,SignedByte permission);

Getting and Setting the Current Resource File

void   UseResFile(short refNum);
short  CurResFile(void);
short  HomeResFile(Handle theResource);

Reading Resources Into Memory

Handle  GetResource(ResType theType,short theID);
Handle  Get1Resource(ResType theType,short theID);
Handle  GetNamedResource(ResType theType,ConstStr255Param name);
Handle  Get1NamedResource(ResType theType,ConstStr255Param name);
void    SetResLoad(Boolean load);
void    LoadResource(Handle theResource);

Getting and Setting Resource Information

void   GetResInfo(Handle theResource,short *theID,ResType *theType,Str255 name);
void   SetResInfo(Handle theResource,short theID,ConstStr255Param name);
short  GetResAttrs(Handle theResource);
void   SetResAttrs(Handle theResource,short attrs);

Modifying Resources

void  ChangedResource(Handle theResource);
void  AddResource(Handle theResource,ResType theType,short theID,ConstStr255Param name);

Writing to Resource Forks

void  UpdateResFile(short refNum);
void  WriteResource(Handle theResource);

Getting a Unique Resource ID

short  UniqueID(ResType theType);
short  Unique1ID(ResType theType);

Counting and Listing Resource Types

short   CountResources(ResType theType);
short   Count1Resources(ResType theType);
Handle  GetIndResource(ResType theType,short index);
Handle  Get1IndResource(ResType theType,short index);
short   CountTypes(void);
short   Count1Types(void);
void    GetIndType(ResType *theType,short index);
void    Get1IndType(ResType *theType,short index);

Getting Resource Sizes

long  GetResourceSizeOnDisk(Handle theResource);
long  GetMaxResourceSize(Handle theResource);

Disposing of Resources and Closing Resource Forks

void  ReleaseResource(Handle theResource);
void  DetachResource(Handle theResource);
void  RemoveResource(Handle theResource);
void  CloseResFile(short refNum);

Getting and Setting Resource Fork Attributes

short  GetResFileAttrs(short refNum);
void  SetResFileAttrs(short refNum,short attrs);

Go to Demo

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Fresh From the Land Down Under – The Tou...
After a two week hiatus, we are back with another episode of The TouchArcade Show. Eli is fresh off his trip to Australia, which according to him is very similar to America but more upside down. Also kangaroos all over. Other topics this week... | Read more »
TouchArcade Game of the Week: ‘Dungeon T...
I’m a little conflicted on this week’s pick. Pretty much everyone knows the legend of Dungeon Raid, the match-3 RPG hybrid that took the world by storm way back in 2011. Everyone at the time was obsessed with it, but for whatever reason the... | Read more »
SwitchArcade Round-Up: Reviews Featuring...
Hello gentle readers, and welcome to the SwitchArcade Round-Up for July 19th, 2024. In today’s article, we finish up the week with the unusual appearance of a review. I’ve spent my time with Hot Lap Racing, and I’m ready to give my verdict. After... | Read more »
Draknek Interview: Alan Hazelden on Thin...
Ever since I played my first release from Draknek & Friends years ago, I knew I wanted to sit down with Alan Hazelden and chat about the team, puzzle games, and much more. | Read more »
The Latest ‘Marvel Snap’ OTA Update Buff...
I don’t know about all of you, my fellow Marvel Snap (Free) players, but these days when I see a balance update I find myself clenching my… teeth and bracing for the impact to my decks. They’ve been pretty spicy of late, after all. How will the... | Read more »
‘Honkai Star Rail’ Version 2.4 “Finest D...
HoYoverse just announced the Honkai Star Rail (Free) version 2.4 “Finest Duel Under the Pristine Blue" update alongside a surprising collaboration. Honkai Star Rail 2.4 follows the 2.3 “Farewell, Penacony" update. Read about that here. | Read more »
‘Vampire Survivors+’ on Apple Arcade Wil...
Earlier this month, Apple revealed that poncle’s excellent Vampire Survivors+ () would be heading to Apple Arcade as a new App Store Great. I reached out to poncle to check in on the DLC for Vampire Survivors+ because only the first two DLCs were... | Read more »
Homerun Clash 2: Legends Derby opens for...
Since launching in 2018, Homerun Clash has performed admirably for HAEGIN, racking up 12 million players all eager to prove they could be the next baseball champions. Well, the title will soon be up for grabs again, as Homerun Clash 2: Legends... | Read more »
‘Neverness to Everness’ Is a Free To Pla...
Perfect World Games and Hotta Studio (Tower of Fantasy) announced a new free to play open world RPG in the form of Neverness to Everness a few days ago (via Gematsu). Neverness to Everness has an urban setting, and the two reveal trailers for it... | Read more »
Meditative Puzzler ‘Ouros’ Coming to iOS...
Ouros is a mediative puzzle game from developer Michael Kamm that launched on PC just a couple of months back, and today it has been revealed that the title is now heading to iOS and Android devices next month. Which is good news I say because this... | Read more »

Price Scanner via MacPrices.net

Amazon is still selling 16-inch MacBook Pros...
Prime Day in July is over, but Amazon is still selling 16-inch Apple MacBook Pros for $500-$600 off MSRP. Shipping is free. These are the lowest prices available this weekend for new 16″ Apple... Read more
Walmart continues to sell clearance 13-inch M...
Walmart continues to offer clearance, but new, Apple 13″ M1 MacBook Airs (8GB RAM, 256GB SSD) online for $699, $300 off original MSRP, in Space Gray, Silver, and Gold colors. These are new MacBooks... Read more
Apple is offering steep discounts, up to $600...
Apple has standard-configuration 16″ M3 Max MacBook Pros available, Certified Refurbished, starting at $2969 and ranging up to $600 off MSRP. Each model features a new outer case, shipping is free,... Read more
Save up to $480 with these 14-inch M3 Pro/M3...
Apple has 14″ M3 Pro and M3 Max MacBook Pros in stock today and available, Certified Refurbished, starting at $1699 and ranging up to $480 off MSRP. Each model features a new outer case, shipping is... Read more
Amazon has clearance 9th-generation WiFi iPad...
Amazon has Apple’s 9th generation 10.2″ WiFi iPads on sale for $80-$100 off MSRP, starting only $249. Their prices are the lowest available for new iPads anywhere: – 10″ 64GB WiFi iPad (Space Gray or... Read more
Apple is offering a $50 discount on 2nd-gener...
Apple has Certified Refurbished White and Midnight HomePods available for $249, Certified Refurbished. That’s $50 off MSRP and the lowest price currently available for a full-size Apple HomePod today... Read more
The latest MacBook Pro sale at Amazon: 16-inc...
Amazon is offering instant discounts on 16″ M3 Pro and 16″ M3 Max MacBook Pros ranging up to $400 off MSRP as part of their early July 4th sale. Shipping is free. These are the lowest prices... Read more
14-inch M3 Pro MacBook Pros with 36GB of RAM...
B&H Photo has 14″ M3 Pro MacBook Pros with 36GB of RAM and 512GB or 1TB SSDs in stock today and on sale for $200 off Apple’s MSRP, each including free 1-2 day shipping: – 14″ M3 Pro MacBook Pro (... Read more
14-inch M3 MacBook Pros with 16GB of RAM on s...
B&H Photo has 14″ M3 MacBook Pros with 16GB of RAM and 512GB or 1TB SSDs in stock today and on sale for $150-$200 off Apple’s MSRP, each including free 1-2 day shipping: – 14″ M3 MacBook Pro (... Read more
Amazon is offering $170-$200 discounts on new...
Amazon is offering a $170-$200 discount on every configuration and color of Apple’s M3-powered 15″ MacBook Airs. Prices start at $1129 for models with 8GB of RAM and 256GB of storage: – 15″ M3... Read more

Jobs Board

*Apple* Systems Engineer - Chenega Corporati...
…LLC,** a **Chenega Professional Services** ' company, is looking for a ** Apple Systems Engineer** to support the Information Technology Operations and Maintenance Read more
Solutions Engineer - *Apple* - SHI (United...
**Job Summary** An Apple Solution Engineer's primary role is tosupport SHI customers in their efforts to select, deploy, and manage Apple operating systems and Read more
*Apple* / Mac Administrator - JAMF Pro - Ame...
Amentum is seeking an ** Apple / Mac Administrator - JAMF Pro** to provide support with the Apple Ecosystem to include hardware and software to join our team and Read more
Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.