# IMoniker - URL Moniker Implementation

The URL moniker implementation of IMoniker is found on a URL moniker object, which also supports IUnknown and IAsyncMoniker. The IMoniker interface inherits its definition from IPersistStream as well as IUnknown and IPersistStream inherits from IPersist. Thus, the IMoniker implementation includes support for IPersistStream and IPersist.

The IAsyncMoniker interface is simply IUnknown (there are no additional methods). It is is used to allow clients to determine if a moniker supports asynchronous binding.

To get a pointer to the IMoniker interface on this object, call the CreateURLMoniker function.

Note The current URL Moniker implementation of IMoniker does not support asynchronous storage. Future implementations will do so.

##### 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; 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 must use item monikers if the objects you’re identifying are contained within another object and can be individually identified using a string. You’ll also need to use another type of moniker (for example, file monikers) in order to identify the container object.

To use item monikers, you must use the CreateItemMoniker function to create the monikers. To allow your objects to be loaded when an item moniker is bound, the container of your objects must implement the IOleItemContainer interface.

The most common example of moniker providers are OLE applications that support linking. If your OLE application supports linking to objects smaller than a file-based documents, you need to use item monikers. For a server application that allows linking to a selection within a document, you use the item monikers to identify those objects. For a container application that allows linking to embedded objects, you use the item monikers to identify the embedded objects.

Remarks

IMoniker::BindToObject
  Since the URL Moniker supports asynchronous binding, the actual return value of its BindToObject may vary depending on the object parameters established in the bind-context, however the semantics of the bind operation are identical regardless of synchronous or asynchronous usage, and are as follows:
  1. The URL Moniker pulls further information for the bind operation from the bind context. For example, the moniker can obtain pointers to the IBindStatusCallback and IEnumFORMATETC interfaces that are registered in the bind context. Note that further information can include additional bind options specified on the bind context through IBindCtx::SetBindOptions, such as the dwTickCountDeadline parameter or the grfFlags value of BIND_MAYBOTHERUSER.

  2. Next, the moniker checks the Running Object Table of the bind-context to determine if the referenced object is already running. The moniker can obtain this information with the following calls:

    IBindCtx::GetRunningObjectTable(&prot)
    prot->IsRunning(this)

If the object is already running, the moniker retrieves the running object with the following call:

    prot->GetObject(this, &punk)

Then, the moniker calls QueryInterface for the requested interface.

- 3. Otherwise, the moniker queries the client by calling IBindStatusCallback::GetBindInfo to obtain additional bind information. The moniker then initiates the bind operation and passes the resulting IBinding interface back to the client by calling IBindStatusCallback::OnStartBinding.

- 4. If in step 1 it was determined that this was an asynchronous bind, BindToObject returns MK_S_ASYNCHRONOUS at this point with NULL in ppv. The caller will receive the actual object pointer during IBindStatusCallback::OnObjectAvailable at some later point. The following steps then occur asynchronously to the caller, typically on another thread of execution.

- 5. The class of the resource designated by the URL Moniker is determined in one of the following ways:

- The URL Moniker examines the media type of the data. If the media type is application/x-oleobject, the first 16-bytes of the actual data (Content-Body) contain the CLSID of the resource and subsequent data is to be interpreted by the class itself. For all other media types, URL Moniker looks in the system registry for the HKEY_CLASSES_ROOT\MIME\Database\Content-Type\<media-type>\CLSID key. Note that application/x-oleobject will be used until application/oleobject is approved.

- The URL Moniker matches portions of arriving data to patterns registered in the system registry under HKEY_CLASSES_ROOT\FileTypes.

- Finally, if all else fails, the URL Moniker correlates the trailing extension of the resource, if any, to a CLSID using the HKEY_CLASSES_ROOT\.??? keys in the system registry, as is done by GetClassFile and the shell.

- 6. Having determined the class, the URL moniker creates an instance using CoCreateInstance of CLSCTX_SERVER asking for the IUnknown interface.

- 7. The URL Moniker next calls the QueryInterface method of the newly created object for the IPersistMoniker interface. If the QueryInterface is successful, the URL Moniker calls IPersistMoniker::Load passing itself (this) as the moniker parameter. The object typically calls IMoniker::BindToStorage asking for the storage interface that they’re interested in.

- 8. Otherwise, the URL Moniker calls the QueryInterface method for IPersistStream and, if successful, calls IPersistStream::Load, passing the object an IStream pointer for a stream object that is being filled asynchronously by the transport.

  If the class being called is not marked with the category CATID_AsyncAware, calls to IStream::Read or IStream::Write which reference data not yet available block until the data becomes available. These calls block in the traditional OLE sense. A message loop is entered which allows certain messages to be processed, and the IMessageFilter of the thread is called appropriately.

  If the class is marked with the category CATID_AsyncAware, calls to IStream::Read or IStream::Write which reference data not yet available return E_PENDING.

- 9. Otherwise, the URL Moniker calls QueryInterface for IPersistFile, and, if successful, completes the download into a temporary file. On completion, the URL Moniker calls IPersistFile::Load. The created file is cached along with other Internet downloaded data. The client must be sure not to delete this file.

- 10. When the object returns from one of the various IPersistXxx::Load calls described in the previous steps, the URL Moniker calls IBindStatusCallback::OnObjectAvailable to return the interface pointer that the client originally requested when the client called IMoniker::BindToObject.

