14    Connectable Objects

[Footnote 63] The COM technology known as Connectable Objects (also called ``connection points'') supports a generic ability for any object, called in this context a ``connectable'' object, to express these capabilities:

Support for these capabilities involves four interfaces: IConnectionPointContainer(), IEnumConnectionPoints(), IConnectionPoint(), and IEnumConnections(). A ``connectable object'' implements IConnectionPointContainer() to indicate existence of outgoing interfaces. Through this interface a client can enumerate connection points for each outgoing IID (via an enumerator with IEnumConnectionPoints()) and can obtain an IConnectionPoint() interface to a connection point for each IID. Through a connection point a client starts or terminates an advisory loop with the connectable object and the client's own sink. The connection point can also enumerate the connections it knows about through an enumerator with IEnumConnections().

14.1    Connectable Objects Interface Descriptions

14.1.1    IConnectionPoint

The ability to connect to a single outgoing interface (that is, for a unique IID) is provided by a "connection point" sub-object that is conceptually owned by the connectable object. The object is separate to avoid circular reference counting problems. Through this interface the connection point allows callers to connect a sink to the connectable object, to disconnect a sink, or to enumerate the existing connections.

IDL:

    [
    uuid(B196B286-BAB4-101A-B69C-00AA00341D07)
        , object, pointer_default(unique)
    ]
    interface IConnectionPoint : IUnknown
        {
        HRESULT GetConnectionInterface([out] IID *pIID);
        HRESULT GetConnectionPointContainer([out] IConnectionPointContainer **ppCPC);
        HRESULT Advise([in] IUnknown *pUnk, [out] DWORD *pdwCookie);
        HRESULT Unadvise([in] DWORD dwCookie);
        HRESULT EnumConnections([out] IEnumConnections **ppEnum);
        }

A connection point is allowed to stipulate how many connections (one or more) it will allow in its implementation of Advise(). A connection point that allows only one interface can return E_NOTIMPL from EnumConnections.  

IConnectionPoint::GetConnectionInterface()

NAME

IConnectionPoint::GetConnectionInterface() - Returns the IID of the outgoing interface managed by this connection point

Synopsis

#include <ocidl.h>

