DEFINE CLASS Command

Creates a user-defined class or subclass and specifies the properties, events, and methods for the class or subclass.

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 [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

    ActiveDoc ProjectHook
    CheckBox Label
    Column Line
    ComboBox ListBox
    CommandButton OLEControl
    CommandGroup OLEBoundControl
    Container OptionButton
    Control OptionGroup
    Cursor Page
    Custom PageFrame
    DataEnvironment Relation
    EditBox Separator
    Form Session
    FormSet Spinner
    Grid TextBox
    Header Timer
    Hyperlink ToolBar
    Image  

    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 when MyForm 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 (this and later versions of Visual FoxPro):

    • 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 this and later versions of Visual FoxPro 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."

    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 called MyClass, 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 @ token, you can specify that the parameter be passed by reference. AS Type, here, 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
    BinaryMemo VARIANT
    Boolean VARIANT_BOOL Logical
    Byte unsigned char Number
    Character VARIANT
    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
  • 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 "mybooksore.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 machine to machine. 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 that makes it possible for you to 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]]
    ...
    ENDDEFINE

    cStatements 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 won't 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