[comp.sys.mac.programmer] System/App resource files

Ken.Knight@f421.n109.z1.fidonet.org (Ken Knight) (02/20/91)

I have an application that I am working on that opens up specified
resource forks. The user determines, via an SFGetFile, what file to
open and then work on. Now, normally, the sequence of events is:
 Get user input (file from SFGetFile());
 Do work on the resource file (we open it with an HOpenResFile() call
after
 determining the dirID of the file specified);
 Do a CloseResFile() when all done.
 
Normally, that works fine. However, if the user chooses to work on the
System file or application itself things go haywire. The problem is
that you DO NOT want to CloseResFile() though two particular resource
files. I want the application to check to see if the user has selelcted
the system/application and then only do an UpdateResFile() on them.
However, it appears that HOpenResFile() creates a NEW ference number
for already open files and so I can't just check to see if the
reference number returned matches either the system's refNum (held in
the system global SysMap) or matches the one for the application
(obtained via a call to CurResFile() at startup). What should I try
next?
 
  ** Ken **


--  

        Ken Knight, Ken.Knight@f421.n109.z1.fidonet.org
      via The Black Cat's Shack's FidoNet<->Usenet Gateway
          blkcat.fidonet.org   and   Fidonet 1:109/401

olson@bootsie.uucp (Eric K. Olson) (02/20/91)

In article <3541.27C202A9@blkcat.fidonet.org> Ken.Knight@f421.n109.z1.fidonet.org (Ken Knight) writes:
>I have an application that I am working on that opens up specified
>resource forks. The user determines, via an SFGetFile, what file to
>open and then work on. Now, normally, the sequence of events is:
> Get user input (file from SFGetFile());
> Do work on the resource file (we open it with an HOpenResFile() call
>after
> determining the dirID of the file specified);
> Do a CloseResFile() when all done.
> 
>Normally, that works fine. However, if the user chooses to work on the
>System file or application itself things go haywire. The problem is
>that you DO NOT want to CloseResFile() though two particular resource
>files. I want the application to check to see if the user has selelcted
>the system/application and then only do an UpdateResFile() on them.
>However, it appears that HOpenResFile() creates a NEW ference number
>for already open files and so I can't just check to see if the
>reference number returned matches either the system's refNum (held in
>the system global SysMap) or matches the one for the application
>(obtained via a call to CurResFile() at startup). What should I try
>next?

See Technote 185 for the behavior of HOpenResFile() on an already open
file.  Suffice to say its not a good idea to use it for the current
Application or the System file.

Instead, when you get an "Open File" request, you can walk through the
FCB queue to find an appropriate refNum for files that are already open.
Something like:

short GetAlreadyOpenRefNum(short volNum, long dirID, StringPtr name)
{
	FCBPBRec	aFCB={0};
	Str255		aName;

	aFCB.ioFCBIndex = 1;
	aFCB.ioNamePtr = aName;
	aFCB.ioVRefNum = 0;		/* Try all drives */
	
	while (!PBGetFCBInfo(&aFCB, FALSE)) {
		if (	aFCB.ioFCBVRefNum == volNum &&
			aFCB.ioFCBParID == dirID &&
			ComparePStrings(name, aName)) {
				return aFCB.ioRefNum
				}
		}

	return 0;		/* Not found */
	}

You can restrict the available files by testing the type and creator
after calling PBHGetFInfo with data returned by PBGetFCBInfo.  You might
want to check which fork is open, too, to avoid using resource manager
calls on a data fork. 

You'll have to do something in your application to avoid closing these
refNums (which would have disasterous effects).  In Prepare(), the
BAppResFile class overrides all the methods of BResFile that Open,
Close, Create, or Delete the file, changing most of them into no-ops. 
This way, your Document class can believe it is closing the file
normally, and yet the file remains open (as it should). 

Cheers!

-Eric


-- 
Eric K. Olson, Editor, Prepare()      NOTE:     olson@bootsie.uucp doesn't work
Lexington Software Design             Internet: olson@endor.harvard.edu
72A Lowell St., Lexington, MA  02173  Uucp:     harvard!endor!olson
(617) 863-9624                        Bitnet:   OLSON@HARVARD