DEFINE CLASS Command
Creates a user-defined class or subclass and specifies the properties, events, and methods for the class or subclass.
Warning
Modifying read-only properties from base classes generates an error message.
The full syntax for the DEFINE CLASS main clauses appears as follows:
DEFINE CLASS ClassName1 AS ParentClass [OF ClassLibrary] [OLEPUBLIC]
[[PROTECTED | HIDDEN] PropertyName1, PropertyName2 ...]
[[.]Object.]PropertyName = eExpression ...]
[PEMName_COMATTRIB = nFlags | DIMENSION PEMName_COMATTRIB[numElements]
[PEMName_COMATTRIB[1] = nFlags
PEMName_COMATTRIB[2] = cHelpString
PEMName_COMATTRIB[3] = cPropertyCapitalization
PEMName_COMATTRIB[4] = cPropertyType
PEMName_COMATTRIB[5] = nOptionalParams]]
[ADD OBJECT [PROTECTED] ObjectName AS ClassName2 [NOINIT] [WITH cPropertylist]]
[IMPLEMENTS cInterfaceName [EXCLUDE] IN TypeLib | TypeLibGUID | ProgID ]
[[PROTECTED | HIDDEN] FUNCTION | PROCEDURE Name[_ACCESS |_ASSIGN]
([cParamName | cArrayName[] [AS Type][@]]) [AS Type]
[HELPSTRING cHelpString] | THIS_ACCESS(cMemberName) [NODEFAULT]
cStatements
[ENDFUNC | ENDPROC]
ENDDEFINE
Remarks
The following code shows a summary of the main clauses:
DEFINE CLASS Clause
[Property_Definition_Clause]
[PEMName_COMATTRIB Clause]
[ADD OBJECT Clause]
[IMPLEMENTS Clause]
[Function_Procedure_Definition_Clause]
ENDDEFINE
The following sections describe detailed syntax and parameters for each clause of the DEFINE CLASS command:
Code for user-defined classes is stored in a program (.prg) file, similar to procedures.
Note
You cannot follow procedures in a .prg file with normal executable program code. Only class definitions, other procedures, and user-defined functions can follow the first DEFINE CLASS, PROCEDURE or FUNCTION statement in the file. For more information, see User-Defined Procedures and Functions.
You cannot place class definitions created with DEFINE CLASS within structured programming commands, for example, IF ... ENDIF or DO CASE ... ENDCASE, or in loops, such as DO WHILE ... ENDDO or FOR ... ENDFOR.
To instantiate, or create instances of, the class you defined, use the CREATEOBJECT( ) function. You can access public properties and call method and event functions and procedures outside the class definition as shown in the following example:
myObject = CREATEOBJECT('MyClass')
myObject.myPropertyName =
myObject.myMethodName( argument1, argument2, ... )
myObject.myEventName
Protected or hidden properties, methods, and events have restricted access as defined by the PROTECTED and HIDDEN keywords. For more information, see DEFINE CLASS Command - Property Definition Clause and DEFINE CLASS Command - Function or Procedure Definition Clause.
Visual FoxPro converts AS Type clause values automatically when other COM servers use them. When you type the AS clause in code, IntelliSense functionality in Visual FoxPro displays the type information for COM servers.
The following table shows the data type information that is displayed.
VFP defined type |
COM Typelib conversion |
IntelliSense displays |
---|---|---|
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 |
You can view code for Access and Assign methods in the Trace window of the Debugger window. However, you cannot execute Access and Assign methods from the Watch and Local windows of the Debugger window. For more information, see Access and Assign Methods, Trace Window, and Debugger Window.
A safe array is a one- or multi-dimensional 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.
Examples
Example 1
The following example creates a class named MyForm from the Form base class and creates a protected property named Version. The class also contains another property called Caption, which is not protected. The class definition initializes the default values of Version and Caption to the strings "1.0" and "My Form", respectively.
DEFINE CLASS MyForm AS Form
PROTECTED Version
Version = "1.0"
Caption = "My Form"
ENDDEFINE
Example 2
The following example creates the form frmOLETest from a Form base class and uses the AddObject method to add an object named OCXTest based on the BlueOLEControl class created by DEFINE CLASS and specifies the OLE class for the Listview ActiveX control. The .Object keyword is used to specify a value for the BackColor property of the control before it is created.
PUBLIC frmOLETest
frmOLETest = CREATEOBJECT('Form')
frmOLETest.Visible = .T.
frmOLETest.AddObject('OCXTest', 'BlueOLEControl', 'MSComctlLib.ListViewCtrl')
frmOLETest.OCXTest.View = 2
frmOLETest.OCXTest.ListItems.Add(1,'one','Item One')
frmOLETest.OCXTest.ListItems.Add(2,'two','Item Two')
DEFINE CLASS BlueOLEControl AS OLEControl
* Set property for Outline ActiveX control.
.Object.Backcolor = 16776960
* Set properties for the OLE Container control.
Visible = .T.
Height = 100
Width = 200
ENDDEFINE
For more information, see AddObject Method.
Example 3
The following example demonstrates how to define an array of type library attributes using the DIMENSION PEMName**_COMATTRIB** clause:
#INCLUDE foxpro.h
DEFINE CLASS myOLEClass AS Custom OLEPUBLIC
MyProperty = 5.2
* Set COM attributes for MyProperty.
DIMENSION MyProperty_COMATTRIB[4]
myProperty_COMATTRIB[1] = COMATTRIB_READONLY
myProperty_COMATTRIB[2] = "Help text displayed in object browser"
myProperty_COMATTRIB[3] = "MyProperty" && Proper capitalization.
myProperty_COMATTRIB[4] = "Float" && Data type
ENDDEFINE
However, if you want to set only the nFlags element, you do not need to create an array:
#INCLUDE foxpro.h
DEFINE CLASS myOLEClass AS Custom OLEPUBLIC
MyProperty = "Test"
* Set the only the nFlags attribute for MyProperty.
myProperty_COMATTRIB = COMATTRIB_READONLY
ENDDEFINE
Example 4
The following example creates a class named MyForm from the Form base class and adds a command button from the CommandButton base class and a check box from the CheckBox base class:
DEFINE CLASS MyForm AS Form
ADD OBJECT cmdButton1 AS CommandButton
ADD OBJECT chkBox1 AS CheckBox
ENDDEFINE
As another example, the following code creates a class called MyForm, adds a command button and check box to the class, and specifies values for the Caption properties of the command button and check box.
DEFINE CLASS MyForm AS Form
ADD OBJECT cmdButton1 AS CommandButton WITH Caption = "Yes"
ADD OBJECT chkBox1 AS CheckBox WITH Caption = "Click Me"
ENDDEFINE
Example 5
The following example creates a class named MyPublisherClass as a Custom class, uses the OLEPUBLIC keyword to specify that Automation clients can access the class when included in an Automation server, uses the IMPLEMENTS clause to inherit the class definition inherit from the Publisher class definition in the type library, MyBookStore.dll, and includes the method ShowPrice from the Publisher interface.
DEFINE CLASS MyPublisherClass AS Custom OLEPUBLIC
IMPLEMENTS Publisher IN "MyBookStore.dll"
PROCEDURE Publisher_ShowPrice(cGetID AS Long) AS Short
ENDPROC
ENDDEFINE
Example 6
The following example creates a class named MyForm from the Form base class and contains a procedure for a Click event definition. The form created from the class contains a Click method that displays a dialog box when you click the form.
DEFINE CLASS MyForm AS Form
PROCEDURE Click
= MESSAGEBOX('MyForm has been clicked!')
ENDPROC
ENDDEFINE
As another example, the following code contains a procedure for one of the objects added to the class. This event procedure overrides the default Click event for the command button:
DEFINE CLASS MyForm AS Form
ADD OBJECT MyButton AS CommandButton
ADD OBJECT chkBox1 AS CheckBox
PROCEDURE MyButton.Click
= MESSAGEBOX('This is my click event procedure')
ENDPROC
ENDDEFINE
Example 7
The following example shows how you can specify strong typing using PROCEDURE cArrayName[] [AS Type][@][AS Type] clause so that arrays can be correctly written as safe arrays to a type library:
DEFINE CLASS mySession 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
As another example, the following code demonstrates how you can specify strong complex typing by defining a type based on a COM class:
DEFINE CLASS mySession AS Session OLEPUBLIC
PROCEDURE GetRS() AS ADODB.Recordset
x=CREATEOBJECT("ADODB.Recordset")
RETURN X
ENDPROC
PROCEDURE SetRS(oRS AS ADODB.Recordset @)
oRS=CREATEOBJECT("ADODB.Recordset")
ENDPROC
ENDDEFINE