What does an Interface look like?

An INTERFACE  is a definition of a set of methods and properties which may be implemented on an object.  Think of it as much like a TYPE declaration, except that it contains Method and Property declarations instead of member variables.  One interface definition may be used in many different classes and objects.

An Interface may appear in two general forms: the declaration form and the implementation form.

In the declaration form, the Interface just provides the "signature" of the member methods, without any other source code:

INTERFACE MyInterface
  INHERIT IAutomation
  METHOD Method1(parm AS LONG)
  PROPERTY GET Prop1() AS STRING
  PROPERTY SET Prop1(BYVAL TEXT AS STRING)
END INTERFACE

This type of declaration interface can be used to provide a description of external interfaces, which you plan to access through COM services, or just as additional self-documentation of internal code.

In the implementation form, it is part of a CLASS definition, so it contains the complete source code to implement each of the member Methods and Properties.

CLASS AnyClass
  INTERFACE AnyInterface
    INHERIT IAutomation
    METHOD Method1(parm AS LONG)
      CALL abc(parm)
    END METHOD

    METHOD Method2(parm AS LONG)
      CALL abc(Parm*1)
    END METHOD
  END INTERFACE
END CLASS

In this case, you have the complete definition of an object, with code implemented so the methods can be called and executed.

The first entry in every INTERFACE block must be the base class upon which it is built.  In PowerBASIC, you choose one of the System Base Classes (IUnknown, IAutomation, or IDispatch), or you might decide to inherit a User Base Class instead.

INTERFACE CustomIface
  INHERIT IUNKNOWN
  METHOD  MethodDef()...
END INTERFACE

The above code defines a custom interface whose methods are available for direct access only.  It uses custom calling conventions and does not support an hResult (OBJRESULT) return value.

INTERFACE AutoIface
  INHERIT IAutomation
  METHOD  MethodDef()...
END INTERFACE   

The above code defines an automation interface whose methods are available for direct access only.  It uses automation calling conventions and always supports an hResult (OBJRESULT) return value. The above two forms will typically be used for internal objects, since they offer the best performance.  Every PowerBASIC interface and every COM interface must ultimately inherit from IUnknown.  As required base classes, the IUnknown and IAutomation declarations are built into the PowerBASIC Compiler.

INTERFACE DispatchIface
  INHERIT IDISPATCH
  METHOD  MethodDef()...
END INTERFACE

The above code defines a dual interface whose methods are available for both direct access and Dispatch access.  This is the form you will typically use for COM objects, since it offers the best compatibility with varied client modules.

Every method and property in a dual interface needs a positive, long integer value to identify it.  That integer value is known as a DispID (Dispatch ID), and it's used internally by COM services to call the correct function on a Dispatch interface.  You can specify a particular DispID by enclosing it in angle brackets immediately following the Method/Property name in an Interface definition block.

INTERFACE DualIface
  INHERIT IDISPATCH
  METHOD  MethodOne <76> ()
  METHOD  MethodTwo <77> ()
END INTERFACE

If you don't specify a DispID, PowerBASIC will assign a random value for you.  This is fine for internal objects, but may cause a failure for published COM objects, as the DispID could change each time you compile your program.

 

See Also

What is an object, anyway?

What does a Class look like?

What is a Base Class?

Just what is COM?