HRESULT IConnectionPoint::GetConnectionInterface((
        [out] IID * pIID );

Description

Returns the IID of the outgoing interface managed by this connection point. This is provided such that a client of IEnumConnectionPoints() can determine the IID of each connection point thus enumerated. The IID returned from this method must enable the caller to access this same connection point through IConnectionPointContainer::FindConnectionPoint.

This function must be completely implemented in any connection point; therefore E_NOTIMPL is not an acceptable return code.

Parameters

pIID

A pointer to the caller's variable to receive the IID of the outgoing interface managed by this connection point.

Return Values

S_OK

Success.

E_POINTER

The address in pIID is not valid (such as NULL).

E_UNEXPECTED

An unknown error occurred.

 

IConnectionPoint::GetConnectionPointContainer()

NAME

IConnectionPoint::GetConnectionPointContainer() - Retrieves the IConnectionPointContainer() interface pointer to the connectable object that conceptually owns this connection point.

Synopsis

#include <ocidl.h>

HRESULT IConnectionPoint::GetConnectionPointContainer(
        [out] IConnectionPointContainer ** ppCPC );

Description

Retrieves the IConnectionPointContainer() interface pointer to the connectable object that conceptually owns this connection point. The caller becomes responsible for the pointer on a successful return.

E_NOTIMPL is not an allowable return code.

Parameters

ppCPC

A pointer to the caller's variable in which to return a pointer to the connectable object's IConnectionPointContainer() interface. The connection point will call IConnectionPointContainer::AddRef() before returning and the caller must call IConnectionPoint::Release() when it is done using the pointer.

Return Values

S_OK

Success

E_POINTER

The value in ppCPC is not valid (such as NULL).

E_UNEXPECTED

An unknown error occurred.

 

IConnectionPoint::Advise()

NAME

IConnectionPoint::Advise() - Establishes an advisory connection between the connection point and the caller's sink object identified with pUnk.

Synopsis

#include <ocidl.h>

HRESULT IConnectionPoint::Advise((
        [in] IUnknown * pUnk,
        [out] DWORD * pdwCookie );

Description

Establishes an advisory connection between the connection point and the caller's sink object identified with pUnk. The connection point must call pUnk->QueryInterface(iid, ...) on this pointer in order to obtain the correct outgoing interface pointer to call when events occur, where iidis the inherent outgoing interface IID managed by the connection point (that is, the that when passed to IConnectionPointContainer::FindConnectionPoint would return an interface pointer to this same connection point).

Upone successful return, the connection point provides a unique ``cookie'' in *pdwCookie that must be later passed to IConnectionPoint::Unadvise() to terminate the connection.

Parameters

pUnk

The IUnknown() pointer to the client's sink that wishes to receive calls for the outgoing interface managed by this connection point. The connection point must query this pointer for the correct outgoing interface. If this query fails, this member returns CONNECT_E_CANNOTCONNECT.

pdwCookie

A pointer to the caller's variable that is to receive the connection ``cookie'' when connection is successful. This cookie must be unique for each connection to any given instance of a connection point.

Return Values

S_OK

The connection has been established and *pdwCookie has the connection key.

E_POINTER

The value of pUnk or pdwCookie is not valid (NULL cannot be passed for either argument).

E_UNEXPECTED

An unknown error occurred.

E_OUTOFMEMORY

There was not enough memory to complete the operation, such as if the connection point failed to allocate memory in which to store the sink's interface pointer.

CONNECT_E_ADVISELIMIT

The connection point has already reached its limit of connections and cannot accept any more.

CONNECT_E_CANNOTCONNECT

The sink does not support the interface required by this connection point.

 

IConnectionPoint::Unadvise()

NAME

IConnectionPoint::Unadvise() - Terminates an advisory connection previously established through IConnectionPoint::Advise()

Synopsis

#include <ocidl.h>

HRESULT IConnectionPoint::Unadvise((
        [in] DWORD dwCookie );

Description

Terminates an advisory connection previously established through IConnectionPoint::Advise(). The dwCookie argument identifies the connection to terminate.

Parameters

dwCookie

The connection ``cookie'' previously returned from IConnectionPoint::Advise().

Return Values

S_OK

The connection was successfully terminated.

E_UNEXPECTED

An unknown error occurred.

CONNECT_E_NOCONNECTION

dwCookie does not represent a valid connection to this connection point

 

IConnectionPoint::EnumConnections()

NAME

IConnectionPoint::EnumConnections() - Creates an enumerator object for iteration through the connections that exist to this connection point.

Synopsis

#include <ocidl.h>

HRESULT IConnectionPoint::EnumConnections((
        [out] IEnumConnections ** ppEnum );

Description

Creates an enumerator object for iteration through the connections that exist to this connection point.

Parameters

ppEnum

A pointer to the caller's variable to receive the interface pointer of the newly created enumerator. The caller is responsible for releasing this pointer when it is no longer needed.

Return Values

S_OK

Success.

E_POINTER

The address in ppEnum is not valid (such as NULL).

E_NOTIMPL

The connection point does not support enumeration.

E_UNEXPECTED

An unknown error occurred

E_OUTOFMEMORY

There was not enough memory to create the enumerator.

14.1.2    IConnectionPointContainer

When implemented on an object, makes the object ``connectable'' and expresses the existence of outgoing interfaces on the object. Through this interface a client may either locate a specific ``connection point'' for one IID or it can enumerate the connections points that exist.

IDL:

    [
    uuid(B196B284-BAB4-101A-B69C-00AA00341D07)
        , object, pointer_default(unique)
    ]
    interface IConnectionPointContainer : IUnknown
        {
        HRESULT EnumConnectionPoints([out] IEnumConnectionPoints **ppEnum);
        HRESULT FindConnectionPoint([in] REFIID riid
            , [out] IConnectionPoint **ppCP);
        }

 

IConnectionPointContainer::EnumConnectionPoints()

NAME

IConnectionPointContainer::EnumConnectionPoints() - Creates an enumerator of all the connection points supported in the connectable object, one connection point per IID.

Synopsis

#include <ocidl.h>

HRESULT IConnectionPointContainer::EnumConnectionPoints((
        [out] IEnumConnectionPoints ** ppEnum );

Description

Creates an enumerator of all the connection points supported in the connectable object, one connection point per IID. Since IEnumConnectionPoints() enumerates IConnectionPoint*() types, the caller must use IConnectionPoint::GetConnectionInterface() to determine the actual IID that the connection point supports.

The caller of this member must call (*ppEnum)->Release() when the enumerator object is no longer needed.

E_NOTIMPL is specifically disallowed because outside of type information there would be no other means through which a caller could find the IIDs of the outgoing interfaces.

Parameters

ppEnum

A pointer to the caller's variable that is to receive the interface pointer to the enumerator. The caller is responsible for releasing this pointer after this function returns successfully.

Return Values

S_OK

The enumerator was created successfully.

E_UNEXPECTED

An unknown error occurred.

E_POINTER

The value passed in ppEnum is not valid (such as NULL).

E_OUTOFMEMORY

There was not enough memory to create the enumerator object.

 

IConnectionPointContainer::FindConnectionPoint()

NAME

IConnectionPointContainer::FindConnectionPoint() - Returns the IConnectionPoint() interface pointer to a connection point.

Synopsis

#include <ocidl.h>

HRESULT FindConnectionPoint(
        [in] REFIID riid,
        [out] IConnectionPoint ** ppCP );

Description

Asks the ``connectable object'' if it has a connection point for a particular IID, and if so, returns the IConnectionPoint() interface pointer to that connection point. Upon successful return, the caller must call IConnectionPoint::Release() when that connection point is no longer needed.

Note that this function is the QueryInterface() equivalent for an object's outgoing interfaces, where the outgoing interface is specified with riid and where the interface pointer returned is always that of a connection point.

E_NOTIMPL is not allowed as a return code for this member. Any implementation of IConnectionPointContainer() must implement this method.

Parameters

riid

A reference to the outgoing interface IID whose connection point is being requested.

ppCP

The address of the caller's variable that is to receive the IConnectionPoint() interface pointer to the connection point that manages the outgoing interface identified with riid. This is set to NULL on failure of the call; otherwise the caller must call IConnectionPoint::Release() when the connection point is no longer needed.

Return Values

S_OK

The call succeeded and *ppCP has a valid interface pointer.

E_POINTER

The address passed in ppCP is not valid (such as NULL).

E_UNEXPECTED

An unknown error occurred.

E_OUTOFMEMORY

There was not enough memory to carry out the operation, such as not being able to create a new connection point object.

CONNECT_E_NOCONNECTION

This connectable object does not support the outgoing interface specified by riid.

14.1.3    IEnumConnectionPoints

A connectable object can be asked to enumerate its supported connection points--in essence, its outgoing interfaces--through IConnectionPointContainer::EnumConnectionPoints(). The resulting enumerator returned from this member implements the interface IEnumConnectionPoints() through which a client can access all the individual connection point sub-objects supported within the connectable object itself, where each connection point, of course, implements IConnectionPoint().

Therefore IEnumConnectionPoints() is a standard enumerator interface typed for IConnectionPoint*().

IDL:

    [
    uuid(B196B285-BAB4-101A-B69C-00AA00341D07)
        , object, pointer_default(unique)
    ]
    interface IEnumConnectionPoints : IUnknown
        {
        HRESULT Next([in] ULONG cConnections
            , [out, max_is(cConnections)] IConnectionPoint **rgpcn
            , [out] ULONG *pcFetched);
        HRESULT Skip([in] ULONG cConnections);
        HRESULT Reset(void);
        HRESULT Clone([out] IEnumConnectionPoints **ppEnum);
        }

 

IEnumConnectionPoints::Next()

NAME

IEnumConnectionPoints::Next() - Enumerates the next cConnections elements in the enumerator's list.

Synopsis

#include <ocidl.h>

HRESULT IEnumConnectionPoints::Next((
        [in] ULONG cConnections,
        [out, max_is(cConnections)] IConnectionPoint ** rgpcn,
        [out] ULONG * pcFetched );

Description

Enumerates the next cConnections elements in the enumerator's list, returning them in rgpcn along with the actual number of enumerated elements in pcFetched. The caller is responsible for calling IConnectionPoint::Release() through each pointer returned in rgpcn.

E_NOTIMPL is not allowed as a return value. If an error value is returned, no entries in the rgpcn array are valid on exit and require no release.

Parameters

cConnections

Specfies the number of IConnectionPoint *() values to return in the array pointed to by rgpcn. This argument must be 1 if pcFetched is NULL.

rgpcn

A pointer to a caller-allocated IConnectionPoint *() array of size cConnections in which to return the enumerated connection points. The caller is responsible for calling IConnectionPoint::Release() through each pointer enumerated into the array once this method returns successfully. If cConnections is greater than one the caller must also pass a non-NULL pointer passed to pcFetched to know how many pointers to release.

pcFetched

A pointer to the variable to receive the actual number of connection points enumerated in rgpcn. This argument can be NULL in which case the cConnections argument must be 1.

Return Values

S_OK

The requested number of elements has been returned and *pcFetched (if non-NULL) is set to cConnections if successful.

S_FALSE

The enumerator returned fewer elements than cConnections because there were not that many elements left in the list.. In this case, unused elements in rgpcn in the enumeration are not set to NULL and *pcFetched holds the number of valid entries, even if zero is returned.

E_POINTER

The address in rgpcn is not valid (such as NULL).

E_INVALIDARG

The value of cConnections is not 1 when pcFetched is NULL; or the value of cConnections is zero.

E_UNEXPECTED

An unknown error occurred.

E_OUTOFMEMORY

There is not enough memory to enumerate the elements.

 

IEnumConnectionPoints::Skip()

NAME

IEnumConnectionPoints::Skip() - Instructs the enumerator to skip the next cConnections elements in the enumeration.

Synopsis

#include <ocidl.h>

HRESULT IEnumConnectionPoints::Skip((
        [in] ULONG cConnections );

Description

Instructs the enumerator to skip the next cConnections elements in the enumeration such that the next call to IEnumConnectionPoints::Next() will not return those elements.

Parameters

cConnections

Specifies the number of elements to skip in the enumeration.

Return Values

S_OK

The number of elements skipped is cConnections.

S_FALSE

The enumerator skipped fewer than cConnections because there were not that many left in the list. The enumerator will, at this point, be positioned at the end of the list such that subsequent calls to Next() (without an intervening Reset()) will return zero elements.

E_INVALIDARG

The value of cConnections is zero, which is not valid.

E_UNEXPECTED

An unknown error occurred.

 

IEnumConnectionPoints::Reset()

NAME

IEnumConnectionPoints::Reset() - Instructs the enumerator to position itself back to the beginning of the list of elements.

Synopsis

#include <ocidl.h>

HRESULT IEnumConnectionPoints::Reset((
        void );

Description

Instructs the enumerator to position itself back to the beginning of the list of elements.

There is no guarantee that the same set of elements will be enumerated on each pass through the list: it depends on the collection being enumerated. It is too expensive for some collections, such as files in a directory, to maintain this condition.

Return Values

S_OK

The enumerator was successfully reset to the beginning of the list.

S_FALSE

The enumerator was not reset to the beginning of the list.

E_UNEXPECTED

An unknown error occurred.

 

IEnumConnectionPoints::Clone()

NAME

IEnumConnectionPoints::Clone() - Creates another connection point enumerator with the same state as the current enumerator, which iterates over the same list.

Synopsis

#include <ocidl.h>

HRESULT IEnumConnectionPoints::Clone((
        [out] IEnumConnectionPoints ** ppEnum );

Description

Creates another connection point enumerator with the same state as the current enumerator, which iterates over the same list. This makes it possible to record a point in the enumeration sequence in order to return to that point at a later time.

Parameters

ppEnum

The address of the variable to receive the IEnumConnectionPoints() interface pointer to the newly created enumerator. The caller must release this new enumerator separately from the first enumerator.

Return Values

S_OK

Clone creation succeeded.

E_NOTIMPL

Cloning is not supported for this enumerator.

E_POINTER

The address in ppEnum is not valid (such as NULL).

E_UNEXPECTED

An unknown error occurred.

E_OUTOFMEMORY

There is not enough memory to create the clone enumerator.

14.1.4    IEnumConnections

Any individual connection point can support enumeration of its known connections through IConnectionPoint::EnumConnections(). The enumerator created by this function implements the interface IEnumConnections() which deals with the type CONNECTDATA. Each CONNECTDATA structure contains the the IUnknown() * of a connected sink and the dwCookie that was returned by IConnectionPoint::Advise() when that sink was connected. When enumerating connections through IEnumConnections(), the enumerator is responsible for calling IUnknown::AddRef() through the pointer in each enumerated structure, and the caller is responsible to later call IUnknown::Release() when those pointers are no longer needed.

IDL:

    [
    uuid(B196B287-BAB4-101A-B69C-00AA00341D07)
        , object, pointer_default(unique)
    ]
    interface IEnumConnections : IUnknown
        {
        typedef struct tagCONNECTDATA
            {
            IUnknown   *pUnk;
            DWORD       dwCookie;
            } CONNECTDATA;
        typedef struct tagCONNECTDATA *PCONNECTDATA;
        typedef struct tagCONNECTDATA *LPCONNECTDATA;
        HRESULT Next([in] ULONG cConnections
            , [out, max_is(cConnections)] CONNECTDATA *rgpcd
            , [out] ULONG *pcFetched);
        HRESULT Skip([in] ULONG cConnections);
        HRESULT Reset(void);
        HRESULT Clone([out] IEnumConnections **ppEnum);
        }

 

IEnumConnections::Next()

NAME

IEnumConnections::Next() - Enumerates the next cConnections elements in the enumerator's list.

Synopsis

#include <ocidl.h>

HRESULT IEnumConnections::Next(
        [in] ULONG cConnections,
        [out, max_is(cConnections)] CONNECTDATA * rgpcd,
        [out] ULONG * pcFetched );

Description

Enumerates the next cConnections elements in the enumerator's list, returning them in rgpcd along with the actual number of enumerated elements in pcFetched. The caller is responsible for calling IUnknown::Release() through each pUnk pointer returned in the structure elements of rgpcd.

E_NOTIMPL is not allowed as a return value. If an error value is returned, no entries in the rgpcn array are valid on exit and require no release.

Parameters

cConnections

Specfies the number of CONNECTDATA structures to return in the array pointed to by rgpcd. This argument must be 1 if pcFetched is NULL.

rgpcd

A pointer to a caller-allocated CONNECTDATA array of size cConnections in which to return the enumerated connections. The caller is responsible for calling CONNECTDATA. pUnk->Release for each element in the array once this method returns successfully. If cConnections is greater than 1, the caller must also pass a non-NULL pointer passed to pcFetched to know how many pointers to release.

pcFetched

A pointer to the variable to receive the actual number of connections enumerated in rgpcd. This argument can be NULL in which case the cConnections argument must be 1.

Return Values

S_OK

The requested number of elements has been returned and *pcFetched (if non-NULL) is set to cConnections if successful.

S_FALSE

The enumerator returned fewer elements than cConnections because there were not that many elements left in the list.. In this case, unused elements in rgpcd in the enumeration are not set to NULL and *pcFetched holds the number of valid entries, even if zero is returned.

E_POINTER

The address in rgpcd is not valid (such as NULL).

E_INVALIDARG

The value of cConnections is not 1 when pcFetched is NULL; or the value of cConnections is zero.

E_UNEXPECTED

An unknown error occurred.

E_OUTOFMEMORY

There is not enough memory to enumerate the elements.

 

IEnumConnections::Skip()

NAME

IEnumConnections::Skip() - Instructs the enumerator to skip the next cConnections elements in the enumeration.

Synopsis

#include <ocidl.h>

HRESULT IEnumConnections::Skip((
        [in] ULONG cConnections );

Description

Instructs the enumerator to skip the next cConnections elements in the enumeration such that the next call to IEnumConnections::Next() will not return those elements.

Parameters

cConnections

Specifies the number of elements to skip in the enumeration.

Return Values

S_OK

The number of elements skipped is cConnections

S_FALSE

The enumerator skipped fewer than cConnections because there were not that many left in the list. The enumerator will, at this point, be positioned at the end of the list such that subsequent calls to Next() (without an intervening Reset()) will return zero elements.

E_INVALIDARG

The value in cConnections is zero which is not valid.

E_UNEXPECTED

An unknown error occurred.

 

IEnumConnections::Reset()

NAME

IEnumConnections::Reset() - Instructs the enumerator to position itself back to the beginning of the list of elements.

Synopsis

#include <ocidl.h>

HRESULT IEnumConnections::Reset((
        void );

Description

Instructs the enumerator to position itself back to the beginning of the list of elements.

There is no guarantee that the same set of elements will be enumerated on each pass through the list: it depends on the collection being enumerated. It is too expensive for some collections, such as files in a directory, to maintain this condition.

Return Values

S_OK

The enumerator was successfully reset to the beginning of the list.

S_FALSE

The enumerator was not reset to the beginning of the list.

E_UNEXPECTED

An unknown error occurred.

 

IEnumConnections::Clone()

NAME

IEnumConnections::Clone() - Creates another connections enumerator with the same state as the current enumerator, which iterates over the same list.

Synopsis

#include <ocidl.h>

HRESULT IEnumConnections::Clone((
        [out] IEnumConnections ** ppEnum );

Description

Creates another connections enumerator with the same state as the current enumerator, which iterates over the same list. This makes it possible to record a point in the enumeration sequence in order to return to that point at a later time.

Parameters

ppEnum

The address of the variable to receive the IEnumConnections() interface pointer to the newly created enumerator. The caller must release this new enumerator separately from the first enumerator.

Return Values

S_OK

Clone creation succeeded.

E_NOTIMPL

Cloning is not supported for this enumerator.

E_POINTER

The address in ppEnum is not valid (such as NULL).

E_UNEXPECTED

An unknown error occurred.

E_OUTOFMEMORY

There is not enough memory to create the clone enumerator.

14.2    Connectable Objects Structure Descriptions

14.2.1    CONNECTDATA

The CONNECTDATA structure is the type enumerated through the IEnumConnections::Next() method. Each structure describes a connection that exists to a given connection point.

typedef struct tagCONNECTDATA 
{ 
    IUnknown*  pUnk 
    DWORD      dwCookie; 
} CONNECTDATA;

Members

pUnk

Pointer to the IUnknown() interface on a connected advisory sink. The caller must call IUnknown::Release() using this pointer when the CONNECTDATA structure is no longer needed. The caller is responsible for calling Release() for each CONNECTDATA structure enumerated through IEnumConnections::Next().

dwCookie

Connection where this value is the same token that is returned originally from calls to IConnectionPoint::Advise(). This token can be used to disconnect the sink pointed to by a pUnk by passing dwCookie to IConnectionPoint::Unadvise().

See Also

IConnectionPoint(), IEnumConnections()