TweetFollow Us on Twitter

MACINTOSH C CARBON
MACINTOSH C CARBON: A Hobbyist's Guide To Programming the Macintosh in C
Version 1.0
2001 K. J. Bricknell
Go to Contents Go to Program Listing

CHAPTER 19

MORE ON RESOURCES, AND CORE FOUNDATION PREFERENCES

Introduction

Chapter 1 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. 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.

This chapter also addresses the matter of storing and retrieving application preferences using Core Foundation Preferences Services.

Search Path for Resources

Preamble

The Resource Manager follows a defined search path to find a resource when you use a Resource Manager function to read, or perform an operation on, a 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, etc.

On startup, the Resource Manager creates a special zone within the system heap, creates a resource map which points to system-resident resources, opens the resource fork of the System file, and reads its resource map into memory.

Application file

Descriptions of menus, windows, controls, icons, etc.

Text used in dialogs or help balloons.

When a user opens an application, system software automatically opens the application's resource fork.

Application's preferences file

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

Information 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

When your application opens the resource fork of a file, that file becomes the current resource file. However, your application can change the current resource file, if necessary, using the function UseResFile.

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.

The current resource file is always the first file in the search path. It is also the file on which most Resource Manager functions assume they should operate.

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.

The Resource Manager normally looks first in the resource map in memory of the last resource fork your application opened. If the resource is not found there, the resource maps of each resource file open to your application are searched in reverse order of opening. If the resource is not found there, your application's resource map is searched. If the resource has still not been found, the searches continues in 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 in the System file.

  • Override resources in the System file.

  • Override your application's resources with document-specific resources.

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

Setting the Current Resource File To Dictate the Search Order

You can, of course, rely on the Resource Manager's search order to find a particular resource; however, it is best to 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.

As previously stated, the function UseResFile is used to set the current resource file. Note that UseResFile takes as its single parameter a file reference number, which identifies an access path to the resource fork. The Resource Manager assigns a resource file a file reference number when it opens that file.

You can get the file reference number of the current resource file using the function CurResFile.

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.

Releasing and Detaching 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

As previously stated, the system software automatically opens your application's resource fork at application launch. The only action required by your application at launch is to call CurResFile to save the file reference number for the application's resource fork.

Creating and Opening a Resource Fork

Creating a Resource Fork

If your application needs to save resources to the resource fork of a file, and assuming the resource fork does not already exist, it must first create the resource fork.. A call to FSpCreateResFile will create the resource fork. FSpCreateResFile requires four parameters: a file system specification structure; the application's signature; the file type; the script code. 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), the function:

    • 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, the function:

    • 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, the function does nothing.

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.

As previously stated, 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

Depending on which Resource Manager function is used to read resources from a resource fork, 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 that 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

When you have opened a resource fork, you can write resources to it (assuming it is the current resource file).

A call to AddResource creates a new entry for a resource in the resource map in memory (but not on the disk) and sets that entry's location to refer to that resource's data. A call to either UpdateResFile or WriteResFile will then write the resource to disk. Note that you usually need to set the current resource file to the desired file before calling AddResource because AddResource always adds the resource to the resource map in memory which corresponds to the current resource file.

When you change a resource referenced through the resource map in memory, you should call 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

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 ' (Mac OS 8/9) and 'sfnt' resources, can be too large to fit into available memory. In these cases, you can read a portion of the resource into memory, or alter a section of the resource while it is still on disk, using the functions ReadPartialResource and WritePartialResource.

Application Preferences

Many applications allow the user to set application preferences, which the application stores in a preferences file and retrieves when the application is launched. On Mac OS 8/9, your Preferences file should be located in the special folder titled Preferences provided by the operating system. The Preferences folder is located in the System folder. On Mac OS X, preferences are stored in the Preferences folder in the Library folder in each user's home directory (~/Library/Preferences).

You can save your application's preferences as a custom resource to the resource fork of your preferences file. Alternatively, and more correctly in the Mac OS X era, you can use the methodology provided by Core Foundation Preferences Services.

Using Core Foundation Preferences Services

Using Core Foundation Preferences Services involves storing values associated with a key, the key being used to later retrieve the value. The concept is similar to that applying to the key/value pairs used in information property lists (see Chapter 9).

Application ID

The name of the file in which Preference Services stores preferences information is specified by an application ID. For Mac OS X, this should be the same as the name associated with the CFBundleIdentifier key in the information property list in your application's 'plst' resource. It thus takes the form of a Java package name, that is, a unique domain name followed by the application's name (for example, com.MyCompany.MyApplication). For Mac OS 8/9, it is sufficient to simply use the application's name. (Indeed, this abbreviation will be essential if the application ID in Java package form exceeds the 31-character limit for Mac OS 8/9 file names.)

Setting, Storing and Retrieving a Preference

You use the function CFPreferencesSetAppValue to set a preferences value. The following example sets a value which specifies that the application should use a full screen display:

     CFStringRef applicationID = CFSTR("com.MyCompany.MyApplication");
     CFStringRef fullScreenKey = CFSTR("fullScreen");
     CFStringRef yes           = CFSTR("yes");
     CFStringRef no            = CFSTR("no");

     CFPreferencesSetAppValue(fullScreenKey,yes,applicationID);

