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 18

FILES AND NAVIGATION SERVICES

Introduction

This chapter addresses:

  • Creating, opening, reading from, writing to, and closing files.

  • Navigation Services, an application programming interface that allows your application to provide a user interface for navigating, opening, and saving Mac OS file objects.

Files

Types of Files

A file is a named, ordered sequence of bytes stored on a volume. The files associated with an application are typically:

  • The application file itself, which comprises the application's executable code and any application-specific resources and data.

  • Document files created by the user using the application, which the user can edit.

  • A preferences file created by the application to store user-specified preference settings for the application.

The Operating System also uses files for certain purposes. For example, as stated at Chapter 9, the File Manager uses a special file called the volume's catalog file to maintain the hierarchical organisation of files and folders in a volume.

Characteristics of Files

File Forks

Macintosh files comprise two forks, called the data fork and the resource fork. The resource fork contains a resource map and resources. Unlike the bytes stored in the resource fork, the bytes in the data fork do not have to have any particular internal structure. Your application must therefore be able to interpret the bytes in the data fork in an appropriate manner.

All Macintosh files contain a data fork and a resource fork; however, one or both of these forks may, in fact, be empty. Fig 1 shows the typical contents of the data and resource forks of an application file and a document file.

If your data can be structured as a resource, you might elect to store that data in the resource fork, in which case you use Resource Manager functions to both store and retrieve it. Retrieving data from a resource fork is a comparatively simple matter because all you have to do is pass the resource type and ID to the relevant Resource Manager function.

If it is neither possible nor advisable to store the data in the resource fork, you must store it in the data fork. This is normally the favoured option for storing, for example, a document's text. In this case, you use File Manager functions to store and retrieve the data. With File Manager functions, unlike Resource Manager functions, you can access any byte, or group of bytes, individually.

Generally speaking, unless the data created by the user will occupy only a small number of resources, you should store it in the data fork. Always bear in mind that the Resource Manager was not designed as a general purpose data storage and retrieval system.

File Size

Volumes

A volume, which can be an entire disk or only part thereof, is that part of a storage device formatted to contain files. Ordinarily, file size is limited only by the size of the volume that contains it.

Logical Blocks and Allocation Blocks

Volumes are formatted into logical blocks. Each logical block can contain up to 512 bytes, the actual size being of interest only to the disk device driver. When the File Manager allocates space for a file, it allocates it in units called allocation blocks, which are groups of consecutive logical blocks. A non-empty file fork always occupies at least one allocation block.

The size of an allocation block is the chief distinguishing feature between the volume format known as the Hierarchical File System (HFS) and the newer, and optional, Hierarchical File System Plus (HFS Plus or HFS+) introduced with Mac OS 8.1. The differences are as follows:

  • HFS (Mac OS Standard Format). For HFS-formatted volumes, the File Manager can access a maximum of 65,535 allocation blocks on any volume. Thus the larger the volume, the larger is the allocation block. For example, on a 500 MB volume, the allocation block size is 8KB under HFS.

  • HFS Plus (Mac OS Extended Format). For HFS Plus-formatted volumes, the File Manager can access a maximum of 4.29 billion allocation blocks on any volume. This means that even huge volumes can be formatted with very small allocation blocks. The default volume format for Carbon is HFS Plus.

    Beginning with Mac OS 9, HFS Plus introduced support for long Unicode filenames, files larger than 2GB, and extended file attributes. The additional File Manager constants, data types, and functions introduced at that time are often referred to as the HFS Plus API.

On large volumes, the significant reduction in allocation block size under HFS Plus results in significant space savings. For example, on a 4 GB volume, a file containing only 4 KB of information requires 64 KB of space under HFS, whereas the same file requires only 4KB of space under HFS Plus.

Physical and Logical End-Of-File

There is a difference between the amount of space allocated to a file and the number of bytes of actual data in the file. This is reflected in the two numbers used to describe the size of a file:

  • Physical End-Of-File. The physical end-of-file is the number of bytes currently allocated to the file by the File Manager. Since the file's first byte is byte number 0, the physical end-of-file is 1 greater than the number of the last byte in its last allocation block. The physical end-of-file is thus always an exact multiple of allocation block size.

  • Logical End-Of-File. The logical end-of-file is one greater than the number of bytes that currently contain data.

Fig 2 illustrates logical end-of-file and physical end-of-file.

Your application can adjust the size of a file by moving the logical end-of-file. If, when you increase the size of a file, the logical end-of-file is moved past the physical end-of-file, one or more allocation blocks are automatically added to the file by the File Manager. By the same token, the File Manager automatically deletes the unneeded allocation block if you move the logical end-of-file more than one allocation block short of the current physical end-of-file.

Clumps and Combating File Fragmentation

The volume's clump size determines the number of allocation blocks added to the file when you move the logical end-of-file past the physical end-of-file. The File Manager enlarges files by adding clumps (which are groups of contiguous allocation blocks) as a way of reducing file fragmentation and improving input/output performance..

Your application can also takes steps to reduce file fragmentation. Suppose you are extending a file with multiple write operations. If you know before you begin how large the file is likely to become, you should first call SetEOF to set the file to that size.

File Access

The operations your application can perform on a file depend on whether it is open or closed. For example, reading and writing operations can only be performed on open files, and deleting operations can only be performed on closed files.

Access Path and File Reference Number

When a file is opened, the File Manager reads in file information and creates an access path to the file. The file information is stored in a file control block (FCB). The access path, which is assigned a unique file reference number, specifies the volume on which the file is located and the location of the file on that volume.

File Mark

The File Manager maintains a file mark (a current-position marker) for each access path. The file mark, which is moved each time a byte is read or written, is the number of the next byte to be read or written. By setting the file mark or specifying an offset, you can control the beginning point of a read or write operation.

Data Buffer

When it transfers data to or from your application, the File Manager uses a data buffer in RAM. You must therefore pass the address of this data buffer whenever you read or write a file's data.

Disk Cache

The File Manager uses an intermediate buffer, called the disk cache, when reading data from, or writing data to, the file system.

During a write operation, data is transferred from your application's data buffer to the disk cache. During a read operation, the File Manager looks for data in the disk cache and, if data is found in the cache, transfers that data to your application's data buffer. If the File Manager finds no data in the disk cache, it reads the requested number of bytes from the disk directly to your application's data buffer.

The Hierarchical File System

Directories and Directory ID

The method used to organise files on a Macintosh volume is called a hierarchical file system. In this system, files are grouped into directories (also called folders). These directories may, in turn, be grouped into other directories (see Fig 3). As shown at Fig 3, each directory has a number associated with it called the directory ID.

Root Directory

The Finder and the File Manager work together to maintain the organisation of files and folders on a volume, ensuring that the representation on the desktop corresponds directly to the hierarchical directory structure on the volume. In file system parlance, the volume is referred to as the root directory, and the folders are referred to as subdirectories (or simply as directories).

Mounted Volumes

When a volume is mounted, the File Manager places information about the volume in a volume control block (VCB) and assigns a volume reference number by which you can refer to the volume until it is unmounted. Mounted volumes appear on the desktop.

You can identify a volume by its volume reference number or by its volume name. To avoid confusion between volumes with the same name, you should ordinarily use the volume reference number to refer to a volume.

When a volume is unmounted, the volume control block is released and the volume is no longer known to the File Manager.

Parent Directory and Parent Directory ID

The directory in which a subdirectory is located is referred to as a parent directory. A parent directory is assigned a parent directory ID. A special parent directory ID is assigned by the File Manager to a volume's root directory. All this facilitates a consistent method of identifying files and directories using the volume reference number, the parent directory ID, and the file or directory name.

Generally speaking, your application does not need to keep track of the location of files in the file system hierarchy. The location of most of the files your application opens and saves is provided by either the Finder or Navigation Services.

Aliases

An alias is a special kind of file that represents another file, folder, or volume. The Finder and Navigation Services automatically resolve aliases.

Identifying Files and Directories - File System Specification Structure and File System Reference

