Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Files /
Chapter 3 - Standard File Package / Using the Standard File Package


Customizing the User Interface

If your application requires it, you can customize the user interface for identifying files. To customize a dialog box, you should

Depending on the level of customizing you require in your dialog box, you may need to write as many as four different callback routines:

To provide the interface illustrated in Figure 3-7, for example, you could replace the definition of DoOpenCmd given earlier in Listing 3-1 by the definition given in Listing 3-3.

In addition to the information passed to StandardGetFile, CustomGetFile requires the resource ID of the customized dialog box, the location of the dialog box on the screen, and pointers to any callback routines and private data you are using.

Listing 3-3 Presenting a customized Open dialog box

FUNCTION DoOpenCmd: OSErr;
VAR
   myReply:    StandardFileReply;   {Standard File reply record}
   myTypes:    SFTypeList;          {types of files to display}
   myPoint:    Point;               {upper-left corner of box}
   myErr:      OSErr;
CONST
   kCustomGetDialog = 4000;         {resource ID of custom dialog}
BEGIN
   myErr := noErr;
   SetPt(myPoint, -1, -1);          {center the dialog}
   myTypes[0] := 'SRFD';            {SurfDraw files}
   myTypes[1] := 'STUP';            {startup screens}
   myTypes[2] := 'PICT';            {picture files}
   myTypes[3] := 'RTFT';            {rich text format}

   CustomGetFile(@MyCustomFileFilter, 4, myTypes, myReply, 
                  kCustomGetDialog, myPoint, @MyDlgHook, 
                  NIL, NIL, NIL, NIL);
   IF myReply.sfGood THEN
      myErr := DoOpenFile(myReply.sfFile);
   DoOpenCmd := myErr;
END;
In Listing 3-3, CustomGetFile is passed two callback routines, a file filter function (MyCustomFileFilter) and a dialog hook function (MyDlgHook). See Listing 3-8 (page 3-21) and Listing 3-9 (page 3-27) for sample definitions of these functions.

You can also supply data of your own to the callback routines through a new parameter, yourDataPtr, which you pass to CustomGetFile and CustomPutFile.

Customizing Dialog Boxes

To describe a dialog box, you supply a 'DLOG' resource that defines the box itself and a 'DITL' resource that defines the items in the dialog box.

