Introduction
Calling Convention
Setting up the Parameter Block's Contents
How GetCatInfo Determines the File or Folder
A Few Examples
More about the Parameter Block
A Complete Description of All the Parameters
Calling Convention
Before you call FN GETCATINFO from a FutureBasic program, you need to set aside some area of memory that's at least 108 bytes long. This area of memory will comprise the "parameter block"; you need to put certain information into the parameter block before you call FN GETCATINFO. The parameter block is also the place where FN GETCATINFO puts all of the information that it returns. If pbPtr&
is a pointer to the parameter block, then you can call FN GETCATINFO like this:
If you want, you can define the parameter block as a 108-byte FutureBasic variable, like this:
OSErr% = FN GETCATINFO(pbPtr&)
Then you can call FN GETCATINFO like this:
DIM pb.ioHFQElSiz '(_ioHFQElSiz = 108)
If the call to FN GETCATINFO was successful, then the result code OSErr% = FN GETCATINFO(@pb)
_noErr
(zero) will be returned in OSErr%
. Result codes that indicate failure include _fnfErr
(file not found) and _nsvErr
(no such volume), and others.
You can also call FN GETCATINFO asynchronously. See the ioCompletion
parameter for more information.
Setting up the parameter block's contents
There are four or five parameters in the parameter block that you need to set correctly before you call FN GETCATINFO. One of the parameters tells FN GETCATINFO where your "completion routine" is. You don't need to concern yourself with completion routines unless you intend to call FN GETCATINFO asynchronously. If you intend to do that, then you need to set the ioCompletion&
parameter either to the address of your completion routine, or to zero (if you set it to zero, you're indicating that you don't have a completion routine. I like to use the FutureBasic constant "_nil
" for this.) In FutureBasic, you can use statements like the following to set the ioCompletion&
parameter:
- or -
pb.ioCompletion& = proCAddress&
If you call FN GETCATINFO synchronously (which is the usual way to call it), then the pbPtr&.ioCompletion& = procAddress&
ioCompletion&
parameter is ignored, and you don't have to set it. See the description of the ioCompletion&
parameter for more information about calling FN GETCATINFO asynchronously.
The purpose of other four input parameters is to tell FN GETCATINFO exactly which file or folder you are interested in. These parameters are:
(You could alternatively use the " pb.ioNamePtr&
pb.ioVRefNum%
pb.ioFDirIndex%
pb.ioDirID&
pbPtr&
" notation with these; e.g., "pbPtr&.ioNamePtr&
," etc.)
The way these parameters are used is very versatile, but at the same time somewhat complex, and deserves a thorough discussion, which we present below. It's worth noting that the description in Inside Macintosh is incorrect regarding the interaction of these four parameters. The real scoop is given here.
How GETCATINFO determines the file or folder
First, let's define something called the "base directory." (Don't look for this term in Inside Macintosh; I just made it up, for the purpose of this discussion.) The "base directory" is a directory that you specify by means of the ioVRefNum%
parameter and the ioDirID&
parameter, according to rules I'll explain in a minute. When you call FN GETCATINFO, you'll be getting information about one of the following:
ioVRefNum%
and ioDirID&
, according to these rules:
ioDirID&
is zero, then:ioVRefNum%
is also zero, then the base directory is the same as your current default directory.ioVRefNum%
is a working directory reference number, then the base directory is that working directory.ioVRefNum%
is a volume reference number, then the base directory is the root directory on the specified volume.ioVRefNum%
is a drive number, then the base directory is the root directory of the volume (if any) contained in that drive.ioDirID&
is non-zero, then it's presumed to be a valid directory ID number. In this case, the base directory is the directory whose ID number is ioDirID&
, on the volume specified by ioVRefNum%
:ioVRefNum%
is zero, then the base directory is on the "default volume" (the default volume is the volume that contains the current default directory).ioVRefNum%
is a working directory reference number, then the base directory is on the same volume that contains that working directory.ioVRefNum%
is a volume reference number, then the base directory is on the specified volume.ioVRefNum%
is a drive number, then the base directory is on the volume (if any) contained in that drive.
Once the base directory is determined as above, then the ioNamePtr&
and ioFDirIndex%
parameters complete the determination of the object. This works as follows:
ioFDirIndex%
is positive, then the string pointed to by ioNamePtr&
is ignored. ioFDirIndex%
is then interpreted as an "index number" into the items (files and folders) contained inside the base directory (at its first level). For example, if ioFDirIndex%
is 4, then FN GETCATINFO returns information about the 4th item in the base directory (the items are indexed in alphabetical order by name). If ioFDirIndex%
exceeds the number of items in the base directory, then FN GETCATINFO returns a "file not found" (_fnfErr
) error code.ioFDirIndex%
is negative, then the string pointed to by ioNamePtr&
is again ignored. FN GETCATINFO returns information about the base directory itself.ioFDirIndex%
is zero, then the item is determined by ioNamePtr&
, as follows:ioNamePtr&
is nil (zero), or it's a pointer to an empty (zero-length) string, then FN GETCATINFO returns information about the base directory itself.ioNamePtr&
points to a full path name (that is, a string that contains one or more colons, but doesn't begin with a colon), then the base directory is ignored, and FN GETCATINFO returns information about the item specified in the path name. Beware of this method! If perchance there are two mounted volumes which both happen to have the same volume name, then using the "full path name" method is ambiguous: FN GETCATINFO may or may not look inside the correct volume.ioNamePtr&
points to a "simple name" (a non-emptry string that doesn't contain any colons), then it's assumed to name an item inside the base directory. FN GETCATINFO returns information about that item.ioNamePtr&
points to a relative path name (a string that begins with a colon), then it's assumed to indicate an item which can be reached by starting at the base directory and then following the relative path. This could indicate an item which exists several directory levels deep within the base directory. FN GETCATINFO returns information about that item. Note that there is a strange (but sometimes useful) variation of the relative path name, in which the string begins with multiple colons (with no name between them). When the string begins with a double colon, then the relative path begins at the parent of the base directory, rather than at the base directory itself. when the string begins with a triple colon, then the relative path begins at the "grandparent" of the base directory, and so forth. For example, you can retrieve information about the base directory's parent by specifying the string, "::
".ioFDirIndex%
is nonzero, then the string pointed to by ioNamePtr&
is ignored, but even in that case you still are required to set the value of ioNamePtr&
properly before calling FN GETCATINFO. Specifically, you must either set it to _nil
, or set it to the address of an area of memory which can receive a name. If you set it to _nil
, then FN GETCATINFO won't return any name. If you set it to the address of a string buffer, then FN GETCATINFO will return the name of the item it finds into that buffer. If you fail to explicitly set ioNamePtr&
, and it happens to contain some random nonzero number, then FN GETCATINFO will interpret that number as an address and will try to stuff the item's name into the memory at that address. In the worst case, this could crash your computer.
So remember:
ioFDirIndex%
is zero, GetCatInfo reads from the buffer (if any) pointed to by ioNamePtr&
.ioFDirIndex%
is nonzero, GetCatInfo writes to the buffer (if any) pointed to by ioNamePtr&
.
A Few Examples
Because the above rules are pretty complex, a few examples are in order here.
Example 1. Return information about the root directory of the volume whose reference number is -1 (this is usually the startup volume). Note that the name of the root directory is just the volume's name.
Example 2. Return information about the item called "MyStuff" which is in the working directory whose reference number is -32544. (Note: in "real life," you would virtually never use a literal constant to represent a working directory reference number.)
DIM pb.108, 31 volName$
pb.ioNamePtr& = @volName$ 'Return volume name here.
pb.ioVRefNum% = -1 'volume reference number.
pb.ioFDirIndex% = -1 'Return info about dir. itself.
pb.ioDirID& = 0 'Use ioVRefNum% field alone for dir.
OSErr% = FN GETCATINFO(@pb)
DIM pb.108, 31 itemName$
itemName$ = "MyStuff"
pb.ioNamePtr& = @itemName$
pb.ioVRefNum% = -32544 'working directory ref. num.
pb.ioFDirIndex% = 0 'Refer to ioNamePtr& for item.
pb.ioDirID& = 0 'Use ioVRefNum% field alone for dir.
OSErr% = FN GETCATINFO(@pb)
Example 3. Return information about the current default directory.
DIM pb.108, 31 itemName$
pb.ioNamePtr& = @itemName$
pb.ioVRefNum% = 0 'Default volume.
pb.ioFDirIndex% = -1 'Return info about dir. itself.
pb.ioDirID& = 0 '0 = default dir, when ioVRefNum is also 0.
OSErr% = FN GETCATINFO(@pb)
Example 4. Return information about the root directory of the current default volume. Here we make use of the fact that every volume's root directory has a directory ID of "2."
DIM pb.108, 31 itemName$
pb.ioNamePtr& = @itemName$
pb.ioVRefNum% = 0 'Default volume.
pb.ioFDirIndex% = -1 'Return info about dir. itself.
pb.ioDirID& = 2 '2 always means "root directory".
OSErr% = FN GETCATINFO(@pb)
Example 5. Return information about the 6th item in the root directory of the volume currently in the floppy drive (the drive number of the floppy drive is 1).
DIM pb.108, 31 itemName$
pb.ioNamePtr& = @itemName$
pb.ioVRefNum% = 1 'Drive number.
pb.ioFDirIndex% = 6 'Return info about 6th item.
pb.ioDirID& = 0 'Use ioVRefNum% field alone for dir
OSErr% = FN GETCATINFO(@pb)
Example 6. Return information about the directory whose ID is 105, in the volume whose reference number is -2. Disregard the directory's name. (Note: in "real life," you would probably not use literal constants to represent a volume reference number and a directory ID, except in special cases.)
DIM pb.108
pb.ioNamePtr& = _nil 'Don't return the item's name.
pb.ioVRefNum% = -2 'Volume reference number.
pb.ioFDirIndex% = -1 'Return info about dir. itself.
pb.ioDirID& = 105 'Directory ID #.
OSErr% = FN GETCATINFO(@pb)
Example 7. Return information about the root directory of the volume called "MacintoshHD" (hopefully, there is only one volume with that name currently mounted).
DIM pb.108, 31 itemName$
itemName$ = "MacintoshHD:" 'non-leading colon makes it a full path name.
pb.ioNamePtr& = @itemName$
pb.ioVRefNum% = 0 'Ignored when full path used.
pb.ioFDirIndex% = 0 'Refer to ioNamePtr& for item.
pb.ioDirID& = 0 'Ignored when full path used.
OSErr% = FN GETCATINFO(@pb)
There are many more possible variations on these examples, but these should give you a taste of what you can do.
More about the parameter block
When you call FN GETCATINFO, the parameter block returns slightly different information depending on whether the selected item is a file or a directory. Sometimes you'll know in advance whether the item is a file or a directory, but other times you may not. After you call FN GETCATINFO, you can always determine whether the returned item is a file or directory by looking at bit 4 of the ioFlAttrib
parameter that FN GETCATINFO returns. One way to do this is as follows:
- or -
itsADirectory = (PEEK(@pb.ioFlAttrib) AND BIT(4)) <> 0
In the above statements, itsADirectory = (PEEK(pbPtr& + _ioFlAttrib) AND BIT(4)) <> 0
itsADirectory
will be set to _zTrue
if the returned item is a directory, or to _false
if the item is a file.
The input and output parameters for files and directories are summarized below. A right-pointing arrow () indicates an input parameter, a left-pointing arrow () indicates an output parameter, and a two-headed arrow () indicates a parameter which requires input and also provides output. The first 12 bytes in the block (which precede the ioCompletion&
field) are used internally.
Direction | Byte offset | Parameters for files | Parameters for directories | Parameter size |
12 | ioCompletion |
ioCompletion |
long integer | |
16 | ioResult |
ioResult |
integer | |
18 | ioNamePtr |
ioNamePtr |
long integer | |
22 | ioVRefNum |
ioVRefNum |
integer | |
24 | ioFRefNum |
integer | ||
28 | ioFDirIndex |
ioFDirIndex |
integer | |
30 | ioFlAttrib |
ioFlAttrib |
byte | |
31 | |
ioAcUser |
byte | |
32 | ioFlFndrInfo |
ioDrUsrWds |
16 bytes | |
48 | ioDirID / File ID |
ioDirID / ioDrDirID |
long integer | |
52 | ioFlStBlk |
ioDrNmFls |
integer | |
54 | ioFlLgLen |
|
long integer | |
58 | ioFlPyLen |
|
long integer | |
62 | ioFlRStBlk |
|
integer | |
64 | ioFlRLgLen |
|
long integer | |
68 | ioFlRPyLen |
|
long integer | |
72 | ioFlCrDat |
ioDrCrDat |
long integer | |
76 | ioFlMdDat |
ioDrMdDat |
long integer | |
80 | ioFlBkDat |
ioDrBkDat |
long integer | |
84 | ioFlXFndrInfo |
ioDrFndrInfo |
16 bytes | |
100 | ioFlParID |
ioDrParID |
long integer | |
104 | ioFlClpSiz |
|
long integer |
A Complete Description of all the Parameters
pb.ioCompletion&
, or to pbPtr&.ioCompletion&
._nil
(zero). If it's not _nil
, then it should be set to the address of a "completion routine," which is a routine that you want FN GETCATINFO to automatically call after it's finished getting its info about the selected item. This is really only useful in cases where you want to call FN GETCATINFO "asynchronously." Calling asynchronously means that FN GETCATINFO puts the request for information onto a queue, and then returns immediately to your application, possibly before the information has actually been retrieved. The system then processes the GETCATINFO request in the background (as soon as it can get around to it), and meanwhile your application is free to do other stuff. When the system completes the GETCATINFO request, it calls your completion routine (if you specified one). You can use the completion routine as a way to notify your application that the GETCATINFO request has been processed. (Another way to check whether the request has been processed is to periodically check the value of the ioResult
parameter, as explained below.) To call FN GETCATINFO asynchronously, call it like this:
OSErr% = FN GETCATINFO _async(@pb)
- or -
OSErr% = FN GETCATINFO _async(pbPtr&)
Calling FN GETCATINFO asynchronously can be useful if you're making a great number of calls, and/or you expect that it might take a while for the information to be returned (as may be the case when you're retrieving information about items on a remote network volume). If you do call FN GETCATINFO asynchronously, you must not dispose of the parameter block until the the routine completes (you can check ioResult
periodically to determine when that happens).
pb.ioResult%
, or pbPtr&.ioResult%.
ioResult
returns the same value that OSErr%
(the function result) returns. But if you're making an asynchronous call, then OSErr%
always returns _noErr
. In this case, one way to determine whether the GETCATINFO request has been processed is to periodically check the value of ioResult
. As long as ioResult
contains a positive value, the request has not yet been processed. Eventually the system will put a result code (either _noErr
(zero), or some negative error code) into ioResult
. When this happens, you'll know that the GETCATINFO request has been processed.
pb.ioNamePtr&
, or to pbPtr&.ioNamePtr&
.ioFDirIndex
parameter.
ioFDirIndex
is zero, then ioNamePtr
should either be set to _nil
, or it should point to a "Pascal string" (a Pascal string is a string which is preceded in memory by a byte which indicates the string's length. This is the kind of string that is stored in FutureBasic string variables that end with the "$" type identifier.) The Pascal string that ioNamePtr
points to may be a "null string" (a string whose length is zero), or a full or partial path name. When you call FN GETCATINFO with ioFDirIndex
= 0, the contents of the string buffer pointed to by ioNamePtr
don't get changed.ioFDirIndex
is nonzero, then ioNamePtr
should either be set to _nil
, or it should point to a buffer in memory which is large enough to hold the name of the returned item (file or folder) in Pascal string format. Typically, your "buffer" will just consist of the space reserved for a FutureBasic string variable, and you'll just set ioNamePtr
to the address of that string variable. If ioFDirIndex
is nonzero when you call FN GETCATINFO, then GETCATINFO will return the name of the item (file or folder) into the buffer that ioNamePtr
points to (if any). If you set ioNamePtr
to _nil
, then the item's name is not returned.pb.ioVRefNum%
, or to pbPtr&.ioVRefNum%
.ioDirID
) to determine the "base directory," as described in a previous section. FN GETCATINFO can interpret ioVRefNum
in any of four distinct ways, depending on its value:
If ioVRefNum is: | ...it's interpreted as: |
zero | the default volume |
positive | a drive ID number |
in the range [-1..-16384] (?) | a volume reference number |
in the range [-16385..-32768] (?) | a working directory reference number |
ioFRefNum
(files only)
pb.ioRefNum%
, or as pbPtr&.ioRefNum%
(note the different spelling of the parameter name in FutureBasic)ioFRefNum
returns the reference number of one of the file's i/o access paths (there may be more than one access path active; for example if two processes are both reading the file concurrently). If no process has the file open, then ioFRefNum
returns zero.
pb.ioFDirIndex%
, or to pbPtr&.ioFDirIndex%
.PEEK(@pb.ioFlAttrib)
, or as PEEK(pbPtr& + _ioFlAttrib)
.The bits in the "file attributes" have these meanings:
Bit | Meaning |
0 | Set if the file is locked |
1 | Reserved |
2 | Set if resource fork is open |
3 | Set if data fork is open |
4 | Always "0" for files |
5-6 | Reserved |
7 | Set if file (either fork) is open |
The bits in the "directory attributes" have these meanings:
Bit | Meaning |
0 | Set if the directory is locked* |
1 | Reserved |
2 | Set if the directory is within a shared area of the directory hierarchy** |
3 | Set if the directory is a share point that is mounted by some remote user** |
4 | Always "1" for directories |
5 | Set if the directory is a share point** |
6-7 | Reserved |
*Does anybody know what this means? It's not the same as the "name locked" bit. Inside Macintosh says that this bit can be set or reset by the PBHSetFLock and PBHRstFLock functions, respectively, if the volume supports directory locking. I have so far been unable to set or reset it, nor determine what it means.
**A "share point" is a directory (or volume) on the local computer that you've enabled for sharing. A directory is "within a shared area of the directory hierarchy" if it's a share point or it's somewhere inside a share point. These three bits (2, 3 and 5) will be zero (for all directories) if file sharing is not currently turned on.
Probably the most popular bit in ioFlAttrib
is bit 4, which determines whether the item is a file or a directory (and hence also determines how the remaining flags should be interpreted). In FutureBasic, an easy way to test whether a particular bit is set is by using the AND
operator and the BIT
function, as in this example:
OSErr% = FN GETCATINFO(@pb)
attrib = PEEK(@pb.ioFlAttrib)
itsADirectory = ((attrib AND BIT(4)) <> 0)
LONG IF itsADirectory
itsLocked = ((attrib AND BIT(1)) <> 0)
inSharedArea = ((attrib AND BIT(2)) <> 0)
mountedSharePoint = ((attrib AND BIT(3)) <> 0)
itsASharePoint = ((attrib AND BIT(5)) <> 0)
XELSE
itsLocked = ((attrib AND BIT(1)) <> 0)
resForkOpen = ((attrib AND BIT(2)) <> 0)
dataForkOpen = ((attrib AND BIT(3)) <> 0)
someForkOpen = ((attrib AND BIT(7)) <> 0)
END IF
ioAcUser
(directories only)
PEEK(@pb + 31)
, or as PEEK(pbPtr& + 31)
. (FB has no appropriate constant name for this parameter.)
Bit | Meaning |
0 | Set if user does not have "See Folders" privelege |
1 | Set if user does not have "See Files" privelege |
2 | Set if user does not have "Make Changes" privelege |
3-6 | Reserved |
7 | Set if user is not an owner of the directory |
Obviously, these flags are most meaningful when you're retrieving information about a directory that's on a remote server. If you retrieve information about a local directory, and you have sharing currently turned off, then FN GETCATINFO seems always to set all these flags to zeros (meaning, essentially, that you're the owner and you have full priveleges). Inside Macintosh has this to say:
"The PBGetCatInfo function returns the directory access rights in the ioACUser field only for shared volumes. As a result, you should set this field to 0 before calling PBGetCatInfo."
However, my experiments seem to indicate that a value is output to ioAcUser
even when the volume in question is not shared. Go figure.
In FutureBasic, an easy way to test whether a particular bit is set is by using the AND
operator and the BIT
function, as in this example:
OSErr% = FN GETCATINFO(@pb)
ioAcUser = PEEK(@pb + 31)
'test whether bit "n" of ioAcUser is set:
bitIsSet = ((ioAcUser AND BIT(n)) <> 0)
ioFlFndrInfo
(files only)
ioFlFndrInfo
in various ways, as explained below. The FutureBasic constant _ioFlFndrInfo
does not give the correct offset to this parameter: use the constant _ioFlUsrWds
instead.ioFlFndrInfo
is a record of type "FInfo
," and contains 16 bytes of "Finder Information" about the file. The fields of the FInfo
record are described below.
fdType.
In FutureBasic, access this field as pb.ioFlUsrWds.fdType&
, or as pbPtr&.ioFlUsrWds.fdType&
. This field contains the 4-byte file type. Note that this is not stored as a string: if you want to get the string equivalent of the file type, do this:
DEFSTR LONG
typeString$ = MKI$(pb.ioFlUsrWds.fdType&)
fdCreator.
In FutureBasic, access this field as pb.ioFlUsrWds.fdCreator&
, or as pbPtr&.ioFlUsrWds.fdCreator&
. This field contains the file's 4-byte creator signature. Note that this is not stored as a string: if you want to get the string equivalent of the creator signature, do this:
DEFSTR LONG
creatorString$ = MKI$(pb.ioFlUsrWds.fdCreator&)
fdFlags.
In FutureBasic, access this field as pb.ioFlUsrWds.fdFlags%
, or as pbPtr&.ioFlUsrWds.fdFlags%
. This field contains the "Finder flags," a collection of flags (most of which consist of 1 bit) which have the following meanings:
Bits | Meaning |
0 | Reserved |
1-3 | 3 bits of color coding; a number in the range 0..7, indicating the color & label as set by the Finder's "Label" menu (or the "Label" option in the "File" menu). |
4-5 | Reserved |
6 | "isShared"--If set, the file is an application which can be used by multiple users simultaneously. (Should always be "0" for files which aren't applications.) |
7 | "hasNoINITs"--If set, the file contains no INIT resources. |
8 | "hasBeenInited"--If set, the Finder has recorded information from the file's bundle resource into the desktop database and given the file a position on the desktop. |
9 | Reserved |
10 | "hasCustomIcon"--If set, the file contains a customized icon. |
11 | "isStationery"--If set, the file is a stationery pad. |
12 | "nameLocked"--If set, the file can't be renamed from the Finder, and the icon cannot be changed. |
13 | "hasBundle"--If set, the file contains a bundle ("BNDL") resource. |
14 | "isInvisible"--If set, the file is invisible from the Finder and from the Standard File Package dialog boxes. (But note it's visible using FutureBasic's FILES$(_fOpen,...) function.) |
15 | "isAlias"--If set, the file is an alias. |
In FutureBasic, you can access the 1-byte flags of fdFlags
by using the AND
operator and the BIT
function. For example, to test whether bit "n" is set, do this:
You can access the 3-bit "color coding" field (bits 1-3) as follows:
bitIsSet = (pb.ioFlUsrWds.fdFlags% AND BIT(n)) <> 0)
colorCode = (pb.ioFlUsrWds.fdFlags% AND 14) >> 1
fdLocation.
This is a field of type "point." It represents the location of the file's icon in its parent directory's Finder window (in the window's local coordinates). In FutureBasic, you can access the entire field (4 bytes) as pb.ioFlUsrWds.fdLocation&
, or as pbPtr&.ioFlUsrWds.fdLocation&
. If you want to access the individual horizontal and vertical components of this point, you can use pb.ioFlUsrWds.fdLocation.h%
(or pbPtr&.ioFlUsrWds.fdLocation.h%
) for the horizontal component, and pb.ioFlUsrWds.fdLocation.v%
(or pbPtr&.ioFlUsrWds.fdLocation.v%
) for the vertical component.
fdFldr.
In FutureBasic, access this field as pb.ioFlUsrWds.fdFldr%
, or as pbPtr&.ioFlUsrWds.fdFldr%
. This is an ID number indicating the window in which the file's icon appears; this information is meaningful only to the Finder. (FutureBasic users: this is in no way related to the Window ID numbers that you assign when you open windows in FB programs.)
ioDrUsrWds
(directories only)
ioDrUsrWds
in various ways, as explained below.ioDrUsrWds
is a record of type "DInfo
," and contains 16 bytes of "Finder Information" about the folder. The fields of the DInfo
record are described below.
frRect.
This is an 8-byte field of type "rect" (rectangle). In FutureBasic, you can copy it to a variable which is DIM'ed as an 8-byte record, as follows:
myRect;8 = @pb.ioDrUsrWds.frRect
or:
myRect;8 = pbPtr& + _ioDrUsrWds + _frRect
You can also access the individual "sides" of the rectangle as follows:
pb.ioDrUsrWds.frRect.top%
pb.ioDrUsrWds.frRect.left%
pb.ioDrUsrWds.frRect.bottom%
pb.ioDrUsrWds.frRect.right%
(Alternatively, you can use the pbPtr&
sytax.) The frRect
field indicates the rectangle (in global coordinates) of this folder's Finder window (that is, the window that opens when the user double-clicks the folder's icon).
frFlags.
In FutureBasic, access this field as pb.ioDrUsrWds.frFlags%
, or as pbPtr&.ioDrUsrWds.frFlags%
. This field contains the "Finder flags," a collection of flags (most of which consist of 1 bit) which have the following meanings:
Bits | Meaning |
0 | Reserved |
1-3 | 3 bits of color coding; a number in the range 0..7, indicating the color & label as set by the Finder's "Label" menu (or the "Label" option in the "File" menu). |
4-9 | Reserved |
10 | "hasCustomIcon"--If set, the folder uses a cusotmized icon. (The customized icon is stored in an invisible resource file within the folder.) |
11 | Reserved |
12 | "nameLocked"--If set, the folder can't be renamed from the Finder, and the icon cannot be changed. |
13 | Reserved |
14 | "isInvisible"--If set, the folder is invisible from the Finder and from the Standard File Package dialog boxes. (But note it's visible using FutureBasic's FILES$(_fOpen,...) function.) |
15 | Reserved |
In FutureBasic, you can access the 1-byte flags of frFlags
by using the AND
operator and the BIT
function. For example, to test whether bit "n" is set, do this:
bitIsSet = (pb.ioDrUsrWds.frFlags% AND BIT(n)) <> 0)
You can access the 3-bit "color coding" field (bits 1-3) as follows:
colorCode = (pb.ioDrUsrWds.frFlags% AND 14) >> 1
frLocation.
This field is of type "point." It represents the location of the folder's icon in its parent directory's Finder window (in the window's local coordinates). In FutureBasic, you can access the entire field (4 bytes) as pb.ioDrUsrWds.frLocation&
, or as pbPtr&.ioDrUsrWds.frLocation&
. If you want to access the individual horizontal and vertical components of this point, you can use pb.ioDrUsrWds.frLocation.h%
(or pbPtr&.ioDrUsrWds.frLocation.h%
) for the horizontal component, and pb.ioDrUsrWds.frLocation.v%
(or pbPtr&.ioDrUsrWds.frLocation.v%
) for the vertical component.
frView.
In FutureBasic, access this field as pb.ioDrUsrWds.frView%
, or as pbPtr&.ioDrUsrWds.frView%
. This field indicates the manner in which the folder's Finder window is displayed, as set by the various options in the Finder's "View" menu. I couldn't find any documentation regarding the interpretation of frView
, but my experiments indicate that its bits have the following meanings:
Bits | Meaning |
0-6 | Reserved |
7 | If viewing by icon: 1="by small icon"; 0="by large icon." If not viewing by icon, this bit should be ignored. |
8-11 | View/Sort: 1 = by icon 2 = by name 3 = by date 4 = by size 5 = by kind 6 = by comments 7 = by label 8 = by version |
12-15 | Reserved |
Note for MacOS 8.x users: frView
apparently does not indicate any difference between the "Icon" view and the "Button" view (in both cases, Bits 8-11 are set to 0001
). I don't know where the "Icon vs. Button" information is stored.
You can access the bit fields of frView
as follows:
viewType = (pb.ioDrUsrWds.frView% AND &0F00) >> 8
LONG IF viewType = 1
'iconSize = 1 if small, or 0 if large:
iconSize = (pb.ioDrUsrWds.frView% AND BIT(7)) >> 7
END IF
File ID
and ioDrDirID
for the output values of this parameter.pb.ioDirID&
, or to pbPtr&.ioDirID&
.ioVRefNum
) to determine the "base directory," as described in a previous section. Because FN GETCATINFO changes the contents of these bytes on output, you must be careful to reset this parameter to the correct value before you use this same parameter block again.
File ID
(files only)
ioDirID
for the input value of this parameter.pb.ioFFlNum&
, or as pbPtr&.ioFFlNum&
.
ioDrDirID
(directories only)
ioDirID
for the input value of this parameter.pb.ioDrDirID&
, or as pbPtr&.ioDrDirID&
.ioDirID
when you called FN GETCATINFO. Note that the directory ID of a volume's root directory is always "2."
ioFlStBlk
(files only)
pb.ioFlStBlk%
, or as pbPtr&.ioFlStBlk%
.
ioDrNmFls
(directories only)
pb.ioDrNmFls%
, or as pbPtr&.ioDrNmFls%
.
ioFlLgLen
(files only)
pb.ioFlLgLen&
, or as pbPtr&.ioFlLgLen&
.LOF(fileID, 1)
function.
ioFlPyLen
(files only)
pb.ioFlPyLen&
, or as pbPtr&.ioFlPyLen&
.ioFlLgLen
value. If ioFlPyLen
is zero, then the file doesn't have a data fork. To determine the total amount of disk space used by the file, add ioFlPyLen
to ioFlRPyLen
.
ioFlRStBlk
(files only)
pb.ioFlRStBlk%
, or as pbPtr&.ioFlRStBlk%
.
ioFlRLgLen
(files only)
pb.ioFlRLgLen&
, or as pbPtr&.ioFlRLgLen&
.
ioFlRPyLen
(files only)
pb.ioFlRPyLen&
, or as pbPtr&.ioFlRPyLen&
.ioFlRLgLen
value. If ioFlRPyLen
is zero, then the file doesn't have a resource fork. To determine the total amount of disk space used by the file, add ioFlPyLen
to ioFlRPyLen
.
ioFlCrDat
(files only)
pb.ioFlCrDat&
, or as pbPtr&.ioFlCrDat&
.
ioDrCrDat
(directories only)
pb.ioDrCrDat&
, or as pbPtr&.ioDrCrDat&
.
ioFlMdDat
(files only)
pb.ioFlMdDat&
, or as pbPtr&.ioFlMdDat&
.
ioDrMdDat
(directories only)
pb.ioDrMdDat&
, or as pbPtr&.ioDrMdDat&
.
ioFlBkDat
(files only)
pb.ioFlBkDat&
, or as pbPtr&.ioFlBkDat&
.
ioDrBkDat
(directories only)
pb.ioDrBkDat&
, or as pbPtr&.ioDrBkDat&
.
ioFlXFndrInfo
(files only)
ioFlXFndrInfo
in various ways, as explained below.
ioFlXFndrInfo
is a record of type "FXInfo
," and contains 16 bytes of "Extended Finder Information" about the file. The fields of the FXInfo
record are described below.
fdIconID.
In FutureBasic, access this field as pb.ioFlXFndrInfo.fdIconID%
, or as pbPtr&.ioFlXFndrInfo.fdIconID%
. This is an ID number for the file's icon; the numbers that identify icons are assigned by the Finder.
fdUnused.
This contains 6 reserved bytes. If you want to look at them in FutureBasic, use the expression @pb.ioFlXFndrInfo.fdUnused
, or pbPtr& + _ioFlXFndrInfo + _fdUnused
, as a pointer to the first of these bytes.
fdScript.
In FutureBasic, access this field as PEEK(@pb.ioFlXFndrInfo.fdScript)
, or as PEEK(pbPtr& + _ioFlXFndrInfo + _fdScript)
. This byte indicates the script system for displaying the file's name. Ordinarily, the Finder (and the Standard File Package) displays the names of all desktop objects in the system script, which depends on the region-specific configuration of the system. The high bit of the byte in the fdScript
field is set by default to 0, which causes the Finder to display the filename in the current system script. If the high bit is set to 1, the Finder (and the Standard File Package) displays the filename and directory name in the script whose code is recorded in the remaining 7 bits. See ioDrFndrInfo.frScript
for additional information.
fdXFlags.
This 1-byte field is reserved. If you want to look at it in FutureBasic, use PEEK(@pb.ioFlXFndrInfo.fdXFlags)
, or PEEK(pbPtr& + _ioFlXFndrInfo + _fdXFlags)
.
fdComment.
In FutureBasic, access this field as pb.ioFlXFndrInfo.fdComment%
, or as pbPtr&.ioFlXFndrInfo.fdComment%
. This is an ID number for the comment that is displayed in the information window when the user selects a file and chooses the Get Info command from the File menu. The numbers that identify comments are assigned by the Finder.
fdPutAway.
In FutureBasic, access this field as pb.ioFlXFndrInfo.fdPutAway&
, or as pbPtr&.ioFlXFndrInfo.fdPutAway&
. If the user has moved the file into the Trash, or from a folder onto the Desktop, this field contains the directory ID of the folder from which the user moved the file.
ioDrFndrInfo
(directories only)
ioDrFndrInfo
in various ways, as explained below.ioDrFndrInfo
is a record of type "DXInfo
," and contains 16 bytes of "Extended Finder
Information" about the directory. The fields of the DXInfo
record are described below.
frScroll.
This field indicates the current positions of the horizontal and vertical scroll bars in the directory's Finder window (these values may not update immediately after the user adjusts the scroll bars). In FutureBasic, you can access the horizontal scroll bar position as pb.ioDrFndrInfo.frScroll.h%
, or as pbPtr&.ioDrFndrInfo.frScroll.h%
. You can access the vertical scroll bar position as pb.ioDrFndrInfo.frScroll.v%
, or as pbPtr&.ioDrFndrInfo.frScroll.v%
.
frOpenChain.
In FutureBasic, access this field as pb.ioDrFndrInfo.frOpenChain&
, or as pbPtr&.ioDrFndrInfo.frOpenChain&
. According to Inside Macintosh, this field represents a "chain of directory ID's for open folders." I've not been able to figure out what this means: the field does not contain a directory ID, nor does it contain a pointer to any valid address.
frScript.
In FutureBasic, access this field as PEEK(@pb.ioDrFndrInfo.frScript)
, or as PEEK(pbPtr& + _ioDrFndrInfo + _frScript)
. This byte indicates the script system for displaying the folder's name. Ordinarily, the Finder (and the Standard File Package) displays the names of all desktop objects in the system script, which depends on the region-specific configuration of the system. The high bit of the byte in the frScript
field is set by default to 0, which causes the Finder to display the folder's name in the current system script. If the high bit is set to 1, the Finder (and the Standard File Package) displays the filename and directory name in the script whose code is recorded in the remaining 7 bits. Inside Macintosh also has this to say:
However, as of system software version 7.1, the Window Manager and Dialog Manager do not support multiple simultaneous scripts, so the system script is always used for displaying filenames and directory names in dialog boxes, window titles, and other user interface elements used by the Finder. Therefore, until the system software's script capability is fully implemented, you should treat this field as reserved.
frXFlags.
This 1-byte field is reserved. If you want to look at it in FutureBasic, use PEEK(@pb.ioDrFndrInfo.frXFlags)
, or PEEK(pbPtr& + _ioDrFndrInfo + _frXFlags)
.
frComment.
In FutureBasic, access this field as pb.ioDrFndrInfo.frComment%
, or as pbPtr&.ioDrFndrInfo.frComment%
. This is an ID number for the comment that is displayed in the information window when the user selects a folder and chooses the Get Info command from the File menu. The numbers that identify comments are assigned by the Finder.
frPutAway.
In FutureBasic, access this field as pb.ioDrFndrInfo.frPutAway&
, or as pbPtr&.ioDrFndrInfo.frPutAway&
. If the user has moved the folder out of some parent folder and into the Trash, or onto the Desktop, this field contains the directory ID of the parent folder from which the user moved the folder.
ioFlParID
(files only)
pb.ioFlParID&
, or as pbPtr&.ioFlParID&
.
ioDrParID
(directories only)
pb.ioDrParID&
, or as pbPtr&.ioDrParID&
.ioDrParID
. The value "1" is a "pseudo" directory ID which always means "the parent of the root directory." There is never any real directory which has that ID number.
ioFlClpSiz
(files only)
pb.ioFlClpSiz&
, or as pbPtr&.ioFlClpSiz&
.