Three pieces of information are all that is needed to identify a file or directory: a volume reference number; a parent directory ID; the name of the file or directory. Of relevance is this regard are two data types, namely, the file system specification structure and the opaque file system reference:

     struct FSSpec
     {
       short  vRefNum;  // Volume reference number.
       long   parID;    // Directory ID of parent directory.
       Str63  name;     // Filename or directory name.
     };
     typedef struct FSSpec FSSpec;
     typedef FSSpec *FSSpecPtr, **FSSpecHandle;
     
     struct FSRef
     {
       UInt8 hidden[80];
     };
     typedef struct FSRef FSRef;
     typedef FSRef *FSRefPtr;

The opaque data type FSRef, whose purpose is similar to that of the file system specification structure, was introduced with the HFS Plus API. . Note that there is no need to call the File Manager to dispose of an FSRef when it is no longer needed.

Creating, Opening, Reading From, Writing To, and Closing Files

Your application typically creates, opens, reads from, writes to, and closes files in response to the user choosing commands from the File menu. In addition, your application opens, reads from, writes to, and closes files in response to the required Apple events (see Chapter 10).

The following describes how to perform typical file operations within the context of a user choosing commands from an imaginary application's File menu. For the purposes of illustration, the assumption is made that the files involved store text documents and that, when retrieved from file, the documents are displayed in a window with scroll bars.

General File Menu and Required Apple Events Handling Strategy

A suggested general strategy for handling user choices of the New, Open..., Close, Save, Save As..., Revert, and Quit commands, and for responding to the required Apple events, is illustrated at Fig 4.

Preliminaries - Creating a Document Structure

The contents of document files are displayed in windows. Ordinarily, your application should define a document structure which contains information about the window and information about the file whose contents are displayed in the window. The following is an example document structure for an application that handles text files:

     typedef struct
     {
       ControlHandle  vScrollBarHdl;  // Handle to vertical scroll bar.
       ControlHandle  hScrollBarHdl;  // Handle to horizontal scroll bar.
       SInt16         fileRefNum;     // File reference number for window's file.
       FSSpec         fileFSSpec;     // File's file system specification structure.
       TEHandle       textEditHdl;    // Handle to TextEdit structure.
       Boolean        windowTouched;  // Has window's data changed?
     }  documentStructure;

     typedef documentStructure *documentStructurePtr;
     typedef documentStructure **documentStructureHdl;

Note the fileRefNum and fileFSSpec fields. Note also that the last field (windowTouched) is used to record whether the content of the document in memory differs from that in the associated file. Your application should set this field to false when it first reads in the file and immediately after each save, and to true when the content of the document in memory is changed by the user after the first read-in and after the subsequent saves. If the windowTouched field is set to true and the user attempts to close the document window, your application should present an alert asking the user whether the changed version of the document should be saved.

Document structures can be associated with the relevant window by storing a handle to the structure in the window object using the function SetWRefCon.

Creating a New Document Window

The user creates a new untitled document window using the New... command in the File menu. In addition, it is usual for an application to open a new untitled document window when it receives an Open Application Apple event from the Finder. (See doNewCommand at Fig 4.)

Although the function which responds to the user choosing the NewÉ command and Open Application Apple event opens a new window, it should not create a new file. The reason for this is that, in the event, the user may elect not to save the document. It is thus preferable to wait until the user decides to save the new document before creating a file. Accordingly, the fileRefNum field of the new window's document structure should be set to 0 to indicate that no file is currently associated with this window.

Opening a File and Reading in Data

Your application will need to open a file when the user chooses the Open... command from the File menu (see doOpenCommand at Fig 4) and when it receives Open Documents and (on Mac OS 8/9) Print Documents Apple events.

Opening the Navigation Services Open Dialog Box

Your application's initial response to the user choosing the Open... command from the File menu should be to elicit a file selection from the user by by creating and displaying a Navigation Services Opne dialog (see Fig 6).

Calls to the Navigation Services 3.0 functions NavCreateGetFileDialog and NavDialogRun create and display the Navigation Services Open dialog. When the user addresses the dialog, selects one or more files, and clicks the Open button, your application examines the selection field of a NavReplyRecord structure (see Navigation Services, below) and disposes of the dialog. The selection field is an Apple Event descriptor list (AEDescList). You can determine the number of files in the list by calling the Apple Event Manager function AECountItems. Each selected file object is described in an AEDesc structure. You can coerce this descriptor into a file system specification (FSSpec) structure to perform operations such as opening the file.

Creating a Window and Opening the File

The next steps are to call a function (doNewDocWindow at Fig 4) to create a window and associated document structure and then open the selected file's data fork (doOpenFile at Fig 4).

The file's data fork is opened using FSpOpenDF:

     OSErr  FSpOpenDF(spec,permission,refNum);

     FSSpec  *spec;       File system specification structure.
     SInt8   permission;  Access mode.
     short   *refNum;     Returned file reference number.

FSpOpenDF takes the FSSpec returned by Navigation Services as its first parameter. The permission field specifies the access mode for opening the file. The access mode may be specified using one of the following constants:

Constant

Value

Description

fsCurPerm 0

Whatever permission is allowed.

fsRdPerm 1

Read permission.

fsWrPerm 2

Write permission.

fsRdWrPerm 3

Exclusive read/write permission.

fsRdWrShPerm 4

Shared read/write permission.

FSpOpenDF returns, in its third parameter, a file reference number. This reference number should be saved to the window's document structure so that it can be readily retrieved for use as a parameter in calls to functions which read from and write to the file.

Reading File Data

When you have opened a file, you can read data from it. Ordinarily, you will want to read data from the file when the user first opens it. And your application will have to read data from the file when the user chooses the Revert command in the File menu to revert to the last saved version of the document (see doRevertCommand at Fig 4). Typically, a function for reading file data:

  • Retrieves the file reference number from the document structure.

  • Calls SetFPos to set the file mark to the beginning of the file:
    OSErr  SetFPos(refNum,posMode,posOff);
    
    short  refNum;   File reference number.
    short  posMode;  Positioning mode.
    long   posOff;   Positioning offset.
    

    The posMode parameter must contain one of the following constants:

    Constant

    Value

    Description

    fsAtMark 0

    Remain at current mark.

    fsFromStart 1

    Set mark relative to beginning of file.

    fsFromLEOF 2

    Set mark relative to logical end of file.

    fsFromMark 3

    Set mark relative to current mark.

    rdVerify 64

    Add to above for read-verify.

  • Determines the number of bytes in the file by calling GetEOF:

    OSErr  GetEOF(refNum,logEOF);
    
    short  refNum;   File reference number.
    long   *logEOF;  Receives length of file, in bytes.
    

  • Calls FSRead to read the specified number of bytes from the file into the specified buffer:

    OSErr  FSRead(refNum,count,buffPtr);
    
    short  refNum;    File reference number.
    long   *count;    On input: bytes to read.  On output: actual bytes read.
    void   *buffPtr;  Address of buffer into which bytes are to be read.
    

    Note that FSRead returns, in the count parameter, the actual number of bytes read.

Saving a File

The user can indicate that the current contents of a document should be saved:

  • By choosing Save or Save As... from the File menu.

  • By clicking the Save button in the Navigation Services Save Changes alert you present when the user attempts to close a "touched" window.

  • By clicking the Save button in the Navigation Services Save Changes alert you present when the user attempts to quit the application while a "touched" window remains open.

Handling the Save Command

To handle the Save command (see doSaveCommand at Fig 4), your application should:

  • Check the file reference number field of the window's document structure to determine if the window already has a file.

  • If the window already has a file, call the function for writing files to disk (see doWriteFile at Fig 4). If the window does not have a file, call the function for handling the Save As... command.

Handling the Save As... Command

