16    Persistent Intelligent Names: Monikers

16.1    Overview

A moniker is simply an object that supports the IMoniker() interface. IMoniker() interface includes the IPersistStream() interface; thus, monikers can be saved to and loaded from streams. The persistent form of a moniker contains the class identifier (CLSID) of its implementation which is used during the loading process, and so new kinds of monikers can be created transparently to clients.

[Footnote 64] The most basic operation in IMoniker() interface is that of binding to the object to which it points, which is supported by IMoniker::BindToObject. This function takes as a parameter the interface identifier by which the caller wishes to talk to the object, runs whatever algorithm is necessary in order to locate the object, then returns a pointer of that interface type to the caller. [Footnote 64] Each moniker class can store arbitrary data its persistent representation, and can run arbitrary code at binding time.

If there is an identifiable piece of persistent storage in which the object referenced by the moniker is stored, then IMoniker::BindToStorage can be used to gain access to it. Many objects have such identifiable storage, but some, such as the objects which are the ranges on a Microsoft Excel spreadsheet do not. (These ranges exist only as a part of Excel's data structures; they are in effect a figment of Excel's imagination and are only reified on demand for clients.)

In most cases, a particular moniker class is designed to be one step along the path to the information source in question. These pieces can be composed together to form a moniker which represents the complete path. For example, the moniker stored inside a chart that refers to its underlying data in a spreadsheet might be a composite moniker formed from three pieces:

Figure 16-1:  A Moniker Referring to a Spreadsheet

This composite is itself a moniker; it just happens to be a moniker which is a sequenced collection of other monikers. The composition here is generic in that it has no knowledge of the pieces involved other than that they are monikers.

Most monikers have a textual representation which is meaningful to the user; this can be retrieved with IMoniker::GetDisplayName. The API function MkParseDisplayName() goes the other direction: it can turn a textual display name into the appropriate moniker, though beware that in general this operation is as expensive as actually binding to the object.

Monikers can compare themselves to other monikers using IMoniker::IsEqual. A hash value useful for storing monikers in lookup tables is available through IMoniker::Hash(). Monikers are not a total order or even a partial order; therefore, monikers cannot be stored in tables that rely on sorting for retrieval; use hashing instead (it is inappropriate to use the display name of a moniker for sorting, since the display name may not reflect the totality of internal state of the moniker).

The earliest time after which the object to which the moniker points is known not to have changed can be obtained with IMoniker::GetTimeOfLastChange. This is not necessarily the time of last change of the object; rather, it is the best cheaply available approximation thereto.

A moniker can be asked to re-write itself into another equivalent moniker by calling IMoniker::Reduce(). This function returns a new moniker that will bind to the same object, but does so in a more efficient way. This capability has several uses:

It enables the construction of user-defined macros or aliases as new kinds of moniker classes. When reduced, the moniker to which the macro evaluates is returned.

It enables the construction of a kind of moniker which tracks data as it moves about. When reduced, the moniker of the data in its current location is returned.

On file systems such as Macintosh System 7 which support an ID-based method of accessing files which is independent of file names, a File Moniker could be reduced to a moniker which contains one of these IDs.

Figure 16-2 shows a (somewhat contrived) example of moniker reduction. It illustrates the reduction of a moniker which names the net income entry for this year's report in the ``Projects'' directory of the current user's home directory.

Figure 16-2:  Reduction of a Moniker

(Note that the particular classes of monikers used here are for illustrative purposes only.) As we can see, many monikers in this example are reduced to something completely different, and some bind to something during their reduction, but some do not. For example, to reduce the alias ``Home'', the reduction must access the information that ``Home'' was an alias for ``\\server\share\fred''.

The process of moniker reduction may also be tied to a global table called the Running Object Table. The Running Object Table serves as the place where monikers in the process of binding look to see if they are already running or not.

Pointers to instances of IMoniker() interface can be marshaled to other processes, just as any other interface pointer can. Many monikers are of the nature that they are immutable once created and that they maintain no object state outside themselves. Item Monikers are an example of a class of such monikers. These monikers, which can be replicated at will, will usually want to support custom marshaling (see IMarshal() interface) so as to simply serialize themselves and de-serialize themselves in the destination context (see IPersistStream() regarding serialization). This is referred to as marshaling an object by value.

16.2    Moniker Interface Descriptions

16.2.1    IBindCtx

The IBindCtx() interface provides access to a bind context, which is an object that stores information about a particular moniker binding operation. You pass a bind context as a parameter when calling many methods of IMoniker() and in certain functions related to monikers.

A bind context includes the following information:

When to Implement

You do not need to implement this interface. The system provides an IBindCtx() implementation, accessible though a call to the CreateBindCtx() function, that is suitable for all situations.

When to Use

Anyone writing a new moniker class by implementing the IMoniker() interface must call IBindCtx() methods in the implementation of several IMoniker() methods. Moniker providers (servers that hand out monikers to identify their objects) may also need to call IBindCtx() methods from their implementations of the IOleItemContainer or IParseDisplayName() interfaces.

Moniker clients (objects that use monikers to acquire interface pointers to other objects) typically don't call many IBindCtx() methods. Instead, they simply pass a bind context as a parameter in a call to an IMoniker() method. To acquire an interface pointer and activate the indicated object (called binding to an object), moniker clients typically do the following:

  1. Call the CreateBindCtx() function to create a bind context and get a pointer to the IBindCtx() interface on the bind context object..

  2. If desired (although this is rarely necessary), the moniker client can call IBindCtx::SetBindOptions() to specify the bind options.

  3. Pass the bind context as a parameter to the desired IMoniker() method (usually IMoniker::BindToObject()).

  4. Call IUnknown::Release() on the bind context to release it.

Although applications that act as link containers (container applications that allow their documents to contain linked objects) are moniker clients, they rarely call IMoniker() methods directly.

Table 16-1:  IBindCtx Methods in VTable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments the reference count.
Release() Decrements the reference count.

Table 16-2:  IBindCtx Methods

IBindCtx() Methods Description
RegisterObjectBound Registers an object with the bind context.
RevokeObjectBound Revokes an object's registration.
ReleaseBoundObjects Releases all registered objects.
SetBindOptions Sets the binding options.
GetBindOptions Retrieves the binding options.
GetRunningObjectTable() Retrieves a pointer to the Running Object Table.
RegisterObjectParam Associates an object with a string key.
GetObjectParam Returns the object associated with a given string key.
EnumObjectParam Enumerates all the string keys in the table.
RevokeObjectParam Revokes association between an object and a string key.

See Also

CreateBindCtx(), IMoniker(), IOleItemContainer(), IParseDisplayName()  

IBindCtx::EnumObjectParam()

NAME

IBindCtx::EnumObjectParam() - Supplies a pointer to an IEnumString() interface on an enumerator that can return the keys of the bind context's string-keyed table of pointers.

Synopsis

#include <objidl.h>

HRESULT EnumObjectParam(
        IEnumString ** ppenum );

Description

This method provides an IEnumString() pointer to an enumerator that can return the keys of the bind context's string-keyed table of pointers. The keys returned are the ones previously specified in calls to IBindCtx::RegisterObjectParam().

Parameters

ppenum

[out] Indirect pointer to the IEnumString() interface on the enumerator. If an error occurs, *ppenum is set to NULL. If *ppenum is non-NULL, the implementation calls IUnknown::AddRef() on the parameter; it is the caller's responsibility to call IUnknown::Release().

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

An enumerator was successfully created and the pointer supplied.

See Also

IBindCtx::RegisterObjectParam(), IEnumString()  

IBindCtx::GetBindOptions()

NAME

IBindCtx::GetBindOptions() - Returns the binding options stored in this bind context.

Synopsis

#include <objidl.h>

HRESULT GetBindOptions(
        BIND_OPTS * pbindopts );

Description

A bind context contains a block of parameters, stored in a BIND_OPTS structure, that are common to most IMoniker() operations and that do not change as the operation moves from piece to piece of a composite moniker.

Notes to Callers

You typically call this method if you are writing your own moniker class (this requires that you implement the IMoniker() interface). You call this method to retrieve the parameters specified by the moniker client.

You must initialize the BIND_OPTS structure that is filled in by this method. Before calling this method, you must initialize the cbStruct field of the structure to the size of the BIND_OPTS structure.

Parameters

pbindopts

[in, out] Pointer to an initialized BIND_OPTS structure on entry that receives the current binding parameters on return.

Return Values

This method supports the standard return value E_UNEXPECTED, as well as the following:

S_OK

The stored binding options were successfully returned.

See Also

IBindCtx::SetBindOptions()  

IBindCtx::GetObjectParam()

NAME

IBindCtx::GetObjectParam() - Retrieves the pointer associated with the specified key in the bind context's string-keyed table of pointers.

Synopsis

#include <objidl.h>

HRESULT GetObjectParam(
        LPOLESTR pszKey,
        IUnknown ** ppunk );

Description

A bind context maintains a table of interface pointers, each associated with a string key. This enables communication between a moniker implementation and the caller that initiated the binding operation. One party can store an interface pointer under a string known to both parties so that the other party can later retrieve it from the bind context.

The pointer this method retrieves must have previously been inserted into the table using the IBindCtx::RegisterObjectParam() method.

Notes to Callers

Those writing a new moniker class (through an implementation of IMoniker()) and some moniker clients (objects using a moniker to bind to an object) can call IBindCtx::GetObjectParam().

Objects using monikers to locate other objects can call this method when a binding operation fails to get specific information about the error that occurred. Depending on the error, it may be possible to correct the situation and retry the binding operation. See IBindCtx::RegisterObjectParam() for more information.

Moniker implementations can call this method to deal with situations where a caller initates a binding operation and requests specific information. By convention, the implementer should use key names that begin with the string form of the CLSID of a moniker class (see the StringFromCLSID() function).

Parameters

pszKey

