MORE INFORMATION
Object
An object is an item in the system that exposes interfaces to
manipulate the data or properties of the object. An object is created
by directly or indirectly calling the CoCreateInstance() application
programming interface (API), which in turn creates a new instance of
the object and returns a pointer to a requested interface. For more
details, see pages 93 and 94 of the "OLE 2.0 Design Specification."
Interfaces
An interface is a group of related functions. Communication between
two objects in a system occurs by calling the functions in an
interface through a pointer to that interface. An interface pointer is
originally obtained at the time the object is created.
A good example of an interface is a window that supports drag and
drop. The window exposes an interface with methods that could be used
during drag and drop. The object being dragged could communicate with
the window through this interface. Such an interface might resemble
the following:
interface IDropTarget : IUnknown {
virtual HRESULT DragEnter() = 0; // Mouse entered the window.
virtual HRESULT DragOver() = 0; // Called each mouse move.
virtual HRESULT DragLeave() = 0; // Mouse left the window.
virtual HRESULT Drop() = 0; // Item dropped on the window.
};
For more information on interfaces, refer to pages 57-60 of the "OLE
2.0 Design Specification."
IUnknown
All interfaces used in the component object model are derived from a
base interface called IUnknown. The methods contained within IUnknown
are related because they deal with object maintenance. The IUnknown
interface is defined as:
interface IUnknown {
virtual HRESULT QueryInterface( REFIID, VOID FAR *) = 0;
virtual ULONG AddRef() = 0;
virtual ULONG Release() = 0;
};
IUnknown::QueryInterface is used for interface negotiation. The other
methods are used for reference counting to control the life of the
object.
More information on the IUnknown interface can be found on pages 81-83
of the "OLE 2.0 Design Specification."
Interface Negotiation
Given a pointer to a particular interface, an object can be queried
for another interface. This is done by calling the QueryInterface()
method in an interface. The following code demonstrates querying for
the IOleObject interface:
// Assume that a pointer to an arbitrary interface, pint,
// exists.
LPOLEOBJECT pOleObject;
HRESULT hErr;
// Query the interface.
hErr = pint->QueryInterface(IID_IOleObject, (LPVOID FAR *)
&pOleObject);
if (hErr == NOERROR)
// Object supports this IOleObject. The IOleObject
// methods can now be called through pOleObject.
else
// Object does not support IOleObject.
Reference Counting
Interface lifetime is controlled through reference counting. To
increment the reference count on an interface, call the AddRef()
method. To decrement the reference count on an interface, call the
Release() method. Once an interface's reference count goes to zero,
the pointer to that interface is no longer valid. If the reference
count on all of an object's interfaces is zero, then the object can be
freed because there are no longer any pointers to the object.
More information on reference counting can be found on pages 83 and 84
of the "OLE 2.0 Design Specification."
Aggregation
Aggregation is the ability of an object to be re-used or extended
dynamically, without having to recompile the original object code. For
more information on the process of aggregation, please refer to the
"OLE 2.0 Design Specification," pages 61-63.