Cheater's Guide to Writing AppleEvent Descriptors


Until I found out about Capture AE (thanks Tom!), there was no simple way to figure out how to write an AEDesc for some applications (I've never learned anything useful from AETracker, but YMMV). Determining something as trivial as a list of the available disks which, in AppleScript, is

	tell application "Finder" to get disks

can be an unholy nightmare to translate into AEGizmos. Note that in recent versions of Tcl there's no need for this particular AppleEvent, because the same result is obtained with [file volumes], but it serves as a nice example. When we wanted to implement [file volumes] in Alpha 7, which uses the Tcl 7.5 library, this is exactly the process we went through.

If you activate Capture AE, execution of this AppleScript dumps

	Process("Finder").SendAE "core,getd,'----':obj {form:indx, want:type(cdis), seld:abso(Ç616C6C20È), from:'null'()}"

This is easily enough rendered with Tcl® as

	tclAE::send -r 'MACS' core getd ---- {obj {form:indx, want:type(cdis), seld:abso(Ç616C6C20È), from:'null'()}}

Although it works, "abso(Ç616C6C20È)" isn't very nice to look at. A quick pass with tclAE::coerce::hexd>TEXT (or perusal of an ASCII chart) reveals this is, reasonably enough, the identifier 'all '. We make this substitution and send it, and call tclAE::print on the resulting descriptor hash key, whichÉ unfortunatelyÉ returns

	aevt\ansr{
		'----':[
			obj {
				want:type(prop), 
				from:'null'(), 
				form:prop, 
				seld:type(sdsk)
			}, 
			obj {
				want:type(cdis), 
				from:'null'(), 
				form:name, 
				seld:ÒcatbertÓ
			}, 
			obj {
				want:type(cdis), 
				from:'null'(), 
				form:name, 
				seld:ÒratbertÓ
			}
		]
	}

which is a parsing nightmare (it's not even usually formatted this nicely). Note that, on top of everything else, the Startup Disk is treated differently from everything else. Fortunately, we can make the Finder do our work for us by using the 'rtyp' tag. We now send

	tclAE::build::resultData 'MACS' core getd rtyp TEXT ---- {obj {form:indx, want:type(cdis), seld:abso('all '), from:'null'()}}

which yields a manageable

	catbert: dogbert: ratbert:

on my computer.

'aete' Resources

Even with Capture AE, it's handy to be able to read 'aete' resources (if for no other reason, to decipher what you just blindly copied into your Tcl® statements). Resourcerer has a template to open 'aete' resources and you can decompile them with Rez. If you can manage to find it, Yuji Hachiya of Apple Japan wrote an 'aete' editor for ResEdit. It would appear, though, that Apple has hired the Mossad to hunt down and destroy every copy of this utility (IÕve seen complaints about it, but it's perfectly adequate for reading 'aete' resources).

Desperate Measures

If, for some reason, Capture AE is unavailable to you (redistribution is prohibited, so WestCodeSoft could conceivably withdraw it), there is, fortunately, a trick you can try:

  1. Enter your desired AppleScript in the Script Editor, but trick it talking to Alpha instead of the actual target application*. For instance,
    	tell application "Alpha"
    		using terms from application "Finder"
    			get disks
    		end using terms from
    	end tell	
    
  2. Return to Alpha (or Wish) and write a dummy Tcl routine to intercept this event, such as
    	proc snoop {theAESubDesc theReplyAE} {
    		return [tclAE::print $theAESubDesc]
    	}
    
    It neednÕt do any more than this.
  3. Declare snoop as an AppleEvent handler for the event you wish to examine:
    	tclAE::installEventHandler core getd snoop
    
  4. Open the Result window and run your script. You should get something like:
    	"core\\getd{'----':obj {form:indx, want:type(cdis), seld:abso(Ç616C6C20È), from:'null'()}, &inte:cans, &timo:3600}"
    

Although this probably seems like a lot of work, I assure you that it's far preferable to the hunt-and-peck alternative. There's no reason that this methodology won't work with other scriptable applications, either, but I take no responsibility for the implosion of your monitor.

Really desperate measures

If youÕre using a version of AppleScript earlier than 1.4, you wonÕt have access to the using terms from construct. In that event, you can try something really sleazy:

  1. Enter the AppleScript you want to decipher in the Script Editor and save it as a compiled script. For example
    	tell application "Finder" to get disks
    
  2. Open the script in a resource editor, open the 'scpt' resources, and open what will likely be the only 'scpt' resource there (if you have a 'scpt' resource editor template installed, you'll want to be sure to open the resource as hexadecimal).
  3. Look for the first occurence of the string 'MACS' (4D414353) and change this to 'ALFA' (414C4641) [or 'WIsH' (57497348)]. Ignore any explicit references to "Finder"; they don't matter. You've just changed the script to ask Alpha for a list of all disks. Alpha obviously doesn't know how to do this, but that's not the point.
  4. Close and save your changes and reopen the script in the Script editor. It should now look like
    	tell application "Alpha" to get every Çclass cdisÈ
    
  5. Proceed as above with writing a core getd handler in Alpha or Wish.

You canÕt just write

	tell application "Alpha" to get disks

because it won't compile, and if you knew enough to write Çclass cdisÈ, you probably wouldn't need the rest of this. We've tricked the Script Editor into thinking that Alpha understands the get disks command.


Copyright © 1998Ð2000 Jonathan E. Guyer
All rights reserved.

Last modified Monday, November 13, 2000 10:22:03 AM