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 |