To handle the Save As... command (see doSaveAsCommand at Fig 4), your application should proceed as follows:

  • Call the Navigation Services 3.0 functions NavCreatePutFileDialog and NavDialogRun to create and display the Navigation Services Save Location dialog (see Fig 10).

    When the user addresses the dialog and clicks the Save button, your application examines the selection field of a NavReplyRecord structure (see Navigation Services, below) and disposes of the dialog. The selection field is an Apple Event descriptor list (AEDescList). The file object is described in an AEDesc structure. If your application is running on Mac OS X, you will be able to coerce this data to type FSRef. If this coercion fails (meaning that your application is running on Mac OS 8/9) you will be able to coerce the data to type FSSpec. The FSRef or FSSpec will be required for the save operation.

  • Save Using FSRef. If the coercion to type FSRef succeeds:

    • Call AEGetDescData to extract the data from the dataHandle field of the AEDesc structure. This is the FSRef for the parent directory.

    • Call CFStringGetCharacters to extract into a buffer the contents of the string referenced in the saveFileName field of the NavReplyRecord structure.

    • If the replacing field of a NavReplyRecord structure contains true, call the HFS Plus API function FSMakeFSRefUnicode to create an FSRef for the file, passing in the FSRef for the parent directory and the extracted filename characters. Pass this FSRef in a call to FSDeleteObject to delete the file:

      OSErr  FSDeleteObject(ref);
      const FSRef *ref;  Pointer to FSRef specifying file or directory to delete.
      

    • Call FSCreateFileUnicode, passing in the FSRef for the parent directory and the extracted filename characters, to create a new file with a Unicode name:

      OSErr  FSCreateFileUnicode(parentRef,nameLength,name,whichInfo,catalogInfo,
                                 newRef,newSpec);
      const FSRef         *parentRef;    FSRef for directory where file to be created.
      UniCharCount        nameLength;    Length of file's name.
      const UniChar       *name;         Unicode name for file.
      FSCatalogInfoBitmap whichInfo;     Catalog information fields to be set, if any.
      const FSCatalogInfo *catalogInfo;  Values of file's catalog infoformation.
      FSRef               *newRef;       On return, FSRef for new file.
      FSSpec              *newSpec;      On return, FSSpec for new file.
      

    • Call FSpGetFInfo, passing in the FSSpec received in the last parameter of the call to FSCreateFileUnicode. Assign the file type and creator to the relevant fields of the obtained Finfo structure and call FSpSetFInfo to set the Finder information.

    • Assign the file system specification (FSSpec) structure to the file system specification structure field of the window's document structure.

    • Call FSpOpenDF to open the data fork.

    • Assign the file reference number returned by FSpOpenDF to the file reference number field of the window's document structure.

    • Call SetWTitle to set the window's title, using the string extracted from the name field of the file system specification (FSSpec) structure.

    • Call the function for writing files to disk (see doWriteFile at Fig 4).

  • Save Using FSSpec. If the coercion to type FSRef does not succeed:

    • Call the Navigation Services 3.0 function NavDialogGetSaveFileName to get the file name from the edit text field of the Save Location dialog, convert it to a Pascal string using CFStringGetPascalString, and assign that string to the name field of the file system specification (FSSpec) structure.

    • If the replacing field of the NavReplyRecord structure does not contain true, call FSpCreate to create a new file and set the file type and creator:

      OSErr  FSpCreate(spec,creator,fileType,sciptTag);
      FSSpec       *spec;     File system specification structure.
      OSType       creator;   File creator.
      OSType       fileType;  File type.
      ScriptCode  scriptTag;  Code of script system in which filename is displayed.
      

    • Assign the coerced file system specification (FSSpec) structure to the file system specification structure field of the window's document structure.

    • If the window already has a file (that is, if the file reference number field of the document structure does not contain 0), close that file with a call to FSClose:
      OSErr  FSClose(refNum);
      short  refNum;  File reference number.
      

    • Call FSpOpenDF to open the data fork.

    • Assign the file reference number returned by FSpOpenDF to the file reference number field of the window's document structure.

    • Call SetWTitle to set the window's title, using the string extracted from the name field of the sfFile field of the Standard File reply structure.

    • Call the function for writing files to disk (see doWriteFile at Fig 4).

Writing File Data

The function for writing data (see doWriteFile at Fig 4) should write to a temporary file, not to the document file itself. If you write directly to the document's file, you risk corrupting that file if the write operation does not complete successfully. The broad approach for saving data safely to disk is therefore to write the data to a temporary file and then, assuming the temporary file has been written successfully, swap the contents of the temporary file and the document's file.

The procedure for updating a file safely is as follows:

  • Get the file system specification from the document structure.

  • Create a temporary filename for the temporary file.

  • Call FindFolder to find the temporary folder on the file's volume, or create it if necessary:
    OSErr  FindFolder(vRefNum,folderType,createFolder,foundVRefNum,foundDirID);
    short    vRefNum;        Volume reference number.
    OSType   folderType;     Folder type for volume.
    Boolean  createFolder;   kCreateFolder or kDontCreateFolder.
    short    *foundVRefNum;  Volume reference number for folder found.
    long     *foundDirID;    Directory ID of folder found.
    

  • Call FSMakeFSSpec to make a file system specification structure for the temporary file:
    OSErr  FSMakeFSSpec(vRefNum,dirID,fileName,spec);
    short             vRefNum;   Volume reference number.
    long              dirID;     Parent directory ID.
    ConstStr255Param  fileName;  Full or partial pathname.
    FSSpec            spec;      Pointer to FSSpec structure.
    

  • Call FSpCreate to create the temporary file, and FSpOpenDF to open the temporary file's data fork.

  • Call the function for writing data to a file (see doWriteData at Fig 4). This function should:

    • Retrieve the address and length of the buffer (for example, from a TextEdit structure).

    • Call SetFPos to set the file mark to the beginning of the file.

    • Call FSWrite to write the buffer to the file:
      OSErr  FSWrite(refNum,count,buffPtr);
      short       refNum;    File reference number.
      long        *count;    On input: bytes to write.  On output: bytes written.
      const void  *buffPtr;  Address of buffer containing data to write.
      

    • Call SetEOF to resize the file to the number of bytes actually written:
      OSErr  SetEOF(refNum,logEOF);
      short  refNum;  File reference number.
      long   logEOF;  Logical end-of-file.
      

    • Call GetVRefNum to determine the volume containing the file:
      OSErr  GetVRefNum(refNum,vRefNum);
      short  refNum;    File reference number.
      short  *vRefNum;  Receives volume reference number.
      

    • Call FlushVol to flush the volume:
      OSErr  FlushVol(volName,vRefNum);
      ConstStr63Param volName;  Pointer to name of mounted volume
      short           vRefNum;  Volume reference number.
      

      Flushing the volume ensures that both the file's data and the file's catalog entry are updated.

      The catalog entry for a file contains fields that describe the physical data (such as the first allocation block and the physical and logical ends of both the resource and data forks) and fields that describe the file within the file system, such as file ID and parent directory ID.

    
    

  • Call FSClose to close the temporary file.

  • Call FSClose to close the existing file.

  • Call FSpExchangeFiles to swap the contents of the temporary file and the existing file:
    OSErr  FSpExchangeFiles(source,dest);
    const FSSpec  *source;  Source file.
    const FSSpec  *dest;    Destination file.
    

    FSpExchangeFiles does not actually move the data on the volume. It merely changes the information in the volume's catalog file and, if the files are open, their file control blocks (FCBs).

  • Call FSpDelete to delete the temporary file:
    OSErr  FSpDelete(spec);
    const FSSpec  *spec;  File system specification.
    

  • Call FSpOpenDF to re-open the data fork of the existing file.

As a final step for Mac OS 8/9, you should call a function which copies the missing application name string resource (see Chapter 9.) from the resource fork of the application file to the resource fork of the newly created file. This function (doCopyAppNameResource at Fig 4) should:

  • Call FSpCreateResFile to create the new file's resource fork:
    void  FSpCreateResFile(spec,creator,fileType,sciptTag);
    const FSSpec  *spec;      File system specification structure.
    OSType        creator;    File creator.
    OSType        fileType;   File type.
    ScriptCode    scriptTag;  Code of script system.
    

  • Call FSpOpenResFile to open the resource fork:
    short  FSpOpenResFile(spec,permission);
    const FSSpec  *spec;       File system specification structure.
    SignedByte    permission;  Permission code.
    

    The constants used to specify the access mode in the FSpOpenDF call (see above) are also used to specify the permission code in the FSpOpenResFile call.

  • Call a function (doCopyResource at Fig 4), which copies specified resources from one resource file to another, to copy the missing-application name 'STR ' resource (ID -16396) from your application's resource fork to the resource fork of the newly-created file.

  • Call FSClose to close the resource fork.

Reverting to a Saved File

