From: [email protected] (Matthew Xavier Mora)
Subject: OpenSelection Code (pascal source)
Date: 11 Sep 92 17:11:08 GMT


Here's the code to have the finder open a control panel.
Just pass the control panel's fsspec to the openselection
function and it should open it. Actually I think it will
open any valid fsspec but I wouldn't bet on it. I haven't
stressed this code so there are probably some bugs in it.

Matt

--------------------------------------------
{ OpenSelection.p ported by Matthew Xavier Mora}
{ ported from C.K. Han's openselection.c code  }
{ 09-11-92                                     }

unit openSelection;
interface
 uses
   AppleTalk, PPCToolBox, Processes, EPPC, Notification, AppleEvents,
   {, Errors, Events, Memory, Resources, SegLoad, }

   (* Group 3 *)
   Aliases {, thermometer};

 function OpenSelection (var theFileToOpen: FSSpec): OSErr;

implementation
 const
   kFinderType = 'FNDR';
   kSysCreator = 'MACS';
   kAEOpenSelection = 'sope';
   aeSelectionKeyword = 'fsel';

{ This runs through the process list looking for the indicated application
}
 function FindAProcess (typeToFind, creatorToFind: Ostype;
                        var processSN:ProcessSerialNumber;
                        var infoRecToFill: ProcessInfoRec): OSErr;
   var
     tempPSN: ProcessSerialNumber;
     myErr: OSErr;

 begin
   myErr := noErr;
   tempPSN.lowLongOfPSN := kNoProcess;
   processSN.lowLongOfPSN := kNoProcess;
   processSN.highLongOfPSN := kNoProcess;
   repeat
     begin
       myErr := GetNextProcess(processSN);
       if (myErr = noErr) then
         myErr := GetProcessInformation(processSN, infoRecToFill);
     end;
   until ((infoRecToFill.processSignature = creatorToFind) or
  (infoRecToFill.processType = Longint(typeToFind)) or (myErr <> noErr));

   FindAProcess := myErr;
 end;

 function OpenSelection (var theFileToOpen: FSSpec): OSErr;
   var
     aeEvent, aeReply: AppleEvent;
     aeDirDesc, listElem: AEDesc;
     interactErr: OSErr;
     dirSpec, procSpec: FSSpec;
     fileList: AEDesc;
     myReply: StandardFileReply;
     myErr: OSErr;
     process: ProcessSerialNumber;
     DirAlias, FileAlias: AliasHandle;
     infoRec: ProcessInfoRec;
     processName: Str31;
     fullPath, appName: Str255;
     myAddressDesc: AEDesc;
 begin
   interactErr := noErr;

   if (true) then
     begin
       infoRec.processInfoLength := sizeof(ProcessInfoRec);
       infoRec.processName := @processName;
       infoRec.processAppSpec := @procSpec;

       myErr := FindAProcess(kFinderType, kSysCreator, process, infoRec);
       if (myErr = noErr) then
         myErr := AECreateDesc(typeProcessSerialNumber, @process,
                               sizeof(process), myAddressDesc);


       if (myErr = noErr) then
         begin

           { Create the FinderEvent }
           myErr := AECreateAppleEvent(kFinderType, kAEOpenSelection,
                                       myAddressDesc,
kAutoGenerateReturnID,
                                       kAnyTransactionID, aeEvent);
           { If you want to keep talking to this machine, you can keep
this  }
           { address desc around }
           myErr := AEDisposeDesc(myAddressDesc);

           if (myErr = noErr) then
             begin
               { Now we build all the bits of an OpenSelection event. }
               { Basically, we need to create an alias for the item to
open,}
               { and an alias to the parent }
               { folder (directory) of that item. }
               { We can also pass a list of files if we want.  }
               { You'll notice that for opening a finder window, the file
and}
               { directory alias both point at the }
               { folder itself }
               { make a spec for the parent folder }


               myErr := FSMakeFSSpec(theFileToOpen.vRefNum,
                                     theFileToOpen.parID, '', dirSpec);
               myErr := NewAlias(nil, dirSpec, DirAlias);

               { Create alias for file }
               { if you are opening a window, then you make the file alias
the}
               { same as the dir alias }
               myErr := NewAlias(nil, theFileToOpen, FileAlias);
               interactErr := AEInteractWithUser(kAEDefaultTimeout, nil,
nil);
               if (interactErr = noErr) then
                 myErr := SetFrontProcess(process);

               { Create the file  list }
               if (myErr = noErr) then
                 begin
                   myErr := AECreateList(nil, 0, false, fileList);

                   {  create the folder  descriptor }
                   HLock(Handle(DirAlias));
                   myErr := AECreateDesc(typeAlias, Ptr(DirAlias^),
                                         GetHandleSize(Handle(DirAlias)),
                                         aeDirDesc);
                   HUnlock(Handle(DirAlias));
                   myErr := AEPutParamDesc(aeEvent, keyDirectObject,
                                           aeDirDesc);
                   if (myErr = noErr) then
                     begin
                       { done with the desc, kill it }
                       myErr := AEDisposeDesc(aeDirDesc);
                       {  create the file descriptor and add to aliasList
}
                       HLock(Handle(FileAlias));
                       myErr := AECreateDesc(typeAlias, Ptr(FileAlias^),

GetHandleSize(Handle(FileAlias)),
                                             listElem);
                       HLock(Handle(FileAlias));
                       myErr := AEPutDesc(fileList, 0, listElem);
                     end;
                   if (myErr = noErr) then
                     begin

                       myErr := AEDisposeDesc(listElem);

                       { Add the file alias list to the event }
                       myErr := AEPutParamDesc(aeEvent,
aeSelectionKeyword,
                                               fileList);
                       myErr := AEDisposeDesc(fileList);

                       if (myErr = noErr) then
                         myErr := AESend(aeEvent, aeReply,
                                         kAENoReply + kAEAlwaysInteract +
                                         kAECanSwitchLayer,
                                         kAENormalPriority,
kAEDefaultTimeout,
                                         nil, nil);
                     end;
                 end;
               myErr := AEDisposeDesc(aeEvent);
             end;
         end;
     end;
   if (DirAlias <> nil) then
     DisposHandle(Handle(DirAlias));
   if (FileAlias <> nil) then
     DisposHandle(Handle(FileAlias));
   OpenSelection := myErr;
 end;

end.