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

See Also

Reference

:: Scope Resolution Operator

ADD CLASS Command

CREATE CLASS Command

CREATE CLASSLIB Command

DODEFAULT( ) Function

EVENTHANDLER( ) Function

GETOBJECT( ) Function

MODIFY CLASS Command

RELEASE CLASSLIB Command

Other Resources

Commands (Visual FoxPro)