To allow the user to revert to the last saved version of a document, your application can include a Revert command in the File menu. To handle this command (see doRevertCommand at Fig 4), you should call the Navigation Services 3.0 functions NavCreateAskDiscardChangesDialog and NavDialogRun to create and display a Navigation Services Discard Changes alert (see Fig 13). When the user addresses the dialog, and clicks on the OK button, you simply call your function for reading file data (doReadFile at Fig 4) to read the file back into the window.

Closing a File

Your application should ordinarily close a file when the user clicks in the close box of the associated window or chooses the Close command from the File menu. You may also need to close files when the user chooses Quit from the File menu or a Quit Application Apple event is received from the Finder.

When your application needs to close a file, it should first check whether the associated window has been "touched" (see doCloseCommand at Fig 4). If the window has been "touched", you should call the Navigation Services 3.0 functions NavCreateAskSaveChangesDialog and NavDialogRun to create and display a Navigation Services Save Changes alert (see Fig 12). When the user addresses the dialog:

  • If the Save button is clicked, call the function for saving files (doSaveCommand at Fig 4), call FSClose to close the file, call FlushVol to ensure that both the file's data and the file's catalog entry are updated, set the file reference number field in the document structure to 0, and release memory associated with the storage of the file's data. Then dispose of the document structure and, finally, the window.

  • If the Don't Save button is clicked, perform the same actions as are performed when the Save button is clicked except for the call to the function for saving files.

If the window has not been "touched", perform the same actions as are performed when the Save button is clicked in an Save Changes alert except for the call to the function for saving files.

File Synchronisation Functions

It is always possible that, while a document file is open, the user may drag its Finder icon or proxy icon to another folder (including the Trash) or change the name of the file via the Finder icon. The application itself has no way of knowing that this has happened and will assume, unless it is informed otherwise, that the document's file is still at its original location with its original name. For this reason, applications often include a frequently-called file synchronisation function which synchronises the application with the actual current location (and name) of its currently open document files.

In applications which use the Classic event model, file synchronisation functions should be called after every call to WaitNextEvent. In applications that use the Carbon event model, a timer should be installed to trigger repeated calls to the file synchronisation function. For each of the application's document windows, the synchronisation function should update the application's internal data structures to match that of the document file as it exists on disk. The function should also ensure that, where necessary, the name of the document window is changed to match the current name of the document file on disk and close the document window if the document file has been moved to the Trash folder.

Navigation Services

The user interface for opening and saving files, confirming saves and discarding changes, choosing a volume, folder, file, or file object, creating a new folder, file format translation, and easy navigation of the file system is provided by Navigation Services.

The following reflects Navigation Service 3.0, which was introduced with CarbonLib 1.1, and which established a new model for the creation, display, and handling of Navigation Services dialogs and alerts. Navigation Services 3.0 also introduced support for Unicode and, on Mac OS X, support for sheets and the ability to specify the modality of a dialog.

Navigation Services Dialogs and Alerts

The primary dialogs created by Navigation Services are as follows:

  • Open.

  • Save Location.

  • Choose a Volume.

  • Choose a Folder.

  • Choose a File.

  • Choose a File Object.

The primary alerts created by Navigation Services are as follows:

  • Save Changes.

  • Discard Changes.

The secondary dialogs and alerts created by Navigation Services are as follows:

  • New Folder dialog.

  • Replace Confirmation alert.

  • Mac OS 8/9 Stationery option dialog.

A further alert, which is applicable only on Mac OS X, and for which no Navigation Services creation function existed at the time of the first release of Mac OS X, is the Review Changes alert.

Modality

On Mac OS 8/9, all primary Navigation Services dialogs are movable modal provided an application-defined event handling (callback) function is provided.

On Mac OS X, your application should ensure that:

  • The Save Location dialog, Save Changes alert, and Discard Changes alert are window-modal (that is, sheets).

  • The other primary dialogs are application-modal.

Standard User Interface Elements in Primary Dialogs

The standard user interface elements in Navigation Services primary dialog boxes are shown at Fig 5.

Preview

On Mac OS 8/9, the user can toggle a preview area on an off using the Show/Hide Preview push button in the Open dialog. A preview of any file that contains a valid 'pnot' resource will be displayed in this area.

On Mac OS X, the preview appears in the column browser as shown at Fig 5. For files of type 'TEXT' a preview is automatically created.

Persistence

Persistence is the ability of Navigation Services to store information, and to store it on a per-application basis. For example, when a primary dialog is displayed, the browser defaults to the directory location that was in use when that particular dialog box was last closed by that particular application. In addition, if a file or folder was selected when the dialog box was last closed, that file or folder is automatically selected when the dialog is re-opened. For dialogs that are not sheets, the size, position, and, on Mac OS 8/9, sort key and sort order are also remembered for each application.

Creating and Displaying an Open Dialog

The Open dialog (see Fig 6) is created by a call to NavCreateGetFileDialog and displayed by a call to NavDialogRun. You pass a universal procedure pointer to an application-defined event handling function in the inEventProc parameter of NavCreateGetFileDialog.

The NavDialogCreationOptions Structure

You pass a pointer to a NavDialogCreationOptions structure, which specifies options controlling the appearance and behaviour of the dialog, in the inOptions parameter of NavCreateGetFileDialog. The NavDialogCreationOptions structure is as follows:

     struct NavDialogCreationOptions 
     {
       UInt16               version;
       NavDialogOptionFlags optionFlags;
       Point                location;
       CFStringRef          clientName;
       CFStringRef          windowTitle;
       CFStringRef          actionButtonLabel;
       CFStringRef          cancelButtonLabel;
       CFStringRef          saveFileName;
       CFStringRef          message;
       UInt32               preferenceKey;
       CFArrayRef           popupExtension;
       WindowModality       modality;
       WindowRef            parentWindow;
       char                 reserved[16];
     };
     typedef struct NavDialogCreationOptions NavDialogCreationOptions;

Field Descriptions

optionsFlags

One of the following constants of type NavDialogOptionFlags:

Constant

Description

kNavDefaultNavDlogOptions

Use default options. The defaults are as follows:

     kNavDontAddTranslateItems
     kNavAllowStationery
     kNavAllowPreviews
     kNavAllowMultipleFiles
kNavNoTypePopup

Don't show file type pop-up menu button.

kNavDontAutoTranslate

Don't auto-translate files. (Application will translate.)

kNavDontAddTranslateItems

Don't add translation options in Show pop-up menu.

kNavAllFilesInPopup

Add "All Documents" menu item in file type pop-up.

kNavAllowStationery

Allow stationery files.

kNavAllowPreviews

Allow preview to show.

kNavAllowMultipleFiles

Allow multiple items to be selected.

kNavAllowInvisibleFiles

Allow invisible items to be shown.

kNavDontResolveAliases

Don't resolve aliases.

kNavSelectDefaultLocation

Make the default location the browser selection.

kNavSelectAllReadableItem

Make dialog select All Readable Documents on open.

kNavSupportPackages

Recognise file system packages.

kNavAllowOpenPackages

Allow opening of packages.

kNavDontAddRecents

Don't add chosen objects to Recents list.

kNavDontUseCustomFrame

Don't draw the custom area bevel frame.

kNavDontConfirmReplacement

Don't show the "Replace File?" alert on save conflict.

location

Location of the upper-left of the dialog (global coordinates). The dialog will appear at the location at which it was last closed if the optionFlags field is assigned NULL or this field is assigned (-1,-1).

clientName

Name of your application. This will appear in the dialog's title bar.

windowTitle

Overrides the default window title.

actionButtonLabel

Title for the dialog's OK push button. If a title is not assigned, the push button will use the default title (Open or Save).

cancelButtonLabel

Title for the dialog's Cancel push button. If a title is not assigned, the push button will use the default title (Cancel).

savedFileName

Default file name for a saved file.

message

A string, which is displayed in the dialog, providing additional instructions to the user. (For an example, see Fig 13).

preferenceKey

A value that identifies the set of dialog box preferences that should be used. Assign 0 if you do not wish to provide a preference key.

popupExtension

A handle to one or more structures of type NavMenuItemSpec used to add extra menu items to an Open dialog box's Show pop-up menu or a Save dialog box's Format pop-up menu.

