Launch another application
It's been a while, but here's how I did it : It uses a combo of Rick Brown's SetCandT and FilePath code, and Jamin's routine.
As I recall, this also uses Jamin's DCOD. Works like a charm.
CLEAR LOCAL ' DCOD Gets called here LOCAL FN FinderAppleEvents(FullPathPtr&,RoutineSelector%) '_FinderUpdate = 1 '_FinderReveal = 2 '_FinderOpeN=3 osErr% = _noErr CALL "DCOD",5000,osErr%,(FullPathPtr&,RoutineSelector%) END FN = osErr% CLEAR LOCAL ' Thanks to whoever posted this routine DIM pBlock.128 DIM 63 dirName$ DIM 255 pathName$ LOCAL FN GetPathname$ (fName$, vRefNum% ,WantFile%) IF WantFile% = _True THEN pathName$ = fName$ 'put filename in pathname pBlock.ioNamePtr& = @dirName$ 'put pointer to dirName$ pBlock.ioVRefNum% = vRefNum% 'set vRefNun pBlock.ioDrParID& = [_curDirStore] 'get currect directory ID pBlock.ioFDirIndex% = - 1 'get info on folder DO osErr% = FN GETCATINFO (@pBlock) 'get catalog info LONG IF osErr% = _noErr 'no error then... pathName$ = dirName$ + " : " + pathName$ 'add dirName to path pBlock.ioDrDirID& = pBlock.ioDrParID& 'get folder's parent ID END IF UNTIL pBlock.ioDirID& = _fsRtParID OR osErr% <> _noErr'volume root ID END FN = pathName$ LOCAL FN SetCandT(fileName$, vRefNum, parID&, newCreator&, newType&) 'Sets the creator and type of the file specified by filename$, 'vRefNum and parID& to the 4 - byte values specified in newCreator& 'and newType&. Returns and error code as the function result ' * You can pass constants such as _"PICT" for the newCreator& and ' newType& parameters, if desired. ' * If you pass _nil in either of the newCreator& or newType& parameters, ' then the corresponding field will not be changed in the file. ' * If you have a working directory reference number for the file's ' folder (such as returned by the FILES$ function), then pass the ' w.d.ref.num in the vRefNum parameter and pass 0 in the parID& parameter. DIM pBlock.128, OSErr pBlock.ioCompletion& = 0 pBlock.ioNamePtr& = @fileName$ pBlock.ioVRefNum% = vRefNum pBlock.ioDirID& = parID& pBlock.ioFDirIndex% = 0 OSErr = FN HGETFILEINFO(@pBlock) 'Don't use FN GETFILEINFO ! LONG IF OSErr = _noErr IF newType& THEN pBlock.IoFlUsrWds.fdType& = newType& IF newCreator& THEN pBlock.IoFlUsrWds.fdCreator& = newCreator& OSErr = FN SETFILEINFO(@pBlock) END IF END FN = OSErrhere's the calling conventions; I use this to launch Inet Explorer.
FN SetCandT(gFileName$, gtheVol%, 0, _"R * ch", _"TEXT") theFullPath$ = FN GetPathname$ (gFileName$, gtheVol%, _True) osErr% = FN FinderAppleEvents(@theFullPath$,3)
Could you explain what this does a little more. Does it this launch an application and open a file in that application? What does the CALL "DCOD" line mean? When I run the example I get an error "Rsrc not found at line 0"
Oh yeah, I guess I wasn't thinking too hard when I wrote this. It changes the creator and type of file for a specified file, then it does a simulated "drag & drop" on the parent application. I guess what you're looking for is something that launches an app without a file. Oops.
Anyway, a DCOD is the neatest little thing; it's a code resource that acts like a "plugin". It's also the model for the Mini - App. It's also what "TOLZ" are. They're compatible with most Mac - Applications, including C and such. You can write an ODBC driver(for instance) and sell it as a DCOD to developers. You then pass this DCOD a group of variables, or my favorite, a pBlock which you can push all sorts of information into.
Its a way of distributing libraries without the source code involved. Very nice, but you're limited by FB to the commands you put in there; most things have to be IM type codes; no OPEN or CLOSE commands, for instance, so managing files is pretty tough.
Take a look at our "SendOpenDoc" example (http://www.stazsoftware.com/extlbx.html). It shows you how to launch an application using the information provided by the FB FILES$ statement.
I hate to promote my own software, but my FinderAppleEvent DCOD will do all the work of finding the app via the Desktop Database, the sending the apple event to launch the app, with the document. All you have to supply is the file that you want opened - it works out what type of file it is etc. In fact the finder does all the work for me, so it should be foolproof.
Its only about 8k, you can get it at :
Use aliases for this guys. You have routines in HFS Util.FLTR at your disposal for creating and using aliases. I can't see any reason not to use them. With an alias, the file can be moved all over the place, renamed, changed, and you will always be able to locate it. On the other hand, if you _want_ the user to have to relocate the file when it is moved, paths may be what you want. In general though, paths are a bad idea, except for certain circumstances.
And it's actually pretty easy to do. You can modify the MakeAlias function to have a fourth parameter for the resRef of the file you want to store the _"alis" resource in. Right now, it is "hard coded" to put it into the resource fork of your application. But to change that, all you need to do is add a param, and then call pGreplaceXRes (passing it the resRef param) rather than pGreplaceRes. You will be responsible of course for opening the res fork of your prefs file and closing it when done.
The UseAlias function is even easier. Just open the resource fork of your prefs file immediately before calling it. Then close the resource fork of your prefs file when done.
I used this to open Poser for my program TweenMachine. I believe it was written by Andy Gariepy, back in the AOL Ariel days. You call it like so:
result% = FN SearchDTDB(_"viOj") 'substitute creator code for your application to be launched, ex. "ttxt"
IF result%<>_noErr THEN SOUND "error" 'sample error catcher
'--------------------------Launch FN CLEAR LOCAL MODE DIM osErr% '___________________________________________________ LOCAL FN LaunchApplication (launchPtr&)'launch the application '___________________________________________________ ` SUBQ.L #2,sp ;clear space for osErr ` MOVE.L ^launchPtr&,-(sp) ;push fileSpec ptr on stack ` DC.W $205F,$A9F2,$3E80 ;trap number ` MOVE.W (sp)+,^osErr% ;D0 = osErr END FN = osErr% LOCAL MODE '___________________________________________________ LOCAL FN PBDTGetPath(DBRecPtr&) 'get the location of the dt data base '___________________________________________________ ` subq.l #2,sp ;Space for result ` move.l ^DBRecPtr&,-(sp) ;pBlock for call ` dc.w $205F,$7020,$A260,$3E80 ;INLINE ` move.w (sp)+,D0 ;Put result in D0 ` ext.l D0 ;Extend for looks END FN LOCAL MODE '___________________________________________________ LOCAL FN PBDTGetAPPLSync(DBPBPtr&) 'find the appl location '___________________________________________________ ` subq.l #2,sp ` move.l ^DBPBPtr&,-(sp) ` dc.w $205F,$7027,$A260,$3E80 ;INLINE ` move.w (sp)+,D0 ` ext.l D0 END FN CLEAR LOCAL MODE DIM result%,OSErr,NoteExists,MyVol% DIM theDB.DTPBRec DIM theLPB.LaunchParamBlockRec DIM theFSSpec.FSSpec DIM resFileID% DIM CurFileID% DIM OSErr% '___________________________________________________ LOCAL FN SearchDTDB(Creator&) '___________________________________________________ OSErr% = _noErr CurFileID% = FN CURRESFILE 'record the current res file theDB.ioCompletion& = _nil 'no completion theDB.ioNamePtr& = _nil 'Don't care yet theDB.ioVRefNum% = -1 'Boot volume only OSErr% = FN PBDTGetPath(@theDB) 'Is anyone out there? LONG IF OSErr = _noErr 'Have a DT DB? _ioFileCreator = 52 'Offset for pBlock _ioAPPLParID = 100 'Offset for pBlock theDB.ioWDIndex% = 0 'Most recent creation date = 0 theDB.ioFileCreator& = Creator& 'The target's signature passed to FN theDB.ioNamePtr& = @theFSSpec.fsName$'Call puts name here OSErr = FN PBDTGetAPPLSync(@theDB)'Find application itself LONG IF OSErr = _noErr 'Ok? theFSSpec.fsVRefNum% = theDB.ioVRefNum%'We need volume ref number theFSSpec.fsParID& = theDB.ioAPPLParID&'and param ID theLPB.launchBlockID% = _extendedBlock'Use extended block theLPB.launchEPBLength% = _extendedBlockLen'Length of extended block theLPB.launchFileFlags% = 0 theLPB.launchControlFlags% = _launchContinue_launchNoFileFlags_launchUseMinimum theLPB.launchAppSpec& = @theFSSpec'The filespec to the application theLPB.launchAppParameters& = &00000000 OSErr = FN LaunchApplication(@theLPB) END IF END IF END FN = OSErr% 'of FN SearchDTDB