From: mxmora@unix.sri.com (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.