modality

The dialog's modality (relevant on Mac OS X only). Relevant Window Manager constants are:

kWindowModalityNone
kWindowModalitySystemModal
kWindowModalityAppModal
kWindowModalityWindowModal
parentWindow

The dialog's parent window. (Relevant on Mac OS X only when the dialog is modal-to-window.)

The function NavGetDefaultDialogCreationOptions may be called to initialise a structure of type NavDialogCreationOptions with the default dialog box options, which are as follows:

  • Show and Format pop-up menu buttons are displayed in the Open and Save Location dialogs (Mac OS 8/9).

  • Files are auto-translated. (This implies that the application will not translate.)

  • Translation options are not included in the Show pop-up menu in the Open dialog.

  • The All Documents item is not included in the Show pop-up menu in the Open dialog.

  • The Stationery Option... item is included in the Format pop-up menu in the Save Location dialog.

  • Previews of selected files, when available, are displayed in the Open dialog.

  • Selection of multiple files in the browser list/column browser in the Open dialog is allowed.

  • Invisible files are nor displayed.

  • Aliases are not resolved.

  • The default location in the browser list/column browser is not selected.

  • The All Readable Documents is not made the default selection in the Show pop-up menu in the Open dialog.

  • File system packages are not displayed.

  • File system packages cannot be opened and navigated.

  • Chosen file objects are added to the Recents list.

  • A border is drawn around the custom area.

  • The default titles for the OK and Cancel buttons are used.

  • No message is displayed in the dialog.

The Show Pop-up Menu

The types of files to be displayed in the browser list may be chosen from a list of available file types in the Show pop-up menu in the Open dialog (see Fig 7). This list is built from information supplied by your application in a structure of type NavTypeList (see below), a handle to which you pass in the inTypeList parameter of NavCreateGetFileDialog.

The Show pop-up menu button will not appear in the Open dialog if you pass NULL in the inTypeList parameter of the NavCreateGetFileDialog function or if you set the kNavNoTypePopup bit in the optionsFlags field of the NavDialogCreationOptions structure passed in the call to NavCreateGetFileDialog. If a handle to a NavTypeList structure is passed in the inTypeList parameter and the kNavNoTypePopup bit is set:

  • All items in the browser will be deactivated except for the file types specified in the NavTypeList structure whether they were created by the application or not.

  • The Show pop-up menu button will not appear.

Native File Types Section

The first item in the native file types section of the Mac OS 8/9 Show pop-up menu defaults to All Known Documents if you do not assign the name of your application to the clientName field of the NavDialogCreationOptions structure passed in the dialogOptions parameter of the NavCreateGetFileDialog function.

The remaining items in the native file types section will default to <Application Name> Document unless you provide kind strings to describe the file types included in your NavTypeList structure (see below). You can do this by including a kind resource (a resource of type 'kind') in your application's resource fork. Fig 8 shows the structure of a compiled 'kind' resource and such a resource being created using Resorcerer

The kind strings from your application's 'kind' resource also appear in the Kind column in Finder window list views.

For Mac OS X, the 'kind' resource is ignored if you provide necessary information in your application's 'plst' resource. The relevant keys are CFBundleDevelopmentRegion, CFBundleSignature, and CFBundleDocumentTypes. 'apnm' as a CFBundleTypeOSTypes has same effect as in 'kind' resource.

The NavTypeList Structure

The NavTypeList structure, which defines the list of file types that your application is capable of opening, is as follows:

The NavTypeList Structure

The NavTypeList structure is as follows:

     struct NavTypeList 
     {
       OSType  componentSignature;  // Your application signature.
       short   reserved;
       short   osTypeCount;         // How many file types will be defined.
       OSType  osType[1];           // A list of file types your application can open.
     };
     typedef struct NavTypeList NavTypeList;
     typedef NavTypeList *NavTypeListPtr;
     typedef NavTypeListPtr *NavTypeListHandle;

You can create your file type list dynamically or you can use an 'open' resource. Fig 9 shows the structure of a compiled 'open' resource and such a resource being created using Resorcerer.

Creating and Displaying a Save Location Dialog

The Save Location dialog (see Fig 10) is created by a call to NavCreatePutFileDialog and displayed by a call to NavDialogRun. You pass a universal procedure pointer to an application-defined event handling function in the inEventProc parameter of NavCreatePutFileDialog.

As with NavCreateGetFileDialog, you pass a pointer to a NavDialogCreationOptions structure in the inOptions parameter of NavCreatePutFileDialog. Other parameters allow you to specify file type and file creator.

Creating and Displaying a Choose a Folder Dialog

The Choose a Folder dialog (see Fig 11) is created by a call to NavCreateChooseFolderDialog and displayed by a call to NavDialogRun. You pass a universal procedure pointer to an application-defined event handling function in the inEventProc parameter of NavCreateChooseFolderDialog and a pointer to a NavDialogCreationOptions structure in the inOptions parameter.

The other dialogs in the Choose family are created and displayed in a similar manner:

  • The Choose a Volume dialog is created by a call to NavCreateChooseVolumeDialog.

  • The Choose a File dialog is created by a call to NavCreateChooseFileDialog, and may be used when you want the user to select a file for a purpose other than opening. The file could be, for example, a preferences file or a dictionary file.

  • The Choose a File Object dialog is created by a call to NavCreateChooseObjectDialog, and may be used when you need the user to select an object that might be one of several different types.

Creating and Displaying Primary Alerts

Save Changes Alert

The Save Changes alert (see Fig 12) is created by a call to NavCreateAskSaveChangesDialog and displayed by a call to NavDialogRun. You pass a universal procedure pointer to an application-defined event handling function in the inEventProc parameter of NavCreateAskSaveChangesDialog and a pointer to a NavDialogCreationOptions structure in the inOptions parameter.

One of the following constants is passed in the inAction parameter of the NavCreateAskSaveChangesDialog function:

     kNavSaveChangesClosingDocument     = 1
     kNavSaveChangesQuittingApplication = 2
     kNavSaveChangesOther               = 0

Discard Changes Alert

To support the Revert command in your application's File menu, Navigation Services provides the Discard Changes alert. The Discard Changes alert (see Fig 13) is created by a call to NavCreateAskDiscardChangesDialog and displayed by a call to NavDialogRun. You pass a universal procedure pointer to an application-defined event handling function in the inEventProc parameter of NavCreateAskDiscardChangesDialog and a pointer to a NavDialogCreationOptions structure in the inOptions parameter.

Review Changes Alert - Mac OS X

On Mac OS X, when the user attempts to quit your application when there is more than one document with unsaved changes open, your application should present a Review Changes alert (see Fig 14). No Navigation Services creation function existed at the time of writing; accordingly, at the time of writing, it was necessary to create, display, and handle this alert using StandardAlert or CreateStandardAlert.

A click on the Discard Changes button should cause all windows to close (without saving changes) and the application to close down. A click on the Cancel button should cancel the Quit command, keeping the application running. A click on the Review Changes... button should cause each window with unsaved changes to be sequentially presented to the user with a Save Changes alert presented.

Event Handling in the Primary Dialogs

Event-Handling Function

As previously stated, you pass a universal procedure pointer to an application-defined event handling (callback) function in the inEventProc parameter of those functions which create the Navigation Services primary dialogs. For an event handling function named myNavEventFunction, you would declare the function as follows:

     void  myNavEventCallback(NavEventCallbackMessage callBackSelector,
                              NavCBRecPtr callBackParms,NavCallBackUserData callBackUD)

callBackSelector

The type of event, as represented by an event message constant. Typical event message constants and their meanings are as follows:

Constant

Value

Description

kNavCBUserAction 12

The user has taken an action such as clicking on an Open or Save button.

kNavCBEvent 0

An event has occurred. Receipt of this event type allows your handler to update other windows, track controls, etc.

kNavCBTerminate 3

The dialog is about to be closed.

callBackParms

A pointer to a NavCBRec structure, which contains data used by your application to process the event:

struct NavCBRec 
{
  UInt16        version;
  NavDialogRef  context;
  WindowRef     window;
  Rect          customRect;
  Rect          previewRect;
  NavEventData  eventData;
  NavUserAction userAction;
  char          reserved[218];
};
typedef struct NavCBRec NavCBRec;
typedef NavCBRec *NavCBRecPtr;
callBackUD

