# IMoniker::ComposeWith

Combines the current moniker with another moniker, creating a new composite moniker.

HRESULT ComposeWith(

IMoniker *pmkRight, | //Pointer to moniker to be composed onto this one
BOOL fOnlyIfNotGeneric, | //Indicates if generic composition permissible
IMoniker **ppmkComposite | //Indirect pointer to the composite
); |

Parameters

pmkRight
  [in] Pointer to the IMoniker interface on the moniker to compose onto the end of this moniker.
fOnlyIfNotGeneric
  [in] If TRUE, the caller requires a non-generic composition, so the operation should proceed only if pmkRight is a moniker class that this moniker can compose with in some way other than forming a generic composite. If FALSE, the method can create a generic composite if necessary.
ppmkComposite
  [out] When the call is successful, indirect pointer to the location of the resulting composite moniker pointer. In this case, the implementation must call IUnknown::AddRef on the parameter; it is the caller’s responsibility to call IUnknown::Release. If an error occurs or if the monikers compose to nothing (e.g., composing an anti-moniker with an item moniker or a file moniker), ppmkComposite should be set to NULL.

Return Values

The method supports the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following:

S_OK
  The monikers were successfully combined.
MK_E_NEEDGENERIC
  Indicates that fOnlyIfNotGeneric was TRUE, but the monikers could not be composed together without creating a generic composite moniker.

Remarks

Joining two monikers together is called composition. Sometimes two monikers of the same class can be combined in what is called non-generic composition. For example, a file moniker representing an incomplete path and another file moniker representing a relative path can be combined to form a single file moniker representing the complete path. Non-generic composition for a given moniker class can be handled only in the implementation of IMoniker::ComposeWith for that moniker class.

Combining two monikers of any class is called generic composition, which can be accomplished through a call to the CreateGenericComposite function.

Composition of monikers is an associative operation. That is, if A, B, and C are monikers, then, where Comp() represents the composition operation:

Comp( Comp( A, B ), C )

is always equal to

Comp( A, Comp( B, C ) )

#### Notes to Callers

To combine two monikers, you should call IMoniker::ComposeWith rather than calling the CreateGenericComposite function to give the first moniker a chance to perform a non-generic composition.

An object that provides item monkers to identify its objects would call IMoniker::ComposeWith to provide a moniker that completely identifies the location of the object. This would apply, for example, to a server that supports linking to portions of a document, or a container that supports linking to embedded objects within its documents. In such a situation, you would do the following:

1. Create an item moniker identifying an object.

2. Get a moniker that identifies the object’s container.

3. Call IMoniker::ComposeWith on the moniker identifying the container, passing the item moniker as the pmkRight parameter.

Most callers of IMoniker::ComposeWith should set the fOnlyIfNotGeneric parameter to FALSE.

#### Notes to Implementers

You can use either non-generic or generic composition to compose the current moniker with the moniker that pmkRight points to. If the class of the moniker indicated by pmkRight is the same as that of the current moniker, it is possible to use the contents of pmkRight to perform a more intelligent non-generic composition.

In writing a new moniker class, you must decide if there are any kinds of monikers, whether of your own class or another class, to which you want to give special treatment. If so, implement IMoniker::ComposeWith to check whether pmkRight is a moniker of the type that should have this treatment. To do this, you can call the moniker’s GetClassID method (derived from the IPersist Interface), or, if you have defined a moniker object that supports a custom interface, you can call IUnknown::QueryInterface on the moniker for that interface. An example of special treatment would be the non-generic composition of an absolute file moniker with a relative file moniker. The most common case of a special moniker is the inverse for your moniker class (whatever you return from your implementation of IMoniker::Inverse).

If pmkRight completely negates the receiver so the resulting composite is empty, you should pass back NULL in ppmkComposite and return the status code S_OK.

If the pmkRight parameter is not of a class to which you give special treatment, examine fOnlyIfNotGeneric to determine what to do next. If fOnlyIfNotGeneric is TRUE, pass back NULL through ppmkComposite and return the status code MK_E_NEEDGENERIC. If fOnlyIfNotGeneric is FALSE, call the CreateGenericComposite function to perform the composition generically.

See Also

CreateGenericComposite, IMoniker::Inverse