PowerBASIC creates objects which are fully compliant with COM specifications. It can also create COM-aware applications - which can access COM-compliant objects in other components.
PowerBASIC provides two groups of function which enable programmers to work with objects, their interfaces (methods and properties) and the classes from which they are derived.
The first group allows programmers to define a class (the Class/End Class statements and everything in-between). The second group enables the use of a class to create and manage objects within a PowerBASIC application (outside the Class/End Class code blocks).
The two groups are presented next, followed by a discussion of how all of these functions play together.
First, here are the PowerBASIC functions for defining a class.
Class, Instance, Interface, Inherit, Method
Object Get, Object Set, Object Let
And here are the PowerBASIC functions for using a class within an application to create and manage objects.
GUID$, GUIDTXT$, CLSID$, PROGID$, IDISPINFO
Property Get, Property Set
VariantVT, Variant$, Variant#, Reset
IsInterface, IsNothing, IsObject
Let (w/Object), Let (w/Variants), Me, MyBase, ObjPtr, ObjActive
#COM DOC, #COM HELP, #COM NAME, #COM GUID
The "Object" in COM refers to a special code library which consists of both variables and procedures. In COM terminology, variables and procedures are called properties and methods. Some of the variables/procedures are exposed - meaning that they may be called by applications outside the code library. Other variables/procedures are private and may only be accessed within the code library.
A COM object is simply an object (code library - collection of properties and methods) which conforms to the Microsoft COM specification. COM objects are kept in files, usually called COM components or COM servers, similar to the way in which DLL files are used to store libraries of code. These files may contain more than one object.
However, DLLs are typically "in-process" libraries, which means they are loaded into the address space of the calling application. COM components do not share the address space of the calling application, and are referred to as "out-of-process".
What COM components actually contain are the blueprints for objects - the compiled source code that will be loaded into memory for actual use. When a copy of the blueprint is loaded into memory it becomes available for use by the calling program. The working copy is called an "object". Multiple copies of the blueprint (code) can be loaded into memory, creating multiple objects, each of which are totally independent of one another.
The blueprint for an object, the compiled code found in the COM component file, is called a "class". A class contains both properties (variables) and methods (procedures). As noted above, some of the properties and methods may be called from outside the object, while others may only be used within the object.
Each object (a copy of a class, loaded into memory, and usually associated with an object variable) is called an "instance" of the class. Each instance is totally separate from all other instances, meaning it's properties can be changed independently of properties values in other instances.
The complete set of exposed properties and methods are called an object's "interface", referring to the way in which code outside an object can interface with the code inside the object. Note that not all methods within an object are exposed, and hence not all are part of an object's interface.
Note that a PowerBASIC application may include objects of its own. In general, objects do not have to be in a separate file, nor do they have to be COM-compliant (there are competing interprocess communication models), although all PowerBASIC objects are COM-compliant.
Syntax - Using Objects
Before getting into more detail about object, classes, and interfaces, let's take a quick look at some simple source code that accesses an object. Consider an object whose interface includes a Print method and a Status property. The commands for creating an object are discussed later, but here's a quick look at the syntax for using an object and its interface.
MyObject.Print "hello" 'method "Print", with a text argument a$ = MyObject.Status 'property "Status", assigned to a variable
This notation is similar to UDT structures, except that an object has both procedures and properties, rather than just the properties of a UDT.
Properties Are Methods
Even though the property example above might be interpreted as accessing a variable with MyObject called "Status", the command "MyObject.Status" is actually running a method (procedure) called "Status" within MyObject. The return value of the procedure is what is passed to the variable a$. More on this later.
More on Interface
The interface is the key information about an object that a programmer must know in order to use an existing object in a program. Creating an object requires even more in-depth understanding of how objects work, particularly in defining and managing the object's interface.
In general, there are two basic interfaces supported by the COM specification - direct and dispatch. With direct, a table is built of pointers for all methods exposed by the object and the calling program uses the pointers to jump immediately to the memory location and to execute the method found there. The table is called a virtual function table (VFT or VTBL). PowerBASIC handles creation of the table, so its use is transparent to programmers.
With a dispatch interface, the calling program simply passes a text string containing the name of the method. Though simpler, this approach is somewhat slower so most programmers avoid it entirely.
The COM specification also allows an object to support BOTH the direct and dispatch interfaces. Also, a class may have more than one direct interface, but only one DUAL or dispatch interface.
Classes, objects and interfaces are assigned unique numbers which differentiate them from any other class/object/interface in the world. The technique for generating a GUID is based on a randomly generated 128-bit string. Windows supplies API for GUID generation.
In addition to a numerical assignment, many programmers also assign a PROGID$, which is simply a more user-friendly name for classes, objects, and interfaces. PROGID$ names are not necessarily unique.
The COM specification requires that all objects provide three common methods AddRef(), Release() and QueryInterface(). Together, these three methods are known as the IUNKNOWN interface. PowerBASIC automatically handles the creation of these methods by the inclusion of an INHERIT IUNKNOWN statement, as shown in an example below.
In addition to the three IUNKNOWN methods, there are several other methods which programmers commonly include in objects, as shown in the following table.
Note that PowerBASIC uses "Create" as a synonym for "Constructor". It also uses "Destroy" as a synonym for "Destructor". The synonyms may be used as the method names in a class.
Automation methods must use the following data types for parameters, return values, and assignment variables.
BYTE INTEGER SINGLE CURRENCY WORD LONG DOUBLE OBJECT DWORD QUAD STRING VARIANT
Automation Methods return a hidden result code, called hResult. It reports the success/failure of a call to a property or method.
Example Class Source Code
Writing the code to create classes and COM components is much like writing any other application code. However, the terminology is somewhat different and there are over a dozen special commands to learn.
Here's the source code for creating a simple class, consisting of a single method.
CLASS MyClass INSTANCE Counter AS LONG ' defines variable Counter INTERFACE MyInterface ' defines 1 inteface (can be >1) INHERIT IUNKNOWN ' inherit the base class METHOD BumpIt(Inc AS LONG) AS LONG Temp& = Counter + Inc INCR Counter METHOD = Temp& END METHOD END INTERFACE ' more interfaces could be implemented here END CLASS
And here is the code which creates an object using the class and then uses one of the object's methods.
FUNCTION PBMAIN() DIM Stuff AS MyInterface LET Stuff = CLASS "MyClass" x& = Stuff.BumpIt(77) END FUNCTION
Example COM Component Source Code
... in work
Object/Class Function Summary
These function are provided in alphabetical order.
Object Function Reference
Here's a quick reference of the available object functions, in alphabetical order.
... in work
If you have any suggestions or corrections, please let me know.