CFPreferencesSetAppValue stores the value in a cache owned by your application. To flush the cache to permananent storage, you must call the function CFPreferencesAppSynchronize, passing in the application ID.

You would use the function CFPreferencesGetAppBooleanValue to retrieve the value, as in the following example:

     CFStringRef applicationID = CFSTR("com.MyCompany.MyApplication");
     CFStringRef fullScreenKey = CFSTR("fullScreen");
     Boolean     booleanValue, success;

     booleanValue = CFPreferencesGetAppBooleanValue(fullScreenKey,applicationID,&success);

You can use CFPreferencesGetAppIntegerValue to retrieve integer values (which are stored as strings) in the same way.

Preference Domains

Preference Services uses the concept of domains when creating or searching for a preference. User name, host name, and application ID identify a domain. CFPreferencesSetAppValue uses the current user and "any host" domain qualifiers as the default, which is why only the application ID is passed in the function call. Alternative low-level Preferences Services functions are available to specify an exact domain.

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);

Main Core Foundation Preferences Services Functions

void    CFPreferencesSetAppValue(CFStringRef key,CFPropertyListRef value,
        CFStringRef applicationID);
void    CFPreferencesSetValue(CFStringRef key,CFPropertyListRef value,
        CFStringRef applicationID,CFStringRef userName,CFStringRef hostName);
Boolean CFPreferencesAppSynchronize(CFStringRef applicationID);
Boolean CFPreferencesSynchronize(CFStringRef applicationID,CFStringRef userName,
        CFStringRef hostName);
Boolean CFPreferencesGetAppBooleanValue(CFStringRef key,CFStringRef applicationID,
        Boolean *keyExistsAndHasValidFormat);
CFIndex CFPreferencesGetAppIntegerValue(CFStringRef key,CFStringRef applicationID,
        Boolean *keyExistsAndHasValidFormat);

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

VueScan 9.5.81 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
iFFmpeg 6.4.2 - Convert multimedia files...
iFFmpeg is a comprehensive media tool to convert movie, audio and media files between formats. The FFmpeg command line instructions can be very hard to master/understand, so iFFmpeg does all the hard... Read more
Fantastical 2.4.1 - Create calendar even...
Fantastical 2 is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event... Read more
Fantastical 2.4.1 - Create calendar even...
Fantastical 2 is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event... Read more
Live Home 3D Pro 3.2.2 - $69.99
Live Home 3D Pro, a successor of Live Interior 3D, is the powerful yet intuitive home design software that lets you build the house of your dreams right on your Mac. It has every feature of Live Home... Read more
Live Home 3D Pro 3.2.2 - $69.99
Live Home 3D Pro, a successor of Live Interior 3D, is the powerful yet intuitive home design software that lets you build the house of your dreams right on your Mac. It has every feature of Live Home... Read more
FileZilla 3.27.0.1 - Fast and reliable F...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface. Version 3.27.0.1: MSW: Add misssing file to .zip binary package... Read more
Spotify 1.0.59.395. - Stream music, crea...
Spotify is a streaming music service that gives you on-demand access to millions of songs. Whether you like driving rock, silky R&B, or grandiose classical music, Spotify's massive catalogue puts... Read more
Sierra Cache Cleaner 11.0.6 - Clear cach...
Sierra Cache Cleaner is an award-winning general purpose tool for macOS X. SCC makes system maintenance simple with an easy point-and-click interface to many macOS X functions. Novice and expert... Read more
DiskCatalogMaker 7.1.2 - Catalog your di...
DiskCatalogMaker is a simple disk management tool which catalogs disks. Simple, light-weight, and fast Finder-like intuitive look and feel Super-fast search algorithm Can compress catalog data for... Read more

Latest Forum Discussions

See All

