Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
AMEMBERS()
This function gives you access to all the stuff inside an object. The parameters you pass it determine whether the array it creates contains all the properties of an object, all the properties, methods and contained objects, or just the contained objects. Beginning in VFP 7, AMEMBERS()
can explore COM objects as well as native VFP objects. AMEMBERS()
is particularly useful for writing black-box code like Builders.
nMemberCount = AMEMBERS( ArrayName, oObject | cClass
[, nInfoType [, cFlags ] ] )
Parameter |
Value |
Meaning |
ArrayName |
Array Name |
The array to hold the information about oObject. |
oObject |
Object |
The object whose members are stored in ArrayName. |
cClass |
Character |
The class whose members are stored in ArrayName. |
nInfoType |
Omitted or 0 |
Put only a list of oObject's properties in ArrayName. In this case, ArrayName is one-dimensional. VFP objects only. |
1 |
Put a complete list of oObject's properties, events, methods, and member objects in ArrayName. ArrayName is two-dimensional with names in the first column and either "Property", "Event", "Method" or "Object" in the second column. VFP objects only. |
|
2 |
Put only a list of oObject's member objects in ArrayName. ArrayName is one-dimensional. VFP objects only. |
|
3 |
Put a complete list of oObject's properties, events, methods and member objects in ArrayName. See the discussion below for an explanation of ArrayName. Works with native or COM objects. |
|
cFlags |
Character |
One or more characters limiting the results to members that meet the specified criteria. See the table below for the meaning of the flag characters. |
Omitted |
Include all members. |
|
nMemberCount |
Positive number |
The number of elements in ArrayName if nInfoType is omitted or 2. If nInfoType is 1 or 3, the number of rows in ArrayName. In all cases, this is the number of members found. |
0 |
There are no members of the type specified. |
When oObject doesn't exist, AMEMBERS() generates an error. That's good. What's not good is that it also goes ahead and creates ArrayName if it doesn't already exist. This is different than the other array-handling functions and appears to be a bug. |
Like GetPEM() and PEMStatus(), AMEMBERS() is documented as being able to report on classes as well as objects, but like those functions, it can't report on a class unless you've already instantiated it. Once you do so, the definition is in memory and AMEMBERS() is happy (for the time being). We understand why it behaves this way, but since the behavior isn't documented, we think it's a bug. |
In VFP 6 and earlier, AMEMBERS()works only for native FoxPro objects. Fortunately, VFP 7 lifts this limit, and provides additional options that make it easier to understand what’s going on with any given object or class.
Passing 3 for nInfoType creates a four- or five-column array. This table shows the contents when a VFP object is passed and when a COM object is passed.
Column |
Object Type |
Meaning |
1 |
VFP or COM |
Member's name |
2 |
VFP |
Member type – "Property", "Event", "Method" or "Object" |
COM |
Member type – "PropertyGet", "PropertyPut" or "Method" |
|
3 |
VFP |
Parameter list, for methods. Empty, for properties. |
COM |
Member's signature, in the form "(Parameters) AS ReturnType" |
|
4 |
VFP or COM |
Member's help string |
5 |
VFP |
Applicable flags |
COM |
Not available |
The cFlags parameter lets you retrieve only a subset of a VFP object’s members; it also offers a list of characteristics for each member. The flags can be divided into several groups.
Character |
Group |
Meaning |
"G" |
Visibility |
Public |
"H" |
Visibility |
Hidden |
"P" |
Visibility |
Protected |
"N" |
Origin |
Native—comes with base class |
"U" |
Origin |
User-defined at some level in the inheritance hierarchy |
"B" |
Inheritance |
Defined at this level |
"I" |
Inheritance |
Inherited |
"C" |
Changed |
Changed at some level in the inheritance hierarchy |
"R" |
Read-only |
Read-only |
"+" |
Management |
Combine flags with "and" rather than "or" |
"#" |
Management |
Include all flags in output |
By default, cFlags combines the flags with “or,” so for example, passing “HP” includes all members that are either hidden or protected. Including the “+” flag anywhere in the string changes the operator to “and,” so “+HP” returns no results, since no member can be both hidden and protected.
When the “#” flag is included in cFlags, the array contains a fifth column, which lists all the flags for each member.
You can't pass just "#" for cFlags. When you do, zero members are returned. Add the "+" flag and all is well. Microsoft says this one is by design, but we can't imagine why it was designed this way. |
While there’s a flag for read-only properties, there’s no flag for read-write and no way to say “give me all the members that don’t have these flags.” Since black-box code is more likely to be interested in the properties it can change than the ones it can’t, this seems like a poor choice to us. There is a work-around, though: Use the “#” flag to get the flags along with the members, then check for an “R” flag in the last column of the array. The properties that don’t have it are read-write.
The "C" flag (for changed properties) doesn't pick up array properties that have changed, whether the change is redimensioning or actually changing the contained data. |
oForm = CREATEOBJECT("Form") && create a form
nPropCnt = AMEMBERS(aProps, oForm) && properties only
nMembCnt = AMEMBERS(aMembs, oForm, 1)&& all members
nChildCnt = AMEMBERS(aKids, oForm, 2)&& contained objects only
&& returns zero in this case
nMembCnt = AMEMBERS(aMembs, oForm, 3)&& all members with
&& additional info
* Now add some objects.
oForm.AddObject("lblName", "Label")
oForm.AddObject("chkPresent", "Checkbox")
nChildCnt = AMEMBERS(aKids, oForm, 2) && now returns 2
nAdded = AMEMBERS(anew, oForm, 3, "B") && also returns 2
* Do it for a class.
nProps = AMEMBERS(aProps, "Form") && gets properties of a form
* Get all members, and include flags.
nProps = AMEMBERS(aProps, "Form", 3, "#+")
* Use a COM Server.
oWord = CREATEOBJECT("Word.Application")
nWordMembers = AMEMBERS(laMember, oWord, 3) && returns 184
AClass(), AInstance(), Array Manipulation, CreateObject(), GetPEM(), PEMStatus()