IMoniker::BindToObject

HRESULT IMoniker::BindToObject(pbc, pmkToLeft, iidResult, ppvResult)

This is the workhorse function in IMoniker interface. Locate and load the object semantically referred to by this moniker according to the interface indicated by iidResult and return the object through ppvResult. After this call has returned, the semantics of the returned interface, whatever they are, should be fully functional.

In general, each kind of moniker is designed to be used as one piece in a composite which gives the complete path to the object in question. In this composite, any given piece has a certain prefix of the composite to its left, and a certain suffix to its right. If IMoniker::BindToObject is invoked on the given piece, then most often the implementation of IMoniker::BindToObject will require certain services of the object indicated by the prefix to its left. Item monikers, for example, require IOleItemContainer interface of the object to their left; see below. The Item Moniker implementation of IMoniker::BindToObject recursively calls pmkToLeft->BindToObject in order to obtain this interface. Other implementations of IMoniker::BindToObject might instead invoke pmkToLeft->BindToStorage if they need access not to the object itself, but to its persistent storage.

Figure 3. Interface calculus of moniker pieces

In situations where the caller of IMoniker::BindToObject does not have a moniker for the object on the left, but instead has the object itself, a Pointer Moniker can be used to wrap the object pointer so that the moniker may be bound.

In situations where the moniker in fact does not need services of the moniker to its left, yet one is provided by the caller nevertheless, no error should occur; the moniker should simply ignore the needless moniker to its left.

If the object indicated by the moniker does not exist, then the error MK_E_NOOBJECT is returned.

In general, binding a moniker can be quite a complicated process, since it may need to launch servers, open files, and so forth. This often may involve binding to other objects, and it is often the case that binding pieces of the composite to the right of the present piece will require the same [from] other objects. In order to avoid loading the object, releasing it, then having it loaded again later, IMoniker::BindToObject can use the bind context passed through the pbc parameter in order to defer releasing the object until the binding process overall is complete. See IBindCtx::RegisterObjectBound for details.

The bind context also contains a deadline time by which the caller would like the binding process to complete, or fail with the error MK_E_EXCEEDEDDEADLINE if it cannot. This capability is not often used with IMoniker::BindToObject; it is more often used with other IMoniker functions such as IMoniker::GetTimeOfLastChange. Nevertheless, IMoniker::BindToObject implementations should (heuristically) honor the request. See IBindCtx::GetBindOptions for details.

Usually, for most monikers, binding a second time will return the same running object as binding the first time, rather than reloading it again from passive backing store. This functionality is supported with the Running Object Table, which is described in detail later in this chapter. Basically, the Running Object Table is a lookup table keyed by a moniker whose values are pointers to the corresponding now-running object. As objects become running, the[y] register themselves in this table. Implementations of IMoniker::BindToObject can use this table to shortcut the binding process if the object to which they point is already running.

More precisely, if the passed pmkToLeft parameter is NULL (and this is not an error; that is, the moniker does not require something to its left), then the moniker should fully reduce itself, then look itself up in the Running Object Table and simply return the pointer to the object found there. If the pmkToLeft parameter is non-NULL, then it is the responsibility of the caller to handle this situation; the BindToObject() implementation should not consult the Running Object Table.2. The Running Object Table is accessible from the bind context using IBindCtx::GetRunningObjectTable, an implementation of IMoniker::BindToObject should not use GetRunningObjectTable().

Argument

Type

Description

pbc

IBindCtx*

The bind context to be used for this binding operation.

pmkToLeft

IMoniker*

The moniker of the object to the left of this moniker.

iidResult

REFIID

The interface by which the caller wishes to connect to the object.

ppvResult

void**

On successful return, a pointer to the instantiated object is placed here, unless BINDFLAGS_JUSTTESTEXISTENCE was specified in the binding options, in which case NULL may be returned instead.

return value

HRESULT

S_OK, MK_E_NOOBJECT, STG_E_ACCESSDENIED, MK_E_EXCEEDEDDEADLINE, MK_E_CONNECTMANUALLY, MK_E_INTERMEDIATEINTERFACENOTSUPPORTED, E_OUTOFMEMORY, E_NOINTERFACE