[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the key to search for. Key string comparison is case-sensitive.

ppunk

[out] When successful, indirect pointer to the IUnknown() interface on the object associated with pszKey. In this case, the implementation calls IUnknown::AddRef() on the parameter. It is the caller's responsibility to call IUnknown::Release(). If an error occurs, ppunk is set to NULL.

Return Values

This method supports the standard return value E_FAIL, as well as the following:

S_OK

The pointer associated with the specified key was successfully returned.

See Also

IBindCtx::RegisterObjectParam(), IBindCtx::EnumObjectParam()  

IBindCtx::GetRunningObjectTable()

NAME

IBindCtx::GetRunningObjectTable() - Provides an interface pointer to the Running Object Table (ROT) for the machine on which this bind context is running.

Synopsis

#include <objidl.h>

HRESULT GetRunningObjectTable((
        IRunningObjectTable ** pprot );

Description

The Running Object Table is a globally accessible table on each machine. It keeps track of all the objects that are currently running on the machine.

Notes to Callers

Typically, those implementing a new moniker class (through an implementation of IMoniker() interface) call IBindCtx::GetRunningObjectTable(). It is useful to call this method in an implementation of IMoniker::BindToObject() or IMoniker::IsRunning() to check whether a given object is currently running. You can also call this method in the implementation of IMoniker::GetTimeOfLastChange() to learn when a running object was last modified.

Moniker implementations should call this method instead of using the GetRunningObjectTable() function. This makes it possible for future implementations of IBindCtx() to modify binding behavior.

Parameters

pprot

[out] When successful, indirect pointer to the IRunningObjectTable() interface on the Running Object Table. If an error occurs, *pprot is set to NULL. If *pprot is non-NULL, the implementation calls IUnknown::AddRef() on the parameter; it is the caller's responsibility to call IUnknown::Release().

Return Values

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

S_OK

A pointer to the ROT was returned successfully.

See Also

IMoniker(), IRunningObjectTable()  

IBindCtx::RegisterObjectBound()

NAME

IBindCtx::RegisterObjectBound() - Calls IUnknown::AddRef() on the specified object to ensure that the object remains active until the bind context is released. The method stores a pointer to the object in the bind context's internal list of pointers.

Synopsis

#include <objidl.h>

HRESULT RegisterObjectBound(
        IUnknown * punk );

Description

Notes to Callers

Those writing a new moniker class (through an implementation of the IMoniker() interface), should call this method whenever the implementation activates an object. This happens most often in the course of binding a moniker, but it can also happen while retrieving a moniker's display name, parsing a display name into a moniker, or retrieving the time that an object was last modified.

IBindCtx::RegisterObjectBound() calls IUnknown::AddRef() to create an additional reference to the object. You must, however, still release your own copy of the pointer. Note that calling this method twice for the same object creates two references to that object. You can release a reference obtained through a call to this method by calling IBindCtx::RevokeObjectBound(). All references held by the bind context are released when the bind context itself is released.

Calling IBindCtx::RegisterObjectBound() to register an object with a bind context keeps the object active until the bind context is released. Reusing a bind context in a subsequent binding operation (either for another piece of the same composite moniker, or for a different moniker) can make the subsequent binding operation more efficient because it doesn't have to reload that object. This, however, improves performance only if the subsequent binding operation requires some of the same objects as the original one, so you need to balance the possible performance improvement of reusing a bind context against the costs of keeping objects activated unnecessarily.

IBindCtx() does not provide a method to retrieve a pointer to an object registered using IBindCtx::RegisterObjectBound(). Assuming the object has registered itself with the Running Object Table, moniker implementations can call IRunningObjectTable::GetObject() to retrieve a pointer to the object.

Parameters

punk

[in] Pointer to the IUnknown() interface on the object that is being registered as bound.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The object was successfully registered.

See Also

IBindCtx::ReleaseBoundObjects(), IBindCtx::RevokeObjectBound(), IRunningObjectTable::GetObject()  

IBindCtx::RegisterObjectParam()

NAME

IBindCtx::RegisterObjectParam() - Stores an IUnknown() pointer on the specified object under the specified key in the bind context's string-keyed table of pointers. The method must call IUnknown::AddRef() on the stored pointer.

Synopsis

#include <objidl.h>

HRESULT RegisterObjectParam(
        LPOLESTR pszKey,
        IUnknown * punk );

Description

A bind context maintains a table of interface pointers, each associated with a string key. This enables communication between a moniker implementation and the caller that initiated the binding operation. One party can store an interface pointer under a string known to both parties so that the other party can later retrieve it from the bind context.

Binding operations subsequent to the use of this method can use IBindCtx::GetObjectParam() to retrieve the stored pointer.

Notes to Callers

IBindCtx::RegisterObjectParam() is useful to those implementing a new moniker class (through an implementation of IMoniker()) and to moniker clients (those who use monikers to bind to objects).

In implementing a new moniker class, you call this method when an error occurs during moniker binding to inform the caller of the cause of the error. The key that you would obtain with a call to this method would depend on the error condition. The following lists common moniker binding errors, describing for each the keys that would be appropriate:

MK_E_EXCEEDEDDEADLINE

If a binding operation exceeds its deadline because a given object is not running, you should register the object's moniker using the first unused key from the list: "ExceededDeadline", "ExceededDeadline1", "ExceededDeadline2", etc. If the caller later finds the moniker in the Running Object Table, the caller can retry the binding operation.

MK_E_CONNECTMANUALLY

The ``ConnectManually'' key indicates a moniker whose binding requires assistance from the end user. The caller can retry the binding operation after showing the moniker's display name to request that the end user manually connect to the object. Common reasons for this error are that a password is needed or that a floppy needs to be mounted.

E_CLASSNOTFOUND

The ``ClassNotFound'' key indicates a moniker whose class could not be found (the server for the object identified by this moniker could not be located). If this key is used for a COM compound-document object, the caller can use IMoniker::BindToStorage() to bind to the object, and then try to carry out a Treat As... or Convert To... operation to associate the object with a different server. If this is successful, the caller can retry the binding operation.

If you're a moniker client with detailed knowledge of the implementation of the moniker you're using, you can also call this method to pass private information to that implementation.

You can define new strings as keys for storing pointers. By convention, you should use key names that begin with the string form of the CLSID of the moniker class (see the StringFromCLSID() function).

If the pszKey parameter matches the name of an existing key in the bind context's table, the new object replaces the existing object in the table.

When you register an object using this method, the object is not released until one of the following occurs:

Parameters

pszKey

[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the key under which the object is being registered. Key string comparison is case-sensitive.

punk

[in] Pointer to the IUnknown() interface on the object that is to be registered.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The pointer was successfully registered under the specified string.

See Also

IBindCtx::GetObjectParam(), IBindCtx::RevokeObjectParam(), IBindCtx::EnumObjectParam()  

IBindCtx::ReleaseBoundObjects()

NAME

IBindCtx::ReleaseBoundObjects() - Releases all pointers to all objects that were previously registered by calls to IBindCtx::RegisterObjectBound().

Synopsis

#include <objidl.h>

HRESULT ReleaseBoundObjects(
        void );

Description

You rarely call this method directly. The system's IBindCtx() implementation calls this method when the pointer to the IBindCtx() interface on the bind context is released (the bind context is released). If a bind context is not released, all of the registered objects remain active.

If the same object has been registered more than once, this method calls the IUnknown::Release() method on the object the number of times it was registered.

Return Values

S_OK

The objects were released successfully.

See Also

IBindCtx::RegisterObjectBound()  

IBindCtx::RevokeObjectBound()

NAME

IBindCtx::RevokeObjectBound() - Releases the IUnknown() pointer to the specified object and removes that pointer from the bind context's internal list of pointers. This undoes a previous call to IBindCtx::RegisterObjectBound() for the same object.

Synopsis

#include <objidl.h>

HRESULT RevokeObjectBound(
        IUnknown * punk );

Description

You rarely call this method. This method is included for completeness.

Parameters

punk

[in] Pointer to the IUnknown() interface on the object to be released.

Return Values

S_OK

The object was released successfully.

MK_E_NOTBOUND

Indicates that punk was not previously registered with a call to IBindCtx::RegisterObjectBound().

See Also

IBindCtx::RegisterObjectBound()  

IBindCtx::RevokeObjectParam()

NAME

IBindCtx::RevokeObjectParam() - Removes the specified key and its associated pointer from the bind context's string-keyed table of objects. The key must have previously been inserted into the table with a call to IBindCtx::RegisterObjectParam().

Synopsis

#include <objidl.h>

HRESULT RevokeObjectParam(
        LPOLESTR pszKey );

Description

A bind context maintains a table of interface pointers, each associated with a string key. This enables communication between a moniker implementation and the caller that initiated the binding operation. One party can store an interface pointer under a string known to both parties so that the other party can later retrieve it from the bind context.

This method is used to remove an entry from the table. If the specified key is found, the bind context also releases its reference to the object.

Parameters

pszKey

[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the key to remove. Key string comparison is case-sensitive.

Return Values

S_OK

The specified key was successfully removed from the table.

S_FALSE

No object has been registered with the specified key.

See Also

IBindCtx::RegisterObjectParam()  

IBindCtx::SetBindOptions()

NAME

IBindCtx::SetBindOptions() - Specifies new values for the binding parameters stored in the bind context. Subsequent binding operations can call IBindCtx::GetBindOptions() to retrieve the parameters.

Synopsis

#include <objidl.h>

HRESULT SetBindOptions(
        BIND_OPTS * pbindopts );

Description

A bind context contains a block of parameters, stored in a BIND_OPTS2 or a BIND_OPTS structure, that are common to most IMoniker() operations. These parameters do not change as the operation moves from piece to piece of a composite moniker.

Notes to Callers

This method can be called by moniker clients (those who use monikers to acquire interface pointers to objects).

When you first create a bind context using the CreateBindCtx() function, the fields of the BIND_OPTS structure are initialized to the following values:

cbStruct = sizeof(BINDOPTS); 
grfFlags = 0; 
grfMode = STGM_READWRITE; 
dwTickCountDeadline = 0;

You can use the IBindCtx::SetBindOptions() method to modify these values before using the bind context, if you want values other than the defaults. See BIND_OPTS for more information.

SetBindOptions only copies the struct members of BIND_OPTS2, but not the COSERVERINFO structure and the pointers it contains. Callers may not free any of these pointers until the bind context is released.

Parameters

pbindopts

[in] Pointer to a BIND_OPTS2 or a BIND_OPTS structure containing the binding parameters.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The parameters were stored successfully.

See Also

Bind_OPTS2, IBindCtx::GetBindOptions()

16.2.2    IClassActivator

IClassActivator() Specifies a method that retrieves a class object.

When to Implement

No implementation of a moniker or an object supporting IClassActivator() currently exists within the system, however future versions of the operating system may contain such implementations. Implement the IClassActivator() interface if you are writing a custom moniker type which you want to be able to compose to the left of a class moniker or any other moniker that supports binding to IClassActivator().

When to Use

Use IClassActivator() if you write a custom moniker class that should behave similarly to class monikers when composed to the right of other monikers. File monikers also use this interface.

Table 16-3:  IClassActivator Methods in VTable Order

IUnknown Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments the reference count.
Release() Decrements the reference count.

Table 16-4:  IClassActivator Methods

IClassActivator() Method Description
GetClassObject Retrieves a class object.

 

IClassActivator::GetClassObject()

NAME

IClassActivator::GetClassObject() - Retrieves a class object. Similar to CoGetClassObject(),

Synopsis

#include <objidl.h>

HRESULT GetClassObject(
        REFCLSID * pClassID,
        DWORD dwClsContext,
        LCID locale,
        REFIID riid,
        void ** ppv );

Description

This method returns the class identifier (CLSID) for an object, used in later operations to load object-specific code into the caller's context.

Parameters

pClassID

[in] Points to the CLSID that Identifies the class whose class object is to be retrieved.

dwClsContext

[in] The context in which the class is expected to run; values are taken from the CLSCTX enumeration.

locale

[in] Any LCID constant as defined in WINNLS.H.

riid

[in] IID of the interface on the object to which a pointer is desired.

ppv

[out] On successful return, an indirect pointer to the requested interface.

Return Values

This method supports the standard return value E_FAIL, as well as the following:

S_OK

The CLSID was successfully returned.

See Also

CoGetClassObject()

16.2.3    IEnumMoniker

The IEnumMoniker() interface is used to enumerate the components of a moniker or to enumerate the monikers in a table of monikers. IEnumMoniker() has the same methods as all enumerator interfaces: Next, Skip, Reset, and Clone. For general information on these methods, refer to IEnumXXXX().

When to Implement

You need to implement IEnumMoniker() if you are writing a new type of moniker and your monikers have an internal structure that can be enumerated. Your implementation of IMoniker::Enum() must return an enumerator that implements IEnumMoniker() and can enumerate your moniker's components. If your moniker has no structure that can be enumerated, your IMoniker::Enum() method can simply return a NULL pointer.

When to Use

Call the methods of the IEnumMoniker() interface if you need to enumerate the components of a composite moniker, or to enumerate the monikers in a table.

COM defines two interfaces that supply an IEnumMoniker() interface pointer:

The prototypes of the methods are as follows:

#include <objidl.h>

HRESULT Next(
        ULONG celt,
        IMoniker * rgelt,
        ULONG * pceltFetched );

#include <objidl.h>

HRESULT Skip(
        ULONG celt );

#include <objidl.h>

HRESULT Reset(
        void );

#include <objidl.h>

HRESULT Clone(
        IEnumMoniker ** ppenum );

See Also

IEnumXXXX, IMoniker::Enum(), IRunningObjectTable::EnumRunning()

16.2.4    IEnumString

IEnumString() is defined to enumerate strings. LPWSTR is the type that indicates a pointer to a zero-terminated string of wide, i.e., Unicode, characters. IEnumString() has the same methods as all enumerator interfaces: Next, Skip, Reset, and Clone. For general information on these methods, refer to IEnumXXXX().

When to Implement

It is usually not necessary to implement this interface unless you have use for a custom string enumerator. A system implementation in the bind context object on which is the IBindCtx() interface also contains an implementation of IEnumString(). IBindCtx::EnumObjectParam() returns a pointer to this IEnumString() interface on an enumerator that can return the keys of the bind context's string-keyed table of pointers.

When to Use

Call the methods of IEnumString() to enumerate through a set of strings.

The prototypes of the member functions are as follows:

#include <objidl.h>

HRESULT Next(
        ULONG celt,
        LPOLESTR * rgelt,
        ULONG * pceltFetched );

#include <objidl.h>

HRESULT Skip(
        ULONG celt );

#include <objidl.h>

HRESULT Reset(
        void );

#include <objidl.h>

HRESULT Clone(
        IEnumString ** ppenum );

16.2.5    IEnumUnknown

This enumerator enumerates objects with the IUnknown() interface. It can be used to enumerate through the objects in a component containing multiple objects. IEnumUnknown() has the same methods as all enumerator interfaces: Next, Skip, Reset, and Clone. For general information on these methods, refer to IEnumXXXX().

When to Implement

You can implement this whenever you want a caller to be able to enumerate the objects contained in another object. You get a pointer to IEnumUnknown() through a call to IOleContainer::EnumObjects.

When to Implement

Call the methods of IEnumUnknown() to enumerate the objects in a compound document, when you get a pointer to the interface on the enumerator through a call to IOleContainer::EnumObjects.

The prototypes of the methods are as follows:

#include <objidl.h>

HRESULT Next(
        ULONG celt,
        IUnknown ** rgelt,
        ULONG * pceltFetched );

#include <objidl.h>

HRESULT Skip(
        ULONG celt );

#include <objidl.h>

HRESULT Reset(
        void );

#include <objidl.h>

HRESULT Clone(
        IEnumUnknown ** ppenum );

16.2.6    IMoniker

The IMoniker() interface contains methods that allow you to use a moniker object, which contains information that uniquely identifies a COM object. An object that has a pointer to the moniker object's IMoniker() interface can locate, activate, and get access to the identified object without having any other specific information on where the object is actually located in a distributed system.

Like a path to a file in a file system, a moniker contains information that allows a COM object to be located and activated. Monikers can identify any type of COM object, from a document object stored in a file to a selection within an embedded object. COM provides a set of moniker classes that allow you to create moniker objects identifying the objects most commonly found in the system. For example, there might be an object representing a range of cells in a spreadsheet which is itself embedded in a text document stored in a file. In a distributed system, this object's moniker would identify the location of the object's system, the file's physical location on that system, the storage of the embedded object within that file, and, finally, the location of the range of cells within the embedded object.

A moniker object supports the IMoniker() interface, which is derived from the IPersistStream() interface, and uniquely identifies a single object in the system. Once an object providing a moniker has created the moniker object, this information cannot be changed within that object. If the moniker provider changes the information, it can only do so by creating a new moniker object, which would then uniquely identify the object in question.

Monikers have two important capabilites:

Monikers are used as the basis for linking in COM. A linked object contains a moniker that identifies its source. When the user activates the linked object to edit it, the moniker is bound; this loads the link source into memory.

When to Implement

Implement IMoniker() only if you are writing a new moniker class. This is necessary only if you need to identify objects that cannot be identified using one of the COM-supplied moniker classes described below.

The COM-supplied moniker classes are sufficient for most situations. Before considering writing your own moniker class, you should make sure that your requirements cannot be satisified by these classes.

If you decide you need to write your own implementation of IMoniker(), you must also implement the IROTData() interface on your moniker class. This interface allows your monikers to be registered with the Running Object Table (ROT).

When to Use

Two kinds of objects call the methods of IMoniker:

The component providing a moniker makes it accessible to other objects. It is important to understand the differences between the various system-supplied moniker classes to know which are appropriate for a given object. COM also provides functions for creating monikers using the COM-supplied moniker classes.

A moniker provider must also implement other interfaces to allow the monikers it hands out to be bound. COM objects that commonly provide monikers are link sources. These include server applications that support linking and container applications that support linking to their embedded objects.

Binding to an object means that a client uses a moniker to locate the object, activate it when necessary, and get a pointer to one of the active object's interfaces. The client of the moniker does not need to be aware of the class of the moniker--it must just get a pointer to the correct moniker's IMoniker() interface. Monikers are used most often in this way by container applications that allow their documents to contain linked objects. However, link containers rarely call IMoniker() methods directly.

Table 16-5:  IMoniker Methods in VTable Order

IUnknown Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 16-6:  IPersist Methods

IPersist Methods Description
GetClassID() Returns the object's CLSID.

Table 16-7:  IPersistStream Methods

IPersistStream Methods Description
IsDirty Checks whether object has been modified.
Load Loads the object from a stream.
Save Saves the object to a stream.
GetSizeMax Returns the buffer size needed to save the object.

Table 16-8:  IMoniker Methods

IMoniker() Methods Description
BindToObject Binds to the object named by the moniker.
BindToStorage Binds to the object's storage.
Reduce Reduces the moniker to simplest form.
ComposeWith Composes with another moniker.
Enum Enumerates component monikers.
IsEqual Compares with another moniker.
Hash Returns a hash value.
IsRunning() Checks whether object is running.
GetTimeOfLastChange Returns time the object was last changed.
Inverse Returns the inverse of the moniker.
CommonPrefixWith Finds the prefix that the moniker has in common with another moniker.
RelativePathTo Constructs a relative moniker between the moniker and another.
GetDisplayName Returns the display name.
ParseDisplayName Converts a display name into a moniker.
IsSystemMoniker Checks whether moniker is one of the system-supplied types.

See Also

BindMoniker(), CreateBindCtx(), CreateGenericComposite(), CreateFileMoniker, CreateItemMoniker(), CreateAntiMoniker(), CreatePointerMoniker(), IPersistStream(), IROTData(), IMoniker--AntiMoniker Implementation, IMoniker--File Moniker Implementation, IMoniker--Item Moniker Implementation, IMoniker--Generic Composite Moniker Implementation, IMoniker--Pointer Moniker Implementation  

IMoniker::BindToObject()

NAME

IMoniker::BindToObject() - Uses the moniker to bind to the object it identifies. The binding process involves finding the object, putting it into the running state if necessary, and supplying the caller with a pointer to a specified interface on the identified object.

Synopsis

#include <objidl.h>

HRESULT BindToObject(
        IBindCtx * pbc,
        IMoniker * pmkToLeft,
        REFIID riidResult,
        void ** ppvResult );

Description

IMoniker::BindToObject() implements the primary function of a moniker, which is to locate the object identified by the moniker and return a pointer to one of its interfaces.

Notes to Callers

If you are using a moniker as a persistent connection between two objects, you activate the connection by calling IMoniker::BindToObject().

You typically call IMoniker::BindToObject() during the following process:

  1. Create a bind context object with a call to the CreateBindCtx() function.

  2. Call IMoniker::BindToObject() using the moniker, retrieving a pointer to a desired interface on the identified object.

  3. Release() the bind context.

  4. Through the acquired interface pointer, perform the desired operations on the object.

  5. When finished with the object, release the object's interface pointer.

The following code fragment illustrates these steps:

// pMnk is an IMoniker() * that points to a previously acquired moniker 
// ICellRange is a custom interface designed for an object that is a
//            range of spreadsheet cells 
ICellRange *pCellRange; 
IBindCtx() *pbc; 
CreateBindCtx( 0, &pbc ); 
pMnk->BindToObject( pbc, NULL, IID_ICellRange, &pCellRange );
pbc->Release(); 
// pCellRange now points to the object; safe to use pCellRange 
pCellRange->Release();

You can also use the BindMoniker() function when you only intend one binding operation and don't need to retain the bind context object. This helper function encapsulates the creation of the bind context, calling IMoniker::BindToObject(), and releasing the bind context.

COM containers that support links to objects use monikers to locate and get access to the linked object, but typically do not call IMoniker::BindToObject() directly.

Notes to Implementors

What your implementation does depends on whether you expect your moniker to have a prefix, that is, whether you expect the pmkToLeft parameter to be NULL or not. For example, an item moniker, which identifies an object within a container, expects that pmkToLeft identifies the container. An item moniker consequently uses pmkToLeft to request services from that container. If you expect your moniker to have a prefix, you should use the pmkToLeft parameter (for instance, calling IMoniker::BindToObject() on it) to request services from the object it identifies.

If you expect your moniker to have no prefix, your IMoniker::BindToObject() implementation should first check the Running Object Table (ROT) to see if the object is already running. To acquire a pointer to the ROT, your implementation should call IBindCtx::GetRunningObjectTable() on the pbc parameter. You can then call the IRunningObjectTable::GetObject() method to see if the current moniker has been registered in the ROT. If so, you can immediately call IUnknown::QueryInterface() to get a pointer to the interface requested by the caller.

When your IMoniker::BindToObject() implementation binds to some object, it should use the pbc parameter to call IBindCtx::RegisterObjectBound() to store a reference to the bound object in the bind context. This ensures that the bound object remains running until the bind context is released, which can avoid the expense of having a subsequent binding operation load it again later.

If the bind context's BIND_OPTS structure specifies the BINDFLAGS_JUSTTESTEXISTENCE flag, your implementation has the option of returning NULL in ppvResult (although you can also ignore the flag and perform the complete binding operation).

Parameters

pbc

[in] Pointer to the IBindCtx() interface on the bind context object, which is used in this binding operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the moniker implementation should retrieve information about its environment.

pmkToLeft

[in] If the moniker is part of a composite moniker, pointer to the moniker to the left of this moniker. This parameter is primarily used by moniker implementers to enable cooperation between the various components of a composite moniker. Moniker clients should pass NULL.

riidResult

[in] IID of the interface the client wishes to use to communicate with the object that the moniker identifies.

ppvResult

[out] When successful, indirect pointer to the interface specified in riidResult on the object the moniker identifies. In this case, the implementation must call IUnknown::AddRef() on this pointer. It is the caller's responsibility to release the object with a call to IUnknown::Release(). If an error occurs, ppvResult should return NULL.

Return Values

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

S_OK

The binding operation was successful.

MK_E_NOOBJECT

The object identified by this moniker, or some object identified by the composite moniker of which this moniker is a part, could not be found.

MK_E_EXCEEDEDDEADLINE

The binding operation could not be completed within the time limit specified by the bind context's BIND_OPTS structure.

MK_E_CONNECTMANUALLY

The binding operation requires assistance from the end user. The most common reasons for returning this value are that a password is needed or that a floppy needs to be mounted. When this value is returned, retrieve the moniker that caused the error with a call to IBindCtx::GetObjectParam() with the key ``ConnectManually''. You can then call IMoniker::GetDisplayName() to get the display name, display a dialog box that communicates the desired information, such as instructions to mount a floppy or a request for a password, and then retry the binding operation.

MK_E_INTERMEDIATEINTERFACENOTSUPPORTED

An intermediate object was found but it did not support an interface required to complete the binding operation. For example, an item moniker returns this value if its container does not support the IOleItemContainer() interface.

STG_E_ACCESSDENIED

Unable to access the storage object.

IOleItemContainer::GetObject() errors

If the moniker used to bind to an object contains an item moniker, errors associated with this method can be returned.

See Also

BindMoniker(), IMoniker::BindToStorage()  

IMoniker::BindToStorage()

NAME

IMoniker::BindToStorage() - Retrieves an interface pointer to the storage that contains the object identified by the moniker. Unlike the IMoniker::BindToObject() method, this method does not activate the object identified by the moniker.

Synopsis

#include <objidl.h>

HRESULT BindToStorage(
        IBindCtx * pbc,
        IMoniker * pmkToLeft,
        REFIID riid,
        void ** ppvObj );

Description

There is an important difference between the IMoniker::BindToObject() and IMoniker::BindToStorage() methods. If, for example, you have a moniker that identifies a spreadsheet object, calling IMoniker::BindToObject() provides access to the spreadsheet object itself, while calling IMoniker::BindToStorage() provides access to the storage object in which the spreadsheet resides.

Notes to Callers

Although none of the COM moniker classes call this method in their binding operations, it might be appropriate to call it in the implementation of a new moniker class. You could call this method in an implementation of IMoniker::BindToObject() that requires information from the object identified by the pmkToLeft parameter and can get it from the persistent storage of the object without activation. For example, if your monikers are used to identify objects that can be activated without activating their containers, you may find this method useful.

A client that can read the storage of the object its moniker identifies could also call this method.

Notes to Implementors

Your implementation should locate the persistent storage for the object identified by the current moniker and return the desired interface pointer. Some types of monikers represent pseudo-objects, which are objects that do not have their own persistent storage. Such objects comprise some portion of the internal state of its container; as, for example, a range of cells in a spreadsheet. If your moniker class identifies this type of object, your implementation of IMoniker::BindToStorage() should return the error MK_E_NOSTORAGE.

If the bind context's BIND_OPTS structure specifies the BINDFLAGS_JUSTTESTEXISTENCE flag, your implementation has the option of returning NULL in ppvObj (although it can also ignore the flag and perform the complete binding operation).

Parameters

pbc

[in] Pointer to the IBindCtx() interface on the bind context object to be used during this binding operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the moniker implementation should retrieve information about its environment. For more information, see IBindCtx().

pmkToLeft

[in] If the moniker is part of a composite moniker, pointer to the moniker to the left of this moniker. This parameter is primarily used by moniker implementers to enable cooperation between the various components of a composite moniker. Moniker clients should pass NULL.

riid

[in] Reference to the identifier of the storage interface requested, whose pointer will be returned in ppvObj. Storage interfaces commonly requested include IStorage(), IStream(), and ILockBytes().

ppvObj

[out] Pointer to the interface identified by riid on the storage of the object identified by the moniker. If ppvObj is non-NULL, the implementation must call IUnknown::AddRef() on the parameter; it is the caller's responsibility to call IUnknown::Release(). If an error occurs, ppvObj is set to NULL.

Return Values

The method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The binding operation was successful.

MK_E_NOSTORAGE

The object identified by this moniker does not have its own storage.

MK_E_EXCEEDEDDEADLINE

The operation could not be completed within the time limit specified by the bind context's BIND_OPTS structure.

MK_E_CONNECTMANUALLY

The operation was unable to connect to the storage, possibly because a network device could not be connected to. For more information, see IMoniker::BindToObject().

MK_E_INTERMEDIATEINTERFACENOTSUPPORTED

An intermediate object was found but it did not support an interface required for an operation. For example, an item moniker returns this value if its container does not support the IOleItemContainer() interface.

STG_E_ACCESSDENIED

Unable to access the storage object.

IOleItemContainer::GetObject() errors

Binding to a moniker containing an item moniker can return any of the errors associated with this function.

See Also

IMoniker::BindToObject()  

IMoniker::CommonPrefixWith()

NAME

IMoniker::CommonPrefixWith() - Creates a new moniker based on the common prefix that this moniker (the one comprising the data of this moniker object) shares with another moniker.

Synopsis

#include <objidl.h>

HRESULT CommonPrefixWith(
        IMoniker * pmkOther,
        IMoniker ** ppmkPrefix );

Description

IMoniker::CommonPrefixWith() creates a new moniker that consists of the common prefixes of the moniker on this moniker object and another moniker. If, for example, one moniker represents the path ``c:\projects\secret\art\pict1.bmp'' and another moniker represents the path ``c:\projects\secret\docs\chap1.txt,'' the common prefix of these two monikers would be a moniker representing the path ``c:\projects\secret.''

Notes to Callers

The IMoniker::CommonPrefixWith() method is primarily called in the implementation of the IMoniker::RelativePathTo() method. Clients using a moniker to locate an object rarely need to call this method.

Call this method only if pmkOther and this moniker are both absolute monikers. An absolute moniker is either a file moniker or a generic composite whose leftmost component is a file moniker that represents an absolute path. Do not call this method on relative monikers, because it would not produce meaningful results.

Notes to Implementors

Your implementation should first determine whether pmkOther is a moniker of a class that you recognize and for which you can provide special handling (for example, if it is of the same class as this moniker). If so, your implementation should determine the common prefix of the two monikers. Otherwise, it should pass both monikers in a call to the MonikerCommonPrefixWith() function, which correctly handles the generic case.

Parameters

pmkOther

[in] Pointer to the IMoniker() interface on another moniker to be compared with this one to determine whether there is a common prefix.

ppmkPrefix

[out] When successful, points to the IMoniker() pointer to the moniker that is the common prefix of this moniker and pmkOther. 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 there is no common prefix, the implementation should set ppmkPrefix to NULL.

Return Values

The method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

A common prefix exists that is neither this moniker nor pmkOther.

MK_S_NOPREFIX

No common prefix exists.

MK_S_HIM

The entire pmkOther moniker is a prefix of this moniker.

MK_S_US

The two monikers are identical.

MK_S_ME

This moniker is a prefix of the pmkOther moniker.

MK_E_NOTBINDABLE

This method was called on a relative moniker. It is not meaningful to take the common prefix on a relative moniker.

See Also

IMoniker::RelativePathTo(), MonikerCommonPrefixWith()  

IMoniker::ComposeWith()

NAME

IMoniker::ComposeWith() - Combines the current moniker with another moniker, creating a new composite moniker.

Synopsis

#include <objidl.h>

HRESULT ComposeWith(
        IMoniker * pmkRight,
        BOOL fOnlyIfNotGeneric,
        IMoniker ** ppmkComposite );

Description

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:

Comp( Comp( A, B ), C )

(where Comp() represents the composition operation) 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 Implementors

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.

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.

See Also

CreateGenericComposite(), IMoniker::Inverse()  

IMoniker::Enum()

NAME

IMoniker::Enum() - Supplies a pointer to an enumerator that can enumerate the components of a composite moniker.

Synopsis

#include <objidl.h>

HRESULT Enum(
        BOOL fForward,
        IEnumMoniker ** ppenumMoniker );

Description

IMoniker::Enum() must supply an IEnumMoniker() pointer to an enumerator that can enumerate the components of a moniker. For example, the implementation of the IMoniker::Enum() method for a generic composite moniker creates an enumerator that can determine the individual monikers that make up the composite, while the IMoniker::Enum() method for a file moniker creates an enumerator that returns monikers representing each of the components in the path.

Notes to Callers

Call this method to examine the components that make up a composite moniker.

Notes to Implementors

If the new moniker class has no discernible internal structure, your implementation of this method can simply return S_OK and set ppenumMoniker to NULL.

Parameters

fForward

[in] If TRUE, enumerates the monikers from left to right. If FALSE, enumerates from right to left.

ppenumMoniker

[out] When successful, indirect pointer to an IEnumMoniker() enumerator on this moniker. 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 moniker has no enumerable components, the implementation sets ppenumMoniker to NULL.

Return Values

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

S_OK

Indicates success. This value is returned even if the moniker does not provide an enumerator (if ppenumMoniker equals NULL).

See Also

IEnumXXXX  

IMoniker::GetDisplayName()

NAME

IMoniker::GetDisplayName() - Gets the display name , which is a user-readable representation of this moniker.

Synopsis

#include <objidl.h>

HRESULT GetDisplayName(
        IBindCtx * pbc,
        IMoniker * pmkToLeft,
        LPOLESTR * ppszDisplayName );

Description

IMoniker::GetDisplayName() provides a string that is a displayable representation of the moniker. A display name is not a complete representation of a moniker's internal state; it is simply a form that can be read by users. As a result, it is possible (though rare) for two different monikers to have the same display name. While there is no guarantee that the display name of a moniker can be parsed back into that moniker when calling the MkParseDisplayName() function with it, failure to do so is rare.

As examples, the file moniker implementation of this method supplies the path the moniker represents, and an item moniker's display name is the string identifying the item that is contained in the moniker.

Notes to Callers

It is possible that retrieving a moniker's display name may be an expensive operation. For efficiency, you may want to cache the results of the first successful call to IMoniker::GetDisplayName(), rather than making repeated calls.

Notes to Implementors

If you are writing a moniker class in which the display name does not change, simply cache the display name and supply the cached name when requested. If the display name can change over time, getting the current display name might mean that the moniker has to access the object's storage or bind to the object, either of which can be expensive operations. If this is the case, your implementation of IMoniker::GetDisplayName() should return MK_E_EXCEEDEDDEADLINE if the name cannot be retrieved by the time specified in the bind context's BIND_OPTS structure.

A moniker that is intended to be part of a generic composite moniker should include any preceding delimiter (such as ``\'') as part of its display name. For example, the display name returned by an item moniker includes the delimiter specified when it was created with the CreateItemMoniker() function. The display name for a file moniker does not include a delimiter because file monikers are always expected to be the leftmost component of a composite.

Parameters

pbc

[in] Pointer to the IBindCtx() interface on the bind context to be used in this operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the moniker implementation should retrieve information about its environment. For more information, see IBindCtx().

pmkToLeft

[in] If the moniker is part of a composite moniker, pointer to the moniker to the left of this moniker. This parameter is primarily used by moniker implementers to enable cooperation between the various components of a composite moniker. Moniker clients should pass NULL.

ppszDisplayName

[out] When successful, indirect pointer to a zero-terminated wide character string (two bytes per character) containing the display name of this moniker. The implementation must use IMalloc::Alloc() to allocate the string returned in ppszDisplayName, and the caller is responsible for calling IMalloc::Free() to free it. Both the caller and and the one called use the COM task allocator returned by CoGetMalloc(). If an error occurs, ppszDisplayName should be set to NULL.

Return Values

The method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The display name was successfully supplied.

MK_E_EXCEEDEDDEADLINE

The binding operation could not be completed within the time limit specified by the bind context's BIND_OPTS structure.

E_NOTIMPL

There is no display name.

See Also

IMoniker::ParseDisplayName(), MkParseDisplayName()  

IMoniker::GetTimeOfLastChange()

NAME

IMoniker::GetTimeOfLastChange() - Provides a number representing the time the object identified by this moniker was last changed. To be precise, the time returned is the earliest time COM can identify after which no change has occurred, so this time may be later than the time of the last change to the object.

Synopsis

#include <objidl.h>

HRESULT GetTimeOfLastChange(
        IBindCtx * pbc,
        IMoniker * pmkToLeft,
        FILETIME * pFileTime );

Description

Notes to Callers

If you're caching information returned by the object identified by the moniker, you may want to ensure that your information is up-to-date. To do so, you would call IMoniker::GetTimeOfLastChange() and compare the time returned with the time you last retrieved information from the object.

For the monikers stored within linked objects, IMoniker::GetTimeOfLastChange() is primarily called by the default handler's implementation of IOleObject::IsUpToDate. Container applications call IOleObject::IsUpToDate to determine if a linked object (or an embedded object containing linked objects) is up-to-date without actually binding to the object. This enables an application to determine quickly which linked objects require updating when the end user opens a document. The application can then bind only those linked objects that need updating (after prompting the end user to determine whether they should be updated), instead of binding every linked object in the document.

Notes to Implementors

It is important to perform this operation quickly because, for linked objects, this method is called when a user first opens a compound document. Consequently, your IMoniker::GetTimeOfLastChange() implementation should not bind to any objects. In addition, your implementation should check the deadline parameter in the bind context and return MK_E_EXCEEDEDDEADLINE if the operation cannot be completed by the specified time.

There are a number of strategies you can use in your implementations:

Parameters

pbc

[in] Pointer to the bind context to be used in this binding operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the moniker implementation should retrieve information about its environment. For more information, see IBindCtx().

pmkToLeft

[in] If the moniker is part of a composite moniker, pointer to the moniker to the left of this moniker. This parameter is primarily used by moniker Implementers to enable cooperation between the various components of a composite moniker. Moniker clients should pass NULL.

pFileTime

[out] Pointer to the FILETIME structure receiving the time of last change. A value of {0xFFFFFFFF,0x7FFFFFFF} indicates an error (for example, exceeded time limit, information not available).

Return Values

The method supports the standard return value E_UNEXPECTED, as well as the following:

S_OK

The method successfully returned a time.

MK_E_EXCEEDEDDEADLINE

The binding operation could not be completed within the time limit specified by the bind context's BIND_OPTS structure.

MK_E_CONNECTMANUALLY

The operation was unable to connect to the storage for this object, possibly because a network device could not be connected to. For more information, see IMoniker::BindToObject().

MK_E_UNAVAILABLE

The time of the change is unavailable, and will not be available no matter what deadline is used.

See Also

IBindCtx::GetRunningObjectTable(), IRunningObjectTable::GetTimeOfLastChange()  

IMoniker::Hash()

NAME

IMoniker::Hash() - Calculates a 32-bit integer using the internal state of the moniker.

Synopsis

#include <objidl.h>

HRESULT Hash(
        DWORD * pdwHash );

Description

Notes to Callers

You can use the value returned by this method to maintain a hash table of monikers. The hash value determines a hash bucket in the table. To search such a table for a specified moniker, calculate its hash value and then compare it to the monikers in that hash bucket using IMoniker::IsEqual().

Notes to Implementors

The hash value must be constant for the lifetime of the moniker. Two monikers that compare as equal using IMoniker::IsEqual() must hash to the same value.

Marshaling and then unmarshaling a moniker should have no effect on its hash value. Consequently, your implementation of IMoniker::Hash() should rely only on the internal state of the moniker, not on its memory address.

Parameters

pdwHash

[out] Pointer to the hash value.

Return Values

S_OK

Successfully received a 32-bit integer hash value.

See Also

IMoniker::IsEqual()  

IMoniker::Inverse()

NAME

IMoniker::Inverse() - Provides a moniker that, when composed to the right of this moniker or one of similar structure, will destroy it (the moniker will compose to nothing).

Synopsis

#include <objidl.h>

HRESULT Inverse(
        IMoniker ** ppmk );

Description

The inverse of a moniker is analogous to the ``..'' directory in MS-DOS file systems; the ``..'' directory acts as the inverse to any other directory name, because appending ``..'' to a directory name results in an empty path. In the same way, the inverse of a moniker typically is also the inverse of all monikers in the same class. However, it is not necessarily the inverse of a moniker of a different class.

The inverse of a composite moniker is a composite consisting of the inverses of the components of the original moniker, arranged in reverse order. For example, if the inverse of A is Inv( A ) and the composite of A, B, and C is Comp( A, B, C ), then:

Inv( Comp( A, B, C ) )

is equal to:

Comp( Inv( C ), Inv( B ), Inv( A ) ).

Not all monikers have inverses. Most monikers that are themselves inverses, such as anti-monikers, do not have inverses. Monikers that have no inverse cannot have relative monikers formed from inside the objects they identify to other objects outside.

Notes to Callers

An object that is using a moniker to locate another object usually does not know the class of the moniker it is using. To get the inverse of a moniker, you should always call IMoniker::Inverse() rather than the CreateAntiMoniker() function, because you cannot be certain that the moniker you're using considers an anti-moniker to be its inverse.

The IMoniker::Inverse() method is also called by the implementation of the IMoniker::RelativePathTo() method, to assist in constructing a relative moniker.

Notes to Implementors

If your monikers have no internal structure, you can call the CreateAntiMoniker() function in to get an anti-moniker in your implementation of IMoniker::Inverse(). In your implementation of IMoniker::ComposeWith(), you need to check for the inverse you supply in the implementation of IMoniker::Inverse().

Parameters

ppmk

[out] When successful, indirect pointer to the IMoniker() interface on a moniker that is the inverse of this moniker. 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, the implementation should set ppmk to NULL.

Return Values

The method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The inverse moniker has been returned successfully.

MK_E_NOINVERSE

The moniker class does not have an inverse.

See Also

CreateAntiMoniker(), IMoniker::ComposeWith(), IMoniker::RelativePathTo()  

IMoniker::IsEqual()

NAME

IMoniker::IsEqual() - Compares this moniker with a specified moniker and indicates whether they are identical.

Synopsis

#include <objidl.h>

HRESULT IsEqual(
        IMoniker * pmkOtherMoniker );

Description

Previous implementations of the Running Object Table (ROT) called this method. The current implementation of the ROT uses the IROTData() interface instead.

Notes to Callers

Call this method to determine if two monikers are identical or not. Note that the reduced form of a moniker is considered different from the unreduced form. You should call the IMoniker::Reduce() method before calling IMoniker::IsEqual(), because a reduced moniker is in its most specific form. IMoniker::IsEqual() may return S_FALSE on two monikers before they are reduced, and S_OK after they are reduced.

Notes to Implementors

Your implementation should not reduce the current moniker before performing the comparison. It is the caller's responsibility to call IMoniker::Reduce() in order to compare reduced monikers.

Note that two monikers that compare as equal must hash to the same value using IMoniker::Hash().

Parameters

pmkOtherMoniker

[in] Pointer to the IMoniker() interface on the moniker to be used for comparison with this one (the one from which this method is called).

Return Values

S_OK

The two monikers are identical.

S_FALSE

The two monikers are not identical.

See Also

IMoniker::Reduce(), IMoniker::Hash(), IROTData()  

IMoniker::IsRunning()

NAME

IMoniker::IsRunning() - Determines whether the object identified by this moniker is currently loaded and running.

Synopsis

#include <objidl.h>

HRESULT IsRunning((
        IBindCtx * pbc,
        IMoniker * pmkToLeft,
        IMoniker * pmkNewlyRunning );

Description

Notes to Callers

If speed is important when you're requesting services from the object identified by the moniker, you may want those services only if the object is already running (because loading an object into the running state may be time-consuming). In such a situation, you'd call IMoniker::IsRunning() to determine if the object is running.

For the monikers stored within linked objects, IMoniker::IsRunning() is primarily called by the default handler's implementation of IOleLink::BindIfRunning.

Notes to Implementors

To get a pointer to the Running Object Table (ROT), your implementation should call IBindCtx::GetRunningObjectTable() on the pbc parameter. Your implementation can then call IRunningObjectTable::IsRunning() to determine whether the object identified by the moniker is running. Note that the object identified by the moniker must have registered itself with the ROT when it first began running.

Parameters

pbc

[in] Pointer to the IBindCtx interface on the bind context to be used in this binding operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the moniker implementation should retrieve information about its environment. For more information, see IBindCtx().

pmkToLeft

[in] Pointer to the IMoniker interface on the moniker to the left of this moniker if this moniker is part of a composite. This parameter is primarily used by moniker Implementers to enable cooperation between the various components of a composite moniker; moniker clients can usually pass NULL.

pmkNewlyRunning

[in] Pointer to the IMoniker interface on the moniker most recently added to the Running Object Table (ROT). This can be NULL. If non-NULL, the implementation can return the results of calling IMoniker::IsEqual() on the pmkNewlyRunning parameter, passing the current moniker. This parameter is intended to enable IMoniker::IsRunning() implementations that are more efficient than just searching the ROT, but the implementation can choose to ignore pmkNewlyRunning without causing any harm.

Return Values

The method supports the standard return value E_UNEXPECTED, as well as the following:

S_OK

The moniker is running.

S_FALSE

The moniker is not running.

See Also

IBindCtx::GetRunningObjectTable(), IRunningObjectTable::IsRunning()  

IMoniker::IsSystemMoniker()

NAME

IMoniker::IsSystemMoniker() - Indicates whether this moniker is of one of the system-supplied moniker classes.

Synopsis

#include <objidl.h>

HRESULT IsSystemMoniker(
        DWORD * pdwMksys );

Description

Notes to Callers

New values of the MKSYS enumeration may be defined in the future; therefore you should explicitly test for each value you are interested in.

Notes to Implementors

Your implementation of this method must return MKSYS_NONE. You cannot use this function to identify your own monikers (for example, in your implementation of IMoniker::ComposeWith()). Instead, you should use your moniker's implementation of IPersist::GetClassID() or use IUnknown::QueryInterface() to test for your own private interface.

Parameters

pdwMksys

[out] Pointer to an integer that is one of the values from the MKSYS enumeration, and refers to one of the COM moniker classes. This parameter cannot be NULL.

Return Values

S_OK

The moniker is a system moniker.

S_FALSE

The moniker is not a system moniker.

See Also

IPersist::GetClassID(), MKSYS  

IMoniker::ParseDisplayName()

NAME

IMoniker::ParseDisplayName() - Reads as many characters of the specified display name as it understands and builds a moniker corresponding to the portion read; this procedure is known as "parsing" the display name.

Synopsis

#include <objidl.h>

HRESULT ParseDisplayName(
        IBindCtx * pbc,
        IMoniker * pmkToLeft,
        LPOLESTR pszDisplayName,
        ULONG * pchEaten,
        IMoniker ** ppmkOut );

Description

Notes to Callers

Moniker clients do not typically call IMoniker::ParseDisplayName() directly. Instead, they call the MkParseDisplayName() function when they want to convert a display name into a moniker (for example, in implementing the Links dialog box for a container application, or for implementing a macro language that supports references to objects outside the document). That function first parses the initial portion of the display name itself.

It then calls IMoniker::ParseDisplayName() on the moniker it has just created, passing the remainder of the display name and getting a new moniker in return; this step is repeated until the entire display name has been parsed.

Notes to Implementors

Your implementation may be able to perform this parsing by itself if your moniker class is designed to designate only certain kinds of objects. Otherwise, you must get an IParseDisplayName() interface pointer for the object identified by the moniker-so-far (i.e., the composition of pmkToLeft and this moniker) and then return the results of calling IParseDisplayName::ParseDisplayName().

There are different strategies for getting an IParseDisplayName() pointer:

Any objects that are bound should be registered with the bind context (see IBindCtx::RegisterObjectBound()) to ensure that they remain running for the duration of the parsing operation.

Parameters

pbc

[in] Pointer to the IBindCtx() interface on the bind context to be used in this binding operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the moniker implementation should retrieve information about its environment. For more information, see IBindCtx().

pmkToLeft

[in] Pointer to the IMoniker() interface on the moniker that has been built out of the display name up to this point.

pszDisplayName

[in] Pointer to a zero-terminated string containing the remaining display name to be parsed. For Win32 applications, the LPOLESTR type indicates a wide character string (two bytes per character); otherwise, the string has one byte per character.

pchEaten

[out] Pointer to the number of characters in pszDisplayName that were consumed in this step.

ppmkOut

[out] When successful, indirect pointer to the IMoniker() interface on the moniker that was built from pszDisplayName. 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, the implementation sets ppmkOut to NULL.

Return Values

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

S_OK

The parsing operation was completed successfully.

MK_E_SYNTAX

An error in the syntax of the input components (pmkToLeft, this moniker, and pszDisplayName). For example, a file moniker returns this error if pmkToLeft is non-NULL, and an item moniker returns it if pmkToLeft is NULL.

IMoniker::BindToObject() errors

Parsing display names may cause binding. Thus, any error associated with this function may be returned.

See Also

IParseDisplayName(), MkParseDisplayName()  

IMoniker::Reduce()

NAME

IMoniker::Reduce() - Returns a reduced moniker; that is, another moniker that refers to the same object as this moniker but can be bound with equal or greater efficiency.

Synopsis

#include <objidl.h>

HRESULT Reduce(
        IBindCtx * pbc,
        DWORD dwReduceHowFar,
        IMoniker ** ppmkToLeft,
        IMoniker ** ppmkReduced );

Description

IMoniker::Reduce() is intended for the following uses:

The intent of the MKRREDUCE flags passed in the dwReduceHowFar parameter is to provide the ability to programmatically reduce a moniker to a form whose display name is recognizable to the user. For example, paths in the file system, bookmarks in word-processing documents, and range names in spreadsheets are all recognizable to users. In contrast, a macro or an alias encapsulated in a moniker are not recognizable to users.

Notes to Callers

The scenarios described above are not currently implemented by the system-supplied moniker classes.

You should call IMoniker::Reduce() before comparing two monikers using the IMoniker::IsEqual() method, because a reduced moniker is in its most specific form. IMoniker::IsEqual() may return S_FALSE on two monikers before they are reduced and return S_OK after they are reduced.

Notes to Implementors

If the current moniker can be reduced, your implementation must not reduce the moniker in-place. Instead, it must return a new moniker that represents the reduced state of the current one. This way, the caller still has the option of using the non-reduced moniker (for example, enumerating its components). Your implementation should reduce the moniker at least as far as is requested.

Parameters

pbc

[in] Pointer to the IBindCtx() interface on the bind context to be used in this binding operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the moniker implementation should retrieve information about its environment. For more information, see IBindCtx().

dwReduceHowFar

[in] DWORD that specifies how far this moniker should be reduced. This parameter must be one of the values from the MKRREDUCE enumeration.

ppmkToLeft

[in, out] On entry, indirect pointer to the moniker to the left of this moniker, if this moniker is part of a composite. This parameter is primarily used by moniker Implementers to enable cooperation between the various components of a composite moniker; moniker clients can usually pass NULL.

On return, ppmkToLeft is usually set to NULL, indicating no change in the original moniker to the left. In rare situations ppmkToLeft indicates a moniker, indicating that the previous moniker to the left should be disregarded and the moniker returned through ppmkToLeft is the replacement. In such a situation, the implementation must call IUnknown::Release() on the passed-in pointer and call IUnknown::AddRef() on the returned moniker; the caller must release it later. If an error occurs, the implementation can either leave the parameter unchanged or set it to NULL.

ppmkReduced

[out] Indirect pointer to the IMoniker() interface on the reduced form of this moniker, which can be NULL if an error occurs or if this moniker is reduced to nothing. If this moniker cannot be reduced, ppmkReduced is simply set to this moniker and the return value is MK_S_REDUCED_TO_SELF. If ppmkReduced is non-NULL, the implementation must call IUnknown::AddRef() on the parameter; it is the caller's responsibility to call IUnknown::Release(). (This is true even if ppmkReduced is set to this moniker.)

Return Values

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

S_OK

This moniker was reduced.

MK_S_REDUCED_TO_SELF

This moniker could not be reduced any further, so ppmkReduced indicates this moniker.

MK_E_EXCEEDEDDEADLINE

The operation could not be completed within the time limit specified by the bind context's BIND_OPTS structure.

See Also

IMoniker::IsEqual(), MKRREDUCE  

IMoniker::RelativePathTo()

NAME

IMoniker::RelativePathTo() - Supplies a moniker that, when composed onto the end of this moniker (or one with a similar structure), yields the specified moniker.

Synopsis

#include <objidl.h>

HRESULT RelativePathTo(
        IMoniker * pmkOther,
        IMoniker ** ppmkRelPath );

Description

A relative moniker is analogous to a relative path (such as ``..\backup''). For example, suppose you have one moniker that represents the path ``c:\projects\secret\art\pict1.bmp'' and another moniker that represents the path ``c:\projects\secret\docs\chap1.txt.'' Calling IMoniker::RelativePathTo() on the first moniker, passing the second one as the pmkOther parameter, would create a relative moniker representing the path ``..\docs\chap1.txt.''

Notes to Callers

Moniker clients typically do not need to call IMoniker::RelativePathTo(). This method is primarily called by the default handler for linked objects. Linked objects contain both an absolute and a relative moniker to identify the link source (this enables link tracking if the user moves a directory tree containing both the container and source files). The default handler calls this method to create a relative moniker from the container document to the link source (that is, it calls IMoniker::RelativePathTo() on the moniker identifying the container document, passing the moniker identifying the link source as the pmkOther parameter).

If you do call IMoniker::RelativePathTo(), call it only on absolute monikers; for example, a file moniker or a composite moniker whose leftmost component is a file moniker, where the file moniker represents an absolute path. Do not call this method on relative monikers.

Notes to Implementors

Your implementation of IMoniker::RelativePathTo() should first determine whether pmkOther is a moniker of a class that you recognize and for which you can provide special handling (for example, if it is of the same class as this moniker). If so, your implementation should determine the relative path. Otherwise, it should pass both monikers in a call to the MonikerRelativePathTo() function, which correctly handles the generic case.

The first step in determining a relative path is determining the common prefix of this moniker and pmkOther. The next step is to break this moniker and pmkOther into two parts each, say (P, myTail) and (P, otherTail) respectively, where P is the common prefix. The correct relative path is then the inverse of myTail composed with otherTail:

Comp( Inv( myTail ), otherTail )

Where Comp() represents the composition operation and Inv() represents the inverse operation.

Note that for certain types of monikers, you cannot use your IMoniker::Inverse() method to construct the inverse of myTail. For example, a file moniker returns an anti-moniker as an inverse, while its IMoniker::RelativePathTo() method must use one or more file monikers that each represent the path ``..'' to construct the inverse of myTail.

Parameters

pmkOther

[in] Pointer to the IMoniker() interface on the moniker to which a relative path should be taken.

ppmkRelPath

[out] Iindirect pointer to the IMoniker() interface on the relative moniker. When successful, the implementation must call IUnknown::AddRef() on the parameter; it is the caller's responsibility to call IUnknown::Release(). If an error occurs, the implementation sets ppmkRelPath to NULL.

Return Values

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

S_OK

A meaningful relative path has been returned.

MK_S_HIM

No common prefix is shared by the two monikers and the moniker returned in ppmkRelPath is pmkOther.

MK_E_NOTBINDABLE

This moniker is a relative moniker, such as an item moniker. This moniker must be composed with the moniker of its container before a relative path can be determined.

See Also

IMoniker::Inverse(), IMoniker::CommonPrefixWith(), MonikerRelativePathTo()

16.2.7    IMoniker - Anti-Moniker Implementation

Anti-monikers are the inverse of the COM implementations of file, item, and pointer monikers. That is, an anti-moniker composed to the right of a file moniker, item moniker, or pointer moniker composes to nothing.

When To Use

If you're a moniker client, you typically do not need to use anti-monikers. When you need the inverse of a moniker, you should call IMoniker::Inverse(). For example, if you need an inverse to remove the last piece of a composite moniker, use IMoniker::Enum() to enumerate the pieces of the moniker and call IMoniker::Inverse() on the rightmost piece. You shouldn't use an anti-moniker for this purpose because you can't be sure that the rightmost piece of a composite considers an anti-moniker to be its inverse.

The only situation in which you should explicitly use an anti-moniker is if you are writing a new moniker class and if you have no special requirements for constructing inverses to your monikers. In that situation, you can return anti-monikers from your implementation of IMoniker::Inverse(). In your implementation of IMoniker::ComposeWith(), you should then annihilate one of your monikers for every anti-moniker you encounter.

Description

See Also

CreateAntiMoniker(), IMoniker()

16.2.8    IMoniker - Class Moniker Implementation

Class monikers are monikers that represent an object class. Class monikers bind to the class object of the class for which they are created.

Class monikers are most useful in composition with other types of monikers, such as file monikers or item monikers. Class monikers may also be composed to the right of monikers supporting binding to the IClassActivator() interface. This allows IClassActivator() to provide access to the class object and instances of the class.

When to Use

To use class monikers, you must use the CreateClassMoniker() function to create the monikers.

Description

See Also

CreateClassMoniker(), IMoniker()

16.2.9    IMoniker - File Moniker Implementation

File monikers are monikers that represent a path in the file system; a file moniker can identify any object that is saved in its own file. To identify objects contained within a file, you can compose monikers of other classes (for example, item monikers) to the right of a file moniker. However, the moniker to the left of a file moniker within a composite must be another file moniker, an anti-moniker, or a class moniker. It is illegal, for example, for an item moniker to appear to the left of a file moniker in a composite.

Note that an anti-moniker is the inverse of an entire file moniker, not the inverse of a component of the path that the moniker represents; that is, when you compose an anti-moniker to the right of a file moniker, the entire file moniker is removed. If you want to remove just the rightmost component of the path represented by a file moniker, you must create a separate file moniker based on the ``..'' path and then compose that to the end of the file moniker.

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 file monikers if the objects you're identifying are stored in files. If each object resides in its own file, file monikers are the only type you need. If the objects you're identifying are smaller than a file, you need to use another type of moniker (for example, item monikers) in addition to file monikers.

To use file monikers, you must use the CreateFileMoniker function to create the monikers. In order to allow your objects to be loaded when a file moniker is bound, your objects must implement the IPersistFile() interface.

The most common example of moniker providers are COM server applications that support linking. If your COM server application supports linking only to file-based documents in their entirety, file monikers are the only type of moniker you need. If your COM server application supports linking to objects smaller than a document (such as sections of a document or embedded objects), you must use item monikers as well as file monikers.

Description

See Also

CreateFileMoniker, IMoniker(), IPersistFile()

16.2.10    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 are a moniker client (that is, you are 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.

Description

See Also

CreateGenericComposite(), IMoniker()

16.2.11    IMoniker - Item Moniker Implementation

Item monikers are used to identify objects within containers, such as a portion of a document, an embedded object within a compound document, or a range of cells within a spreadsheet. Item monikers are often used in combination with file monikers; a file moniker is used to identify the container while an item moniker is used to identify the item within the container.

An item moniker contains a text string; this string is used by the container object to distinguish the contained item from the others. The container object must implement the IOleItemContainer() interface; this interface enables the item moniker code to acquire a pointer to an object, given only the string that identifies the object.

When to Use

If you are a moniker client (that is, you are 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. In order 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 COM applications that support linking. If your COM application supports linking to objects smaller than a file-based document, 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.

Description

See Also

CreateItemMoniker(), IMoniker(), IOleItemContainer()

16.2.12    IMoniker - Pointer Moniker Implementation

A pointer moniker essentially wraps an interface pointer so that it looks like a moniker and can be passed to those interfaces that require monikers. Binding a pointer moniker is done by calling the pointer's QueryInterface() method.

Instances of pointer monikers refuse to be serialized, that is, IPersistStream::Save() will return an error. These monikers can, however, be marshaled to a different process in an RPC call; internally, the system marshals and unmarshals the pointer using the standard paradigm for marshaling interface pointers.

When to Use

Pointer monikers are rarely needed. Use pointer monikers only if you need monikers to identify objects that have no persistent representation. Pointer monikers allow such objects to participate in a moniker-binding operation.

Description

See Also

IMoniker(), CreatePointerMoniker()

16.2.13    IOleItemContainer

The IOleItemContainer() interface is used by item monikers when they are bound to the objects they identify.

When any container of objects uses item monikers to identify its objects, it must define a naming scheme for those objects. The container's IOleItemContainer() implementation uses knowledge of that naming scheme to retrieve an object given a particular name. Item monikers use the container's IOleItemContainer() implementation during binding.

When to Implement

You must implement IOleItemContainer() if you're a moniker provider handing out item monikers. Being a moniker provider means 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.

The most common example of moniker providers are COM applications that support linking. If your COM application supports linking to objects smaller than a file-based document, you need to use item monikers. For a server application that allows linking to a portion of a document (such as selections 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.

You must define a naming scheme for identifying the objects within the container; for example, embedded objects in a document could be identified with names of the form ``embedobj1,'' ``embedobj2,'' and so forth, while ranges of cells in a spreadsheet could be identified with names of the form ``A1:E7,'' ``G5:M9,'' and so forth. (Ranges of cells in a spreadsheet are examples of ``pseudo-objects'' because they do not have their own persistent storage, but simply represent a portion of the container's internal state.) You create an item moniker that represents an object's name using the CreateItemMoniker() function and hand it out to a moniker client. When an item moniker is bound, your implementation of IOleItemContainer() must be able to take a name and retrieve the corresponding object.

When to Use

Applications typically do not call IOleItemContainer() methods directly. The item moniker implementation of IMoniker() is the primary caller of IOleItemContainer() methods.

Table 16-9:  IOleItemContainer Methods in VTable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments the reference count.
Release() Decrements the reference count.

Table 16-10:  IParseDisplayName Methods

IParseDisplayName Method Description
ParseDisplayName Parses object's display name to form moniker.

Table 16-11:  IOleContainer Methods

IOleContainer Methods Description
EnumObjects Enumerates objects in a container.
LockContainer Keeps container running until explicitly released.

Table 16-12:  IOleItemContainer Methods

IOleItemContainer() Methods Description
GetObject Returns a pointer to a specified object.
GetObjectStorage Returns a pointer to an object's storage.
IsRunning() Checks whether an object is running.

See Also

CreateItemMoniker(), IMoniker - Item Moniker Implementation  

IOleItemContainer::GetObject()

NAME

IOleItemContainer::GetObject() - Returns a pointer to the object identified by the specified name.

Synopsis

#include <oleidl.h>

HRESULT GetObject(
        LPOLESTR pszItem,
        DWORD dwSpeedNeeded,
        IBindCtx * pbc,
        REFIID riid,
        void ** ppvObject );

Description

The item moniker implementation of IMoniker::BindToObject() calls this method, passing the name stored within the item moniker as the pszItem parameter.

Notes to Implementers

Your implementation of IOleItemContainer::GetObject() should first determine whether pszItem is a valid name for one of the container's objects. If not, you should return MK_E_NOOBJECT.

If pszItem names an embedded or linked object, your implementation must check the value of the dwSpeedNeeded parameter. If the value is BINDSPEED_IMMEDIATE and the object is not yet loaded, you should return MK_E_EXCEEDEDDEADLINE. If the object is loaded, your implementation should determine whether the object is running (for example, by calling the OleIsRunning() function). If it is not running and the dwSpeedNeeded value is BINDSPEED_MODERATE, your implementation should return MK_E_EXCEEDEDDEADLINE. If the object is not running and dwSpeedNeeded is BINDSPEED_INDEFINITE, your implementation should call the OleRun function to put the object in the running state. Then it can query the object for the requested interface. Note that it is important the object be running before you query for the interface.

If pszItem names a pseudo-object, your implementation can ignore the dwSpeedNeeded parameter because a pseudo-object is running whenever its container is running. In this case, your implementation can simply query for the requested interface.

If you want more specific information about the time limit than is given by dwSpeedNeeded, you can call IBindCtx::GetBindOptions() on the pbc parameter to get the actual deadline parameter.

Parameters

pszItem

[in] Pointer to a zero-terminated string containing the container's name for the requested object. For Win32 applications, the LPOLESTR type indicates a wide character string (two bytes per character); otherwise, the string has one byte per character.

dwSpeedNeeded

[in] Indicates approximately how long the caller will wait to get the object. The legal values for dwSpeedNeeded are taken from the enumeration BINDSPEED. For information on the BINDSPEED enumeration, see the ``Data Structures'' section.

pbc

[in] Pointer to the IBindCtx() interface on the bind context object to be used in this binding operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the binding implementation should retrieve information about its environment. For more information, see IBindCtx().

riid

[in] Reference to the identifier of the interface pointer requested.

ppvObject

[out] When successful, indirect pointer to the location of the interface specified in riid on the object named by pszItem. 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, the implementation sets ppvObject to NULL.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The specified object was successfully returned.

MK_E_EXCEEDEDDEADLINE

The binding operation could not be completed within the time limit specified by the bind context's BIND_OPTS structure, or with the speed indicated by the dwSpeedNeeded parameter.

MK_E_NOOBJECT

The parameter pszItem does not identify an object in this container.

E_NOINTERFACE

The requested interface was not available.

See Also

IMoniker::BindToObject(), IBindCtx::GetBindOptions()  

IOleItemContainer::GetObjectStorage()

NAME

IOleItemContainer::GetObjectStorage() - Returns a pointer to the storage for the object identified by the specified name.

Synopsis

#include <oleidl.h>

HRESULT GetObjectStorage(
        LPOLESTR pszItem,
        IBindCtx * pbc,
        REFIID riid,
        void ** ppvStorage );

Description

The item moniker implementation of IMoniker::BindToStorage() calls this method.

Notes to Implementers

If pszItem designates a pseudo-object, your implementation should return MK_E_NOSTORAGE, because pseudo-objects do not have their own independent storage. If pszItem designates an embedded object, or a portion of the document that has its own storage, your implementation should return the specified interface pointer on the appropriate storage object.

Parameters

pszItem

[in] Pointer to a zero-terminated string containing the compound document's name for the object whose storage is requested. For Win32 applications, the LPOLESTR type indicates a wide character string (two bytes per character); otherwise, the string has one byte per character.

pbc

[in] Pointer to the IBindCtx() interface on the bind context to be used in this binding operation. The bind context caches objects bound during the binding process, contains parameters that apply to all operations using the bind context, and provides the means by which the binding implementation should retrieve information about its environment. For more information, see IBindCtx().

riid

[in] Reference to the identifier of the interface to be used to communicate with the object, usually IStorage().

ppvStorage

[out] When successful, indirect pointer to the location of the interface specified in riid, on the storage for the object named by pszItem. 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, ppvStorage is set to NULL.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The storage of the specified object was successfully returned.

MK_E_NOOBJECT

The parameter pszItem does not identify an object in this container.

MK_E_NOSTORAGE

The object does not have its own independent storage.

E_NOINTERFACE

The requested interface is not available.

See Also

IMoniker - Item Moniker Implementation  

IOleItemContainer::IsRunning()

NAME

IOleItemContainer::IsRunning() - Indicates whether the object identified by the specified name is running.

Synopsis

#include <oleidl.h>

HRESULT IsRunning((
        LPOLESTR pszItem );

Description

The item moniker implementation of IMoniker::IsRunning() calls this method.

Notes to Implementers

Your implementation of IOleItemContainer::IsRunning() should first determine whether pszItem identifies one of the container's objects. If it does not, your implementation should return MK_E_NOOBJECT. If the object is not loaded, your implementation should return S_FALSE. If it is loaded, your implementation can call the OleIsRunning() function to determine whether it is running.

If pszItem names a pseudo-object, your implementation can simply return S_OK because a pseudo-object is running whenever its container is running.

Parameters

pszItem

[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the container's name for the object.

Return Values

S_OK

The specified object is running.

S_FALSE

The object is not running.

MK_E_NOOBJECT

The parameter pszItem does not identify an object in this container.

See Also

IMoniker::IsRunning()

16.2.14    IParseDisplayName

The IParseDisplayName() interface parses a displayable name string to convert it into a moniker for custom moniker implementations. Display name parsing is necessary when the end user inputs a string to identify a component, as in the following situations:

A compound document application that supports linked components typically supports the ``Edit:Links...'' dialog box. Through this dialog box, the end user can enter a display name to specify a new link source for a specified linked component. The compound document needs to have this input string converted into a moniker. A script language such as the macro language of a spreadsheet can allow textual references to a component. The language's interpreter needs to have such a reference converted into a moniker in order to execute the macro.

When to Implement

Compound document applications that support links to embedded components or to pseudo-objects within their documents must provide an implementation of the IOleItemContainer() interface, which is derived indirectly from IParseDisplayName(). In effect, such a compound document is providing a namespace for identifying its internal components; and its IOleItemContainer() implementation (which includes the IParseDisplayName() implementation) is the interface through which another application can access this namespace. Alternatively, the compound document application can implement IParseDisplayName() as part of its class object, which is accessible through the CoGetClassObject() function.

Monikers that support their own namespace with custom requirements for parsing names also implement this interface.

When to Use

If you are implementing your own moniker class, you might need to use this interface from your implementation of IMoniker::ParseDisplayName(). If you call the MkParseDisplayName() or the MkParseDisplayNameEx functions, you are indirectly using IParseDisplayName(). These two functions call IParseDisplayName() to parse display names for objects that provide custom moniker implementations.

Table 16-13:  IParseDisplayName Methods in VTable Order

IUnknown Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 16-14:  IParseDisplayName Method

IParseDisplayName() Method Description
ParseDisplayName Parses the display name returning a moniker corresponding to it.

See Also

IMoniker::ParseDisplayName(), IOleItemContainer(), MkParseDisplayName(), MkParseDisplayNameEx  

IParseDisplayName::ParseDisplayName()

NAME

IParseDisplayName::ParseDisplayName() - Parses the display name to extract a component of the string that it can convert into a moniker, using the maximum number of characters from the left side of the string.

Synopsis

#include <oleidl.h>

HRESULT ParseDisplayName(
        IBindCtx * pbc,
        LPOLESTR pszDisplayName,
        ULONG * pchEaten,
        IMoniker ** ppmkOut );

Description

In general, the maximum prefix of szDisplayName that is syntactically valid and that represents an object should be consumed by this method and converted to a moniker.

Typically, this method is called by MkParseDisplayName[Ex]. In the initial step of the parsing operation, the MkParseDisplayName[Ex] function can retrieve the IParseDisplayName() interface directly from an instance of a class identified with either the ``@ProgID'' or ``ProgID'' notation. Subsequent parsing steps can query for the interface on an intermediate object.

The main loop of MkParseDisplayName[Ex] finds the next moniker piece by calling the equivalent method in the IMoniker() interface, that is, IMoniker::ParseDisplayName(), on the moniker that it currently holds. In this call to IMoniker::ParseDisplayName(), the MkParseDisplayName[Ex] function passes NULL in the pmkToLeft parameter. If the moniker currently held by MkParseDisplayName[Ex] is a generic composite, the call to IMoniker::ParseDisplayName() is forwarded by that composite onto its last piece, passing the prefix of the composite to the left of the piece in pmkToLeft.

Some moniker classes will be able to handle this parsing internally to themselves since they are designed to designate only certain kinds of objects. Others will need to bind to the object that they designate to accomplish the parsing process. As is usual, these objects should not be released by IMoniker::ParseDisplayName() but instead should be transferred to the bind context via IBindCtx::RegisterObjectBound() or IBindCtx::GetRunningObjectTable() followed by IRunningObjectTable::Register() for release at a later time.

Parameters

pbc

[in] Pointer to the bind context to be used in this binding operation.

pszDisplayName

[in] Pointer to a zero-terminated string containing the display name to be parsed. For Win32 applications, the LPOLESTR type indicates a wide character string (two bytes per character); otherwise, the string has one byte per character.

pchEaten

[out Pointer to the number of characters in the display name that correspond to the ppmkOut moniker.

ppmkOut

[out] Indirect pointer to the resulting moniker. If an error occurs, the implementation sets *ppmkOut to NULL. If *ppmkOut is non-NULL, the implementation must call (*ppmkOut)->IUnknown::AddRef; so it is the caller's responsibility to call (*ppmkOut)->IUnknown::Release.

Return Values

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

S_OK

The parse operation was successful.

MK_E_SYNTAX

Syntax error in the display name. Parsing failed because szDisplayName could only be partially resolved into a moniker. In this case, *pchEaten has the number of characters that were successfully parsed into a moniker prefix. The parameter ppmkOut should be NULL.

MK_E_NOOBJECT

The display name does not identify a component in this namespace.

E_INVALIDARG

One or more parameters are invalid.

See Also

MkParseDisplayName(), MkParseDisplayNameEx IMoniker::ParseDisplayName()

16.2.15    IROTData

The IROTData() interface is implemented by monikers to enable the Running Object Table (ROT) to compare monikers against each other.

The ROT uses the IROTData() interface to test whether two monikers are equal. The ROT must do this when, for example, it checks whether a specified moniker is registered as running.

When to Implement

You must implement IROTData() if you are writing your own moniker class (that is, writing your own implementation of the IMoniker() interface), and if your monikers are meant to be registered in the ROT.

When to Use

You typically do not need to use this interface. This interface is used by the system's implementation of the ROT.

Table 16-15:  IROTData Methods in VTable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 16-16:  IROTData Method

IROTData() Method Description
GetComparisonData Retrieve data to allow moniker to be compared with another.

See Also

IMoniker(), IRunningObjectTable()  

IROTData::GetComparisonData()

NAME

IROTData::GetComparisonData() - Retrieves data from a moniker that can be used to test the moniker for equality against another moniker.

Synopsis

#include <objidl.h>

HRESULT GetComparisonData(
        PVOID * ppvData,
        ULONG cbMax,
        PULONG pcbData );

Description

The IROTData::GetComparisonData() method is primarily called by the Running Object Table (ROT). The comparison data returned by the method is tested for binary equality against the comparison data returned by another moniker. The pcbData parameter enables the ROT to locate the end of the data returned.

Notes to Implementers

The comparison data that you return must uniquely identify the moniker, while still being as short as possible. The comparison data should include information about the internal state of the moniker, as well as the moniker's CLSID. For example, the comparison data for a file moniker would include the path name stored within the moniker, as well as the CLSID of the file moniker implementation. This makes it possible to distinguish two monikers that happen to store similar state information but are instances of different moniker classes.

The comparison data for a moniker cannot exceed 2048 bytes in length. For composite monikers, the total length of the comparison data for all of its components cannot exceed 2048 bytes; consequently, if your moniker can be a component within a composite moniker, the comparison data you return must be significantly less than 2048 bytes.

If your comparison data is longer than the value specified by the cbMax parameter, you must return an error. Note that when IROTData::GetComparisionData() is called on the components of a composite moniker, the value of cbMax becomes smaller for each moniker in sequence.

Parameters

ppvData

[out] Indirect pointer to a buffer that receives the comparison data.

cbMax

[in] Length of the buffer specified in ppvData.

pcbData

[out] Pointer to the length of the comparison data.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The comparison data was successfully returned.

See Also

IMoniker(), IRunningObjectTable()

16.2.16    IRunningObjectTable

The IRunningObjectTable() interface manages access to the Running Object Table (ROT), a globally accessible look-up table on each workstation. A workstation's ROT keeps track of those objects that can be identified by a moniker and that are currently running on the workstation. When a client tries to bind a moniker to an object, the moniker checks the ROT to see if the object is already running; this allows the moniker to bind to the current instance instead of loading a new one.

The ROT contains entries of the form:

(pmkObjectName, pUnkObject)

The pmkObjectName element is a pointer to the moniker that identifies the running object. The pUnkObject element is a pointer to the running object itself. During the binding process, monikers consult the pmkObjectName entries in the Running Object Table to see if an object is already running.

Objects that can be named by monikers must be registered with the ROT when they are loaded and their registration must be revoked when they are no longer running.

When to Implement

You do not need to implement this interface. The system provides an implementation of the Running Object Table that is suitable for all situations.

When to Use

You typically use the ROT if you're a moniker provider (that is, you hand out monikers identifying your objects to make them accessible to others) or if you're writing your own moniker class (that is, implementing the IMoniker() interface).

If you are a moniker provider, you register your objects with the ROT when they begin running and revoke their registrations when they are no longer running. This enables the monikers that you hand out to be bound to running objects. You should also use the ROT to record the object's last modification time. You can get an IRunningObjectTable() interface pointer to the local ROT by calling the GetRunningObjectTable() function.

The most common type of moniker provider is a compound-document link source. This includes server applications that support linking to their documents (or portions of a document) and container applications that support linking to embeddings within their documents. Server applications that do not support linking can also use the ROT to cooperate with container applications that support linking to embeddings.

If you are writing your own moniker class, you use the ROT to determine whether a object is running and to retrieve the object's last modification time. You can get an IRunningObjectTable() interface pointer to the local ROT by calling the IBindCtx::GetRunningObjectTable() method on the bind context for the current binding operation. Moniker implementations should always use the bind context to acquire a pointer to the ROT; this allows future implementations of IBindCtx() to modify binding behavior. Note that you must also implement the IROTData() interface on your moniker class in order to allow your monikers to be registered with the ROT.

Table 16-17:  IRunningObjectTable Methods in VTable Order

IUnknown Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 16-18:  IRunningObjectTable Methods

IRunningObjectTable() Methods Description
Register Registers an object with the ROT.
Revoke Revokes an object's registration with the ROT.
IsRunning() Checks whether an object is running.
GetObject Returns a pointer to an object given its moniker.
NoteChangeTime Notifies the ROT that an object has changed.
GetTimeOfLastChange Returns the time an object was last changed.
EnumRunning Returns an enumerator for the ROT.

See Also

IBindCtx::GetRunningObjectTable(), IROTData(), GetRunningObjectTable()  

IRunningObjectTable::EnumRunning()

NAME

IRunningObjectTable::EnumRunning() - Creates and returns a pointer to an enumerator that can list the monikers of all the objects currently registered in the Running Object Table (ROT).

Synopsis

#include <objidl.h>

HRESULT EnumRunning(
        IEnumMoniker ** ppenumMoniker );

Description

IRunningObjectTable::EnumRunning() must create and return a pointer to an IEnumMoniker() interface on an enumerator object. The standard enumerator methods can then be called to enumerate the monikers currently registered in the registry. The enumerator cannot be used to enumerate monikers that are registered in the ROT after the enumerator has been created.

The EnumRunning method is intended primarily for the use by the system in implementing the Alert Object Table. Note that COM does not include an implementation of the Alert Object Table.

Parameters

ppenumMoniker

[out] When successful, indirect pointer to the IEnumMoniker() interface on the new enumerator. In this case, the implementation calls IUnknown::AddRef() on the parameter; it is the caller's responsibility to call IUnknown::Release(). If an error occurs; the implementation sets ppenumMoniker to NULL.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

An enumerator was successfully returned.

See Also

IEnumXXXX, IEnumMoniker()  

IRunningObjectTable::GetObject()

NAME

IRunningObjectTable::GetObject() - Determines whether the object identified by the specified moniker is running, and if it is, retrieves a pointer to that object. This method looks for the moniker in the Running Object Table (ROT), and retrieves the pointer registered there.

Synopsis

#include <objidl.h>

HRESULT GetObject(
        IMoniker * pmkObjectName,
        IUnknown ** ppunkObject );

Description

This method checks the ROT for the moniker specified by pmkObjectName. If that moniker had previously been registered with a call to IRunningObjectTable::Register(), this method returns the pointer that was registered at that time.

Notes to Callers

Generally, you call the IRunningObjectTable::GetObject() method only if you are writing your own moniker class (that is, implementing the IMoniker() interface). You typically call this method from your implementation of IMoniker::BindToObject().

However, note that not all implementations of IMoniker::BindToObject() need to call this method. If you expect your moniker to have a prefix (indicated by a non-NULL pmkToLeft parameter to IMoniker::BindToObject()), you should not check the ROT. The reason for this is that only complete monikers are registered with the ROT, and if your moniker has a prefix, your moniker is part of a composite and thus not complete. Instead, your moniker should request services from the object identified by the prefix (for example, the container of the object identified by your moniker).

Parameters

pmkObjectName

[in] Pointer to the moniker to search for in the Running Object Table.

ppunkObject

[out] When successful. indirect pointer to the IUnknown() interface on the running object. In this case, the implementation calls IUnknown::AddRef() on the parameter; it is the caller's responsibility to call IUnknown::Release(). If the object is not running or if an error occurs, the implementation sets ppunkObject to NULL.

Return Values

S_OK

Indicates that pmkObjectName was found in the ROT and a pointer was returned.

S_FALSE

There is no entry for pmkObjectName in the ROT, or that the object it identifies is no longer running (in which case, the entry is revoked).

See Also

IMoniker::BindToObject()  

IRunningObjectTable::GetTimeOfLastChange()

NAME

IRunningObjectTable::GetTimeOfLastChange() - Returns the time that an object was last modified. The object must have previously been registered with the Running Object Table (ROT). This method looks for the last change time recorded in the ROT.

Synopsis

#include <objidl.h>

HRESULT GetTimeOfLastChange(
        IMoniker * pmkObjectName,
        FILETIME * pfiletime );

Description

This method returns the change time that was last reported for this object by a call to IRunningObjectTable::NoteChangeTime(). If IRunningObjectTable::NoteChangeTime() has not been called previously, the method returns the time that was recorded when the object was registered.

This method is provided to enable checking whether a connection between two objects (represented by one object holding a moniker that identifies the other) is up-to-date. For example, if one object is holding cached information about the other object, this method can be used to check whether the object has been modified since the cache was last updated. See IMoniker::GetTimeOfLastChange().

Notes to Callers

Generally, you call IRunningObjectTable::GetTimeOfLastChange() only if you are writing your own moniker class (that is, implementing the IMoniker() interface). You typically call this method from your implementation of IMoniker::GetTimeOfLastChange(). However, you should do so only if the pmkToLeft parameter of IMoniker::GetTimeOfLastChange() is NULL. Otherwise, you should call IMoniker::GetTimeOfLastChange() on your pmkToLeft parameter instead.

Parameters

pmkObjectName

[in] Pointer to the IMoniker() interface on the moniker to search for in the ROT.

pfiletime

[out] Pointer to a FILETIME structure that receives the object's last change time.

Return Values

S_OK

The last change time was successfully retrieved.

S_FALSE

There is no entry for pmkObjectName in the ROT, or that the object it identifies is no longer running (in which case, the entry is revoked).

See Also

IMoniker::GetTimeOfLastChange(), IRunningObjectTable::NoteChangeTime()  

IRunningObjectTable::IsRunning()

NAME

IRunningObjectTable::IsRunning() - Determines whether the object identified by the specified moniker is currently running. This method looks for the moniker in the Running Object Table (ROT).

Synopsis

#include <objidl.h>

HRESULT IsRunning((
        IMoniker * pmkObjectName );

Description

This method simply indicates whether a object is running. To retrieve a pointer to a running object, use the IRunningObjectTable::GetObject() method.

Notes to Callers

Generally, you call the IRunningObjectTable::IsRunning() method only if you are writing your own moniker class (that is, implementing the IMoniker() interface). You typically call this method from your implementation of IMoniker::IsRunning(). However, you should do so only if the pmkToLeft parameter of IMoniker::IsRunning() is NULL. Otherwise, you should call IMoniker::IsRunning() on your pmkToLeft parameter instead.

Parameters

pmkObjectName

[in] Pointer to the IMoniker() interface on the moniker to search for in the Running Object Table.

Return Values

S_OK

The object identified by pmkObjectName is running.

S_FALSE

There is no entry for pmkObjectName in the ROT, or that the object it identifies is no longer running (in which case, the entry is revoked).

See Also

IMoniker::IsRunning()  

IRunningObjectTable::NoteChangeTime()

NAME

IRunningObjectTable::NoteChangeTime() - Records the time that a running object was last modified. The object must have previously been registered with the Running Object Table (ROT). This method stores the time of last change in the ROT.

Synopsis

#include <objidl.h>

HRESULT NoteChangeTime(
        DWORD dwRegister,
        FILETIME * pfiletime );

Description

The time recorded by this method can be retrieved by calling IRunningObjectTable::GetTimeOfLastChange().

This method is provided to enable a program to check whether a connection between two objects (represented by one object holding a moniker that identifies the other) is up-to-date. For example, if one object is holding cached information about the other object, this method can be used to check whether the object has been modified since the cache was last updated. See IMoniker::GetTimeOfLastChange().

Notes to Callers

If you're a moniker provider (that is, you hand out monikers identifying your objects to make them accessible to others), you must call the IRunningObjectTable::NoteChangeTime() method whenever your objects are modified. You must have previously called IRunningObjectTable::Register() and stored the identifier returned by that method; you use that identifier when calling IRunningObjectTable::NoteChangeTime().

The most common type of moniker provider is a compound-document link source. This includes server applications that support linking to their documents (or portions of a document) and container applications that support linking to embeddings within their documents. Server applications that do not support linking can also use the ROT to cooperate with container applications that support linking to embeddings.

When an object is first registered in the ROT, the ROT records its last change time as the value returned by calling IMoniker::GetTimeOfLastChange() on the moniker being registered.

Parameters

dwRegister

[in] Value identifying the ROT entry of the changed object. This value was previously returned by IRunningObjectTable::Register().

pfiletime

[in] Pointer to a FILETIME structure containing the object's last change time.

Return Values

This method supports the standard return value E_INVALIDARG, as well as the following:

S_OK

The change time was recorded successfully.

See Also

IRunningObjectTable::GetTimeOfLastChange(), IMoniker::GetTimeOfLastChange()  

IRunningObjectTable::Register()

NAME

IRunningObjectTable::Register() - Registers an object and its identifying moniker in the Running Object Table (ROT).

Synopsis

#include <objidl.h>

HRESULT Register(
        DWORD grfFlags,
        IUnknown * punkObject,
        IMoniker * pmkObjectName,
        DWORD * pdwRegister );

Description

This method registers a pointer to an object under a moniker that identifies the object. The moniker is used as the key when the table is searched with IRunningObjectTable::GetObject().

Registering a second object with the same moniker, or re-registering the same object with the same moniker, creates a second entry in the ROT. In this case, IRunningObjectTable::Register() returns MK_S_MONIKERALREADYREGISTERED. Each call to IRunningObjectTable::Register() must be matched by a call to IRunningObjectTable::Revoke() because even duplicate entries have different pdwRegister identifiers. A problem with duplicate registrations is that there is no way to determine which object will be returned if the moniker is specified in a subsequent call to IRunningObjectTable::IsRunning().

Notes to Callers

If you are a moniker provider (that is, you hand out monikers identifying your objects to make them accessible to others), you must call the IRunningObjectTable::Register() method to register your objects when they begin running. You must also call this method if you rename your objects while they are loaded.

The most common type of moniker provider is a compound-document link source. This includes server applications that support linking to their documents (or portions of a document) and container applications that support linking to embeddings within their documents. Server applications that do not support linking can also use the ROT to cooperate with container applications that support linking to embeddings.

If you are writing a container application that supports linking to embeddings, you should register your document with the ROT when it is loaded.

You must cache the identifier returned in pdwRegister, and use it in a call to IRunningObjectTable::Revoke() to revoke the registration when the object is no longer running or when its moniker changes. This revocation is important because there is no way for the system to automatically remove entries from the ROT.

The system's implementation of IRunningObjectTable::Register() calls IMoniker::Reduce() on the pmkObjectName parameter to ensure that the moniker is fully reduced before registration. If a object is known by more than one fully reduced moniker, then it should be registered under all such monikers.

Parameters

grfFlags

[in] Specifies whether the ROT's reference to punkObject is weak or strong. This value must be either zero, indicating a weak reference that does not call IUnknown::AddRef(); or ROTFLAGS_REGISTRATIONKEEPSALIVE, indicating a strong reference that calls IUnknown::AddRef() and can keep the object running. If a strong reference is registered, a strong reference is released when the object's registration is revoked. Most callers specify zero, indicating a weak reference.

punkObject

[in] Pointer to the object that is being registered as running.

pmkObjectName

[in] Pointer to the moniker that identifies punkObject.

pdwRegister

[out] Pointer to a 32-bit value that can be used to identify this ROT entry in subsequent calls to IRunningObjectTable::Revoke() or IRunningObjectTable::NoteChangeTime(). The caller cannot specify NULL for this parameter. If an error occurs, *pdwRegister is set to zero.

Return Values

This method supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following:

S_OK

The object was successfully registered.

MK_S_MONIKERALREADYREGISTERED

The moniker/object pair was successfully registered, but that another object (possibly the same object) has already been registered with the same moniker.

See Also

IMoniker::Reduce(), IRunningObjectTable::IsRunning(), IRunningObjectTable::Revoke()  

IRunningObjectTable::Revoke()

NAME

IRunningObjectTable::Revoke() - Removes from the Running Object Table (ROT) an entry that was previously registered by a call to IRunningObjectTable::Register().

Synopsis

#include <objidl.h>

HRESULT Revoke(
        DWORD dwRegister );

Description

This method undoes the effect of a call to IRunningObjectTable::Register(), removing both the moniker and the pointer to the object identified by that moniker.

Notes to Callers

If you are a moniker provider (that is, you hand out monikers identifying your objects to make them accessible to others), you must call the IRunningObjectTable::Revoke() method to revoke the registration of your objects when they stop running. You must have previously called IRunningObjectTable::Register() and stored the identifier returned by that method; you use that identifier when calling IRunningObjectTable::Revoke().

The most common type of moniker provider is a compound-document link source. This includes server applications that support linking to their documents (or portions of a document) and container applications that support linking to embeddings within their documents. Server applications that do not support linking can also use the ROT to cooperate with container applications that support linking to embeddings.

If you're writing a container application, you must revoke a document's registration when the document is closed. You must also revoke a document's registration before re-registering it when it is renamed.

If you're writing a server application, you must revoke an object's registration when the object is closed. You must also revoke an object's registration before re-registering it when its container document is renamed.

Parameters

dwRegister

[in] Value identifying the ROT entry to revoke. This value was previously returned by IRunningObjectTable::Register().

Return Values

This method supports the standard return value E_INVALIDARG, as well as the following:

S_OK

The object's registration was successfully revoked.

See Also

IRunningObjectTable::Register()

16.3    Moniker API Descriptions

 

BindMoniker()

NAME

BindMoniker() - Locates an object by means of its moniker, activates the object if it is inactive, and retrieves a pointer to the specified interface on that object.

Synopsis

#include <objbase.h>

HRESULT BindMoniker((
        LPMONIKER pmk,
        DWORD grfOpt,
        REFIID iidResult,
        LPVOID FAR * ppvResult );

Description

BindMoniker() is a helper function supplied as a convenient way for a client that has the moniker of an object to obtain a pointer to one of its interfaces. The BindMoniker() function packages the following calls:

CreateBindCtx(0, &pbc); 
pmk->BindToObject(pbc, NULL, riid, ppvObj);

CreateBindCtx() creates a bind context object that supports the system implementation of IBindContext. The pmk parameter is actually a pointer to the IMoniker() implementation on a moniker object. This implementation's BindToObject method supplies the pointer to the requested interface pointer.

If you have several monikers to bind in quick succession, and if you know that those monikers will activate the same object, it may be more efficient to call the IMoniker::BindToObject() method directly, which allows you to use the same bind context object for all the monikers. See the IBindCtx() interface for more information.

Container applications that allow their documents to contain linked objects are a special client that generally does not make direct calls to IMoniker() methods.

Parameters

pmk

[in] Pointer to the object's moniker.

grfOpt

[in] Reserved for future use; must be zero.

iidResult

[in] Interface identifier to be used to communicate with the object.

ppvResult

[out] Address of pointer variable that receives the interface pointer requested in iidResult. Upon successful return, *ppvResult contains the requested interface pointer. If an error occurs, *ppvResult is NULL. If the call is successful, the caller is responsible for releasing the pointer with a call to the object's IUnknown::Release().

Return Values

S_OK

The object was located and activated, if necessary, and that a pointer to the requested interface was returned.

MK_E_NOOBJECT

The object that the moniker object identified could not be found.

This function can also return any of the error values returned by the IMoniker::BindToObject() method.

See Also

CreateBindCtx(), IMoniker::BindToObject()  

MkParseDisplayName()

NAME

MkParseDisplayName() - Converts a string into a moniker that identifies the object named by the string. This is the inverse of the IMoniker::GetDisplayName() operation, which retrieves the display name associated with a moniker.

Synopsis

#include <objbase.h>

WINOLEAPI MkParseDisplayName((
        LPBC pbc,
        LPCOLESTR szUserName,
        ULONG FAR * pchEaten,
        LPMONIKER FAR * ppmk );

Description

The MkParseDisplayName() function parses a human-readable name into a moniker that can be used to identify a link source. The resulting moniker can be a simple moniker (such as a file moniker), or it can be a generic composite made up of the component moniker pieces. For example, the following display name:

``c:\mydir\somefile!item 1''

could be parsed into the following generic composite moniker:

(FileMoniker based on ``c:\mydir\somefile'') + (ItemMoniker based on ``item 1'')

The most common use of MkParseDisplayName() is in the implementation of the standard Links dialog box, which allows an end user to specify the source of a linked object by typing in a string. You may also need to call MkParseDisplayName() if your application supports a macro language that permits remote references (reference to elements outside of the document).

Parsing a display name often requires activating the same objects that would be activated during a binding operation, so it can be just as expensive (in terms of performance) as binding. Objects that are bound during the parsing operation are cached in the bind context passed to the function. If you plan to bind the moniker returned by MkParseDisplayName(), it is best to do so immediately after the function returns, using the same bind context, which removes the need to activate objects a second time.

MkParseDisplayName() parses as much of the display name as it understands into a moniker. The function then calls IMoniker::ParseDisplayName() on the newly created moniker, passing the remainder of the display name. The moniker returned by IMoniker::ParseDisplayName() is composed onto the end of the existing moniker and, if any of the display name remains unparsed, IMoniker::ParseDisplayName() is called on the result of the composition. This process is repeated until the entire display name has been parsed.

The MkParseDisplayName function attempts the following strategies to parse the beginning of the display name, using the first one that succeeds:

  1. The function looks in the Running Object Table for file monikers corresponding to all prefixes of szDisplayName that consist solely of valid file name characters. This strategy can identify documents that are as yet unsaved.

  2. The function checks the maximal prefix of szDisplayName, which consists solely of valid file name characters, to see if an OLE 1 document is registered by that name (this may require some DDE broadcasts). In this case, the returned moniker is an internal moniker provided by the OLE 1 compatibility layer of COM.

  3. The function consults the file system to check whether a prefix of szDisplayName matches an existing file. The file name can be drive-absolute, drive-relative, working-directory relative, or begin with an explicit network share name. This is the common case.

  4. If the initial character of szDisplayName is an `@', the function finds the longest string immediately following it that conforms to the legal ProgID syntax. The function converts this string to a CLSID using the CLSIDFromProgID() function. If the CLSID represents a COM class, the function loads the corresponding class object and asks for an IParseDisplayName() interface pointer. The resulting IParseDisplayName() interface is then given the whole string to parse, starting with the `@'. If the CLSID represents an OLE 1 class, then the function treats the string following the ProgID as an OLE1/DDE link designator having <filename>!<item> syntax.

Parameters

pbc

[in] Pointer to the IBindCtx() interface on the bind context object to be used in this binding operation.

szUserName

[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the display name to be parsed.

pchEaten

[out] Pointer to the number of characters of szUserName that were consumed. If the function is successful, *pchEaten is the length of szUserName; otherwise, it is the number of characters successfully parsed.

ppmk

[out] Address of *IMoniker pointer variable that receives the interface pointer to the moniker that was built from szUserName. When successful, the function has called IUnknown::AddRef() on the moniker and the caller is responsible for calling IUnknown::Release(). If an error occurs, the supplied interface pointer value is NULL.

Return Values

This function supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The parse operation was successful and the moniker was created.

MK_E_SYNTAX

Error in the syntax of a file name or an error in the syntax of the resulting composite moniker.

This function can also return any of the error values returned by IMoniker::BindToObject(), IOleItemContainer::GetObject(), or IParseDisplayName::ParseDisplayName().

See Also

IMoniker::ParseDisplayName(), IMoniker::GetDisplayName(), IParseDisplayName()  

MkParseDisplayNameEx()

NAME

MkParseDisplayNameEx() - Given a string, this function returns a moniker of the object that the string denotes.

Synopsis

#include <urlmon.h>

HRESULT MkParseDisplayNameEx(
        IBindCtx * pbc,
        LPWSTR szDisplayName,
        ULONG * pcchEaten,
        IMoniker ** ppmk );

Description

Given a string, this function returns a moniker for the object that the string denotes. This operation is known as parsing. A display name is parsed into a moniker; it is resolved into its component moniker parts.

If a syntax error occurs, then an indication of how much of the string was successfully parsed is returned in *pcchEaten and NULL is returned through **ppmk. Otherwise, the value returned through *pcchEaten indicates the entire size of the display name.

This function differs from the original MkParseDisplayName() function in that it supports Universal Resource Indicator (URI) syntax. See the IETC RFC1630 specification for more information on URIs.

Parsing a display name may in some cases be as expensive as binding to the object that it denotes, since, along the way, the parsing mechanism must connect to various non-trivial name space managers (such as a spreadsheet application that can parse into ranges in its sheets). As might be expected, objects are not released by the parsing operation itself, but are instead handed over to the bind context that was passed in through IBindCtx::RegisterObjectBound(). Thus, if the moniker resulting from the parse is immediately bound using this same bind context, redundant loading of objects is maximally avoided.

In many other cases, however, parsing a display name may be quite inexpensive since a single name-space manager may quickly return a moniker that will perform further expensive analysis on any acceptable name during IMoniker::BindToObject() or other methods. An example of such an inexpensive parser is the Win32 implementation of a File Moniker. A theoretical example would be a naive URL moniker which parsed from any valid URL strings (i.e., ``http:...'', ``file:...'') and only during binding took time to resolve the string against the Internet, a potentially expensive operation.

The parsing process is an inductive one, in that there is an initial step that gets the process going, followed by the repeated application of an inductive step. At any point after the beginning of the parse, a certain prefix of szDisplayName has been parsed into a moniker, and a suffix of the display name remains unresolved.

The inductive step asks the moniker-so-far using IMoniker::ParseDisplayName() to consume as much as it would like of the remaining suffix and return the corresponding moniker and the new suffix. The moniker is composed onto the end of the existing moniker, and the process repeats.

Implementations of IMoniker::ParseDisplayName() vary in exactly where the knowledge of how to carry out the parsing is kept. Some monikers by their nature are only used in particular kinds of containers. It is likely that these monikers themselves have the knowledge of the legal display name syntax within the objects that they themselves denote, so they can carry out the processes completely within IMoniker::ParseDisplayName(). The common case, however, is that the moniker is generic in the sense that is not specific to one kind of container, and thus cannot know the legal syntax for elements within the container. File monikers are an example of these, as are Item Monikers. These monikers in general employ the following strategy to carry out parsing. First, the moniker connects to the class of object that it currently denotes, asking for IParseDisplayName() interface. If that succeeds, then it uses the obtained interface pointer to attempt to carry out the parse. If the class refuses to handle the parse, then the moniker binds to the object it denotes, asking again for IParseDisplayName() interface. If this fails, then the parse is aborted.

The effect is that ultimately an object always gets to be in control of the syntax of elements contained inside of itself. It's just that objects of a certain nature can carry out parsing more efficiently by having a moniker or their class do the parsing on their behalf.

Notice that since MkParseDisplayNameEx knows nothing of the legal syntax of display names (with the exception of the initial parsing step; see below). It is of course beneficial to the user that display names in different contexts not have gratuitously different syntax. While there some rare situations which call for special purpose syntax, it is recommended that, unless there are compelling reasons to do otherwise, the syntax for display names should be the same as or similar to the native file system syntax. The aim is to build on user familiarity. Most important about this are the characters allowed for the delimiters used to separate the display name of one of the component monikers from the next. Unless through some special circumstances they have very good reason not to, all moniker implementations should use inter-moniker delimiters from the following character set:

\ / : ! [

Standardization in delimiters promotes usability. But more importantly, notice that the parsing algorithm has the characteristic that a given container consumes as much as it can of the string being parsed before passing the remainder on to the designated object inside themselves. If the delimiter expected of the next-to-be-generated moniker in fact forms (part of) a valid display name in the container, then the container's parse will consume it!

Monikers and objects which have implementations on more than one platform (such as File Monikers) should always parse according to the syntax of the platform on which they are currently running. When asked for their display name, monikers should also show delimiters appropriate to the platform on which they are currently running, even if they were originally created on a different platform. In total, users will always deal with delimiters appropriate for the host platform.

The initial step of the parsing process is a bit tricky, in that it needs to somehow determine the initial moniker. MkParseDisplayNameEx is omniscient with respect to the syntax with which the display name of a moniker may legally begin, and it uses this omniscience to choose the initial moniker.

The initial moniker is determined by trying the following strategies in order, using the first to succeed.

  1. ``ProgID:'' Case: If a prefix of szDisplayName conforms to the legal ProgID syntax, is more than 1 character long, and is followed by a colon (`:'), the ProgID is converted to a CLSID with CLSIDFromProgID, An instance of this class is asked for the IParseDisplayName() interface, and IParseDisplayName:ParseDisplayName is called with the entire szDisplayName. This case distinguishes MkParseDisplayNameEx from MkParseDisplayName().

  2. ROT Case: All prefixes of szDisplayName that consist solely of valid file name characters are consulted as file monikers in the Running Object Table.

  3. File-System Case: The file system is consulted to check if a prefix of szDisplayName matches an existing file. The file name may be drive absolute, drive relative, working-directory relative, or begin with an explicit network share name. This is a common case.

  4. ``@ProgID'' Case: If the initial character of szDisplayName is `@', then the maximal string immediately following the `@' which conforms to the legal ProgID syntax is determined. This is converted to a CLSID with CLSIDFromProgID(). An instance of this class is asked in turn for IParseDisplayName() interface; the IParseDisplayName() interface so found is then given the whole string (starting with the `@') to continue parsing.

Parameters

pbc

[in] Pointer to the bind context in which to accumulate bound objects.

szDisplayName

[in] Display name to be parsed.

pcchEaten

[out] Pointer to the number of characters of the display name that were successfully parsed. Most useful on syntax error, when a non-zero value is often returned and therefore a subsequent call to MkParseDisplayNameEx with the same pbc and a shortened szDisplayName should return a valid moniker.

ppmk

[out] Address of IMoniker* pointer variable that receives the interface pointer to the resulting moniker.

Return Values

S_OK

The operation was successful.

MK_E_SYNTAX

Parsing failed because szDisplayName could only be partially resolved into a moniker. In this case, *pcchEaten has the number of characters that were successfully parsed into a moniker prefix.

E_OUTOFMEMORY

The operation ran out of memory.

See Also

IParseDisplayName()  

MonikerCommonPrefixWith()

NAME

MonikerCommonPrefixWith() - Creates a new moniker based on the common prefix that this moniker (the one comprising the data of this moniker object) shares with another moniker. This function is intended to be called only in implementations of IMoniker::CommonPrefixWith().

Synopsis

#include <objbase.h>

WINOLEAPI MonikerCommonPrefixWith((
        LPMONIKER pmkThis,
        LPMONIKER pmkOther,
        LPMONIKER FAR * ppmkCommon );

Description

Call MonikerCommonPrefixWith() only in the implementation of IMoniker::CommonPrefixWith() for a new moniker class.

Your implementation of IMoniker::CommonPrefixWith() should first check whether the other moniker is of a type that you recognize and handle in a special way. If not, you should call MonikerCommonPrefixWith(), passing itself as pmkThis and the other moniker as pmkOther. MonikerCommonPrefixWith() correctly handles the cases where either moniker is a generic composite.

You should call this function only if pmkThis and pmkOther are both absolute monikers (where an absolute moniker is either a file moniker or a generic composite whose leftmost component is a file moniker, and where the file moniker represents an absolute path). Do not call this function on relative monikers.

Parameters

pmkThis

[in] Pointer to the IMoniker() interface on one of the monikers for which a common prefix is sought; usually the moniker in which this call is used to implement IMoniker::CommonPrefixWith().

pmkOther

[in] Pointer to the IMoniker() interface on the other moniker to compare with the first moniker.

ppmkCommon

[out] Address of IMoniker* pointer variable that receives the interface pointer to the moniker based on the common prefix of pmkThis and pmkOther. When successful, the function has called IUnknown::AddRef() on the moniker and the caller is responsible for calling IUnknown::Release(). If an error occurs, the supplied interface pointer value is NULL.

Return Values

This function supports the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following:

S_OK

A common prefix exists that is neither pmkThis nor pmkOther.

MK_S_HIM

The entire pmkOther moniker is a prefix of the pmkThis moniker.

MK_S_ME

The entire pmkThis moniker is a prefix of the pmkOther moniker.

MK_S_US

The pmkThis and pmkOther monikers are equal.

MK_E_NOPREFIX

The monikers have no common prefix.

MK_E_NOTBINDABLE

This function was called on a relative moniker. It is not meaningful to take the common prefix of relative monikers.

See Also

IMoniker::CommonPrefixWith()  

MonikerRelativePathTo()

NAME

MonikerRelativePathTo() - Provides a moniker that, when composed onto the end of the first specified moniker (or one with a similar structure), yields the second specified moniker. This function is intended for use only by IMoniker::RelativePathTo() implementations.

Synopsis

#include <objbase.h>

WINOLEAPI MonikerRelativePathTo((
        LPMONIKER pmkSrc,
        LPMONIKER pmkDest,
        LPMONIKER FAR * ppmkRelPath,
        BOOL dwReserved );

Description

Call MonikerRelativePathTo() only in the implementation of IMoniker::RelativePathTo() if you are implementing a new moniker class.

Your implementation of IMoniker::RelativePathTo() should first check whether the other moniker is of a type you recognize and handle in a special way. If not, you should call MonikerRelativePathTo(), passing itself as pmkThis and the other moniker as pmkOther. MonikerRelativePathTo() correctly handles the cases where either moniker is a generic composite.

You should call this function only if pmkSrc and pmkDest are both absolute monikers, where an absolute moniker is either a file moniker or a generic composite whose leftmost component is a file moniker, and where the file moniker represents an absolute path. Do not call this function on relative monikers.

Parameters

pmkSrc

[in] Pointer to the IMoniker() interface on the moniker that, when composed with the relative moniker to be created, produces pmkDest. This moniker identifies the ``source'' of the relative moniker to be created.

pmkDest

[in] Pointer to the IMoniker() interface on the moniker to be expressed relative to pmkSrc. This moniker identifies the destination of the relative moniker to be created.

ppmkRelPath

[out] Address of IMoniker* pointer variable that receives the interface pointer to the new relative moniker. When successful, the function has called IUnknown::AddRef() on the moniker and the caller is responsible for calling IUnknown::Release(). If an error occurs, the interface pointer value is NULL.

dwReserved

[in] Reserved; must be non-zero.

Return Values

This function supports the standard return value E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following:

S_OK

A meaningful relative path has been returned.

MK_S_HIM

The only form of the relative path is the other moniker.

MK_E_NOTBINDABLE

Indicates that pmkSrc is a relative moniker, such as an item moniker, and must be composed with the moniker of its container before a relative path can be determined.

See Also

IMoniker::RelativePathTo()  

CreateAntiMoniker()

NAME

CreateAntiMoniker() - Creates and supplies a new anti-moniker.

Synopsis

#include <objbase.h>

WINOLEAPI CreateAntiMoniker((
        LPMONIKER FAR * ppmk );

Description

You would call this function only if you are writing your own moniker class (implementing the IMoniker() interface). If you are writing a new moniker class that has no internal structure, you can use CreateAntiMoniker() in your implementation of the IMoniker::Inverse() method, and then check for an anti-moniker in your implementation of IMoniker::ComposeWith().

Like the ``..'' directory in Unix file systems, which acts as the inverse to any directory name just preceding it in a path, an anti-moniker acts as the inverse of a simple moniker that precedes it in a composite moniker. An anti-moniker is used as the inverse of simple monikers with no internal structure. For example, the system-provided implementations of file monikers, item monikers, and pointer monikers all use anti-monikers as their inverse; consequently, an anti-moniker composed to the right of one of these monikers composes to nothing.

A moniker client (an object that is using a moniker to bind to another object) typically does not know the class of a given moniker, so the client cannot be sure that an anti-moniker is the inverse. Therefore, to get the inverse of a moniker, you would call IMoniker::Inverse() rather than CreateAntiMoniker().

To remove the last piece of a composite moniker, you would do the following:

  1. Call IMoniker::Enum() on the composite, specifying FALSE as the first parameter. This creates an enumerator that returns the component monikers in reverse order.

  2. Use the enumerator to retrieve the last piece of the composite.

  3. Call IMoniker::Inverse() on that moniker. The moniker returned by IMoniker::Inverse() will remove the last piece of the composite.

Parameters

ppmk

[out] Address of IMoniker* pointer variable that receives the interface pointer to the new anti-moniker. When successful, the function has called IUnknown::AddRef() on the anti-moniker and the caller is responsible for calling IUnknown::Release(). When an error occurs, the pointer is NULL.

Return Values

This function supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The anti-moniker has been created successfully.

See Also

IMoniker::Inverse(), IMoniker::ComposeWith, IMoniker - Anti-Moniker Implementation, ISequentialStream::Read storage and stream access errors.  

CreateBindCtx()

NAME

CreateBindCtx() - Supplies a pointer to an implementation of IBindCtx() (a bind context object). This object stores information about a particular moniker-binding operation. The pointer this function supplies is required as a parameter in many methods of the IMoniker() interface and in certain functions related to monikers.

Synopsis

#include <objbase.h>

WINOLEAPI CreateBindCtx((
        DWORD reserved,
        LPBC FAR * ppbc );

Description

CreateBindCtx() is most commonly used in the process of binding a moniker (locating and getting a pointer to an interface by identifying it through a moniker), as in the following steps:

  1. Get a pointer to a bind context by calling the CreateBindCtx() function.

  2. Call the IMoniker::BindToObject() method on the moniker, retrieving an interface pointer to the object to which the moniker refers.

  3. Release() the bind context.

  4. Use the interface pointer.

  5. Release() the interface pointer.

The following code fragment illustrates these steps:

// pMnk is an IMoniker() * that points to a previously acquired moniker 
IFoo *pFoo; 
IBindCtx() *pbc; 
CreateBindCtx( 0, &pbc ); 
pMnk->BindToObject( pbc, NULL, IID_IFoo, &pFoo ); 
pbc->Release(); 
// pFoo now points to the object; safe to use pFoo 
pFoo->Release();

Bind contexts are also used in other methods of the IMoniker() interface besides IMoniker::BindToObject() and in the MkParseDisplayName() function.

A bind context retains references to the objects that are bound during the binding operation, causing the bound objects to remain active (keeping the object's server running) until the bind context is released. Reusing a bind context when subsequent operations bind to the same object can improve performance. You should, however, release the bind context as soon as possible, because you could be keeping the objects activated unnecessarily.

A bind context contains a BIND_OPTS structure, which contains parameters that apply to all steps in a binding operation. When you create a bind context using CreateBindCtx(), the fields of the BIND_OPTS structure are initialized to the following values:

cbStruct = sizeof(BIND_OPTS) 
grfFlags = 0 
grfMode = STGM_READWRITE 
dwTickCountDeadline = 0.

You can call the IBindCtx::SetBindOptions() method to modify these default values.

Parameters

reserved

[in] Reserved for future use; must be zero.

ppbc

[out] Address of IBindCtx* pointer variable that receives the interface pointer to the new bind context object. When the function is successful, the caller is responsible for calling IUnknown::Release() on the bind context. A NULL value for the bind context indicates that an error occurred.

Return Values

This function supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The bind context was allocated and initialized successfully.

See Also

BIND_OPTS, IBindCtx,IMoniker, MkParseDisplayName  

CreateClassMoniker()

NAME

CreateClassMoniker() - Creates a file moniker based on the specified path.

Synopsis

#include <objbase.h>

WINOLEAPI CreateClassMoniker((
        REFCLSID rclsid,
        IMoniker ** ppmk );

Description

CreateClassMoniker() creates a class moniker that refers to the given class. The class moniker will supports binding to a fresh instance of the class identified by the CLSID in rclsid..

Parameters

rclsid

[in] Reference to the CLSID of the object type to which this moniker binds.

ppmk

[out] Address of IMoniker* pointer variable that receives the interface pointer to the new class moniker. On successful return, the function has called IUnknown::AddRef() on the moniker and the caller is responsible for calling IUnknown::Release(). When an error occurs, the value of the moniker pointer is NULL.

Return Values

S_OK

The moniker has been created successfully.

E_INVALIDARG

One or more arguments are invalid.

See Also

IMoniker - Class Moniker Implementation  

CreateFileMoniker()

NAME

CreateFileMoniker() - Creates a file moniker based on the specified path.

Synopsis

#include <objbase.h>

WINOLEAPI CreateFileMoniker(
        LPCOLESTR lpszPathName,
        LPMONIKER FAR * ppmk );

Description

CreateFileMoniker creates a moniker for an object that is stored in a file. A moniker provider (an object that provides monikers to other objects) can call this function to create a moniker to identify a file-based object that it controls, and can then make the pointer to this moniker available to other objects. An object identified by a file moniker must also implement the IPersistFile() interface so it can be loaded when a file moniker is bound.

When each object resides in its own file, as in a COM server application that supports linking only to file-based documents in their entirety, file monikers are the only type of moniker necessary. To identify objects smaller than a file, the moniker provider must use another type of moniker (such as an item moniker) in addition to file monikers, creating a composite moniker. Composite monikers would be needed in a COM server application that supports linking to objects smaller than a document (such as sections of a document or embedded objects).

The lpszPathName can be a relative path, a UNC path (e.g., \\server\share\path), or a drive-letter-based path (e.g., c:\). If based on a relative path, the resulting moniker must be composed onto another file moniker before it can be bound.

A file moniker can be composed to the right only of another file moniker when the first moniker is based on an absolute path and the other is a relative path, resulting in a single file moniker based on the combination of the two paths. A moniker composed to the right of another moniker must be a refinement of that moniker, and the file moniker represents the largest unit of storage. To identify objects stored within a file, you would compose other types of monikers (usually item monikers) to the right of a file moniker.

Parameters

lpszPathName

[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the path on which this moniker is based.

ppmk

[out] Address of IMoniker* pointer variable that receives the interface pointer to the new file moniker. When successful, the function has called IUnknown::AddRef() on the file moniker and the caller is responsible for calling IUnknown::Release(). When an error occurs, the value of the interface pointer is NULL.

Return Values

This function supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The moniker has been created successfully.

MK_E_SYNTAX

Error in the syntax of a path was encountered while creating a moniker.

See Also

IMoniker - File Moniker Implementation  

CreateGenericComposite()

NAME

CreateGenericComposite() - Performs a generic composition of two monikers and supplies a pointer to the resulting composite moniker.

Synopsis

#include <objbase.h>

WINOLEAPI CreateGenericComposite((
        LPMONIKER pmkFirst,
        LPMONIKER pmkRest,
        LPMONIKER FAR * ppmkComposite );

Description

CreateGenericComposite() joins two monikers into one. The moniker classes being joined can be different, subject only to the rules of composition. Call this function only if you are writing a new moniker class by implementing the IMoniker() interface, within an implementation of IMoniker::ComposeWith() that includes generic composition capability.

Moniker providers should call IMoniker::ComposeWith() to compose two monikers together. Implementations of ComposeWith should (as do COM implementations) attempt, when reasonable for the class, to perform non-generic compositions first, in which two monikers of the same class are combined. If this is not possible, the implementation can call CreateGenericComposite() to do a generic composition, which combines two monikers of different classes, within the rules of composition. You can define new types of non-generic compositions if you write a new moniker class.

During the process of composing the two monikers, CreateGenericComposite() makes all possible simplifications. Consider the example where pmkFirst is the generic composite moniker, A + B + C, and pmkRest is the generic composite moniker, C -1 + B -1 + Z (where C -1 is the inverse of C). The function first composes C to C -1, which composes to nothing. Then it composes B and B -1 to nothing. Finally, it composes A to Z, and supplies a pointer to the generic composite moniker, A + Z.

Parameters

pmkFirst

[in] Pointer to the moniker to be composed to the left of the moniker that pmkRest points to. Can point to any kind of moniker, including a generic composite.

pmkRest

[in] Pointer to the moniker to be composed to the right of the moniker that pmkFirst points to. Can point to any kind of moniker compatible with the type of the pmkRest moniker, including a generic composite.

ppmkComposite

[out] Address of IMoniker* pointer variable that receives the interface pointer to the composite moniker object that is the result of composing pmkFirst and pmkRest. This object supports the COM composite moniker implementation of IMoniker(). When successful, the function has called IUnknown::AddRef() on the moniker and the caller is responsible for calling IUnknown::Release(). If either pmkFirst or pmkRest are NULL, the supplied pointer is the one that is non-NULL. If both pmkFirst and pmkRest are NULL, or if an error occurs, the returned pointer is NULL.

Return Values

This function supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The two input monikers were successfully composed.

MK_E_SYNTAX

The two monikers could not be composed due to an error in the syntax of a path (for example, if both pmkFirst and pmkRest are file monikers based on absolute paths).

See Also

IMoniker::ComposeWith(), IMoniker - Generic Composite Moniker Implementation  

CreateItemMoniker()

NAME

CreateItemMoniker() - Creates an item moniker that identifies an object within a containing object (typically a compound document).

Synopsis

#include <objbase.h>

WINOLEAPI CreateItemMoniker((
        LPCOLESTR lpszDelim,
        LPCOLESTR lpszItem,
        LPMONIKER FAR * ppmk );

Description

A moniker provider, which hands out monikers to identify its objects so they are accessible to other parties, would call CreateItemMoniker() to identify its objects with item monikers. Item monikers are based on a string, and identify objects that are contained within another object and can be individually identified using a string. The containing object must also implement the IOleContainer interface.

Most moniker providers are COM applications that support linking. Applications that support linking to objects smaller than file-based documents, such as a server application that allows linking to a selection within a document, should use item monikers to identify the objects. Container applications that allow linking to embedded objects use item monikers to identify the embedded objects.

The lpszItem parameter is the name used by the document to uniquely identify the object. For example, if the object being identified is a cell range in a spreadsheet, an appropriate name might be something like ``A1:E7.'' An appropriate name when the object being identified is an embedded object might be something like ``embedobj1.'' The containing object must provide an implementation of the IOleItemContainer() interface that can interpret this name and locate the corresponding object. This allows the item moniker to be bound to the object it identifies.

Item monikers are not used in isolation. They must be composed with a moniker that identifies the containing object as well. For example, if the object being identified is a cell range contained in a file-based document, the item moniker identifying that object must be composed with the file moniker identifying that document, resulting in a composite moniker that is the equivalent of ``C:\work\sales.xls!A1:E7.''

Nested containers are allowed also, as in the case where an object is contained within an embedded object inside another document. The complete moniker of such an object would be the equivalent of ``C:\work\report.doc!embedobj1!A1:E7.'' In this case, each containing object must call CreateItemMoniker() and provide its own implementation of the IOleItemContainer() interface.

Parameters

lpszDelim

[in] Pointer to a wide character string (two bytes per character) zero-terminated string containing the delimiter (typically ``!'') used to separate this item's display name from the display name of its containing object.

lpszItem

[in] Pointer to a zero-terminated string indicating the containing object's name for the object being identified. This name can later be used to retrieve a pointer to the object in a call to IOleItemContainer::GetObject().

ppmk

[out] Address of IMoniker* pointer variable that receives the interface pointer to the new item moniker. When successful, the function has called IUnknown::AddRef() on the item moniker and the caller is responsible for calling IUnknown::Release(). If an error occurs, the supplied interface pointer has a NULL value.

Return Values

This function supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The moniker was created successfully.

See Also

IMoniker::ComposeWith(), IOleItemContainer, IMoniker() - Item Moniker Implementation  

CreatePointerMoniker()

NAME

CreatePointerMoniker() - Creates a pointer moniker based on a pointer to an object.

Synopsis

#include <objbase.h>

WINOLEAPI CreatePointerMoniker((
        LPUNKNOWN punk,
        LPMONIKER FAR * ppmk );

Description

A pointer moniker wraps an existing interface pointer in a moniker that can be passed to those interfaces that require monikers. Pointer monikers allow an object that has no persistent representation to participate in a moniker-binding operation.

Pointer monikers are not commonly used, so this function is not often called.

Parameters

punk

[in] Pointer to an IUnknown() interface on the object to be identified by the resulting moniker.

ppmk

[out] Address of IMoniker* pointer variable that receives the interface pointer to the new pointer moniker. When successful, the function has called IUnknown::AddRef() on the moniker and the caller is responsible for calling IUnknown::Release(). When an error occurs, the returned interface pointer has a NULL value.

Return Values

This function supports the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following:

S_OK

The pointer moniker was created successfully.

See Also

IMoniker - Pointer Moniker Implementation

16.4    Moniker Structure Definitions

16.4.1    BIND_OPTS

Contains parameters used during a moniker-binding operation. The BIND_OPTS2 structure may be used in its place. A BIND_OPTS structure is stored in a bind context; the same bind context is used by each component of a composite moniker during binding, allowing the same parameters to be passed to all components of a composite moniker. See IBindCtx() for more information about bind contexts.

If you're a moniker client (that is, you use a moniker to acquire an interface pointer to an object), you typically do not need to specify values for the fields of this structure. The CreateBindCtx() function creates a bind context with the bind options set to default values that are suitable for most situations; the BindMoniker() function does the same thing when creating a bind context for use in binding a moniker. If you want to modify the values of these bind options, you can do so by passing a BIND_OPTS structure to the IBindCtx::SetBindOptions() method. Moniker implementers can pass a BIND_OPTS structure to the IBindCtx::GetBindOptions() method to retrieve the values of these bind options.

The BIND_OPTS structure is defined in OBJIDL.IDL

typedef struct tagBIND_OPTS 
{ 
    DWORD cbStruct; 
    DWORD grfFlags; 
    DWORD grfMode; 
    DWORD dwTickCountDeadline; 
} BIND_OPTS, *LPBIND_OPTS;

Members

cbStruct

Size of this structure in bytes (that is, the size of the BIND_OPTS structure).

grfFlags

Flags that control aspects of moniker binding operations. This value is any combination of the bit flags in the BINDFLAGS enumeration. New values may be defined in the future, so moniker implementations should ignore any bits in this field that they do not understand. The CreateBindCtx() function initializes this field to zero.

grfMode

Flags that should be used when opening the file that contains the object identified by the moniker. The values are taken from the STGM enumeration. The binding operation uses these flags in the call to IPersistFile::Load() when loading the file. If the object is already running, these flags are ignored by the binding operation. The CreateBindCtx() function initializes this field to STGM_READWRITE.

dwTickCountDeadline

Clock time (in milliseconds, as returned by the GetTickCount function) by which the caller would like the binding operation to be completed. This member lets the caller limit the execution time of an operation when speed is of primary importance. A value of zero indicates that there is no deadline. Callers most often use this capability when calling the IMoniker::GetTimeOfLastChange() method, though it can be usefully applied to other operations as well. The CreateBindCtx() function initializes this field to zero.

Typical deadlines allow for a few hundred milliseconds of execution. This deadline is a recommendation, not a requirement; however, operations that exceed their deadline by a large amount may cause delays for the end user. Each moniker implementation should try to complete its operation by the deadline, or fail with the error MK_E_EXCEEDEDDEADLINE.

If a binding operation exceeds its deadline because one or more objects that it needs are not running, the moniker implementation should register the objects responsible in the bind context using the IBindCtx::RegisterObjectParam(). The objects should be registered under the parameter names "ExceededDeadline", "ExceededDeadline1", "ExceededDeadline2", and so on. If the caller later finds the object in the Running Object Table, the caller can retry the binding operation.

The GetTickCount function indicates the number of milliseconds since system startup, and wraps back to zero after 231 milliseconds. Consequently, callers should be careful not to inadvertently pass a zero value (which indicates no deadline), and moniker implementations should be aware of clock wrapping problems (see the GetTickCount function for more information).

See Also

BIND_OPTS2, BIND_FLAGS, CreateBindCtx(), IBindCtx::SetBindOptions()

16.4.2    BIND_OPTS2

Contains parameters used during a moniker-binding operation. A BIND_OPTS2 structure is stored in a bind context; the same bind context is used by each component of a composite moniker during binding, allowing the same parameters to be passed to all components of a composite moniker. See IBindCtx() for more information about bind contexts. BIND_OPTS2 replaces the previously defined BIND_OPTS structure, including the previously defined members, and adding four new members.

Moniker clients (those using a moniker to acquire an interface pointer to an object) typically do not need to specify values for the fields of this structure. The CreateBindCtx() function creates a bind context with the bind options set to default values that are suitable for most situations. The BindMoniker() function does the same thing when creating a bind context for use in binding a moniker. If you want to modify the values of these bind options, you can do so by passing a BIND_OPTS2 structure to the IBindCtx::SetBindOptions() method. Moniker implementers can pass a BIND_OPTS2 structure to the IBindCtx::GetBindOptions() method to retrieve the values of these bind options.

The BIND_OPTS2 structure is defined in OBJIDL.IDL

typedef struct tagBIND_OPTS2 {
    DWORD           cbStruct;       //  sizeof(BIND_OPTS2)
    DWORD           grfFlags;
    DWORD           grfMode;
    DWORD           dwTickCountDeadline;
    DWORD           dwTrackFlags;
    DWORD           dwClassContext;
    LCID            locale;
    COSERVERINFO *  pServerInfo;
} BIND_OPTS2, * LPBIND_OPTS2;

Members

cbStruct

Size of this structure in bytes (that is, the size of the BIND_OPTS2 structure).

grfFlags

Flags that control aspects of moniker binding operations. This value is any combination of the bit flags in the BINDFLAGS enumeration. New values may be defined in the future, so moniker implementations should ignore any bits in this field that they do not understand. The CreateBindCtx() function initializes this field to zero.

grfMode

Flags that should be used when opening the file that contains the object identified by the moniker. The values are taken from the STGM enumeration. The binding operation uses these flags in the call to IPersistFile::Load() when loading the file. If the object is already running, these flags are ignored by the binding operation. The CreateBindCtx() function initializes this field to STGM_READWRITE.

dwTickCountDeadline

Clock time (in milliseconds, as returned by the GetTickCount function) by which the caller would like the binding operation to be completed. This member lets the caller limit the execution time of an operation when speed is of primary importance. A value of zero indicates that there is no deadline. Callers most often use this capability when calling the IMoniker::GetTimeOfLastChange() method, though it can be usefully applied to other operations as well. The CreateBindCtx() function initializes this field to zero.

Typical deadlines allow for a few hundred milliseconds of execution. This deadline is a recommendation, not a requirement; however, operations that exceed their deadline by a large amount may cause delays for the end user. Each moniker implementation should try to complete its operation by the deadline, or fail with the error MK_E_EXCEEDEDDEADLINE.

If a binding operation exceeds its deadline because one or more objects that it needs are not running, the moniker implementation should register the objects responsible in the bind context using the IBindCtx::RegisterObjectParam(). The objects should be registered under the parameter names "ExceededDeadline", "ExceededDeadline1", "ExceededDeadline2", and so on. If the caller later finds the object in the Running Object Table, the caller can retry the binding operation.

The GetTickCount function indicates the number of milliseconds since system startup, and wraps back to zero after 231 milliseconds. Consequently, callers should be careful not to inadvertently pass a zero value (which indicates no deadline), and moniker implementations should be aware of clock wrapping problems (see the GetTickCount function for more information).

dwTrackFlags

A moniker can use this value during link tracking. If the original persisted data that the moniker is referencing has been moved, the moniker can attempt to reestablish the link by searching for the original data though some adequate mechanism. dwTrackFlags provides additional information on how the link should be resolved. See the documentation of the fFlags parameter in IShellLink::Resolve in the Win32 SDK for more details.

COM's file moniker implementation uses the shell link mechanism to reestablish links and passes these flags to IShellLink::Resolve.

dwClassContext

The class context, taken from the CLSCTX enumeration, that is to be used for instantiating the object. Monikers typically pass this value to the dwClsContext parameter of CoCreateInstance().

locale

The LCID value indicating the client's preference for the locale to be used by the object to which they are binding. A moniker passes this value to IClassActivator::GetClassObject().

pServerInfo

Points to a COSERVERINFO structure. This member allows clients calling IMoniker::BindToObject() to specify server information. Clients may pass a BIND_OPTS2 structure to the IBindCtx::SetBindOptions() method. If a server name is specified in the COSERVERINFO struct, the moniker bind will be forwarded to the specified machine. SetBindOptions only copies the struct members of BIND_OPTS2, not the COSERVERINFO structure and the pointers it contains. Callers may not free any of these pointers until the bind context is released. COM's new class moniker does not currently honor the pServerInfo flag.

See Also

BIND_OPTS, BIND_FLAGS, CreateBindCtx(), IBindCtx::SetBindOptions()

16.5    Moniker Enumeration Definitions

16.5.1    BIND_FLAGS

The BIND_FLAGS enumeration values are used to control aspects of moniker binding operations. The values are used in the BIND_OPTS structure. Callers of IMoniker() methods can specify values from this enumeration, and implementers of IMoniker() methods can use these values in determining what they should do.

<The BIND_FLAGS enumeration is defined in OBJIDL.IDL and in OBJIDL.H]>

typedef enum tagBIND_FLAGS 
{ 
    BIND_MAYBOTHERUSER     = 1, 
    BIND_JUSTTESTEXISTENCE = 2, 
} BIND_FLAGS;

Elements

BIND_MAYBOTHERUSER

If this flag is specified, the moniker implementation can interact with the end user. If not present, the moniker implementation should not interact with the user in any way, such as by asking for a password for a network volume that needs mounting. If prohibited from interacting with the user when it otherwise would, a moniker implementation can use a different algorithm that does not require user interaction, or it can fail with the error MK_MUSTBOTHERUSER.

BIND_JUSTTESTEXISTENCE

If this flag is specified, the caller is not interested in having the operation carried out, but only in learning whether the operation could have been carried out had this flag not been specified. For example, this flag lets the caller indicate only an interest in finding out whether an object actually exists by using this flag in a IMoniker::BindToObject() call. Moniker implementations can, however, ignore this possible optimization and carry out the operation in full. Callers must be able to deal with both cases.

See Also

BIND_OPTS, IBindCtx()

16.5.2    MKRREDUCE

The MKRREDUCE enumeration constants are used to specify how far the moniker should be reduced. They are used in the IMoniker::Reduce() method.

< MKRREDUCE is defined in OBJIDL.IDL and in OBJIDL.H].>

typedef enum tagMKRREDUCE 
{ 
    MKRREDUCE_ONE            = 3<<16, 
    MKRREDUCE_TOUSER         = 2<<16, 
    MKRREDUCE_THROUGHUSER    = 1<<16, 
    MKRREDUCE_ALL            = 0 
} MKRREDUCE;

Elements

MKRREDUCE_ONE

Performs only one step of reducing the moniker. In general, the caller must have specific knowledge about the particular kind of moniker to take advantage of this option.

MKRREDUCE_TOUSER

Reduces the moniker to a form that the user identifies as a persistent object. If no such point exists, then this option should be treated as MKRREDUCE_ALL.

MKRREDUCE_THROUGHUSER

Reduces the moniker to where any further reduction would reduce it to a form that the user does not identify as a persistent object. Often, this is the same stage as MKRREDUCE_TOUSER.

MKRREDUCE_ALL

Reduces the moniker until it is in its simplest form, that is, reduce it to itself.

See Also

IMoniker::Reduce()

16.5.3    MKSYS

The MKSYS enumeration constants indicate the moniker's class. They are returned from the IMoniker::IsSystemMoniker() method. MKSYS is defined in Objidl.h.

typedef enum tagMKSYS 
{ 
    MKSYS_NONE                = 0, 
    MKSYS_GENERICCOMPOSITE    = 1, 
    MKSYS_FILEMONIKER         = 2, 
    MKSYS_ANTIMONIKER         = 3, 
    MKSYS_ITEMMONIKER         = 4, 
    MKSYS_POINTERMONIKER      = 5, 
    MKSYS_CLASSMONIKER        = 7 
} MKSYS;

Elements

MKSYS_NONE

Indicates a custom moniker implementation.

MKSYS_GENERICCOMPOSITE

Indicates the system's generic composite moniker class.

MKSYS_FILEMONIKER

Indicates the system's file moniker class.

MKSYS_ANTIMONIKER

Indicates the system's anti-moniker class.

MKSYS_ITEMMONIKER

Indicates the system's item moniker class.

MKSYS_POINTERMONIKER

Indicates the system's pointer moniker class.

MKSYS_CLASSMONIKER

Indicates the system's class moniker class.

See Also

IMoniker::IsSystemMoniker()