A pointer to a value passed in the inClientData parameter of the dialog creation functions.

kNavCBUserAction Message Received

When the kNavCBUserAction message is received, your application typically calls NavDialogGetReply to obtain the results of the dialog session, which are returned in a NavReplyRecord structure.

The NavReplyRecord Structure

     struct NavReplyRecord 
     {
       UInt16                         version;
       Boolean                        validRecord;
       Boolean                        replacing;
       Boolean                        isStationery;
       Boolean                        translationNeeded;
       AEDescList                     selection;
       ScriptCode                     keyScript;
       FileTranslationSpecArrayHandle fileTranslation;
       UInt32                         reserved1;
       CFStringRef                    saveFileName;
       char                           reserved[227];
     };
     typedef struct NavReplyRecord  NavReplyRecord;

Field Descriptions

validRecord

true if the user closed a dialog by clicking the Open button in an Open dialog, the Save button in a Save Location dialog, or the Choose button in a Choose dialog, or by pressing the Return or Enter key. If this field is false, the remaining fields do not contain valid data.

replacing

true if the user chooses to save a file by replacing an existing file.

isStationery

true if the file about to be saved should be saved as a stationery document.

translationNeeded

true if translation was or will be needed for selected files in Open and Save Location dialogs.

selection

An Apple event descriptor list (AEDescList) created from FSSpec or FSRef references to selected items. You can determine the number of items in the list by calling AECountItems. Each selected item is described in an AEDesc structure by the descriptor type typeFSS or typeFSRef. This descriptor can be coerced into an FSSpec or FSRef preparatory to, for example, opening the file.

keyScript

Keyboard script system used for the filename.

fileTranslation

Handle to a FileTranslationSpec structure, which contains a corresponding translation array for each file reference returned in the selection field.

saveFileName

The save file name in CFString form.

This field was introduced with Navigation Services 3.0 because there is no way to fit a 255-character Unicode name into the name field of an FSSpec or into an FSRef. (See selection field.)

Note 1: On Mac OS 9, you will never get a file name that won't fit into the name field of an FSSpec structure.

Note 2: On Mac OS X, you cannot reliably convert the name in the saveFileName field to a 31-byte Pascal string.

When your application has finished using this structure, it should dispose of it by calling the function NavDisposeReply.

Responding to User Actions

If the validRecord field of the NavReplyRecord structure contains true, your application typically calls NavDialogGetUserAction to determine the user action, as represented by user action constants. Typical user action constants are as follows:

Constant

Value

Description

kUserActionCancel 1

The user clicked the Cancel button.

kUserActionOpen 2

The user clicked the Open button in an Open dialog.

kUserActionSaveAs 3

The user clicked the Save button in a Save Location dialog.

kUserActionChoose 4

The user clicked the Choose button in a Choose dialog

As an alternative to calling NavDialogGetUserAction, you can extract the user action from the userAction field of the NavCBRec structure.

After determining the user action, your event handling function should take the appropriate action. For example, if the Open button was clicked, your event handling function should proceed to open the file, or files, selected by the user in the Open dialog.

Note that you should always call the function NavCompleteSave to complete any save operation. Amongst other things, NavCompleteSave performs any needed translation.

kNavCBTerminate Message Received

When the kNavCBTerminate message is received, your event handler should call NavDialogDispose to dispose of the dialog reference.

Event Handling in Primary Alerts

Your event handling function for the primary alerts should be declared in the same way as that for the event handling function for the primary dialogs.

When the kNavCBUserAction message is received, your application should call NavDialogGetUserAction to determine the user action, and then take the appropriate action. The user action constants relevant to the primary alerts are as follows:

Constant

Value

Description

kUserActionCancel 1

The user clicked the Cancel button.

kUserActionSaveChanges 6

he user clicked the Save button in a Save Changes alert.

kUserActionDontSaveChanges 7

The user clicked the Don't Save button in a Save Changes alert.

kUserActionDiscardChanges 8

The user clicked the OK button in a Discard Changes alert.

When the appropriate action has been taken, your event handler should call NavDialogDispose to dispose of the dialog reference.

Other Application-Defined (Callback) Functions

Application-Defined Object Filtering

If your application needs simple, straightforward object filtering, and as previously described, you simply pass a pointer to a structure of type NavTypeList to the relevant Navigation Services function (NavCreateGetFileDialog or NavCreateChooseFileDialog). If you desire more specific filtering, you can provide an application-defined filter function. Filter functions give you more control over what can and cannot be displayed. You can pass a universal procedure pointer to your filter function in calls to the functions NavCreateGetFileDialog, NavCreateChooseFileDialog, NavCreateChooseFolderDialog, NavCreateChooseVolumeDialog, and NavCreateChooseObjectDialog.

You can use both a NavTypeList structure and a filter function for the Open and Choose a File dialogs if you wish, but be aware that your filter function is directly affected by the NavTypeList structure. For example, if the NavTypeList structure contains only 'TEXT' and 'PICT' types, only 'TEXT' and 'PICT' files will be passed into your filter function.

Your filter function should return true if an object is to be displayed. The following is an example of a filter function that allows only text files to be displayed:

     Boolean  myNavFilterFunction(AEDesc *theItem, void *info,void *callBackUD,
                                  NavFilterModes filterMode)
     {
       OSErr                theErr = noErr;
       Boolean              display = true;
       NavFileOrFolderInfo  *theInfo;

       theInfo = (NavFileOrFolderInfo *) info;
       if(theItem->descriptorType == typeFSS)
         if(!theInfo->isFolder)
           if(theInfo->fileAndFolder.fileInfo.finderInfo.fdType != 'TEXT')
             display = false;

       return display;
     }

Application-Defined (Callback) Previews

To override how previews are drawn and handled, you can create a preview function and pass a universal procedure pointer to it in the inpreviewProc parameter of the Navigation Services functions NavCreateGetFileDialog, NavCreateChooseFileDialog and NavCreateChooseObjectDialog:

Boolean  myPreviewProc(NavCBRecPtr callBackParms,void *callBackUD);
callBackParms

A pointer to a NavCBRec structure that contains event data needed for your function to draw the preview.

callBackUD

A value set by your application.

Return: true if your preview function successfully draws the file preview. If your preview function returns false, Navigation Services will display the preview if the file contains a valid 'pnot' resource.

Main File Manager Constants, Data Types and Functions

Constants

Read/Write Permission

fsCurPerm     = 0
fsRdPerm      = 1
fsWrPerm      = 2
fsRdWrPerm    = 3
fsRdWrShPerm  = 4

File Mark Positioning Modes

fsAtMark     = 0
fsFromStart  = 1
fsFromLEOF   = 2
fsFromMark   = 3
rdVerify     = 64

Data Types

File System Specification Structure

struct FSSpec
{
  short  vRefNum;  // Volume reference number.
  long   parID;    // Directory ID of parent directory.
  Str63  name;     // Filename or directory name.
};
typedef struct FSSpec FSSpec;
typedef FSSpec *FSSpecPtr, **FSSpecHandle;

File System Reference

struct FSRef
{
  UInt8 hidden[80];
}

File Information Structure

struct FInfo
{
  OSType          fdType;      // File type.
  OSType          fdCreator;   // File's creator.
  unsigned short  fdFlags;     // Finder flags (fHasBundle, fInvisible, etc).
  Point           fdLocation;  // Position of top-left corner of file's icon.
  short           fdFldr;      // Folder containing file.
};
typedef struct FInfo FInfo;

Functions

Reading, Writing and Closing Files

OSErr  FSClose(short refNum); 
OSErr  FSRead(short refNum,long *count,void *buffPtr); 
OSErr  FSWrite(short refNum,long *count,const void *buffPtr);

Manipulating the File Mark

OSErr  GetFPos(short refNum,long *filePos); 
OSErr  SetFPos(short refNum,short posMode,long posOff);

Manipulating the End-Of-File

OSErr  GetEOF(short refNum,long *logEOF); 
OSErr  SetEOF(short refNum,long logEOF);

Opening and CreatingFiles