- IMoniker::BindToStorage

  The system implementation of URL Monikers supports the BindToStorage for stream objects on all URLs and for storage objects in the case where the designated resource is in fact a compound file. Future support for ILockBytes may also be added.

  Since the URL Moniker supports asynchronous binding, the actual return value of its BindToStorage may vary depending on the object parameters established in the bind-context. However, the semantics of the bind operation are identical regardless of synchronous or asynchronous usage as described below:

  1. The URL Moniker pulls further information for the bind operation from the bind context. For example, the moniker can obtain pointers to the IBindStatusCallback and IEnumFORMATETC interfaces that are registered in the bind context. Note that further information can include additional bind options specified on the bind context through IBindCtx::SetBindOptions, such as the dwTickCountDeadline parameter or the grfFlags value of BIND_MAYBOTHERUSER. The moniker then queries the client by calling IBindStatusCallback::GetBindInfo and initiates the bind operation with the transport, and passes the resulting IBinding to the client by calling IBindStatusCallback::OnStartBinding.

  2. If the caller requested an asynchronous IStream or IStorage by specifying the BINDF_ASYNCSTORAGE flag in the BINDINFO structure retrieved from IBindStatusCallback::GetBindInfo, the URL moniker returns the object as soon as possible. Calls to these IStorage or IStream objects which reference data not yet available return E_PENDING.

  3. If the caller does not specify asynchronous IStream or IStorage as described above, the URL Moniker will still return an object through IBindStatusCallback::OnDataAvailable as soon as possible. However calls to these objects which reference data not yet available will block until the data becomes available. For some applications this will require the least modification of their existing I/O code, yet may still result in improved performance depending on their access-patterns.

- IMoniker::Reduce

  Returns MK_S_REDUCED_TO_SELF and itself (this) in *ppmkReduced.

- IMoniker::ComposeWith

  URL Monikers support composition of two URLs: a base URL composed with a relative URL. This composition is done according to the RFC on relative URLs. URL Monikers do not currently support the composition of a base URL moniker with a relative file moniker, although this may be supported in the future.

  However, URL Monikers do support generic composition. If fOnlyIfNotGeneric==TRUE, the ComposeWith method returns MK_E_NEEDGENERIC. Otherwise, this method simply returns CreateGenericComposite(this, pmkRight, ppmkComposite). See the Win32 documentation for more information about IMoniker::ComposeWith.

- IMoniker::Enum

  Returns S_OK and sets *ppenumMoniker to NULL, indicating that the moniker does not contain sub-monikers.

- IMoniker::IsEqual

  Returns S_FALSE if the other moniker (pmkOtherMoniker) is not an URL moniker, which it checks using IPersist::GetClassID to see if the CLSID is CLSID_URLMoniker. If the other moniker is an URL moniker, it compares the display names of the monikers for equality, returning either S_OK if they are identical or S_FALSE if not.

- IMoniker::Hash

  Creates a hash value based on the URL string of the moniker. This hash value is identical when URL strings are identical, although it may also be identical for different URL strings. This method is used to speed up comparisons by reducing the amount of time that it is necessary to call IMoniker::IsEqual.

- IMoniker::IsRunning

  Returns S_OK if this moniker is currently running. Otherwise, it returns S_FALSE. The URL Moniker determines if it is running by first checking if it is equal to the newly running moniker by making the following call:

    pmkNewlyRunning->IsEqual

Typically, this call an inexpensive operation. If this does not succeed, the moniker next checks to see if it is registered with the Running Object Table of the passed-in bind-context.

- IMoniker::GetTimeOfLastChange

  Returns the time of last change of an object that is registered in the running object table.

- IMoniker::Inverse

  Returns MK_E_NOINVERSE.

- IMoniker::CommonPrefixWith

  Currently returns E_NOTIMPL. In the future, it may properly compute the proper common prefix of two URL monikers. See the Win32 documentation about IMoniker::CommonPrefixWith for details.

- IMoniker::RelativePathTo

  Currently returns E_NOTIMPL. In the future, it may properly compute the relative path between two URL monikers. See the Win32 documentation about IMoniker::RelativePathTo for details.

- IMoniker::GetDisplayName

  THe URL Moniker attempts to return its full URL string. If the moniker was created with a partial URL string (see CreateURLMoniker), it will first attempt to find an URL moniker in the bind-context under SZ_URLCONTEXT, and will next look to the moniker to its left for contextual information. If it can not return its full URL string, it will return its partial URL string.

- IMoniker::ParseDisplayName

  Parses a full or partial URL string into a result moniker (ppmkOut). If szDisplayName represents a full URL string (i.e. “http://foo.com/default.html”), the result is a new full URL moniker. If szDisplayName represents a partial URL string (i.e. “..\default.html”), the result is a full URL that takes its context from either the bind-context’s SZ_URLCONTEXT object-parameter or from this URL moniker. For example, if the context moniker was “http://foo.com/pub/list.html” and szDisplayName was “..\default.html”, the resulting URL moniker would represent “http://foo.com/default.html”.

- IMoniker::IsSystemMoniker

  Returns S_TRUE and MKSYS_URLMONIKER in *pdwMksys.

See Also

CreateURLMoniker, IPersistStream - URL Moniker Implementation