The best deals on the App Store this wee...
There are quite a few truly superb games on sale on the App Store this week. If you haven't played some of these, many of which are true classics, now's the time to jump on the bandwagon. Here are the deals you need to know about. [Read more] | Read more »
Realpolitiks Mobile (Games)
Realpolitiks Mobile 1.0 Device: iOS Universal Category: Games Price: $5.99, Version: 1.0 (iTunes) Description: PLEASE NOTE: The game might not work properly on discontinued 1GB of RAM devices (iPhone 5s, iPhone 6, iPhone 6 Plus, iPad... | Read more »
Layton’s Mystery Journey (Games)
Layton’s Mystery Journey 1.0.0 Device: iOS Universal Category: Games Price: $15.99, Version: 1.0.0 (iTunes) Description: THE MUCH-LOVED LAYTON SERIES IS BACK WITH A 10TH ANNIVERSARY INSTALLMENT! Developed by LEVEL-5, LAYTON’S... | Read more »
Full Throttle Remastered (Games)
Full Throttle Remastered 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Originally released by LucasArts in 1995, Full Throttle is a classic graphic adventure game from industry legend Tim... | Read more »
Stunning shooter Morphite gets a new tra...
Morphite is officially landing on iOS in September. The game looks like the space shooter we've been needing on mobile, and we're going to see if it fits the bill quite shortly. The game's a collaborative effort between Blowfish Studios, We're Five... | Read more »
Layton's Mystery Journey arrives to...
As you might recall, Layton's Mystery Journey is headed to iOS and Android -- tomorrow! To celebrate the impending launch, Level-5's released a new trailer, complete with an adorable hamster. [Read more] | Read more »
Sidewords (Games)
Sidewords 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Grab a cup of coffee and relax with Sidewords. Sidewords is part logic puzzle, part word game, all original. No timers. No... | Read more »
Noodlecake Games' 'Leap On!...
Noodlecake Games is always good for some light-hearted arcade fun, and its latest project, Leap On! could carry on that tradition. It's a bit like high stakes tetherball in a way. Your job is to guide a cute little blob around a series of floating... | Read more »
RuneScape goes mobile later this year
Yes, RuneScape still exists. In fact, it's coming to iOS and Android in just a few short months. Jagex, creators of the hit fantasy MMORPG of yesteryear, is releasing RuneScape Mobile and Old School RuneScape for mobile devices, complete with... | Read more »
Crash of Cars wants you to capture the c...
Crash of Cars is going full on medieval in its latest update, introducing castles and all manner of new cars and skins fresh from the Dark Ages. The update introduces a new castle-themed map (complete with catapults) and a gladiator-style battle... | Read more »

Price Scanner via MacPrices.net

Sale! New 2017 13-inch 2.3GHz MacBook Pros fo...
Amazon has new 2017 13″ 2.3GHz/128GB MacBook Pros on sale today for $150 off MSRP including free shipping. Their prices are the lowest available for these models from any reseller: – 13″ 2.3GHz/128GB... Read more
13″ 2.3GHz/128GB Space Gray MacBook Pro on sa...
MacMall has the 13″ 2.3GHz/128GB Space Gray MacBook Pro (MPXQ2LL/A) on sale for $1219 including free shipping. Their price is $80 off MSRP. Read more
Clearance 2016 12-inch Retina MacBooks, Apple...
Apple recently dropped prices on Certified Refurbished 2016 12″ Retina MacBooks, with models now available starting at $1019. Apple will include a standard one-year warranty with each MacBook, and... Read more
Save or Share
FotoJet Designer, is a simple but powerful new graphic design apps available on both Mac and Windows. With FotoJet Designer’s 900+ templates, thousands of resources, and powerful editing tools you... Read more
Logo Maker Shop iOS App Lets Businesses Get C...
A newly released app is designed to help business owners to get creative with their branding by designing their own logos. With more than 1,000 editable templates, Logo Maker Shop 1.0 provides the... Read more
Sale! New 15-inch MacBook Pros for up to $150...
Amazon has the new 2017 15″ MacBook Pros on sale for up to $150 off MSRP including free shipping: – 15″ 2.8GHz MacBook Pro Space Gray: $2249 $150 off MSRP – 15″ 2.89Hz MacBook Pro Space Gray: $2779 $... Read more
DEVONthink To Go 2.1.7 For iOS Brings Usabili...
DEVONtechnologies has updated DEVONthink To Go, the iOS companion to DEVONthink for Mac, with enhancements and bug fixes. Version 2.1.7 adds an option to clear the Global Inbox and makes the grid... Read more
15-inch 2.2GHz Retina MacBook Pro, Apple refu...
Apple has Certified Refurbished 2015 15″ 2.2GHz Retina MacBook Pros available for $1699. That’s $300 off MSRP, and it’s the lowest price available for a 15″ MacBook Pro. An Apple one-year warranty is... Read more
13-inch 2.3GHz Silver MacBook Pro on sale for...
B&H Photo has the new 2017 13″ 2.3GHz/256GB Silver MacBook Pro (MPXU2LL/A) on sale for $1399 including free shipping plus NY & NJ sales tax only. Their price is $100 off MSRP. Read more
Apple Tackles Distracted Driving With iOS 11...
One of the most important new features coming in iOS 11 is Do Not Disturb while driving, intended to help drivers stay more focused on the road. With Do Not Disturb while driving, your iPhone can... Read more

Jobs Board

Frameworks Engineering Manager, *Apple* Wat...
Frameworks Engineering Manager, Apple Watch Job Number: 41632321 Santa Clara Valley, California, United States Posted: Jun. 15, 2017 Weekly Hours: 40.00 Job Summary Read more
Product Manager - *Apple* Pay on the *Appl...
Job Summary Apple is looking for a talented product manager to drive the expansion of Apple Pay on the Apple Online Store. This position includes a unique Read more
*Apple* Retail - Multiple Positions - Apple...
SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions - Apple...
SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Senior Payments Architect - *Apple* Pay - A...
Changing the world is all in a day's work at Apple . If you love innovation, here's your chance to make a career of it. You'll work hard. But the job comes with more Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.