Listing 3-4 shows the resource definition of the default Open dialog box, in Rez input format. (Rez is the resource compiler provided with Apple's Macintosh Programmer's Workshop [MPW]. For a description of Rez format, see the manual that accompanies the MPW software, MPW: Macintosh Programmer's Development Environment.)

Listing 3-4 The definition of the default Open dialog box

resource 'DLOG' (-6042, purgeable)
   {
      {0, 0, 166, 344}, dBoxProc, invisible, noGoAway, 0,
       -6042, "", noAutoCenter
   };
Listing 3-5 shows the resource definition of the default Save dialog box, in Rez
input format.

Listing 3-5 The definition of the default Save dialog box

resource 'DLOG' (-6043, purgeable)
   {
      {0, 0, 188, 344}, dBoxProc, invisible, noGoAway, 0,
       -6043, "", noAutoCenter
   };
Note
You can also use the stand-alone resource editor ResEdit, available from Apple Computer, Inc., or other resource-editing utilities available from third-party developers to create customized dialog box and dialog item list resources.
You must provide an item list (in a 'DITL' resource with the ID specified in the
'DLOG' resource) for each dialog box you define. Add new items to the end of the default lists. CustomGetFile expects the first 9 items in a customized dialog box to have the same functions as the corresponding items in the StandardGetFile dialog box; CustomPutFile expects the first 12 items to have the same functions as the corresponding items in the StandardPutFile dialog box. If you want to eliminate
one of the standard items from the display, leave it in the item list but place its coordinates outside the bounds of the dialog box rectangle.

Listing 3-6 shows the dialog item list for the default Open dialog box, in Rez input format. See "Writing a Dialog Hook Function" beginning on page 3-21 for a list of the dialog box elements these items represent.

Listing 3-6 The item list for the default Open dialog box

resource 'DITL'(-6042)
   {  {
      {135, 252, 155, 332}, Button { enabled, "Open" },
      {104, 252, 124, 332}, Button { enabled, "Cancel" },
      {0, 0, 0, 0}, HelpItem { disabled, HMScanhdlg {-6042}},
      {8, 235, 24, 337}, UserItem { enabled },
      {32, 252, 52, 332}, Button { enabled, "Eject" },
      {60, 252, 80, 332}, Button { enabled, "Desktop" },
      {29, 12, 159, 230}, UserItem { enabled },
      {6, 12, 25, 230}, UserItem { enabled },
      {91, 251, 92, 333}, Picture  { disabled, 11 },
   }  };
Listing 3-7 shows the dialog item list for the default Save dialog box, in Rez input format.

Listing 3-7 The item list for the default Save dialog box

resource 'DITL'(-6043)
   {  {
      {161, 252, 181, 332}, Button { enabled, "Save" },
      {130, 252, 150, 332}, Button { enabled, "Cancel" },
      {0, 0, 0, 0}, HelpItem { disabled, HMScanhdlg {-6043}},
      {8, 235, 24, 337}, UserItem { enabled },
      {32, 252, 52, 332}, Button { enabled, "Eject" },
      {60, 252, 80, 332}, Button { enabled, "Desktop" },
      {29, 12, 127, 230}, UserItem { enabled },
      {6, 12, 25, 230}, UserItem { enabled },
      {119, 250, 120, 334}, Picture { disabled, 11 },
      {157, 15, 173, 227}, EditText { enabled, "" },
      {136, 15, 152, 227}, StaticText { disabled, "Save as:" },
      {88, 252, 108, 332}, UserItem { disabled },
   }  };
The third item in each list (HelpItem) supplies Apple's Balloon Help for items in the dialog box. This third item specifies the resource ID of the 'hdlg' resource that contains the help strings for the standard dialog items. If you want to modify the help text of an existing dialog item, you should copy the original 'hdlg' resource from the System
file into your application's resource fork and modify the text in the copied resource as desired; then you must change the resource ID specified in HelpItem to the resource ID of the copied and modified resource. To provide Balloon Help for your own items, supply a second 'hdlg' resource and reference it with another help item at the end
of the list. The existing items retain their default text (unless you change that text,
as described).

The default dialog item lists used by the original Standard File Package routines do not contain help items, but the Standard File Package does provide Balloon Help when you call those routines in system software version 7.0 and later. If you call one of the original routines and the specified dialog item list does not contain any help items, the Standard File Package uses its default help text for the standard dialog items. If, however, the dialog item list does contain a help item, the Standard File Package assumes that your application provides the text for all help items, including the standard dialog items.

Note
The default Standard File Package dialog boxes support color. The System file contains 'dctb' resources with the same resource IDs as
the default dialog boxes, so that the Dialog Manager uses color graphics ports for the default dialog boxes. (See the chapter "Dialog Manager"
of Inside Macintosh: Macintosh Toolbox Essentials for a description of
the 'dctb' resource.) If you create your own dialog boxes, include 'dctb' resources.

Writing a File Filter Function

A file filter function determines which files appear in the displayed list when the user
is opening a file. Both StandardGetFile and CustomGetFile recognize file
filter functions.

When the Standard File Package is displaying the contents of a volume or folder, it checks the file type of each file and filters out files whose types do not match your application's specifications. (Your application can specify which file types are to be displayed through the typeList parameter to either StandardGetFile or CustomGetFile, as described in "Presenting the Standard User Interface" beginning on page 3-14.) If your application also supplies a file filter function, the Standard File Package calls that function each time it identifies a file of an acceptable type.

The file filter function receives a pointer to the file's catalog information record (described in the chapter "File Manager" in this book). The function evaluates the catalog entry and returns a Boolean value that determines whether the file is filtered (that is, a value of TRUE suppresses display of the filename, and a value of FALSE
allows the display). If you do not supply a file filter function, the Standard File Package displays all files of the specified types.

A file filter function to be called by StandardGetFile must use this syntax:

FUNCTION MyStandardFileFilter (pb: CInfoPBPtr): Boolean;
The single parameter passed to your standard file filter function is the address of a catalog information parameter block; see the chapter "File Manager" in this book for a description of the fields of that parameter block.

When CustomGetFile calls your file filter function, it can also receive a pointer to any data that you passed in through the call to CustomGetFile. A file filter function to be called by CustomGetFile must use this syntax:

FUNCTION MyCustomFileFilter (pb: CInfoPBPtr; myDataPtr: Ptr):
                               Boolean;
