# IMoniker - Generic Composite Moniker Implementation

A generic composite moniker is a composite moniker whose components have no special knowledge of each other.

Composition is the process of joining two monikers together. Sometimes two monikers of specific classes can be combined in a special manner; 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. This is an example of “non-generic” composition. “Generic” composition, on the other hand, can connect any two monikers, no matter what their classes. Because a non-generic composition depends on the class of the monikers involved, it can be performed only by a particular class’s implementation of the IMoniker::ComposeWith method. You can define new types of non-generic compositions if you write a new moniker class. By contrast, generic compositions are performed by the CreateGenericComposite function.

##### When to Use

If you’re a moniker client (that is, you’re using a moniker to get an interface pointer to an object), you typically don’t need to know the class of the moniker you’re using, or whether it is a generic composite or a non-generic composite; you simply call methods using an IMoniker interface pointer.

If you’re a moniker provider (that is, you’re handing out monikers that identify your objects to make them accessible to moniker clients), you may have to compose two monikers together. (For example, if you are using an item moniker to identify an object, you must compose it with the moniker identifying the object’s container before you hand it out.) You use the IMoniker::ComposeWith method to do this, calling the method on the first moniker and passing the second moniker as a parameter; this method may produce either a generic or a non-generic composite.

The only time you should explicitly create a generic composite moniker is if you are writing your own moniker class. In your implementation of IMoniker::ComposeWith, you should attempt to perform a non-generic composition whenever possible; if you cannot perform a non-generic composition and generic composition is acceptable, you can call the CreateGenericComposite function to create a generic composite moniker.

Remarks

IMoniker::BindToObject
  If pmkToLeft is NULL, this method looks for the moniker in the ROT, and if found, queries the retrieved object for the requested interface pointer. If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call.
IMoniker::BindToStorage
  This method recursively calls BindToStorage on the rightmost component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call.
IMoniker::Reduce
  This method recursively calls Reduce for each of its component monikers. If any of the components reduces itself, the method returns S_OK and passes back a composite of the reduced components. If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.
IMoniker::ComposeWith
  If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; otherwise, the method returns the result of combining the two monikers by calling the CreateGenericComposite function.
IMoniker::Enum
  If successful, this method returns S_OK and passes back an enumerator that enumerates the component monikers that make up the composite; otherwise, the method returns E_OUTOFMEMORY.
IMoniker::IsEqual
  This method returns S_OK if the components of both monikers are equal when compared in the left-to-right order.
IMoniker::Hash
  This method calculates a hash value for the moniker.
IMoniker::IsRunning
  If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.

  If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this moniker.

  If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of the composite as the pmkToLeft parameter for that call. This handles the case where the moniker identifies a pseudo-object that is not registered as running; see the Item Moniker implementation of IMoniker::IsRunning.

IMoniker::GetTimeOfLastChange
  This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to retrieve the time of last change. If the object is not in the ROT, the method recursively calls IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder of the composite as the pmkToLeft parameter for that call.
IMoniker::Inverse
  This method returns a composite moniker that consists of the inverses of each of the components of the original composite, stored in reverse order. For example, if the inverse of A is A (-1) , then the inverse of the composite A () B () C is C (-1) () B (-1) () A (-1) .
IMoniker::CommonPrefixWith
  If the other moniker is a composite, this method compares the components of each composite from left to right. The returned common prefix moniker might also be a composite moniker, depending on how many of the leftmost components were common to both monikers. If the other moniker is not a composite, the method simply compares it to the leftmost component of this moniker.

  If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker. If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets ppmkPrefix to the other moniker. If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix to this moniker.

  If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL.

IMoniker::RelativePathTo
  This method finds the common prefix of the two monikers and creates two monikers that consist of the remainder when the common prefix is removed. Then it creates the inverse for the remainder of this moniker and composes the remainder of the other moniker on the right of it.
IMoniker::GetDisplayName
  This method returns the concatenation of the display names returned by each component moniker of the composite.
IMoniker::ParseDisplayName
  This method recursively calls IMoniker::ParseDisplayName on the rightmost component of the composite, passing everything else as the pmkToLeft parameter for that call.
IMoniker::IsSystemMoniker
  This method returns S_OK and indicates MKSYS_GENERICCOMPOSITE.

See Also

CreateGenericComposite, IMoniker