home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / PRG / AESample.sit / AESample / sources / sample.send.c < prev    next >
Text File  |  1996-06-22  |  25KB  |  838 lines

  1. /*
  2.  *--------------------------------------------------------------
  3.  * sample.send.c
  4.  *--------------------------------------------------------------
  5.  */
  6. #include <Processes.h>
  7. #include <PPCToolBox.h>
  8. #include <Strings.h>
  9.  
  10. #include <AppleEvents.h>
  11. #include <AERegistry.h>
  12.  
  13. #include "sample.h"
  14. #include "sample.AE.h"
  15. #include "sample.subs.h"
  16. #include "sample.send.h"
  17. #include "sample.dlog.h"
  18. #include "sample.alrt.h"
  19.  
  20. /*
  21.  *--------------------------------------------------------------
  22.  * constant definitions
  23.  *--------------------------------------------------------------
  24.  */
  25. /* abbreviations */
  26. #define    PSN        ProcessSerialNumber
  27. #define    PSNPtr    ProcessSerialNumberPtr
  28.  
  29. /* resources IDs and indexes */
  30. enum constPromptStrIDs {
  31.     strPromotID    = 130,
  32.     strPPCindex    = 1
  33. };
  34.  
  35. /* Finder Types */
  36. enum FinderTypes {
  37.     kFinderSig    = 'MACS',
  38.     kAEFinder    = 'FNDR',
  39.     kSystemType    = 'FNDR'
  40. };
  41.  
  42. /*
  43.  *--------------------------------------------------------------
  44.  * file filter callback procedure
  45.  *--------------------------------------------------------------
  46.  */
  47. pascal Boolean MyCustomFileFilter(ParmBlkPtr);
  48.  
  49. /*
  50.  *--------------------------------------------------------------
  51.  * static function prototypes
  52.  *--------------------------------------------------------------
  53.  */
  54. static Boolean DoGetFileDialog(FSSpecPtr);
  55. static OSErr GetOriginalFromAlias(FSSpecPtr);
  56. static OSErr OpenAnyFileUsingAE(const FSSpecPtr);
  57. static OSErr JustLaunchAnApp(const FSSpecPtr);
  58. static OSErr LaunchAppWithDoc(const FSSpecPtr app, const FSSpecPtr doc);
  59. static OSErr LaunchAppWithAEDesc(const FSSpecPtr, AEDescList *);
  60. static OSErr SendMyAppleEvent(AEAddressDesc *, AEDescList *, const AEEventID);
  61. static OSErr MakeMyDocDescList(const FSSpecPtr, AEDescList *);
  62. static OSErr FindAppFromItsSig(const OSType, FSSpecPtr);
  63. static OSErr FindAProcess(const OSType, const OSType, ProcessSerialNumberPtr, FSSpecPtr);
  64. static OSErr FindAProcessByFSS(ProcessSerialNumberPtr, const FSSpecPtr);
  65. static Boolean FindSameProcess(ProcessSerialNumberPtr);
  66. static Boolean EqualFSSpec(FSSpecPtr, FSSpecPtr);
  67.  
  68. /*
  69.  *--------------------------------------------------------------
  70.  * global FSSpec for sending document
  71.  *--------------------------------------------------------------
  72.  */
  73. FSSpec    gDocSpec;
  74.  
  75. /*
  76.  *--------------------------------------------------------------
  77.  * DoOpenFile
  78.  *--------------------------------------------------------------
  79.  *    handle file open dialog
  80.  *--------------------------------------------------------------
  81.  */
  82. void DoOpenFile(void)
  83. {
  84.     FSSpec    myFSpec;
  85.  
  86.     /* */
  87.     if (DoGetFileDialog(&myFSpec)) {
  88.         /* send an OpenDocument AppleEvent to myself */
  89.         SendSpecToMyself(&myFSpec, kAEOpenDocuments);
  90.     }
  91. }
  92. /*
  93.  *--------------------------------------------------------------
  94.  * DoPrintFile
  95.  *--------------------------------------------------------------
  96.  *    handle print menu; open dialog -> send print event
  97.  *--------------------------------------------------------------
  98.  */
  99. void DoPrintFile(void)
  100. {
  101.     FSSpec    myFSpec;
  102.  
  103.     if (DoGetFileDialog(&myFSpec)) {
  104.         SendAEToFinder(&myFSpec, kAEPrintSelection);
  105.     }
  106. }
  107. /*
  108.  *--------------------------------------------------------------
  109.  * DoHoldFile
  110.  *--------------------------------------------------------------
  111.  *    handle send menu; open dialog -> hold a document
  112.  *--------------------------------------------------------------
  113.  */
  114. void DoHoldFile(void)
  115. {
  116.     FSSpec    aFileSpec;
  117.  
  118.     if (DoGetFileDialog(&aFileSpec)) {
  119.         OpenMyViewDialog(&aFileSpec);
  120.     }
  121. }
  122. /*
  123.  *--------------------------------------------------------------
  124.  * DoSendFile
  125.  *--------------------------------------------------------------
  126.  *    handle send menu; open dialog -> send a document to target
  127.  *    using PPCBrowser
  128.  *--------------------------------------------------------------
  129.  */
  130. void DoSendFile(void)
  131. {
  132.     AEAddressDesc    targetAddress = { typeNull, nil };
  133.     AEDescList        myDocDescList = { typeNull, nil };
  134.     TargetID        myTargetID;
  135.     PortInfoRec        myPortInfo;
  136.     Str255            prompt;
  137.     OSErr            result;
  138.     
  139.     if (gDocSpec.name[0] != 0) {
  140.         GetIndString(prompt, strPromotID, strPPCindex);
  141.         BlockMoveData(&gDocSpec.name[1], &prompt[prompt[0] +1], gDocSpec.name[0]);
  142.         prompt[0] += gDocSpec.name[0];
  143.  
  144.         result = PPCBrowser(prompt, nil, false, &myTargetID.location, &myPortInfo, nil, nil);
  145.         if (result == noErr) {
  146.             myTargetID.name = myPortInfo.name;
  147.             result = AECreateDesc(typeTargetID, &myTargetID, sizeof(TargetID), &targetAddress);
  148.         }
  149.         if (result == noErr) {
  150.             result = MakeMyDocDescList(&gDocSpec, &myDocDescList);
  151.         }
  152.         if (result == noErr) {
  153.             result = SendMyAppleEvent(&targetAddress, &myDocDescList, kAEOpenDocuments);
  154.         }
  155.         AEDisposeDesc(&targetAddress);
  156.         AEDisposeDesc(&myDocDescList);
  157.     }
  158. }
  159. /*
  160.  *--------------------------------------------------------------
  161.  * DoGetFileDialog
  162.  *--------------------------------------------------------------
  163.  *    handle file open dialog
  164.  *--------------------------------------------------------------
  165.  */
  166. static Boolean DoGetFileDialog(FSSpecPtr gotSpec)
  167. {
  168.     FileFilterUPP        MyFileFilterUPP;
  169.     StandardFileReply    myReply;
  170.     SFTypeList            myTypes;
  171.  
  172.     myReply.sfGood = false;
  173.  
  174.     /* install custom file filter */
  175.     MyFileFilterUPP = NewFileFilterProc(MyCustomFileFilter);
  176.     if (MyFileFilterUPP != nil) {
  177.  
  178.         /* call file select dialog */
  179.         StandardGetFile(MyFileFilterUPP, -1, myTypes, &myReply);
  180.         DisposeRoutineDescriptor(MyFileFilterUPP);
  181.  
  182.         if (myReply.sfGood) {
  183.             *gotSpec = myReply.sfFile;
  184.         }
  185.     }
  186.     return (myReply.sfGood);
  187. }
  188. /*
  189.  *--------------------------------------------------------------
  190.  * MyCustomFileFilter
  191.  *--------------------------------------------------------------
  192.  *    it hides invisible file in Select File Dialog
  193.  *--------------------------------------------------------------
  194.  */
  195. pascal Boolean MyCustomFileFilter(ParmBlkPtr thePB)
  196. {
  197.     if (((FileParam *)thePB)->ioFlFndrInfo.fdFlags & fInvisible) {
  198.         return (true);
  199.     }
  200.     return (false);
  201. }
  202. /*
  203.  *--------------------------------------------------------------
  204.  * OpenDroppedFile
  205.  *--------------------------------------------------------------
  206.  *    handle the given file
  207.  *--------------------------------------------------------------
  208.  */
  209. OSErr OpenDroppedFile(const FSSpecPtr theSpec)
  210. {
  211.     FSSpec    myFSpec;
  212.     OSErr    result;
  213.  
  214.     myFSpec = *theSpec;
  215.     result = GetOriginalFromAlias(&myFSpec);
  216.     if (result == noErr) {
  217.         result = OpenAnyFileUsingAE(&myFSpec);
  218.     }
  219.     return (result);
  220. }
  221. /*
  222.  *--------------------------------------------------------------
  223.  * PrintDroppedFile
  224.  *--------------------------------------------------------------
  225.  *    handle the given file
  226.  *--------------------------------------------------------------
  227.  */
  228. OSErr PrintDroppedFile(const FSSpecPtr theSpec)
  229. {
  230.     FSSpec    myFSpec;
  231.     OSErr    result;
  232.  
  233.     myFSpec = *theSpec;
  234.     result = GetOriginalFromAlias(&myFSpec);
  235.     if (result == noErr) {
  236.         result = SendAEToFinder(&myFSpec, kAEPrintSelection);
  237.     }
  238.     return (result);
  239. }
  240. /*
  241.  *--------------------------------------------------------------
  242.  * GetOriginalFromAlias
  243.  *--------------------------------------------------------------
  244.  *    check if its an alias file and get original file spec
  245.  *--------------------------------------------------------------
  246.  */
  247. static OSErr GetOriginalFromAlias(FSSpecPtr theSpec)
  248. {
  249.     OSErr    result;
  250.     Boolean    isFolder, wasAlias;
  251.  
  252.     result = ResolveAliasFile(theSpec, true, &isFolder, &wasAlias);
  253.     if (result != noErr) {
  254.         DoAliasAlert(theSpec->name, result);
  255.     }
  256.     return (result);
  257. }
  258. /*
  259.  *--------------------------------------------------------------
  260.  * OpenAnyFileUsingAE
  261.  *--------------------------------------------------------------
  262.  *    launch document using AppleEvent
  263.  *    it checks whether the FSSpec is an application
  264.  *    if so, it just launches it
  265.  *    if not, it attempts to find the application of the document
  266.  *    and launches it using LaunchApplication() with AEDesc
  267.  *--------------------------------------------------------------
  268.  */
  269. static OSErr OpenAnyFileUsingAE(const FSSpecPtr theSpec)
  270. {
  271.     ProcessSerialNumber    itsPSN;
  272.     FInfo        itsInfo;
  273.     FSSpec        appSpec, docSpec;
  274.     OSErr        result;
  275.  
  276.     /* copy FSSpec */
  277.     appSpec = docSpec = *theSpec;
  278.  
  279.     /* get info of the FSSpec */
  280.     result = FSpGetFInfo(&docSpec, &itsInfo);
  281.     if (result != noErr) {
  282.         DoFileAlert(docSpec.name, result);
  283.         return (result);
  284.     }
  285.     /* check if the passed file is an application */
  286.     if (itsInfo.fdType == 'APPL') {
  287.         /* launch the application */
  288.         result = JustLaunchAnApp(&appSpec);
  289.     } else {
  290.         result = FindAProcess('APPL', itsInfo.fdCreator, &itsPSN, &appSpec);
  291.         if (result == noErr) {
  292.             /* the process is already running */
  293.             result = SendAEToApp(&itsPSN, &docSpec, kAEOpenDocuments);
  294.         } else {
  295.             /* find the application of the document and launch it */
  296.             result = FindAppFromItsSig(itsInfo.fdCreator, &appSpec);
  297.             if (result == noErr) {
  298.                 /* if the document belongs to an application */
  299.                 result = LaunchAppWithDoc(&appSpec, &docSpec);
  300.             } else {
  301.                 /* if the document may be a DA or a control panel */
  302.                 result = SendAEToFinder(theSpec, kAEOpenSelection);
  303.             }
  304.         }
  305.     }
  306.     return (result);
  307. }
  308. /*
  309.  *--------------------------------------------------------------
  310.  * JustLaunchAnApp
  311.  *--------------------------------------------------------------
  312.  *    simply launch application using LaunchApplication
  313.  *--------------------------------------------------------------
  314.  */
  315. static OSErr JustLaunchAnApp(const FSSpecPtr theAppSpec)
  316. {
  317.     LaunchParamBlockRec    launchPrm;
  318.     OSErr        result;
  319.  
  320.     launchPrm.launchBlockID   = extendedBlock;
  321.     launchPrm.launchEPBLength = extendedBlockLen;
  322.     launchPrm.launchFileFlags = launchNoFileFlags;
  323.     launchPrm.launchAppSpec   = theAppSpec;
  324.     launchPrm.launchControlFlags = launchContinue + launchNoFileFlags;
  325.     launchPrm.launchAppParameters = nil;
  326.  
  327.     result = LaunchApplication(&launchPrm);    
  328.     return (result);
  329. }
  330. /*
  331.  *--------------------------------------------------------------
  332.  * LaunchAppWithDoc
  333.  *--------------------------------------------------------------
  334.  *    launch application with 'odoc' AppleEvent
  335.  *--------------------------------------------------------------
  336.  */
  337. static OSErr LaunchAppWithDoc(const FSSpecPtr theAppSpec, const FSSpecPtr theDocSpec)
  338. {
  339.     AEDescList    itsDocList = { typeNull, nil };
  340.     OSErr    result;
  341.  
  342.     result = MakeMyDocDescList(theDocSpec, &itsDocList);
  343.     if (result == noErr) {
  344.         result = LaunchAppWithAEDesc(theAppSpec, &itsDocList);
  345.     }
  346.     AEDisposeDesc(&itsDocList);
  347.     return (result);
  348. }
  349. /*
  350.  *--------------------------------------------------------------
  351.  * SendAEToApp
  352.  *--------------------------------------------------------------
  353.  *    send Open Document AppleEvent to the designated application
  354.  *--------------------------------------------------------------
  355.  */
  356. static OSErr SendAEToApp(
  357.     ProcessSerialNumberPtr    thePSN,
  358.     const FSSpecPtr    theDocSpec,
  359.     const AEEventID    theEventID)
  360. {
  361.     AEAddressDesc    targetAddress    = { typeNull, nil };
  362.     AEDescList        myDocDescList    = { typeNull, nil };
  363.     OSErr            result;
  364.  
  365.     /* create a descriptor of the application with its ProcessSerialNumber */
  366.     result = AECreateDesc(typeProcessSerialNumber, thePSN,
  367.             sizeof(ProcessSerialNumber), &targetAddress);
  368.  
  369.     /* create a descriptor list of the document */
  370.     if (result == noErr) {
  371.         result = MakeMyDocDescList(theDocSpec, &myDocDescList);
  372.     }
  373.  
  374.     /* send an AppleEvent to the application along with the documet list */
  375.     if (result == noErr) {
  376.         result = SendMyAppleEvent(&targetAddress, &myDocDescList, theEventID);
  377.     }
  378.     /* cleanup */
  379.     AEDisposeDesc(&targetAddress);
  380.     AEDisposeDesc(&myDocDescList);
  381.     return (result);
  382. }
  383. /*
  384.  *--------------------------------------------------------------
  385.  * SendSpecToMyself
  386.  *--------------------------------------------------------------
  387.  *    This is called from Drag and Drop recieve handler.
  388.  *    Note that Drag Manager does not allow process switching.
  389.  *    If we want to interract with user or Finder within the Receive
  390.  *    Handlers, we will meet a fatal lock up.
  391.  *    To avoid such trouble, we have to send the got file spec to
  392.  *    myself via AppleEvent
  393.  *--------------------------------------------------------------
  394.  */
  395. OSErr SendSpecToMyself(const FSSpecPtr theDocSpec, const AEEventID theEventID)
  396. {
  397.     ProcessSerialNumber    myPSN;
  398.     OSErr    result;
  399.  
  400.     /* get my process serial number */
  401.     result = GetCurrentProcess(&myPSN);
  402.     if (result == noErr) {
  403.         result = SendAEToApp(&myPSN, theDocSpec, theEventID);
  404.     }
  405.     return (result);
  406. }
  407. /*
  408.  *--------------------------------------------------------------
  409.  * SendAEToFinder
  410.  *--------------------------------------------------------------
  411.  *    launch designated file using AppleEvent
  412.  *--------------------------------------------------------------
  413.  */
  414. OSErr SendAEToFinder(const FSSpecPtr theSpec, const AEEventID sentAEKind)
  415. {
  416.     AppleEvent        myAppleEvent    = { typeNull, nil };
  417.     AEAddressDesc    findersAddress    = { typeNull, nil };
  418.     AEDesc            myDirDesc    = { typeNull, nil };
  419.     AEDesc            listElement    = { typeNull, nil };
  420.     AEDesc            fileList    = { typeNull, nil };
  421.     FSSpec            appSpec;
  422.     FSSpec            dirSpec;
  423.     AliasHandle        docAlias;
  424.     AliasHandle        dirAlias;
  425.     ProcessSerialNumber    findersPSN;
  426.     Size        itsSize;
  427.     OSErr        result;
  428.  
  429.     /* check if Finder is running */
  430.     if (FindAProcess(kSystemType, kFinderSig, &findersPSN, &appSpec) != noErr)
  431.         return (procNotFound);
  432.  
  433.     /* create a target address of Finder */
  434.     itsSize = sizeof(ProcessSerialNumber);
  435.     result = AECreateDesc(typeProcessSerialNumber, &findersPSN,
  436.         itsSize, &findersAddress);
  437.  
  438.     /* create an AppleEvent record to be sent to Finder */
  439.     if (result == noErr) {
  440.         result = AECreateAppleEvent(kAEFinder, sentAEKind, &findersAddress,
  441.             kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
  442.     }
  443.  
  444.     /* create alias records of the target document and its folder */
  445.     if (result == noErr) {
  446.         FSMakeFSSpec(theSpec->vRefNum, theSpec->parID, nil, &dirSpec);
  447.         NewAlias(nil, &dirSpec, &dirAlias);
  448.         NewAlias(nil, theSpec,  &docAlias);
  449.         result = AECreateList(nil, 0, false, &fileList);
  450.     }
  451.  
  452.     /* create a descriptor of the target folder */
  453.     if (result == noErr) {
  454.         HLock((Handle)dirAlias);
  455.         itsSize = GetHandleSize((Handle)dirAlias);
  456.         result = AECreateDesc(typeAlias, *dirAlias, itsSize, &myDirDesc);
  457.         DisposeHandle((Handle)dirAlias);
  458.     }
  459.  
  460.     /* put the folder descriptor into the AppleEvent */
  461.     if (result == noErr) {
  462.         result = AEPutParamDesc(&myAppleEvent, keyDirectObject, &myDirDesc);
  463.         AEDisposeDesc(&myDirDesc);
  464.     }
  465.  
  466.     /* create a descriptor of the target document */
  467.     if (result == noErr) {
  468.         HLock((Handle)docAlias);
  469.         itsSize = GetHandleSize((Handle)docAlias);
  470.         result = AECreateDesc(typeAlias, *docAlias, itsSize, &listElement);
  471.         DisposeHandle((Handle)docAlias);
  472.     }
  473.  
  474.     /* put the document descriptor into the file list */
  475.     if (result == noErr) {
  476.         result = AEPutDesc(&fileList, 0, &listElement);
  477.         AEDisposeDesc(&listElement);
  478.     }
  479.  
  480.     /* put the file list into the AppleEvent */
  481.     if (result == noErr) {
  482.         result = AEPutParamDesc(&myAppleEvent, keySelection, &fileList);
  483.         AEDisposeDesc(&fileList);
  484.     }
  485.  
  486.     /* at last, send the AppleEvent containing the document list */
  487.     if (result == noErr) {
  488.         result = AESend(&myAppleEvent, nil,
  489.             kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer,
  490.             kAENormalPriority, kAEDefaultTimeout, nil, nil);
  491.     }
  492.  
  493.     /* clean up memory */
  494.     AEDisposeDesc(&findersAddress);
  495.     AEDisposeDesc(&myAppleEvent);
  496.  
  497.     /* if error occurred, show an alert */
  498.     if (result != noErr) DoAEError(result, sentAEKind);
  499.     return (result);
  500. }
  501. /* 
  502.  *--------------------------------------------------------------
  503.  * LaunchAppWithAEDesc
  504.  *--------------------------------------------------------------
  505.  *    Launch specified application with doc list
  506.  *    FSSpec should be the application spec and 
  507.  *    AEDescList should be the document descriptor
  508.  *--------------------------------------------------------------
  509.  */
  510. static OSErr LaunchAppWithAEDesc(const FSSpecPtr theAppSpec, AEDescList *theDocDesc)
  511. {
  512.     LaunchParamBlockRec    launchPrm;
  513.     ProcessSerialNumber    myPSN;
  514.     AppleEvent            myAppleEvent    = { typeNull, nil };
  515.     AEDesc                targetDesc    = { typeNull, nil };
  516.     AEDesc                launchDesc    = { typeNull, nil };
  517.     OSErr                result;
  518.  
  519.     /* get the ProcessSerialNumber of myself */
  520.     result = GetCurrentProcess(&myPSN);
  521.  
  522.     /* create an address descriptor of myself */
  523.     if (result == noErr) {
  524.         result = AECreateDesc(typeProcessSerialNumber, (Ptr)&myPSN,
  525.             sizeof(ProcessSerialNumber), &targetDesc);
  526.     }
  527.  
  528.     /* create an AppleEvent record to be sent */
  529.     if (result == noErr) {
  530.         result = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &targetDesc,
  531.             kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
  532.  
  533.         AEDisposeDesc(&targetDesc);
  534.     }
  535.  
  536.     /* put the document list into the AppleEvent */
  537.     if (result == noErr) {
  538.         result = AEPutParamDesc(&myAppleEvent, keyDirectObject, theDocDesc);
  539.     }
  540.  
  541.     /* coerce (convert) the AppleEvent into launching descriptor */
  542.     if (result == noErr) {
  543.         result = AECoerceDesc(&myAppleEvent, typeAppParameters, &launchDesc);
  544.  
  545.         AEDisposeDesc(&myAppleEvent);
  546.     }
  547.  
  548.     /* set the launch parameters */
  549.     if (result == noErr) {
  550.         HLock(launchDesc.dataHandle);
  551.  
  552.         launchPrm.launchBlockID   = extendedBlock;
  553.         launchPrm.launchEPBLength = extendedBlockLen;
  554.         launchPrm.launchFileFlags = launchNoFileFlags;
  555.         launchPrm.launchAppSpec   = theAppSpec;
  556.         launchPrm.launchControlFlags = launchContinue;
  557.         launchPrm.launchAppParameters = (AppParametersPtr)(*launchDesc.dataHandle);
  558.  
  559.         /* now launch it! */
  560.         result = LaunchApplication(&launchPrm);    
  561.  
  562.         /* cleanup */
  563.         HUnlock(launchDesc.dataHandle);
  564.         AEDisposeDesc(&launchDesc);
  565.     }
  566.     return (result);
  567. }
  568. /* 
  569.  *--------------------------------------------------------------
  570.  * SendMyAppleEvent
  571.  *--------------------------------------------------------------
  572.  *    send AppleEvent with the target application's address and
  573.  *    the descriptor of the file
  574.  *--------------------------------------------------------------
  575.  */
  576. static OSErr SendMyAppleEvent(
  577.     AEAddressDesc    *theTargetAddress,
  578.     AEDescList        *theDocDescList,
  579.     const AEEventID    theAEKind)
  580. {
  581.     AppleEvent    myAppleEvent = { typeNull, nil };
  582.     OSErr        result;
  583.     
  584.     /* create an AppleEvent record to be sent */
  585.     result = AECreateAppleEvent(kCoreEventClass, theAEKind, theTargetAddress,
  586.                 kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
  587.  
  588.     /* put the document list into the AppleEvent */
  589.     if (result == noErr) {
  590.         result = AEPutParamDesc(&myAppleEvent, keyDirectObject, theDocDescList);
  591.     }
  592.     /* now send the AppleEvent */
  593.     if (result == noErr) {
  594.         AppleEvent    nilReply = { typeNull, nil };
  595.  
  596.         result = AESend(&myAppleEvent, &nilReply,
  597.                     kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer,
  598.                     kAENormalPriority, kAEDefaultTimeout, nil, nil);
  599.     }
  600.     /* cleanup */
  601.     AEDisposeDesc(&myAppleEvent);
  602.     if (result != noErr) {
  603.         DoAEError(result, theAEKind);
  604.     }
  605.     return (result);
  606. }
  607. /* 
  608.  *--------------------------------------------------------------
  609.  * MakeMyDocDescList
  610.  *--------------------------------------------------------------
  611.  *    make AEDescList from FSSpec; its content is just one FSSpec
  612.  *--------------------------------------------------------------
  613.  */
  614. static OSErr MakeMyDocDescList(const FSSpecPtr theSpec, AEDescList *theList)
  615. {
  616.     AEDesc         itsDocDesc    = { typeNull, nil };
  617.     AliasHandle    itsAlias;
  618.     Size        itsSize;
  619.     OSErr         result = noErr;
  620.  
  621.     /* create a new document list */
  622.     result = AECreateList(nil, 0, false, theList);    /* new description */
  623.  
  624.     /* create an alias record of the document */
  625.     if (result == noErr) {
  626.         result = NewAlias(nil, theSpec, &itsAlias);
  627.     }
  628.     if (result == noErr) {
  629.         HLock((Handle)itsAlias);
  630.         itsSize = GetHandleSize((Handle)itsAlias);
  631.  
  632.         /* create a descriptor of the document alias */
  633.         result = AECreateDesc(typeAlias, (Ptr)*itsAlias, itsSize, &itsDocDesc);
  634.  
  635.         /* put the alias descriptor into the document list */
  636.         if (result == noErr) {
  637.             result = AEPutDesc(theList, 0, &itsDocDesc);
  638.         }
  639.         /* dispose the alias descriptor and the alias record */
  640.         AEDisposeDesc(&itsDocDesc);
  641.         DisposeHandle((Handle)itsAlias);
  642.     }
  643.     return (result);
  644. }
  645. /*--------------------------------------------------------------
  646.  * FindAppFromItsSig
  647.  *--------------------------------------------------------------
  648.  *    find a process from the application's signature
  649.  *--------------------------------------------------------------
  650.  */
  651. static OSErr FindAppFromItsSig(const OSType theSig, FSSpecPtr theSpec)
  652. {
  653.     DTPBRec            aDTPBRec;
  654.     DTPBPtr            aDBP;
  655.     VolumeParam        *aVLP;
  656.     HFileParam        *aFIP;
  657.     Str63    itsName;
  658.     short    volIndex;
  659.     OSErr    result;
  660.  
  661.     /* substitute pointers */
  662.     aDBP = &aDTPBRec;
  663.     aVLP = (VolumeParam *)aDBP;
  664.     aFIP = (HFileParam    *)aDBP;
  665.  
  666.     /* search the application */
  667.     volIndex = 0;
  668.     do {
  669.         /* get a volume info */
  670.         itsName[0] = 0;
  671.         aVLP->ioCompletion = nil;
  672.         aVLP->ioVolIndex = ++volIndex;
  673.         aVLP->ioNamePtr = itsName;
  674.         result = PBGetVInfoSync((ParmBlkPtr)aVLP);
  675.  
  676.         /* get a desktop file path */
  677.         if (result == noErr) {
  678.             result = PBDTGetPath(aDBP);
  679.         }
  680.  
  681.         /* get an application info of the volume */
  682.         if (result == noErr) {
  683.             itsName[0] = 0;
  684.             aDBP->ioNamePtr = itsName;
  685.             aDBP->ioIndex = 0;
  686.             aDBP->ioFileCreator = theSig;
  687.             result = PBDTGetAPPLSync(aDBP);
  688.         }
  689.  
  690.         /* confirm the result */
  691.         if (result == noErr) {
  692.             /* once copy answers */
  693.             theSpec->vRefNum = aDBP->ioVRefNum;
  694.             theSpec->parID = aDBP->ioAPPLParID;
  695.             BlockMoveData(itsName, theSpec->name, *itsName +1);
  696.  
  697.             aFIP->ioFVersNum = 0;
  698.             aFIP->ioFDirIndex = 0;
  699.             aFIP->ioVRefNum    = theSpec->vRefNum;
  700.             aFIP->ioDirID     = theSpec->parID;
  701.             result = PBHGetFInfoSync((HParmBlkPtr)aFIP);
  702.         }
  703.         if (result == noErr) {
  704.             if (aFIP->ioFlFndrInfo.fdType != 'APPL') {
  705.                 result = afpItemNotFound;
  706.             }
  707.         }
  708.         if (result == noErr) {
  709.             return (noErr);
  710.         }
  711.     } while (result != nsvErr);    /* until no such volume */
  712.     return (result);
  713. }
  714. /*
  715.  *--------------------------------------------------------------
  716.  * FindAProcess
  717.  *--------------------------------------------------------------
  718.  *    returns its ProcessSerialNumber and file spec of the process
  719.  *--------------------------------------------------------------
  720.  */
  721. static OSErr FindAProcess(
  722.     const OSType theType,
  723.     const OSType theCreator,
  724.     ProcessSerialNumberPtr thePSN,
  725.     FSSpecPtr theSpec)
  726. {
  727.     ProcessInfoRec    itsInfo;
  728.     Str31    itsName;
  729.     short    found;
  730.     OSErr    result;
  731.  
  732.     /* initialize the ProcessSerialNumber */
  733.     thePSN->lowLongOfPSN  = kNoProcess;
  734.     thePSN->highLongOfPSN = kNoProcess;
  735.  
  736.     itsInfo.processInfoLength = sizeof(ProcessInfoRec);
  737.     itsInfo.processName = itsName;
  738.     itsInfo.processAppSpec = theSpec;
  739.  
  740.     do {
  741.         /* search the processes */
  742.         result = GetNextProcess(thePSN);
  743.         if (result == noErr) {
  744.             result = GetProcessInformation(thePSN, &itsInfo);
  745.         }
  746.         /* compare the creators and the types */
  747.         if (result == noErr) {
  748.             found = (itsInfo.processSignature == theCreator
  749.                   && itsInfo.processType      == theType);
  750.         } else {
  751.             break;
  752.         }
  753.     } while (found == false);
  754.     return (result);
  755. }
  756. /*
  757.  *--------------------------------------------------------------
  758.  * FindAProcessByFSS
  759.  *--------------------------------------------------------------
  760.  *    Search process table by its FSSpec.
  761.  *    If the process has specified FSSpec,
  762.  *    fill appropriate contents in thePSN and return noErr,
  763.  *    else return procNotFound
  764.  *--------------------------------------------------------------
  765.  */
  766. static OSErr FindAProcessByFSS(
  767.     ProcessSerialNumberPtr thePSN,
  768.     const FSSpecPtr theSpec)
  769. {
  770.     ProcessSerialNumber thisPSN;
  771.     ProcessInfoRec        thisInfo;
  772.     FSSpec                thisSpec;
  773.     Str31                itsName;
  774.  
  775.     /* initialize the ProcessSerialNumber */
  776.     thePSN->lowLongOfPSN  = thisPSN.lowLongOfPSN  = kNoProcess;
  777.     thePSN->highLongOfPSN = thisPSN.highLongOfPSN = kNoProcess;
  778.  
  779.     /* search the processes */
  780.     while (GetNextProcess(&thisPSN) != procNotFound) {
  781.  
  782.         thisInfo.processInfoLength = sizeof(ProcessInfoRec);
  783.         thisInfo.processName       = itsName;
  784.         thisInfo.processAppSpec    = &thisSpec;
  785.         GetProcessInformation(&thisPSN, &thisInfo);
  786.  
  787.         /* compare the FSSpecs */
  788.         if (EqualFSSpec(thisInfo.processAppSpec, theSpec)) {
  789.             if (thePSN != nil) {
  790.                 thePSN->lowLongOfPSN  = thisPSN.lowLongOfPSN;
  791.                 thePSN->highLongOfPSN = thisPSN.highLongOfPSN;
  792.             }
  793.             return (noErr);
  794.         }
  795.     }
  796.     return (procNotFound);
  797. }
  798. /*
  799.  *--------------------------------------------------------------
  800.  * FindSameProcess
  801.  *--------------------------------------------------------------
  802.  *    search a process that has same ProcessSerialNumber
  803.  *--------------------------------------------------------------
  804.  */
  805. static Boolean FindSameProcess(ProcessSerialNumberPtr thePSNP)
  806. {
  807.     ProcessSerialNumber queryPSN;
  808.     OSErr        result;
  809.     Boolean        found;
  810.  
  811.     /* initialize the ProcessSerialNumber */
  812.     queryPSN.lowLongOfPSN  = kNoProcess;
  813.     queryPSN.highLongOfPSN = kNoProcess;
  814.     found = false;
  815.  
  816.     /* search the same ProcessSerialNumber */
  817.     while (GetNextProcess(&queryPSN) != procNotFound) {
  818.         result = SameProcess(thePSNP, &queryPSN, &found);
  819.         if (found || (result != noErr)) break;
  820.     }
  821.     return (found);
  822. }
  823. /*
  824.  *--------------------------------------------------------------
  825.  * EqualFSSpec
  826.  *--------------------------------------------------------------
  827.  *    compare two FSSpecs
  828.  *--------------------------------------------------------------
  829.  */
  830. static Boolean EqualFSSpec(FSSpecPtr f1, FSSpecPtr f2)
  831. {
  832.     return (
  833.         f1->vRefNum == f2->vRefNum
  834.      && f1->parID   == f2->parID
  835.      && EqualString(f1->name, f2->name, false, true)
  836.     );
  837. }
  838.