Listing 3-8 shows a sample file filter function to be called by CustomGetFile. You might define a file filter function like this to support the custom dialog box illustrated in Figure 3-7, which lists files of the type shown in the pop-up box.

Listing 3-8 A sample file filter function

FUNCTION MyCustomFileFilter (pb: CInfoPBPtr; myDataPtr: Ptr): Boolean;
BEGIN
   MyCustomFileFilter := TRUE;               {default: don't show the file}
   IF pb^.ioFlFndrInfo.fdType = gTypesArray[gCurrentType] THEN
      MyCustomFileFilter := FALSE;           {show the file}
END;
In Listing 3-8, the application global variable gCurrentType contains the index in
the array gTypesArray of the currently selected file type. If the type of a file passed in for evaluation matches the current file type, the filter returns FALSE, indicating that StandardGetFile should put it in the list. See Listing 3-9 (page 3-27) for an example
of how you can use a dialog hook function to change the value of gCurrentType according to user selections in the pop-up menu control.

Writing a Dialog Hook Function

A dialog hook function handles item selections in a dialog box. It receives a pointer to the dialog record and an item number from the ModalDialog procedure via the Standard File Package each time the user selects one of the dialog items. Your dialog hook function checks the item number of each selected item, and then either handles the selection or passes it back to the Standard File Package.

If you provide a dialog hook function, CustomPutFile and CustomGetFile call
your function immediately after calling ModalDialog. They pass your function the
item number returned by ModalDialog, a pointer to the dialog record, and a pointer
to the data received from your application, if any. The dialog hook function must use
this syntax:

FUNCTION MyDlgHook (item: Integer; theDialog: DialogPtr;
                     myDataPtr: Ptr): Integer;
Your dialog hook function returns as its function result an integer that is either the item number passed to it or some other item number. If it returns one of the item numbers in the following list of constants, the Standard File Package handles the selected item as described later in this section. If your dialog hook function does not handle a selection, it should pass the item number back to the Standard File Package for processing by setting its return value equal to the item number.

CONST {items that appear in both the Open and Save dialog boxes}
   sfItemOpenButton        =  1;       {Save or Open button}
   sfItemCancelButton      =  2;       {Cancel button}
   sfItemBalloonHelp       =  3;       {Balloon Help}
   sfItemVolumeUser        =  4;       {volume icon and name}
   sfItemEjectButton       =  5;       {Eject button}
   sfItemDesktopButton     =  6;       {Desktop button}
   sfItemFileListUser      =  7;       {display list}
   sfItemPopUpMenuUser     =  8;       {directory pop-up menu}
   sfItemDividerLinePict   =  9;       {dividing line between buttons}

   {items that appear in Save dialog boxes only}
   sfItemFileNameTextEdit  =  10;      {filename field}
   sfItemPromptStaticText  =  11;      {filename prompt text area}
   sfItemNewFolderUser     =  12;      {New Folder button}
You must write your own dialog hook function to handle any items you have added to the dialog box.

Note
The constants that represent disabled items (sfItemBalloonHelp, sfItemDividerLinePict, and sfItemPromptStaticText) have no effect, but they are defined in the header files for the sake of completeness.
The Standard File Package also recognizes a number of constants that do not represent any actual item in the dialog list; these constants are known as pseudo-items. There are two kinds of pseudo-items:

The sfHookFirstCall constant is an example of the first kind of pseudo-item. The Standard File Package sends this pseudo-item to your dialog hook function immediately before it displays the dialog box. Your function typically reacts to this item number by performing any necessary initialization.

You can pass back other pseudo-items to indicate that you've handled the user selection or to request some action by the Standard File Package. For example, if the list of
files and folders must be rebuilt because of a user selection, you can pass back the pseudo-item sfHookRebuildList. Similarly, when your application handles the selection and needs no further action by the Standard File Package, it should return sfHookNullEvent. When the dialog hook function passes either sfHookNullEvent or an item number that the Standard File Package doesn't recognize, it does nothing.

The Standard File Package recognizes these pseudo-item numbers:

CONST {pseudo-items available prior to version 7.0}
   sfHookFirstCall         =  -1;      {initialize display}
   sfHookCharOffset        =  $1000;   {offset for character input}
   sfHookNullEvent         =  100;     {null event}
   sfHookRebuildList       =  101;     {redisplay list}
   sfHookFolderPopUp       =  102;     {display parent-directory menu}
   sfHookOpenFolder        =  103;     {display contents of }
                                       { selected folder or volume}

   {additional pseudo-items introduced in version 7.0}
   sfHookLastCall          =  -2;      {clean up after display}
   sfHookOpenAlias         =  104;     {resolve alias}
   sfHookGoToDesktop       =  105;     {display contents of desktop}
   sfHookGoToAliasTarget   =  106;     {select target of alias}
   sfHookGoToParent        =  107;     {display contents of parent}
   sfHookGoToNextDrive     =  108;     {display contents of next drive}
   sfHookGoToPrevDrive     =  109;     {display contents of previous drive}
   sfHookChangeSelection   =  110;     {select target of reply record}
   sfHookSetActiveOffset   =  200;     {switch active item}
The Standard File Package uses a set of modal-dialog filter functions (described in "Writing a Modal-Dialog Filter Function" on page 3-28) to map user actions during
the dialog onto the defined item numbers. Some of the mapping is indirect. A click of
the Open button, for example, is mapped to sfItemOpenButton only if a file is selected in the display list. If a folder or volume is selected, the Standard File Package maps the selection onto the pseudo-item sfHookOpenFolder.

The lists that follow summarize when various items and pseudo-items are generated
and how they are handled. The descriptions indicate the simplest mouse action that generates each item; many of the items can also be generated by keyboard actions, as described in "Keyboard Equivalents" on page 3-7.

Note
Any indicated effects of passing back these constants do not occur until the Standard File Package receives the constant back from your dialog hook function.
Constant descriptions

sfItemOpenButton

Generated when the user clicks Open or Save while a filename is selected. The Standard File Package fills in the reply record (setting sfGood to TRUE), removes the dialog box, and returns.
sfItemCancelButton

Generated when the user clicks Cancel. The Standard File Package sets sfGood to FALSE, removes the dialog box, and returns.
sfItemVolumeUser

Generated when the user clicks the volume icon or its name. The Standard File Package rebuilds the display list to show the contents of the folder that is one level up the hierarchy (that is, the parent directory of the current parent directory).
sfItemEjectButton

Generated when the user clicks Eject. The Standard File Package ejects the volume that is currently selected.
sfItemDesktopButton

Generated when the user clicks the Drive button in a customized dialog box defined by one of the earlier procedures. You never receive this item number with the new procedures; when the user clicks the Desktop button, the action is mapped to the item sfHookGoToDesktop, described later in this section. The Standard File Package displays the contents of the next drive.
sfItemFileListUser

Generated when the user clicks an item in the display list. The Standard File Package updates the selection and generates this
item for your information.
sfItemPopUpMenuUser

Never generated. The Standard File Package's modal-dialog filter function maps clicks on the directory pop-up menu to sfHookFolderPopUp, described later in this section.
sfItemFileNameTextEdit

Generated when the user clicks the filename field. TextEdit and the Standard File Package process mouse clicks in the filename field, but the item number is generated for your information.
sfItemNewFolderUser

Generated when the user clicks New Folder. The Standard File Package displays the New Folder dialog box.
The pseudo-items are messages that allow your application and the Standard File Package to communicate and support various features added since the original design
of the Standard File Package.

The Standard File Package generates three pseudo-items that give your application the chance to control a customized display.

Constant descriptions

sfHookFirstCall

Generated by the Standard File Package as a signal to your dialog hook function that it is about to display a dialog box. If you
want to initialize the display, do so when you receive this item.
You can specify the current directory either by returning sfHookGoToDesktop or by changing the reply record and returning sfHookChangeSelection.
sfHookLastCall
Generated by the Standard File Package as a signal to your dialog hook function that it is about to remove a dialog box. If you created any structures when the dialog box was first displayed, remove them when you receive this item.
sfHookNullEvent

Issued periodically by the Standard File Package if no user action has taken place. Your application can use this null event to perform any updating or periodic processing that might be necessary.
Your application can generate three pseudo-items to request services from the Standard File Package.

Constant descriptions

sfHookRebuildList

Returned by your dialog hook function to the Standard File Package when it needs to redisplay the file list. Your application might need to redisplay the list if, for example, it allows the user to change the file types to be displayed. The Standard File Package rebuilds and displays the list of files that can be opened.
sfHookChangeSelection

Returned by your application to the Standard File Package after your application changes the reply record so that it describes a different file or folder. (You'll need to pass the address of the reply record in the yourDataPtr field if you want to do this.) The Standard File Package rebuilds the display list to show the contents of the folder or volume containing the object described in the reply record. It selects the item described in the reply record.
sfHookSetActiveOffset

Your application adds this constant to an item number and sends the result to the Standard File Package. The Standard File Package activates that item in the dialog box, making it the target of keyboard input. This constant allows your application to activate a specific field in the dialog box without explicit input from the user.
The Standard File Package's own modal-dialog filter functions generate a number of pseudo-items that allow its dialog hook functions to support various features introduced since the original design of the standard file dialog boxes. Except under extraordinary circumstances, your dialog hook function always passes any of these item numbers back to the Standard File Package for processing.

Constant descriptions

sfHookCharOffset

The Standard File Package adds this constant to the value of an ASCII character when it's using keyboard input for item selection. The Standard File Package uses the decoded ASCII character to select an entry in the display list.
sfHookFolderPopUp

Generated when the user clicks the directory pop-up menu. The Standard File Package displays the pop-up menu showing all parent directories.
sfHookOpenFolder

Generated when the user clicks the Open button while a folder
or volume is selected in the display list. The Standard File Package rebuilds the display list to show the contents of the folder
or volume.
sfHookOpenAlias

Generated by the Standard File Package as a signal that the selected item is an alias for another file, folder, or volume. If the selected item is an alias for a file, the Standard File Package resolves the alias, places the file system specification record of the target in the reply record, and returns.
If the selected item is an alias for a folder or volume, the Standard File Package resolves the alias and rebuilds the display list to show the contents of the alias target.
sfHookGoToDesktop

Generated when the user clicks the Desktop button. The Standard File Package displays the contents of the desktop in the display list.
sfHookGoToAliasTarget

Generated when the user presses the Option key while opening an item that is an alias. The Standard File Package rebuilds the display list to display the volume or folder containing the alias target and selects the target.
sfHookGoToParent

Generated when the user presses Command-Up Arrow (or
clicks the volume icon). The Standard File Package rebuilds the display list to show the contents of the folder that is one level
up the hierarchy (that is, the parent directory of the current
parent directory).
sfHookGoToNextDrive

Generated when the user presses Command-Right Arrow. The Standard File Package displays the contents of the next volume.
sfHookGoToPrevDrive

Generated when the user presses Command-Left Arrow. The Standard File Package displays the contents of the previous volume.
The CustomGetFile and CustomPutFile procedures call your dialog hook
function for item selections in both the main dialog box and any subsidiary dialog
boxes (such as the dialog box for naming a new folder while saving a document
through CustomPutFile). To determine whether the dialog record describes the
main dialog box or a subsidiary dialog box, check the value of the refCon field in
the window record in the dialog record.

Note
Prior to system software version 7.0, the Standard File Package did not call your dialog hook function during subsidiary dialog boxes. Dialog hook functions for the new CustomGetFile and CustomPutFile procedures must check the dialog window's refCon field to determine the target of the dialog record.
The defined values for the refCon field represent the Standard File dialog boxes.

CONST
   sfMainDialogRefCon      =  'stdf';  {main dialog box}
   sfNewFolderDialogRefCon =  'nfdr';  {New Folder dialog box}
   sfReplaceDialogRefCon   =  'rplc';  {name conflict dialog box}
   sfStatWarnDialogRefCon  =  'stat';  {stationery warning}
   sfErrorDialogRefCon     =  'err ';  {general error report}
   sfLockWarnDialogRefCon  =  'lock';  {software lock warning}
Constant descriptions

sfMainDialogRefCon
The main dialog box, either Open or Save.
sfNewFolderDialogRefCon
The New Folder dialog box.
sfReplaceDialogRefCon
The dialog box requesting verification for replacing a file of the same name.
sfStatWarnDialogRefCon
The dialog box warning that the user is opening
the master copy of a stationery pad, not a piece
of stationery.
sfErrorDialogRefCon
A dialog box reporting a general error.
sfLockWarnDialogRefCon
The dialog box warning that the user is opening a locked file and won't be allowed to save any changes.
Listing 3-9 defines a dialog hook function that handles user selections in the customized Open dialog box illustrated in Figure 3-7. Note that this dialog hook function handles selections only in the main dialog box, not in any subsidiary dialog boxes.

Listing 3-9 A sample dialog hook function

FUNCTION MyDlgHook (item: Integer; theDialog: DialogPtr; myDataPtr: Ptr):
                   Integer;
VAR
   myType:        Integer;       {menu item selected}
   myHandle:      Handle;        {needed for GetDItem}
   myRect:        Rect;          {needed for GetDItem}
   myIgnore:      Integer;       {needed for GetDItem; ignored}
CONST
   kMyPopUpItem = 10;            {item number of File Type pop-up menu}
BEGIN
   MyDlgHook := item;            {by default, return the item passed in}
   IF GetWRefCon(WindowPtr(theDialog)) <> LongInt(sfMainDialogRefCon) THEN
      Exit(MyDlgHook);           {this function is only for main dialog}

   {Do processing of pseudo-items and your own additional item.}
   CASE item OF 
      sfHookFirstCall:           {pseudo-item: first time function called}
         BEGIN
            GetDItem(theDialog, kPopUpItem, myType, myHandle, myRect);
            SetCtlValue(ControlHandle(myHandle), gCurrentType);
            MyDlgHook := sfHookNullEvent;
         END;
      kMyPopUpItem:              {user selected File Type pop-up menu}
         BEGIN
            GetDItem(theDialog, item, myIgnore, myHandle, myRect);
            myType := GetCtlValue(ControlHandle(myHandle));
            IF myType <> gCurrentType THEN
               BEGIN
                  gCurrentType := myType;
                  MyDlgHook := sfHookRebuildList;
               END;
         END;
      OTHERWISE
         ;                       {ignore all other items}
   END;
END;
The pop-up menu is stored as a control in the application's resource fork. Values stored in the resource determine the appearance of the control, such as the pop-up title text and the menu associated with the control. The Dialog Manager's ModalDialog procedure takes care of drawing the box around the pop-up menu and the title of the dialog box. When the dialog hook function is first called, it simply retrieves a handle to that control and sets the value of the pop-up control to the current menu item (stored in the global variable gCurrentType). The MyDlgHook function then returns sfHookNullEvent to indicate that no further processing is required.

When the user clicks the pop-up menu control, ModalDialog calls the standard control definition function associated with it. If the user makes a selection in the pop-up menu, MyDlgHook is called with the item parameter equal to kPopUpItem. Your dialog hook function needs simply to determine the current value of the control and respond accordingly. In this case, if the user has selected a new file type, the global variable gCurrentType is updated to reflect the new selection, and MyDlgHook returns sfHookRebuildList to cause the Standard File Package to rebuild the list of files and folders displayed in the dialog box.

For complete details on handling pop-up menus, see the chapters "Control Manager" and "Menu Manager" in Inside Macintosh: Macintosh Toolbox Essentials.

Writing a Modal-Dialog Filter Function

A modal-dialog filter function controls events closer to their source by filtering the events received from the Event Manager. The Standard File Package itself contains
an internal modal-dialog filter function that maps keypresses and other user input
onto the equivalent dialog box items. If you also want to process events at this level,
you can supply your own filter function.

Note
You can supply a modal-dialog filter function only when you use one of the procedures that displays a customized dialog box (that is, CustomGetFile, CustomPutFile, SFPGetFile, or SFPPutFile).
Your modal-dialog filter function determines how the Dialog Manager procedure ModalDialog filters events. The ModalDialog procedure retrieves events by calling the Event Manager function GetNextEvent. As just indicated, the Standard File Package contains an internal filter function that performs some preliminary processing on each event it receives. If you provide a modal-dialog filter function, ModalDialog calls your filter function after it calls the internal Standard File Package filter function and before it sends the event to your dialog hook function.

You might provide a modal-dialog filter function for several reasons. If you have customized the Open or Save dialog boxes by adding one or more items, you might want to map some of the user's keypresses to those items in the same way that the internal filter function maps certain keypresses to existing items.

Another reason to provide a modal-dialog filter function is to avoid a problem that
can arise if an update event is received for one of your application's windows while
a Standard File Package dialog box is displayed.

Note
The problem described in the following paragraph occurs only in system software versions earlier than version 7.0. The internal modal-dialog filter function installed by the Standard File Package when running in version 7.0 and later avoids the problem by passing the update event to your dialog filter and, if your filter doesn't handle the event, mapping it to a null event.
When ModalDialog calls GetNextEvent and receives the update event, ModalDialog does not know how to respond to it and therefore passes the update event to the Standard File Package's internal filter function. The internal filter function cannot handle the update event either. As a result, if you do not provide your own modal-dialog filter function that handles the update event, that event is never cleared. The next time ModalDialog calls GetNextEvent, it receives the same update event. ModalDialog never receives a null event, so your dialog hook function never performs any processing in response to the sfHookNullEvent pseudo-item. You can solve this problem by providing a modal-dialog filter function that handles the update event or changes it to a null event. See Listing 3-10 for details.

A modal-dialog filter function used with SFPGetFile and SFPPutFile is declared like any filter function passed to ModalDialog. Your function is passed a pointer to the dialog record, a pointer to the event record, and the item number. (The modal-dialog filter function is described in the chapter "Dialog Manager" in Inside Macintosh: Macintosh Toolbox Essentials.)

FUNCTION MyModalFilter (theDialog: DialogPtr; 
                        VAR theEvent: EventRecord; 
                        VAR itemHit: Integer): Boolean;
The modal-dialog filter function used with CustomGetFile and CustomPutFile requires an additional parameter, a pointer (myDataPtr) to the data received from
your application, if any.

FUNCTION MyModalFilterYD (theDialog: DialogPtr; 
                           VAR theEvent: EventRecord; 
                           VAR itemHit: Integer; 
                           myDataPtr: Ptr): Boolean;
Your modal-dialog filter function returns a Boolean value that reports whether it handled the event. If your function returns a value of FALSE, ModalDialog
processes the event through its own filters. If your function returns a value of TRUE, ModalDialog returns with no further action.

The CustomGetFile and CustomPutFile procedures call your filter function to process events in both the main dialog box and any subsidiary dialog boxes (such as the dialog box for naming a new folder while saving a document through CustomPutFile). To determine whether the dialog record describes the main dialog box or a subsidiary dialog box, check the value of the refCon field in the window record in the dialog record, as described in "Writing a Dialog Hook Function" beginning on page 3-21.

Listing 3-10 shows how to define a modal-dialog filter function that prevents update events from clogging the event queue.

Listing 3-10 A sample modal-dialog filter function

FUNCTION MyModalFilter (theDialog: DialogPtr; VAR theEvent: EventRecord;
                        VAR itemHit: Integer): Boolean;
BEGIN
   MyModalFilter := FALSE;             {we haven't handled the event yet}
   IF theEvent.what = updateEvt THEN
      IF IsAppWindow(WindowPtr(theEvent.message)) THEN
         BEGIN
            DoUpdateEvent(WindowPtr(theEvent.message));
            MyModalFilter := TRUE;     {we have handled the event}
         END;
END;
If this filter function receives an update event for a window other than the Standard File Package dialog box, it calls the application's routine for handling update events (DoUpdateEvent) and returns TRUE to indicate that the event has been handled. See
the chapters "Event Manager" and "Window Manager" in Inside Macintosh: Macintosh Toolbox Essentials for complete details on handling update events.

Writing an Activation Procedure

The activation procedure controls the highlighting of dialog items that are defined by your application and can receive keyboard input. Ordinarily, you need to supply an activation procedure only if your application builds a list from which the user can select entries. The Standard File Package supplies the activation procedure for the file display list and for all TextEdit fields. You can also use the activation procedure to keep track of which field is receiving keyboard input, if your application needs that information.

The target of keyboard input is called the active field. The two standard keyboard-input fields are the filename field (present only in Save dialog boxes) and the display list. Unless you override it through your own dialog hook function, the Standard File Package handles the highlighting of its own items and TextEdit fields. When the user changes the keyboard target by pressing the mouse button or the Tab key, the Standard File Package calls your activation procedure twice: the first call specifies which field is being deactivated, and the second specifies which field is being activated. Your application is responsible for removing the highlighting when one of its fields becomes inactive and for adding the highlighting when one of its fields becomes active. The Standard File Package can handle the highlighting of all TextEdit fields, even those defined by your application.

The activation procedure receives four parameters: a dialog pointer, a dialog item number, a Boolean value that specifies whether the field is being activated (TRUE) or deactivated (FALSE), and a pointer to your own data.

PROCEDURE MyActivateProc (theDialog: DialogPtr; itemNo: Integer;
                           activating: Boolean; myDataPtr: Ptr);

Previous Book Contents Book Index Next

© Apple Computer, Inc.
2 JUL 1996