LaunchWithDoc.c

/*
    File:       LaunchWithDoc.c
 
    Contains:   The smallest LaunchAplication example I could come up with. 
                this launches an application with a 'odoc' AppleEventª  
                this little bit of code here uses two Standard File calls to get    
                the application to launch and the file to launch with, you will of course   
                want to replace these with whatever you want to do  
                ¥¥¥ NOTE: This also works for launching non-System 7 applications.  
                If the Finderª sees an 'odoc' or 'pdoc' Apple event in the launch block     
                and the application being launched is NOT system 7 aware, the Finder    
                coerces the Apple event into puppetstrings.  So you     
                don't need to special case for non-7.0 applications.    
                Pretty neat, huh?   
                ¥¥¥ Important: I'm not doing any error checking, you of course should   
                so your users don't hunt you down and burn your keyboard.
                Please see the sample FinderOpenSel 1.0.1 for more information on 
                opening/launching applications and stuff.  Using the Finder event is much
                more versitile than just using launchApplication.
 
    Written by: C.K. Haun   
 
    Copyright:  Copyright © 1984-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                7/27/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
*/
#include <Dialogs.h>
#include <QuickDraw.h>
#include <Windows.h>
#include <Menus.h>
#include <Fonts.h>
#include <appleevents.h>
#include <processes.h>
#include <files.h>
#include <StandardFile.h>
#include <Aliases.h>
 
void main()
{
    FSSpec launchApp, fileToLaunch;   /* file spec for the app (launchApp) and the file (fileToLaunch) */
    OSErr myErr;
    LaunchParamBlockRec launchThis;
    AEDesc myAddress;
    ProcessSerialNumber myPSN;
    AEDesc docDesc, launchDesc;
    AEDescList theList;
    AliasHandle withThis;
    StandardFileReply myReply;
    AppleEvent theEvent;
    InitGraf((Ptr)&qd.thePort);  /* standard setup stuff */
    InitFonts();
    InitWindows();
    InitMenus();
    TEInit();
    InitDialogs(nil);
    InitCursor();
    /* get the app to launch, using the Sys7 versions of Standard File */
    /* which return FSSpecs */
    /* Preset our address descriptor to our PSN */
    /* The Finder is going to change this to whatever is appropriate  */
    /* for the application that eventually gets launched, so I'll */
    /* just fill it with my own address. */
    /* I'm doing this because I have heard sporadic reports that  */
    /* _not_ doing this causes address errors sometimes, I've never had that happen. */
    /* But since it has, you should prefill. */
    GetCurrentProcess(&myPSN);
    /* create the address desc for the event */
    myErr = AECreateDesc(typeProcessSerialNumber, (Ptr)&myPSN, sizeof(ProcessSerialNumber), &myAddress);
    /* get the application to launch */
    StandardGetFile(nil, -1, nil, &myReply);
    if (!myReply.sfGood)
        return;
    launchApp = myReply.sfFile;
    /* stuff it in my launch parameter block */
    launchThis.launchAppSpec = &launchApp;
    
    /* get the file to pass */
    StandardGetFile(nil, -1, nil, &myReply);
    if (!myReply.sfGood)
        return;
    
    /* the caller may have already done this, but it doesn't hurt to do it again */
    fileToLaunch = myReply.sfFile;
    /* create an appleevent to carry it */
    AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &myAddress, kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
    /* create a list for the alaises.  In this case, I only have one, but you still need */
    /* a list */
    AECreateList(nil, 0, false, &theList);
    /* create an alias out of the file spec */
    /* I'm not real sure why I did this, since there is a system coercion handler for */
    /* alias to FSSpec, but I'm paranoid */
    NewAlias(nil, &fileToLaunch, &withThis);
    HLock((Handle)withThis);
    /* now create an alias descriptor */
    AECreateDesc(typeAlias, (Ptr)*withThis, GetHandleSize((Handle)withThis), &docDesc);
 
    HUnlock((Handle)withThis);
    /* put it in the list */
    AEPutDesc(&theList, 0, &docDesc);
    AEPutParamDesc(&theEvent, keyDirectObject, &theList);
    /* coerce the event from being an event into being appParms */
    /* ¥¥¥¥ If you just want to send an 'odoc' to an application that is */
    /* already running, you can stop here and do an AESend on theEvent */
    AECoerceDesc(&theEvent, typeAppParameters, &launchDesc);
    HLock((Handle)theEvent.dataHandle);
    /* and stuff it in the parameter block */
    /* This is a little weird, since we're actually moving the event out of the */
    /* AppParameters descriptor.  But it's necessary, the coercison to typeAppParameters */
    /* stuffs the whole appleevent into one AERecord (instead of a AEDesc) so  */
    /* the Finder gets the whole event as one handle.  It can then parse it itself */
    /* to do the sending */
    launchThis.launchAppParameters = (AppParametersPtr)*(launchDesc.dataHandle);
    /* launch the thing */
    launchThis.launchBlockID = extendedBlock;
    launchThis.launchEPBLength = extendedBlockLen;
    launchThis.launchFileFlags = nil;
    launchThis.launchControlFlags = launchContinue + launchNoFileFlags;
    LaunchApplication(&launchThis);
    /* and launch it */
    
    
}