DEFINE CLASS Command
Creates a user-defined class or subclass and specifies the properties, events, and methods for the class or subclass.
Caution Modifying read-only properties from base classes generates an error message. However, when creating a user-defined class or subclass from a base class that has read-only properties, modifying read-only properties does not generate the appropriate message. This might break existing code.
DEFINE CLASS ClassName1 AS ParentClass [OF ClassLibrary] [OLEPUBLIC]
[IMPLEMENTS cInterfaceName [EXCLUDE]
IN TypeLib | TypeLibGUID | ProgID ]
[[PROTECTED | HIDDEN PropertyName1, PropertyName2 ...]
[[.]Object.]PropertyName = eExpression ...]
[ADD OBJECT [PROTECTED] ObjectName AS ClassName2 [NOINIT]
[WITH cPropertylist]]
[[PROTECTED | HIDDEN] FUNCTION | PROCEDURE Name[_ACCESS |_ASSIGN]
([cParamName | cArrayName[] [AS Type][@]]) [AS Type]
[HELPSTRING cHelpString] |
THIS_ACCESS(cMemberName)
[NODEFAULT]
cStatements
[ENDFUNC | ENDPROC]]
[PEMName_COMATTRIB = nFlags | DIMENSION PEMName_COMATTRIB[5]
[PEMName_COMATTRIB[1] = nFlags
PEMName_COMATTRIB[2] = cHelpString
PEMName_COMATTRIB[3] = cPropertyCapitalization
PEMName_COMATTRIB[4] = cPropertyType
PEMName_COMATTRIB[5] = nOptionalParams]]
ENDDEFINE
Parameters
ClassName1
Specifies the name of the class to create.AS ParentClass
Specifies the parent class on which a class or subclass is based. The parent class can be a Visual FoxPro base class, such as the Form class, or another user-defined class or subclass. The following table lists the Visual FoxPro base classes:Base class names
If you specify Custom as ParentClass, Visual FoxPro creates a non-visual user-defined class*.*
The following example code creates a subclass named
MyForm
based on the Form base class. The form contains a Click method that displays a dialog box whenMyForm
is clicked.DEFINE CLASS MyForm AS Form PROCEDURE Click = MESSAGEBOX('MyForm has been clicked!') ENDPROC ENDDEFINE
If you specify Session as ParentClass, Visual FoxPro creates a non-visual user defined class that maintains its own private Data Session. Since the Session Object is not a container, the AddObject clause is not available when you specify the Session ParentClass. The following Session properties have new default settings when used in a private Data Session (Visual FoxPro 7 and later versions):
- EXCLUSIVE = OFF
- TALK = OFF
- SAFETY = OFF
If you specify OLEPUBLIC for a class whose BaseClass is Session, the type library generated for an EXE or DLL will only contain your custom properties and methods. All intrinsic properties, methods, and events of the Session BaseClass are excluded from the type library. The behavior is supported in Visual FoxPro 7 and later.
OF ClassLibrary
Enables you to identify the class library for AS ParentClass without explicitly specifying the path to the class library containing it, such as through SET CLASSLIB or SET PROCEDURE. ClassLibrary can be a class library (.vcx), program (.prg), or compiled program (.fxp) file.If the specified ClassLibrary cannot be found when one attempts to instantiate an instance of the class, an error will occur saying, "Class definition ... is not found."
If an OF <programfile> reference is used in a program that is bound inside of an executable application, the <programfile> name should have an .fxp file name extension and not a .prg extension.
The specified ClassLibrary setting can contain a relative path as long as Visual FoxPro can locate the library along its usual class library searching paths.
Visual FoxPro will automatically add the ClassLibrary to the project during build if the program containing the class is included in the project.
OLEPUBLIC
Specifies that the class in an Automation server can be accessed by an Automation client.If you add a program containing an OLEPUBLIC class definition to a project, an executable (.exe) file or a dynamic link library (.dll) containing the class can be created interactively in the Project Manager or with BUILD EXE, BUILD DLL, or BUILD MTDLL, The EXE or DLL is automatically registered with the operating system, and becomes available to any Automation client.
For information about creating custom Automation servers, see Creating Automation Servers.
[PROTECTED | HIDDEN PropertyName1, PropertyName2 ...][Object.]PropertyName = eExpression ... Creates a class or subclass property and assigns a default value to the property. Properties are named attributes of the class and define characteristics and behaviors for the class. Classes and subclasses can have multiple properties.
Use = to assign a value to the property. The following example creates a user-defined class named
MyClass
and creates two properties called Name and Version. The Name property is initialized to the empty string and the Version property is initialized to the character string 1.0.DEFINE CLASS MyClass AS Custom Name = '' Version = '1.0' ENDDEFINE
A property can be accessed outside the class or subclass definition after the object is created with CREATEOBJECT( ):
MyObject = CREATEOBJECT('MyClass')
Properties are accessed with the following syntax:
ObjectName.Property
The .Object keyword indicates to Visual FoxPro that the property value should be applied when the ActiveX control is created.
The following example adds the Outline ActiveX control to a form. The Object keyword is used to specify a property for the Outline control before it is created.
PUBLIC frmOLETest frmOLETest = CREATEOBJECT('Form') frmOLETest.Visible = .T. frmOLETest.ADDOBJECT('OCXTest', 'BlueOLEControl', ; 'MSOutl.Outline') frmOLETest.OCXTest.AddItem('Item One') frmOLETest.OCXTest.AddItem('Item Two') DEFINE CLASS BlueOLEControl AS OLEControl * Set a property of the ActiveX control .Object.Backcolor = 16776960 * Set properties of the OLE Container Control Visible = .T. Height = 100 Width = 200 ENDDEFINE
Include PROTECTED and a list of property names to prevent access and changes to the properties from outside of the class or subclass definition. Methods and events within the class or subclass definition can access the protected properties.
In the following example, the Version property is protected, preventing it from being accessed and changed outside of the class definition. However, the Name property is not protected and can be accessed and changed.
DEFINE CLASS MyClass AS Custom PROTECTED Version Name = '' Version = '1.0' ENDDEFINE
Include HIDDEN and a list of property names to prevent access and changes to the properties from outside of the class definition. Only methods and events within the class definition can access the hidden properties. While protected properties can be accessed by subclasses of the class definition, hidden properties can only be accessed from within the class definition.
Note If you don't include the HIDDEN keyword, you can subclass Access and Assign methods.
ADD OBJECT
Adds an object to a class or subclass definition from a Visual FoxPro base class, user-defined class or subclass, or ActiveX custom control.PROTECTED
Prevents access and changes to the object's properties from outside the class or subclass definition. The PROTECTED keyword must be placed immediately before ObjectName or FoxPro generates a syntax error.ObjectName
Specifies the name of the object and is used to reference the object from within the class or subclass definition after an object is created from the class or subclass definition.AS ClassName2
Specifies the name of the class or subclass containing the object you add to the class definition. For example, the following class definition adds a command button from the CommandButton base class and a list box from the ListBox base class.DEFINE CLASS MyClass AS Custom ADD OBJECT CB1 AS CommandButton ADD OBJECT LIST1 AS ListBox ENDDEFINE
NOINIT
Specifies that an object's Init method is not executed when the object is added.WITH cPropertyList
Specifies a list of properties and property values for the object you add to the class or subclass definition. For example, the following class definition creates a class calledMyClass
, adds a command button to the class definition, and specifies the Caption and BackColor properties for the command button.DEFINE CLASS MyClass AS CUSTOM ADD OBJECT CB1 AS CommandButton; WITH Caption = 'Cancel', BackColor = 2 ENDDEFINE
FUNCTION | PROCEDURE Name[_ACCESS | _ASSIGN] | THIS_ACCESS
Create events and methods for the class or subclass. Events and methods are created as a set of functions or procedures.You can create an event function or procedure within a class or subclass definition to respond to an event. An event is an action such as a mouse click that is recognized by an object created with a class or subclass definition. For additional information about Visual FoxPro event processing, see Understanding the Event Model.
Events are called with the following syntax:
ObjectName.Event
You can also create a method function or procedure within a class or subclass definition. A method is a procedure that acts upon the object created with the class or subclass definition. Methods are called with this syntax:
ObjectName.Method
You can add _ACCESS and _ASSIGN suffixes to a procedure or function name to create an Access or Assign method for a property of the same name. The code in an Access method is executed whenever the property is queried. The code in an Assign method is executed whenever you attempt to change the value of the property.
In addition, you can create a THIS_ACCESS procedure or function that is executed whenever a value change or query is made on a member of an object.
The following code creates an object whose internal procedures, MyProperty_ACCESS and MyProperty_ASSIGN, respond to queries (Access method) and to property changes (Assign method).
Note the use of an LPARAMETERS statement to accept the value passed to the Assign method. This example also demonstrates creation of read-only properties.
DEFINE CLASS MyClass AS Custom MyProperty = 100 && A user-defined property PROCEDURE MyProperty_ACCESS && Access method WAIT WINDOW 'This is the Access method'; + ' ' + PROGRAM( ) RETURN THIS.MyProperty ENDPROC PROCEDURE MyProperty_ASSIGN && Assign method LPARAMETERS tAssign && Required to accept value WAIT WINDOW 'This is the Assign method'; + ' ' + PROGRAM( ) ENDPROC ENDDEFINE
The following code adds an Assign method to a native Visual FoxPro property that performs simple validation on the property the value.
DEFINE CLASS is used to create a Form class, frmMyForm. An Assign method, Left_ASSIGN, created by a PROCEDURE statement, runs whenever an attempt is made to assign a value to the form's Left property.
DEFINE CLASS frmMyForm AS Form PROCEDURE Left_ASSIGN && Assign method LPARAMETERS tAssign && Required to accept value DO CASE CASE tAssign < 0 && Left value negative WAIT WINDOW 'Value must be greater than 0' OTHERWISE && Left value not negative THIS.Left = tAssign ENDCASE ENDPROC ENDDEFINE
If you attempt to change the Left property value to a negative value, the method displays a message and the value is left unchanged. If you attempt to change the Left property value to a non-negative value, the method sets the property to the specified value.
Access and Assign methods are not supported for native properties, events, or methods of ActiveX controls. However, Access and Assign methods are supported for properties, events, and methods of the Visual FoxPro OLE Container in which an ActiveX control is contained.
For more information about creating Access and Assign methods with DEFINE CLASS, see Access and Assign Methods.
cParamName [AS Type][@]
Specifies the parameter and its type passed to the procedure or function of the defined class. By using the at sign (@) token, you can specify that the parameter be passed by reference. Here, the AS Type clause specifies the data type of the named parameter.Note The AS Type clause is used only for IntelliSense and class definition information stored in a type library (OLEPUBLIC). Visual FoxPro does not enforce type checking during compilation or code execution. Strict typing is also recommended for use with the interface methods specified by IMPLEMENTS.
For the parameters and their types to appear in the type library, you must use the inline parameter syntax instead of using LPARAMETERS to declare the parameters: ex. FUNCTION Publisher_ShowPrice(Bookid As Integer, Bookprice As String).
DEFINE CLASS f1 AS custom OLEPUBLIC PROTECTED myprop FUNCTION mymethod (parm1 AS integer @, parm2 AS string) ; AS integer RETURN parm1 ENDFUNC ENDDEFINE
Use AS VOID for the return value of a method if the method does not return anything (oneway procedure). This is required for certain technologies such as Microsoft COM+ Services Queued Components.
Visual FoxPro will automatically convert AS Type values when used by other COM servers. Visual FoxPro also displays type info for COM servers in IntelliSense Quick Info tips according to the following table:
VFP Defined Type COM Typelib Conversion IntelliSense Quick Info Array SAFEARRAY(type) Array BinaryMemo VARIANT — Boolean VARIANT_BOOL Logical Byte unsigned char Number Character * BSTR String Currency * CURRENCY Currency Date DATE Date DateTime DATE Date Decimal * wchar_t Number Double double Number Float VARIANT — Integer long Number Logical VARIANT_BOOL Logical Long long Number Memo VARIANT — Number double Number Object IDispatch* Object Short long Number Single * single Number String BSTR String Variant VARIANT — Void void VOID cArrayName[] [AS Type ][@][AS Type]
Specifies the name of the array used in the creation of a type library using the first AS Type clause. Using the cArrayName[] [AS Type][@] clause, you can specify strong typing for arrays so they can be correctly written as safe arrays to a type library. For example:DEFINE CLASS foo AS Session OLEPUBLIC PROCEDURE GetWidgets1(aWidgets[]) ENDPROC PROCEDURE GetWidgets2(aWidgets[] AS Integer) ENDPROC PROCEDURE GetWidgets3(aWidgets[] AS Integer @) ENDPROC PROCEDURE GetRS(oRS[] AS ADODB.RECORDSET @) ENDPROC ENDDEFINE
Note Strong typing for arrays is used primarily for type library creation and is not enforced at run time.
The type that you specify must be a valid COM data type (see the previous table). The type can also be a reference to a COM CoClass ProgID such as ADODB.Recordset.
If you specify an argument for the first AS Type clause, Visual FoxPro creates a SAFEARRAY with the specified type. If you do not specify an argument for the first AS Type clause, Visual FoxPro creates a SAFEARRAY of Variant data types. If the type specified is invalid, Visual FoxPro defaults to using the Variant data type.
Note When specifying an array, you must use square brackets ([]); DEFINE CLASS does not recognize parentheses (()) notation.
A safe array is a one or multidimensional array of a single data type, which can be of type VARIANT, allowing you to create arrays of mixed types. The safe array stores its lower bound, which does not have to be zero, and its size. Safe arrays allow locking and unlocking so you can be sure that the pointer you receive to the data is valid.
You cannot specify arrays as return types. The following code, while valid, only writes out the return type of the type library as VARIANT and not a SAFEARRAY.
PROCEDURE GetWidgets() AS aWidgets[] ENDPROC
Using the cArrayName[] [AS Type][@][AS Type] clause, you can specify complex strong typing by defining a type based on a COM class. For example:
DEFINE CLASS foo AS Session OLEPUBLIC REFERENCE "ADODB.Recordset" PROCEDURE GetRS() AS ADODB.Recordset x=CREATEOBJECT("ADODB.Recordset") RETURN X ENDPROC PROCEDURE SetRS(oRS AS ADODB.Recordset @) oRS=CREATEOBJECT("ADODB.Recordset") ENDPROC ENDDEFINE
If you pass a valid COM CoClass ProgID as an argument to an AS Type clause, Visual FoxPro includes it in the type library. For example, the following method:
PROCEDURE Test(oRS AS ADODB.Recordset @) AS ADODB.Recordset
Creates an entry in the type library:
Recordset Test([in, out] Recordset** oRS);
You cannot specify a reference to a ProgID that is generated from the type library itself. For example, you cannot reference a class that is contained within the same COM server.
You can specify ProgID' names with or without quotation marks (""). For example:
PROCEDURE Test(oRS AS "ADODB.Recordset" @) AS ADODB.Recordset
HELPSTRING cHelpString
Specifies the string added to the type library, for display in an object browser or IntelliSense, as a description of the functionality of a method.IMPLEMENTS InterfaceName
Specifies that this class definition inherits the interface (class definition) of another COM component. One class can include several IMPLEMENTS statements.DEFINE CLASS myClass AS custom olepublic IMPLEMENTS Publisher IN "mybookstore.dll" PROCEDURE Publisher_ShowPrice(cGetID AS Long) AS Short ENDPROC ENDDEFINE
EXCLUDE
Excludes the implemented interface from type library.IN TypeLib | TypeLibGUID | ProgID
Specifies the location of the interface.You can specify the COM object by TypeLib, the type library of the COM object, TypeLibGUID, the GUID of the type library, or by specifying the ProgID of the program that initializes the COM object.
DEFINE CLASS MyBooks AS Custom olepublic IMPLEMENTS Publisher IN "c:\sample4\Publisher.VB\BooksPub.dll" FUNCTION Publisher_ShowPrice(Bookid As Integer, Bookprice As String) ACTIVATE SCREEN ? TRANS(Bookid)+"-"+TRANS(Bookprice),Sys(1011),Sys(1016) ENDFUNC ENDDEFINE
When you use the TypeLibGUID option, pass the option with the major and minor version designation as in the following example:
IMPLEMENTS IDict1 IN {04BCEF93-7A77-11D0-9AED-CE3E5F000000}#1.0
The Typelib option is the least recommended way to specify the typelib since this requires a file name whose path may differ from computer to computer. If your DLL is being distributed, consider using TypeLibGUID or ProgID.
When you implement an interface, you must include in the class definition all methods of that interface. Use the interface name as preface to the method name (for example, Publisher_ShowPrice). This also avoids conflict between two interfaces that contain methods of the same name since you can have multiple IMPLEMENTS statements in a class definition. You must use the interface name exactly as it appears in the type library. For interface names preceded by an underscore, "_", such as the ADODB Recordset class, the underscore is optional.
Since properties are essentially stored as two methods inside a type library (put and get), the class definition must include both methods.
Tip Use the Visual FoxPro Object Browser to drag and drop an interface definition to your code to save time. The IMPLEMENTS statement, along with all the implemented methods with their proper parameter signatures, will be automatically written out for you.
Certain technologies, such as Microsoft COM+ Events, require the COM component to implement the interface of the event class being bound to.
NODEFAULT
Prevents Visual FoxPro from performing its default event or method processing for Visual FoxPro events and methods. For example, if the KeyPress event occurs, including NODEFAULT in the KeyPress procedure or function prevents Visual FoxPro from placing the key press into the Visual FoxPro keyboard buffer. This makes it possible for you to create a KeyPress procedure so you can test which key is pressed before the key is sent to the keyboard buffer.You can place NODEFAULT anywhere within the event or method procedure. Note that NODEFAULT may also be placed within an event or method procedure in the Form Designer.
cStatements
[ENDFUNC | ENDPROC]]
...
ENDDEFINEcStatements are the Visual FoxPro commands that are executed when an event or method is executed.
Event and method functions and procedures can accept values by including a PARAMETERS or LPARAMETERS statement as the first executable line of the function or procedure.
Unlike most Visual FoxPro keywords, you cannot abbreviate ENDFUNC and ENDPROC. This prevents conflicts with the ENDFOR and ENDPRINTJOB keywords.
The following example demonstrates how to create an event procedure that displays a message when the command button is clicked. This event procedure overrides the default command button Click event.
DEFINE CLASS MyClass AS Custom ADD OBJECT MyButton AS CommandButton ADD OBJECT MyList AS ListBox PROCEDURE MyButton.Click = MESSAGEBOX('This is my click event procedure') ENDPROC ENDDEFINE
PEMName_COMATTRIB
Creates an array that specifies type library attributes for the PEMName property or method. This feature applies only to OLEPUBLIC classes. Use this option to specify additional information about the property or method that you want written to the type library such as a description or read-only attribute.The PEMName_COMATTRIB setting can either be a property or property array. If a property is specified, then the value assigned is that of nFlags (first element of the array). Visual FoxPro generates an error for invalid values or types in the PEMName_COMATTRIB array. Empty elements will use default values.
COMATTRIB element Description Type 1 Attribute flags Number 2 Help string String 3 Capitalization String 4 Property type String 5 Number of parameters If you specify fewer than the actual number of parameters, the number greater than those declared are optional.
Number
Note Unlike Access and Assign method, the _COMATTRIB properties described here are automatically marked hidden and are not accessible in Visual FoxPro. They are strictly for use by Visual FoxPro during the Build process when writing out a COM type library.
nFlags
Specifies a set of attribute flags for PEMName as it appears in the type library. The following table describes the valid flags.nFlag Value #DEFINE Description 0x1 (1) COMATTRIB_RESTRICTED The property/method should not be accessible from macro languages. This flag is intended for system-level functions or functions that type browsers should not display. 0x40 (64) COMATTRIB_HIDDEN The property/method should not be displayed to the user, although it exists and is bindable. 0x400 (1024) COMATTRIB_NONBROWSABLE The property/method appears in an object browser, but not in a properties browser. You can also use either one of the following as valid flag values. Using both properties is the same as using neither.
#DEFINE Value Description COMATTRIB_READONLY 0x100000 The property is read-only (applies only to Properties). Equivalent to a PropertyGet. COMATTRIB_WRITEONLY 0x200000 The property is write-only (applies only to Properties). Equivalent to a PropertyLet. cHelpString
Specifies a string value to be stored in the type library for the PEMName property*.* For methods, use the HELPSTRING cHelpString clause.cPropertyCapitalization
Specifies the property name, a string value, as it will appear in the type library. All capitalization is preserved. Without this setting, Visual FoxPro will write out the property to the type library in all uppercase.cPropertyType
This string value is property data type as it appears in the type library (same as AS Type clause). Applies to Properties only.nOptionalParms
Specifies the number of optional parameters in a method. If this value is 2 for a method with 5 parameters, then the last 3 are optional. With late-binding clients, default values for optional parameters will still be .F. and PCOUNT() will accurately reflect the true number of parameters passed in. For early-bound clients, default values for optional parameters will always be set to "" and PCOUNT() will always be total number of parameters for the method (not number passed in). Applies to Methods only.**Note **COMATTRIB_RESRICTED means that macro-oriented programmers should not be allowed to access this member. These members are usually treated as _HIDDEN by tools such as Visual Basic, with the main difference being that code cannot bind to those members. COMATTRIB_HIDDEN means that the property should never be shown in object browsers, property browsers, and so on. This function is useful for removing items from an object model. Code can bind to the member, but the user will never know that the member exists. COMATTRIB _NONBROWSABLE means that the property should not be displayed in a properties browser. It is used in circumstances in which an error would occur if the property were shown in a properties browser. Early and late binding impose differing access restrictions. Early binding clients will not be able to write to a read-only property, nor read from a write-only property because there will not be an entry in the vtable. Late binding clients can still access a propertyget on a write-only or a propertyput on a read-only PEMName.
Remarks
User-defined classes are a set of commands placed in a program file, similar to a procedure. The commands that follow the class or subclass definition define the properties, events, and methods for the class or subclass.
Note You cannot include normal executable program code after procedures in a program file; only class definitions, procedures, and user-defined functions can follow the first DEFINE CLASS, PROCEDURE or FUNCTION command in the file.
Class and subclass definitions created with DEFINE CLASS cannot be placed within structured programming commands, such as IF ... ENDIF or DO CASE ... ENDCASE. Nor can they be placed in loops, such as DO WHILE ... ENDDO or FOR ... ENDFOR.
To create an object from a class or subclass definition, issue CREATEOBJECT( ) with the class or subclass name.
If you use the IMPLEMENTS clause, you must include all the methods of the specified interface. Visual FoxPro does not enforce strong typing so you must ensure that you use valid data types. Because properties are stored as two methods, PUT and GET, you must include both methods in the class definition.
Access and Assign methods are protected by default - you cannot access or make changes to an Access or Assign method from outside of the class in which the Access or Assign method is created.
You can view the code for Access and Assign methods in the Trace window of the Debugger window. However, Access and Assign methods cannot be executed from within the Watch and Local windows of the Debugger window.
Arrays are passed to Access and Assign methods in the same manner as standard Visual FoxPro procedures.
The entire array is passed to an Access or Assign method if you issue SET UDFPARMS TO REFERENCE or preface the array name with @. The first element of the array is passed by value if you issue SET UDFPARMS TO VALUE or enclose the array name by parentheses. Array elements are always passed by value. See SET UDFPARMS for more information about passing values and arrays.
Example
The following example uses DEFINE CLASS and CREATEOBJECT( ) to create two custom classes named FormChild and FormGrandChild from the Visual FoxPro Form base class. ACLASS( ) is used to create an array named gaNewarray
containing the class names, which are then displayed.
CLEAR
frmMyForm = CREATEOBJECT("FormGrandChild")
FOR nCount = 1 TO ACLASS(gaNewarray, frmMyForm) && Creates an array
? gaNewarray(nCount) && Displays the names of the classes
ENDFOR
RELEASE frmMyForm
DEFINE CLASS FormChild AS FORM
ENDDEFINE
DEFINE CLASS FormGrandChild AS FormChild
ENDDEFINE
The following code defines an array of typelib attributes using the _COMATTRIB parameter.
#INCLUDE foxpro.h
DEFINE CLASS myclass AS CUSTOM olepublic
* Define property
MyProperty = 5.2
* Set the COM attributes for MyProperty
DIMENSION MyProperty_COMATTRIB[4]
myproperty_COMATTRIB[1] = COMATTRIB_READONLY
myproperty_COMATTRIB[2] = "Helptext displayed in object browser"
myproperty_COMATTRIB[3] = "MyProperty"&& Proper capitalization.
myproperty_COMATTRIB[4] = "Float"&& Data type
ENDDEFINE
If you want to only set the nFlags element, you do not need to dimension the _COMATTRIB property as an array.
#INCLUDE foxpro.h
DEFINE CLASS myclass AS SESSION olepublic
* Define property
MyProperty = "Test"
* Only set the nFlags attribute for MyProperty
myproperty_comattrib = COMATTRIB_READONLY
ENDDEFINE
See Also
:: Scope Resolution Operator | ADD CLASS | _BROWSER | CREATE CLASS | CREATE CLASSLIB | CREATEOBJECT( ) | DODEFAULT( ) Function | EVENTHANDLER( ) | GETOBJECT( ) | MODIFY CLASS | OBJECT BROWSER | RELEASE CLASSLIB | Session Object | SET CLASSLIB | WITH ... ENDWITH | NODEFAULT Command