OSErr  FSpOpenDF(const FSSpec *spec,SInt8 permission,short *refNum);
OSErr  FSpOpenRF(const FSSpec *spec,SInt8 permission,short *refNum);
OSErr  FSpCreate(const FSSpec *spec,OSType creator,OSType fileType,ScriptCode scriptTag);
OSErr  FSCreateFileUnicode(const FSRef *parentRef,UniCharCount nameLength,const UniChar *name,
       FSCatalogInfoBitmap whichInfo,const FSCatalogInfo *catalogInfo,FSRef *newRef,
       FSSpec *newSpec);

Deleting Files and Directories

OSErr  FSpDelete(const FSSpec *spec);
OSErr  FSDeleteObject(const FSRef *ref);

Exchanging Data in Two Files

OSErr  FSpExchangeFiles(const FSSpec *source,const FSSpec *dest);
OSErr  FSExchangeObjects(const FSRef *ref,const FSRef *destRef);

Creating File System Specifications and File System References

OSErr  FSMakeFSSpec(short vRefNum,long dirID,ConstStr255Param fileName,FSSpec *spec);
OSErr  FSpMakeFSRef(const FSSpec *source,FSRef *newRef);
OSErr  FSMakeFSRefUnicode(const FSRef *parentRef,UniCharCount nameLength,const UniChar *name,
       TextEncoding textEncodingHint,FSRef *newRef)

Obtaining Volume Information

OSErr  GetVInfo(short drvNum,StringPtr volName,short *vRefNum,long *freeBytes); 
OSErr  GetVRefNum(short fileRefNum,short *vRefNum);

Getting and Setting Finder Information

OSErr  FSpGetFInfo(FSSpec *spec,FInfo *fndrInfo);
OSErr  FSpSetFInfo(const FSSpec *spec,const FInfo *fndrInfo);

Relevant Resource Manager Functions

Creating and Opening Resource Files

void   FSpCreateResFile(const FSSpec *spec,OSType creator,OSType fileType,
       ScriptCode scriptTag);
short  FSpOpenResFile(const FSSpec *spec,SignedByte permission);

Relevant Finder Interface Functions

Find a Specified Folder

OSErr  FindFolder(short vRefNum,OSType folderType,Boolean createFolder,
       short *foundVRefNum,long *foundDirID)

Main Navigation Services Constants, Data Types, and Functions

Constants

Navigation Services Dialog Option Flags

kNavDefaultNavDlogOptions  = 0x000000E4
kNavNoTypePopup            = 0x00000001
kNavDontAutoTranslate      = 0x00000002
kNavDontAddTranslateItems  = 0x00000004
kNavAllFilesInPopup        = 0x00000010
kNavAllowStationery        = 0x00000020
kNavAllowPreviews          = 0x00000040
kNavAllowMultipleFiles     = 0x00000080
kNavAllowInvisibleFiles    = 0x00000100
kNavDontResolveAliases     = 0x00000200
kNavSelectDefaultLocation  = 0x00000400
kNavSelectAllReadableItem  = 0x00000800
kNavSupportPackages        = 0x00001000
kNavAllowOpenPackages      = 0x00002000
kNavDontAddRecents         = 0x00004000
kNavDontUseCustomFrame     = 0x00008000
kNavDontConfirmReplacement = 0x00010000

Event Messages

kNavCBEvent           = 0
kNavCBCustomize       = 1
kNavCBStart           = 2
kNavCBTerminate       = 3
kNavCBAdjustRect      = 4
kNavCBNewLocation     = 5
kNavCBShowDesktop     = 6
kNavCBSelectEntry     = 7
kNavCBPopupMenuSelect = 8
kNavCBAccept          = 9
kNavCBCancel          = 10
kNavCBAdjustPreview   = 11
kNavCBUserAction      = 12
kNavCBOpenSelection   = (long) 0x80000000

User Action

kNavUserActionNone            = 0
kNavUserActionCancel          = 1
kNavUserActionOpen            = 2
kNavUserActionSaveAs          = 3
kNavUserActionChoose          = 4
kNavUserActionNewFolder       = 5
kNavUserActionSaveChanges     = 6
kNavUserActionDontSaveChanges = 7
kNavUserActionDiscardChanges  = 8

Save Changes Action

kNavSaveChangesClosingDocument     = 1
kNavSaveChangesQuittingApplication = 2

Data Types

typedef struct __NavDialog *NavDialogRef;
typedef UInt32              NavDialogOptionFlags;
typedef SInt32              NavEventCallbackMessage;
typedef void               *NavCallBackUserData;
typedef UInt32              NavUserAction;
typedef UInt32              NavAskSaveChangesAction;

NavDialogCreationOptions

struct NavDialogCreationOptions 
{
  UInt16               version;
  NavDialogOptionFlags optionFlags;
  Point                location;
  CFStringRef          clientName;
  CFStringRef          windowTitle;
  CFStringRef          actionButtonLabel;
  CFStringRef          cancelButtonLabel;
  CFStringRef          saveFileName;
  CFStringRef          message;
  UInt32               preferenceKey;
  CFArrayRef           popupExtension;
  WindowModality       modality;
  WindowRef            parentWindow;
  char                 reserved[16];
};
typedef struct NavDialogCreationOptions NavDialogCreationOptions;

NavTypeList

struct NavTypeList
{
  OSType componentSignature;
  short  reserved;
  short  osTypeCount;
  OSType osType[1];
};
typedef struct NavTypeList NavTypeList;
typedef NavTypeList *NavTypeListPtr;
typedef NavTypeListPtr *NavTypeListHandle;

NavCBRec

struct NavCBRec 
{
  UInt16        version;
  NavDialogRef  context;
  WindowRef     window;
  Rect          customRect;
  Rect          previewRect;
  NavEventData  eventData;
  NavUserAction userAction;
  char          reserved[218];
};
typedef struct NavCBRec NavCBRec;
typedef NavCBRec *NavCBRecPtr;

NavReplyRecord

struct NavReplyRecord 
{
  UInt16                         version;
  Boolean                        validRecord;
  Boolean                        replacing;
  Boolean                        isStationery;
  Boolean                        translationNeeded;
  AEDescList                     selection;
  ScriptCode                     keyScript;
  FileTranslationSpecArrayHandle fileTranslation;
  UInt32                         reserved1;
  CFStringRef                    saveFileName;
  char                           reserved[227];
};
typedef struct NavReplyRecord  NavReplyRecord;

Functions

Initialising the NavDialogCreationOptions Structure

OSStatus      NavGetDefaultDialogCreationOptions(NavDialogCreationOptions *outOptions);

Creating and Disposing Of Navigation Services Dialogs

OSStatus      NavCreateGetFileDialog(const NavDialogCreationOptions *inOptions,
              NavTypeListHandle inTypeList,NavEventUPP inEventProc,NavPreviewUPP inPreviewProc,
              NavObjectFilterUPP inFilterProc,void *inClientData,NavDialogRef *outDialog);
OSStatus      NavCreatePutFileDialog(const NavDialogCreationOptions *inOptions,
              OSType inFileType,OSType inFileCreator,NavEventUPP inEventProc,
              void *inClientData,NavDialogRef *outDialog);
OSStatus      NavCreateAskSaveChangesDialog(const NavDialogCreationOptions *inOptions,
              NavAskSaveChangesAction inAction,NavEventUPP inEventProc,void *inClientData,
              NavDialogRef *outDialog);
OSStatus      NavCreateAskDiscardChangesDialog(const NavDialogCreationOptions *inOptions,
              NavEventUPP inEventProc,void *inClientData,NavDialogRef *outDialog);
OSStatus      NavCreateChooseFileDialog(const NavDialogCreationOptions *inOptions,
              NavTypeListHandle inTypeList,NavEventUPP inEventProc,NavPreviewUPP inPreviewProc,
              NavObjectFilterUPP inFilterProc,void *inClientData,NavDialogRef *outDialog);
OSStatus      NavCreateChooseVolumeDialog(const NavDialogCreationOptions *inOptions,
              NavEventUPP inEventProc,NavObjectFilterUPP inFilterProc,void *inClientData,
              NavDialogRef *outDialog);
