there is a classic solution: blessed folders
these are things like 'extensions' 'tableau de bord' 'dossier menu pomme' that clutter my system folder. (BTW those are probably 'Extensions' 'Control Panels' and 'Apple Menu Folder' to you).
If folks just had a single language system and used software only in that language then you could hard code the names... but of course, there are all sorts of reasons folks can have the system in one language and apps in another, and even more than one other! [I even had a mac with a french system and an American finder... gives for strange messages sometimes]
So apple devised a way of identifying the 'blessed' folders other than by name. There are tons of them.. even temporary memory is a blessed folder!
But... what happened before this system? Well folks just used the names, so in the sample code in the FB books the seeking out of preference files uses a hard coded method. Staz did include a sample 'new way' of doing things at some point, but it seems that most folks used the books, not the code - including yourself tedd as Quarters made a 'Preferences' folder in my system!
I did code a DCOD - PLU_Prefs that did the work for folks...
Here is the source code: remember however... it was intended as a compact DCOD and not as sample code: To confuse matters, this is the version that isn't a DCOD, but this is how i tested before lumping it into a DCOD! You'll probably have to clean this up as the mail clients will mangle it a little...
It also needs a 'STR#' id 4800 with entry 1 - the pref type... usually 'pref' entry 2 - the name of your application
a 'STR ' id -16397 with the info that the document will present when double-clicked and a 'pref' resource with an ID of 4800 giving the default application prefs.
'/------------------------------------------------ INFO -------
' preparation for a PrefStuff DCOD
' CALL "PrefStuff",0,(switch%,recAdr&,recLen%,resNum%)
' returns _noErr -> all ok
' or _rsrcNotFndErr, _osErr, etc.
' which should be considered fatal errs
'/--------------------------------------------------------------
' version alpha 5
' this successfully sets type = "pref" so that the sys icon appears
' & creator to "****" so that dble-clicking on icon doesn't start app
' and adds "STR " num -16397 so that double clicking gives correct
' message - youpee - 21/12/96
'/--------------------------------------------------------------
' switch% - call to _prefsRead,_prefsWrite,_prefsDefault
' recAdr& - address of record containing prefs
' recLen% - length of record containing prefs
' resNum% - number of pref resource
' the type of the pref resource is contained in
' a STR# bearing this same number
RESOURCES "MaMwS.rsrc"
',"APPLmA=9Fw","CODE",1,"Code Segment"
COMPILE 0, _STRresource_dimmedVarsOnly '_appendRes
'
'RESOURCES "", "rsrcRSED","DCOD", 4800, "PLU/Prefs"
'str consts into not into STR# resource as i want this self contained
'only dimmed vars
'COMPILE 0, _dimmedVarsOnly_appendRes
'OUTPUT FILE "MaMwS.rsrc" 'saves time
'/------------------------------------------ CONSTANTS --------
_prefResNum = 4800
_prefsDefault = 1
_prefsRead = 2
_prefsWrite = 3
'/-------------------------------------------- GLOBALS --------
'DIM switch% 'determines what was called
DIM result% 'returns err code
DIM resType& 'contains 4 letter resource type
DIM 31 prefName$ 'name of doc in prefs folder
'DIM resNum% 'passed id for STR# & pref rsrc
'DIM recAdr& 'passed adr of pref record
'DIM recLen% 'length of passed pref record
DIM curRes 'to backup and restore on leaving
DIM tempRes 'for use in FN
DIM resHndl& 'hndl for different resource
DIM totalStrings;0,createFlag 'num strings in STR# & temp flag
DIM prefVRefNum 'volRefNum for prefs file
DIM prefDirID& 'directory ID for prefs file
DIM FSSpec.70 'FSSpec record
DIM crea&,type& 'info for FSSpec record
'DIM FSSpecAdr&
DIM tag 'misc vars
END GLOBALS
'/------------------------------------------ VARIABLES --------
'/-------------------------------------- END OF HEADER --------
GOTO "main"
LOCAL FN doCopyRes(sourceRes,destRes,myType&,myName$,myResNum)
DIM osErr,prefAttrbs
DIM hndl&
'
osErr = _noErr
CALL USERESFILE(sourceRes) 'get app resources
hndl& = FN GET1RESOURCE(myType&,myResNum) 'get hndl to pref res
LONG IF hndl& 'if ok
prefAttrbs = FN GETRESATTRS(hndl&) 'get attrbs
CALL DETACHRESOURCE(hndl&) 'disconnect from app-ready for copy
CALL USERESFILE(destRes) 'set to prefs file
'osErr = FN HNOPURGE(resHndl&) 'stop it disappearing during
CALL ADDRESOURCE(hndl&,myType&,myResNum,myName$)
IF FN RESERROR = 0 THEN CALL SETRESATTRS(hndl&,prefAttrbs)
IF FN RESERROR = 0 THEN CALL CHANGEDRESOURCE(hndl&)
IF FN RESERROR = 0 THEN CALL WRITERESOURCE(hndl&)
'osErr = FN HPURGE(resHndl&) 'purgeable again
osErr = FN RESERROR
CALL RELEASERESOURCE(hndl&)
hndl& = &DEADBEEF 'will fail if reusedÑtake out in final
CALL CLOSERESFILE(destRes)
CALL USERESFILE(sourceRes) 'put back in place
XELSE
osErr = _resNotFound
END IF
END FN = osErr
'
' these next two are copied and inspired by routines posted by
' RickJBrown, in answer to someone else's question about alias.
'
' puts tpgether a FSSpec record and returns a -43 error as, of
' course, the file doesn't exist yet - just ignore error, but
' record is ok for next call
' Call as follows
' osErr = FN FSMakeFSSpec (volRefNum%, dirID&, fileName$, @spec)
' where spec is a 70 byte record
' and other information is standard - obtained from findFolder
' in this case
'
LOCAL FN FSMakeFSSpec(vRefNum,dirID&,fileName$,FSSpecAdr&)
DIM osErr, fileNameAdr&
fileNameAdr& = @fileName$
` CLR.W -(SP)
` MOVE.W ^vRefNum, -(SP)
` MOVE.L ^dirID&, -(SP)
` MOVE.L ^fileNameAdr&, -(SP)
` MOVE.L ^FSSpecAdr&, -(SP)
` MOVE.W #$0001, D0
` DC.W $AA52
` MOVE.W (SP)+,^osErr
END FN = osErr
'/------------------------------------------ FUNCTIONS --------
' for the moment, implement as a FN
'ENTERPROC% (switch%,recAdr&,recLen%,resNum%)
LOCAL FN prefStuff(switch%,recAdr&,recLen%,resNum%)
'
result = _noErr 'default initialization
prefVRefNum = 0 ' -->>--
curRes = FN CURRESFILE 'get active resource file
'
DEFSTR LONG
resHndl&=FN GETRESOURCE(_"STR#",resNum) 'hndle to resource
LONG IF resHndl& > 0 'make sure handle valid
totalStrings={[resHndl&]} '1st word in
hndl=totalStrings%
LONG IF totalStrings > 1 'are there at least 2?
resType& = CVI(STR#(resNum,1)) 'get from STR#
prefName$ = STR#(resNum,2) 'get from STR#
XELSE
result = _resNotFound 'say the error
'it would be better to have a _strNotFound error here
'so there is no confusion as to where the error is
'but i can't find one...
END IF
CALL RELEASERESOURCE(resHndl&) 'release resource from mem
resHndl& = &DEADBEEF 'will fail if reusedÑtake out in final
XELSE
result = _resNotFound 'say the error
END IF
DEFSTR WORD 'restore to default
IF result <> _noErr THEN GOTO "PLU:End" 'if error then get out
'
'get the volRefNum & DirID of prefs folder
'not needed if just getting default from app
'this needed to complete Spec record
'
LONG IF switch <> _prefsDefault
result = FN FINDFOLDER(_kOnSystemDisk,_kPreferencesFolderType,_kCreateFolder, ¬
prefVRefNum, prefDirID&)
END IF
' if bad then just get out
IF result <> _noErr THEN GOTO "PLU:End"
'
SELECT switch
CASE _prefsDefault
GOSUB "PLU:defaultPrefs"
CASE _prefsRead
'Look for pref file in system prefs folder. If not found create it and
'copy in default prefs - on return recAdr& contains default prefs.
'
GOSUB "PLU:openResFile"
LONG IF result = _noErr
LONG IF createFlag = 0
CALL USERESFILE(tempRes) 'set to prefs file
resHndl& = FN GET1RESOURCE(resType&,resNum)'get hndl& to resource
LONG IF resHndl& 'we got it, copy into record
BLOCKMOVE [resHndl&], recAdr&, recLen%
CALL RELEASERESOURCE(resHndl&)
resHndl& = &DEADBEEF 'will fail if reusedÑtake out in final
XELSE
result = _resNotFound
END IF
'
CALL CLOSERESFILE(tempRes)
XELSE
'as i just created the prefs file, i must copy default ones in
'first open res fork and try and get a refence number on pref file
tempRes = FN HOPENRESFILE(prefVRefNum,prefDirID&,prefName$,_fsRdWrPerm)
result = FN RESERROR
'copy pref resource from app to prefs
IF result = _noErr THEN ¬
result = FN doCopyRes(curRes,tempRes,resType&,prefName$,resNum)
'if ok then init default prefs
IF result = _noErr THEN GOSUB "PLU:defaultPrefs"
END IF
END IF
CASE _prefsWrite
'Look for prefs file in System Prefs folder. If not found create it
'and copy current prefs from recAdr& unchanged. On return recAdr& unchanged
GOSUB "PLU:openResFile"
LONG IF result = 0
CALL USERESFILE(tempRes) 'set to prefs res
resHndl& = FN GET1RESOURCE(resType&,resNum)
LONG IF resHndl& 'we got it, go copy record in
BLOCKMOVE recAdr&, [resHndl&], recLen%
CALL CHANGEDRESOURCE(resHndl&)
CALL WRITERESOURCE(resHndl&)
CALL RELEASERESOURCE(resHndl&)
resHndl& = &DEADBEEF 'will fail if reusedÑtake out in final
XELSE
result = _resNotFound
END IF
CALL CLOSERESFILE(tempRes)
END IF
END SELECT
'
GOTO "PLU:End" 'jump over subroutines
'----------------------------------------- SUBROUTINES ------
"PLU:openResFile"
'------------------------------------------------------------
'This opens the resource file - if it fails it assumes that it
'doesn't exist and creates it. Only then does it give an error
'createFlag is a flag to let me know if i created the prefs
'in which case i need to use the default prefs if i'm reading in
createFlag = 0
'opens the res file and gives me the refernce number
tempRes = FN HOPENRESFILE(prefVRefNum,prefDirID&,prefName$,_fsRdWrPerm)
'if the error is 1, then i couldn't open - i assume then that the
'file doesn't exist and set about creating it
LONG IF tempRes = -1
'set the type and creator info, and info on default system script
crea& = _"****" : type& = _"pref" : tag = _smSystemScript
'call to make the spec record - this returns a -43 err which is ignored
result = FN FSMakeFSSpec(prefVRefNum,prefDirID&,prefName$,@FSSpec)
'this is the real work - it creates a file with a resource fork in the
'right place, with the correct type and creator, name etc.
CALL FSPCREATERESFILE(#@FSSpec,crea&,type&,tag)
'check if all went ok
result = FN RESERROR
'and continue if still ok
LONG IF result = _noErr
'no, again try to open the resource fork and get a reference number
tempRes = FN HOPENRESFILE(prefVRefNum,prefDirID&,prefName$,_fsRdWrPerm)
'this "STR " gives information if the user dble-clicks the prefs file
'set up the information for the copy, using vars that i no longer need
type& = _"STR " : tag = -16397
'copy in the resource from app
result = FN doCopyRes(curRes,tempRes,type&,prefName$,tag)
'it's not too important if this fails - so i won't abort
'set the flag saying creation went ok
createFlag = 1
END IF
END IF
RETURN
'------------------------------------------------------------
"PLU:defaultPrefs"
'------------------------------------------------------------
'This copies default prefs from your pref resource in your app.
'The type of the resource (for example 'PRFN') must be in first
'string of the STR# resource with its resNumber identical to the
'resNum passed on entry. The resNumber of this resource will
'also be identical to this number.
resHndl& = FN GET1RESOURCE(resType&,resNum)
LONG IF resHndl&
BLOCKMOVE [resHndl&], recAdr&, recLen%
CALL RELEASERESOURCE(resHndl&)
resHndl& = &DEADBEEF 'will fail if reusedÑtake out in final
XELSE
result = _resNotFound
END IF
RETURN
'------------------------------------------------------------
"PLU:End"
CALL USERESFILE(curRes) 'put back in place
END FN = result
'EXITPROC% = result 'return result
'RETURN 'get out
'------------------------------------------------------------
"main"
WINDOW 1
DIM fred,test
DIM RECORD testRec
DIM foo1
DIM foo2
DIM foo3
DIM foo4
DIM foo5
DIM foo6
DIM foo7
DIM foo8
DIM foo9
DIM foo10
DIM END RECORD .testRec
DIM my.testRec
my.foo1 = 1
my.foo2 =2
my.foo3 =3
my.foo4 =4
my.foo5 =5
my.foo6 =6
my.foo7 =7
my.foo8 =8
my.foo9 =9
my.foo10 =10
test = _prefsRead
FN prefStuff(test,@my,_testRec,_prefResNum)
'CALL "PLU/Prefs",0, fred%,(%test,@my,%_testRec,%_prefResNum)
'CALL "DCOD", 4800, fred%,(%test,@my,%_testRec,%_prefResNum)
PRINT HEX$(my.foo1)
PRINT HEX$(my.foo2)
PRINT HEX$(my.foo3)
PRINT HEX$(my.foo4)
PRINT HEX$(my.foo5)
PRINT HEX$(my.foo6)
PRINT HEX$(my.foo7)
PRINT HEX$(my.foo8)
PRINT HEX$(my.foo9)
PRINT HEX$(my.foo10)
PRINT fred
DO
UNTIL LEN(INKEY$)