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 1 - Introduction to File Management / Using Files


Closing a File

In most cases, your application closes a file after a user clicks in a window's close box or chooses the Close command in the File menu. The Close menu command should be active only when there is actually an active window on the desktop. If there is an active window, you need to determine whether it belongs to your application; if so, you need to handle dialog windows and document windows differently, as illustrated in Listing 1-15.

Listing 1-15 Handling the Close menu command

FUNCTION DoCloseCmd: OSErr;
VAR
   myWindow:   WindowPtr;
   myData:     MyDocRecHnd;
   myErr:      OSErr;
BEGIN
   myErr := FALSE;
   myWindow := FrontWindow;         {get window to be closed}
   CASE MyGetWindowType(myWindow) OF
      kDAWindow:
         CloseDeskAcc(WindowPeek(myWindow)^.windowKind);
      kMyModelessDialog:
         HideWindow(myWindow);      {for dialogs, hide the window}
      kMyDocWindow:
         BEGIN
            myData := MyDocRecHnd(GetWRefCon(myWindow));
            myErr := DoCloseFile(myData);
            IF myErr = noErr THEN
               DisposeWindow(myWindow);
         END;
      OTHERWISE
         ;
   END;
   DoCloseCmd := myErr;
END;
The DoCloseCmd function determines the type of the frontmost window by calling the application-defined function MyGetWindowType. (See the chapter "Window Manager" in Inside Macintosh: Macintosh Toolbox Essentials for a definition of MyGetWindowType.) If the window to be closed is a window belonging to a desk accessory, DoCloseCmd closes the desk accessory. If the window to be closed is a dialog window, this procedure just hides the window. If the window to be closed is a document window, DoCloseCmd retrieves its document record handle and calls both DoCloseFile (defined in
Listing 1-16) and DisposeWindow. Before you close the file associated with a
window, you should check whether the contents of the window have changed since
the last time the document was saved. If so, you should ask the user whether to save those changes. Listing 1-16 illustrates one way to do this.

Listing 1-16 Closing a file

FUNCTION DoCloseFile (myData: MyDocRecHnd): OSErr;
VAR
   myErr:      OSErr;
   myDialog:   DialogPtr;        {pointer to modal dialog box}
   myItem:     Integer;          {item selected in alert box}
   myPort:     GrafPtr;          {the original graphics port}
CONST
   kSaveChangesDialog = 129;     {resource of Save changes dialog}
BEGIN
   IF myData^^.windowDirty THEN  {see whether window is dirty}
      BEGIN
         myItem := CautionAlert(kSaveChangesDialog, NIL);
         IF myItem = iCancel THEN{user clicked Cancel}
            BEGIN
               DoCloseFile := usrCanceledErr;
               Exit(DoCloseFile);
            END;
         IF myItem = iSave THEN
            myErr := DoSaveCmd;
      END;
   IF myData^^.fileRefNum <> 0 THEN
      BEGIN
         myErr := FSClose(myData^^.fileRefNum);
         IF myErr = noErr THEN
            BEGIN
               myErr := FlushVol(NIL, myData^^.fileFSSpec.vRefNum);
               myData^^.fileRefNum := 0;  {clear the file reference number}
            END;
      END;
   {Dispose of TextEdit record and controls here (code omitted).}
   DisposeHandle(Handle(myData));         {dispose of document record}
   DoCloseFile := myErr;
END;
If the document is an existing file that has not been changed since it was last saved, your application can simply call the FSClose function. This routine writes to disk any unwritten data remaining in the volume buffer. The FSClose function also updates the information maintained on the volume for that file and removes the access path. The information about the file is not actually written to the disk, however, until the volume is flushed, ejected, or unmounted. To keep the file information current, it's a good idea to follow each call to FSClose with a call to the FlushVol function.

If the contents of an existing file have been changed, or if a new file is being closed for the first time, your application can call the Dialog Manager routine CautionAlert (specifying a resource ID of an 'ALRT' template) to ask the user whether or not to save the changes. If the user decides not to save the file, you can just call FSClose and dispose of the window. Otherwise, DoCloseFile calls the DoSaveCmd function to save the file to disk.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
2 JUL 1996