OSStatus      NavCreateChooseObjectDialog(const NavDialogCreationOptions *inOptions,
              NavEventUPP inEventProc,NavPreviewUPP inPreviewProc,
              NavObjectFilterUPP inFilterProc,void *inClientData,NavDialogRef *outDialog);
void          NavDialogDispose(NavDialogRef inDialog);

Displaying and Running a Navigation Services Dialog

OSStatus      NavDialogRun(NavDialogRef inDialog);

Filling In and Disposing Of NavReplyRecord Structures

OSStatus      NavDialogGetReply(NavDialogRef inDialog,NavReplyRecord *outReply);
OSErr         NavDisposeReply(NavReplyRecord *reply);

Getting the User Action

NavUserAction NavDialogGetUserAction(NavDialogRef inDialog);

Getting and Setting the Save File Name

CFStringRef   NavDialogGetSaveFileName(NavDialogRef inPutFileDialog);
OSStatus      NavDialogSetSaveFileName(NavDialogRef inPutFileDialog,CFStringRef inFileName);
Getting the Window In Which a Navigation Services Dialog Appears
WindowRef     NavDialogGetWindow(NavDialogRef inDialog);

Completing a Save Operation

OSErr         NavCompleteSave(NavReplyRecord *reply,NavTranslationOptions howToTranslate);

Creating New Folders

OSStatus      NavCreateNewFolderDialog(const NavDialogCreationOptions *inOptions,
              NavEventUPP inEventProc,void *inClientData,NavDialogRef *outDialog);

Creating Previews

OSErr         NavCreatePreview(AEDesc *theObject,OSType previewDataType,
              const void *previewData,Size  previewDataSize);

Creating and Disposing of Universal Procedure Pointers

NavEventUPP        NewNavEventUPP(NavEventProcPtr userRoutine);
NavPreviewUPP      NewNavPreviewUPP(NavPreviewProcPtr userRoutine);
NavObjectFilterUPP NewNavObjectFilterUPP(NavObjectFilterProcPtr userRoutine);
void               DisposeNavEventUPP(NavEventUPP userUPP);
void               DisposeNavPreviewUPP(NavPreviewUPP userUPP);
void               DisposeNavObjectFilterUPP(NavObjectFilterUPP userUPP);

Application-Defined (Callback) Functions - Event Handling, Previews, and Filters

void               myNavEventFunction(NavEventCallbackMessage callBackSelector,
                   NavCBRecPtr callBackParms,void *callBackUD);
Boolean            myNavPreviewFunction(NavCBRecPtr callBackParms,void *callBackUD);
Boolean            myNavObjectFilterFunction(AEDesc *theItem,void *info,void *callBackUD,
                   NavFilterModes filterMode);

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Challenge those pesky wyverns to a dance...
After recently having you do battle against your foes by wildly flailing Hello Kitty and friends at them, GungHo Online has whipped out another surprising collaboration for Puzzle & Dragons. It is now time to beat your opponents by cha-cha... | Read more »
Pack a magnifying glass and practice you...
Somehow it has already been a year since Torchlight: Infinite launched, and XD Games is celebrating by blending in what sounds like a truly fantastic new update. Fans of Cthulhu rejoice, as Whispering Mist brings some horror elements, and tests... | Read more »
Summon your guild and prepare for war in...
Netmarble is making some pretty big moves with their latest update for Seven Knights Idle Adventure, with a bunch of interesting additions. Two new heroes enter the battle, there are events and bosses abound, and perhaps most interesting, a huge... | Read more »
Make the passage of time your plaything...
While some of us are still waiting for a chance to get our hands on Ash Prime - yes, don’t remind me I could currently buy him this month I’m barely hanging on - Digital Extremes has announced its next anticipated Prime Form for Warframe. Starting... | Read more »
If you can find it and fit through the d...
The holy trinity of amazing company names have come together, to release their equally amazing and adorable mobile game, Hamster Inn. Published by HyperBeard Games, and co-developed by Mum Not Proud and Little Sasquatch Studios, it's time to... | Read more »
Amikin Survival opens for pre-orders on...
Join me on the wonderful trip down the inspiration rabbit hole; much as Palworld seemingly “borrowed” many aspects from the hit Pokemon franchise, it is time for the heavily armed animal survival to also spawn some illegitimate children as Helio... | Read more »
PUBG Mobile teams up with global phenome...
Since launching in 2019, SpyxFamily has exploded to damn near catastrophic popularity, so it was only a matter of time before a mobile game snapped up a collaboration. Enter PUBG Mobile. Until May 12th, players will be able to collect a host of... | Read more »
Embark into the frozen tundra of certain...
Chucklefish, developers of hit action-adventure sandbox game Starbound and owner of one of the cutest logos in gaming, has released their roguelike deck-builder Wildfrost. Created alongside developers Gaziter and Deadpan Games, Wildfrost will... | Read more »
MoreFun Studios has announced Season 4,...
Tension has escalated in the ever-volatile world of Arena Breakout, as your old pal Randall Fisher and bosses Fred and Perrero continue to lob insults and explosives at each other, bringing us to a new phase of warfare. Season 4, Into The Fog of... | Read more »
Top Mobile Game Discounts
Every day, we pick out a curated list of the best mobile discounts on the App Store and post them here. This list won't be comprehensive, but it every game on it is recommended. Feel free to check out the coverage we did on them in the links below... | Read more »

Price Scanner via MacPrices.net

Free iPhone 15 plus Unlimited service for $60...
Boost Infinite, part of MVNO Boost Mobile using AT&T and T-Mobile’s networks, is offering a free 128GB iPhone 15 for $60 per month including their Unlimited service plan (30GB of premium data).... Read more
$300 off any new iPhone with service at Red P...
Red Pocket Mobile has new Apple iPhones on sale for $300 off MSRP when you switch and open up a new line of service. Red Pocket Mobile is a nationwide MVNO using all the major wireless carrier... Read more
Clearance 13-inch M1 MacBook Airs available a...
Apple has clearance 13″ M1 MacBook Airs, Certified Refurbished, available for $759 for 8-Core CPU/7-Core GPU/256GB models and $929 for 8-Core CPU/8-Core GPU/512GB models. Apple’s one-year warranty is... Read more
Updated Apple MacBook Price Trackers
Our Apple award-winning MacBook Price Trackers are continually updated with the latest information on prices, bundles, and availability for 16″ and 14″ MacBook Pros along with 13″ and 15″ MacBook... Read more
Every model of Apple’s 13-inch M3 MacBook Air...
Best Buy has Apple 13″ MacBook Airs with M3 CPUs in stock and on sale today for $100 off MSRP. Prices start at $999. Their prices are the lowest currently available for new 13″ M3 MacBook Airs among... Read more
Sunday Sale: Apple iPad Magic Keyboards for 1...
Walmart has Apple Magic Keyboards for 12.9″ iPad Pros, in Black, on sale for $150 off MSRP on their online store. Sale price for online orders only, in-store price may vary. Order online and choose... Read more
Apple Watch Ultra 2 now available at Apple fo...
Apple has, for the first time, begun offering Certified Refurbished Apple Watch Ultra 2 models in their online store for $679, or $120 off MSRP. Each Watch includes Apple’s standard one-year warranty... Read more
AT&T has the iPhone 14 on sale for only $...
AT&T has the 128GB Apple iPhone 14 available for only $5.99 per month for new and existing customers when you activate unlimited service and use AT&T’s 36 month installment plan. The fine... Read more
Amazon is offering a $100 discount on every M...
Amazon is offering a $100 instant discount on each configuration of Apple’s new 13″ M3 MacBook Air, in Midnight, this weekend. These are the lowest prices currently available for new 13″ M3 MacBook... Read more
You can save $300-$480 on a 14-inch M3 Pro/Ma...
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

Jobs Board

Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple 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
IT Systems Engineer ( *Apple* Platforms) - S...
IT Systems Engineer ( Apple Platforms) at SpaceX Hawthorne, CA SpaceX was founded under the belief that a future where humanity is out exploring the stars is Read more
*Apple* Systems Administrator - JAMF - Activ...
…**Public Trust/Other Required:** None **Job Family:** Systems Administration **Skills:** Apple Platforms,Computer Servers,Jamf Pro **Experience:** 3 + years of Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.