home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / HyperCard / GetFileXFCN / FileName.p next >
Text File  |  1987-11-01  |  6KB  |  210 lines

  1. Name:                “FileName” -- a HyperCard "XFCN" (External Function) resource
  2.  
  3. Written By: Steve Maller
  4.                         Apple Computer Training Support
  5.                         Copyright © 1987 Apple Computer
  6.                         AppleLink: MALLER1
  7.                         Saturday, August 22, 1987 
  8.  
  9. Language:        MPW Pascal
  10.  
  11. To build:        pascal FileName.p
  12.                         link -m ENTRYPOINT -rt XFCN=913 -sn Main=FileName ∂
  13.                             -t STAK -c WILD ∂
  14.                             FileName.p.o ∂
  15.                             hd:dev:mpw:libraries:Interface.o ∂
  16.                             hd:dev:mpw:PLibraries:Paslib.o ∂
  17.                             -o "hd:hyper:hypercard stacks:TestXFCN"
  18.  
  19. Usage:            FileName("fileType")    -- "fileType" is optional
  20.  
  21. Examples:        FileName("STAK")            -- limits list to HyperCard Stacks
  22.                         FileName("TEXT")            -- limits list to text files
  23.                         FileName("APPL")            -- limits list to applications
  24.                         FileName()                      -- lists ALL files
  25.  
  26. Result:            The full pathname of the selected file.
  27.                         For example, if you selected the file "Address Stack" which is
  28.                         in the folder "My Stacks" in the folder "HyperCard" on the
  29.                         disk "HD" the result is:
  30.                                     HD:HyperCard:My Stacks:Address Stack
  31.                         If the user clicks “Cancel” an empty string is returned.
  32.                         
  33. Warning:        A word of caution: the Mac's file system can NOT accept
  34.                         pathnames longer than 255 characters. Be careful...
  35.                         
  36. Script
  37. Example:        on mouseUp
  38.                             put FileName("TEXT") into theFile
  39.                             if theFile is not empty then
  40.                                 open file theFile
  41.                                 read from file theFile for 2000
  42.                                 put it into bkgnd field 1
  43.                                 close file theFile
  44.                             end if
  45.                         end mouseUp
  46.  
  47. Why?                You must access files in HyperCard by their full pathname.
  48.                         Unfortunately, HyperCard offers you no clear way of finding
  49.                         out what that full name is. If files are on a hard disk, it
  50.                         can be a real pain to remember the entire pathname. This
  51.                         function simplifies that task for both the stackware developer
  52.                         and the end user.
  53.  
  54. Thanks to:    Ted Kaehler, Dan Winkler, and Bill Atkinson - my hero!
  55.  
  56. }
  57.  
  58. {$S FileName }
  59.  
  60. UNIT Snoopy_Vs_TheRedBaron;        { obviously this is irrelevant }
  61.  
  62.     INTERFACE
  63.  
  64.         USES
  65.             {$LOAD HD:Hyper:XCMDs:PasSymDump}
  66.             MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf, HyperXCmd;
  67.  
  68.         PROCEDURE EntryPoint(paramPtr: XCmdPtr);
  69.  
  70.     IMPLEMENTATION
  71.  
  72.         TYPE
  73.             Str31 = String[31];
  74.  
  75.         PROCEDURE FileName(paramPtr: XCmdPtr);
  76.             FORWARD;
  77.  
  78.         PROCEDURE EntryPoint(paramPtr: XCmdPtr);
  79.  
  80.             BEGIN
  81.                 FileName(paramPtr);
  82.             END;
  83.  
  84.         PROCEDURE FileName(paramPtr: XCmdPtr);
  85.  
  86.             VAR
  87.                 myWDPB: WDPBPtr;                            { some variants of the same animal }
  88.                 myCPB: CInfoPBPtr;
  89.                 myPB: HParmBlkPtr;
  90.                 fullPathName: Str255;
  91.                 numTypes: Integer;
  92.                 reply: SFReply;
  93.                 typeList: SFTypeList;
  94.  
  95.                 {$I XCmdGlue.inc }
  96.  
  97.             FUNCTION TheyChoseAFile: Boolean;
  98.  
  99.                 VAR
  100.                     pt: Point;
  101.  
  102.                 BEGIN
  103.                     TheyChoseAFile := FALSE;
  104.                     pt.v := 60;
  105.                     pt.h := 82;
  106.                     SFGetFile(pt, '', NIL, numTypes, typeList, NIL, reply);
  107.                                                                                                 { have 'em pick a file }
  108.                     IF reply.good THEN                                         { if they didn't choose Cancel }
  109.                         BEGIN
  110.                             TheyChoseAFile := TRUE;
  111.                             fullPathName := reply.fName;             { start the ball rolling }
  112.                         END;
  113.                 END;
  114.  
  115.             PROCEDURE BuildThePathName;
  116.  
  117.                 VAR
  118.                     name: Str255;
  119.                     err: Integer;
  120.  
  121.                 BEGIN
  122.                     name := '';                                                        { start with an empty name }
  123.                     myPB^.ioNamePtr := @name;                            { we want the Volume name }
  124.                   myPB^.ioCompletion := pointer(0);
  125.                     myPB^.ioVRefNum := reply.vRefNum;            { returned from SFGetFile }
  126.                     myPB^.ioVolIndex := 0;                                { use the vRefNum and name }
  127.                     err := PBHGetVInfo(myPB, FALSE);            { fill in the Volume info }
  128.                     IF err <> noErr THEN
  129.                         Exit(FileName);
  130.  
  131. { Now we need the Working Directory (WD) information because we're going 
  132.     to step backwards from the file through all of the the folders until
  133.     we reach the root directory }
  134.     
  135.                     myWDPB^.ioVRefNum := reply.vRefNum;        { this got set to 0 above }
  136.                     myWDPB^.ioWDProcID := 0;                            { use the vRefNum }
  137.                     myWDPB^.ioWDIndex := 0;                                { we want ALL directories }
  138.                     err := PBGetWDInfo(myWDPB, FALSE);        { do it }
  139.                     IF err <> noErr THEN
  140.                         Exit(FileName);
  141.  
  142.                     myCPB^.ioFDirIndex := - 1;                        { use the ioDirID field only }
  143.                     myCPB^.ioDrDirID := myWDPB^.ioWDDirID;{ info returned above }
  144.                     err := PBGetCatInfo(myCPB, FALSE);        { do it }
  145.                     IF err <> noErr THEN
  146.                         Exit(FileName);
  147.  
  148. { Here starts the real work - start to climb the tree by continually
  149.     looking in the ioDrParId field for the next directory above until we
  150.     fail... }
  151.     
  152.                     myCPB^.ioDrDirID := myCPB^.ioDrParId;    { the first folder}
  153.                     fullPathName := Concat(myCPB^.ioNamePtr^, ':', reply.fName);
  154.                     REPEAT
  155.                         myCPB^.ioDrDirID := myCPB^.ioDrParId;
  156.                         err := PBGetCatInfo(myCPB, FALSE);    { the next level }
  157.  
  158. { Be careful of an error returned here - it means the user chose a file 
  159.     on the desktop level of this volume. If this is the case, just stop
  160.     here and return "VolumeName:FileName", otherwise loop until failure }
  161.                         IF err = noErr THEN
  162.                             fullPathName := Concat(myCPB^.ioNamePtr^, ':', fullPathName);
  163.  
  164.                     UNTIL err <> noErr;
  165.                     
  166.                 END;        { PROCEDURE BuildThePathName }
  167.  
  168.             BEGIN        { PROCEDURE FileName }
  169.             
  170. { First we allocate some memory in the heap for the parameter block. This
  171.     could in theory work on the stack, but in reality it makes no difference
  172.     as we're entirely modal (ugh) here... }
  173.     
  174.                 fullPathName := '';
  175.     
  176.                 myCPB := CInfoPBPtr(NewPtr(SizeOf(HParamBlockRec)));
  177.                 IF ord4(myCPB) <= 0 THEN
  178.                     Exit(FileName);                            { Rats! Bill didn't leave enough room }
  179.                 myWDPB := WDPBPtr(myCPB);            { icky Pascal type coercions follow }
  180.                 myPB := HParmBlkPtr(myCPB);
  181.  
  182.                 numTypes := 1;                                { for SFGetFile }
  183.                 WITH paramPtr^ DO
  184.                     BEGIN
  185.                         IF paramCount = 0 THEN
  186.                             numTypes := - 1                    { FileName() - get all files }
  187.                         ELSE
  188.                             BlockMove(params[1]^, @typeList[0], 4);
  189.                                                                             { FileName("TYPE") }
  190.  
  191.                         IF TheyChoseAFile THEN
  192.                             BuildThePathName;
  193.  
  194. { PasToZero is very interesting - it is a HyperTalk command
  195.     that you can actually call from OUTSIDE of HyperCard.
  196.     You need it because HyperCard uses C format strings with
  197.     no length byte; they are terminated by a null byte. They are
  198.     actually HANDLES to C format strings. Nice work, Dan! }
  199.     
  200.                         returnValue := PasToZero(fullPathName);
  201.  
  202.                     END;        { WITH paramPtr^ DO }
  203.  
  204.                 DisposPtr(pointer(myCPB));             { Clean Up Your Heap! }
  205.  
  206.             END;        { PROCEDURE FileName }
  207.  
  208. END.
  209.