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:
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.
(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.
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:
A
BIND_OPTS
structure containing a set
of parameters that do not change during the binding operation.
When a composite
moniker is bound, each component uses the same bind context, so it acts as
a mechanism for passing the same parameters to each component of a composite
moniker.
A set of pointers to objects that the binding operation has activated. The bind context holds pointers to these bound objects, keeping them loaded and thus eliminating redundant activations if the objects are needed again during subsequent binding operations.
A pointer to the Running Object Table on the machine of the
process that started the bind operation.
Moniker implementations that need
to access the Running Object Table should use the
IBindCtx::GetRunningObjectTable()
method rather than using the
GetRunningObjectTable()
function.
This allows future enhancements to the system's
IBindCtx()
implementation to modify binding behavior.
A table of interface pointers, each associated with a string
key.
This capability enables moniker implementations to store interface pointers
under a well-known string so that they can later be retrieved from the bind
context.
For example, COM defines several string keys (e.g., ``ExceededDeadline
'', ``ConnectManually
'') that can be used to
store a pointer to the object that caused an error during a binding operation.
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.
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:
Call the
CreateBindCtx()
function to create
a bind context
and get a pointer to the
IBindCtx()
interface on the bind
context
object..
If desired (although this is rarely necessary), the moniker
client can call
IBindCtx::SetBindOptions()
to specify the bind options.
Pass the bind context as a parameter to the desired
IMoniker()
method (usually
IMoniker::BindToObject()
).
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.
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments the reference count. |
Release()
|
Decrements the reference count. |
|
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. |
CreateBindCtx()
,
IMoniker()
,
IOleItemContainer()
,
IParseDisplayName()
- Supplies a pointer to an
IBindCtx::EnumObjectParam()
IEnumString()
interface
on an enumerator that can return the keys of the bind context's string-keyed
table of pointers.
HRESULT EnumObjectParam(
#include <objidl.h>
IEnumString ** ppenum
);
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()
.
[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()
.
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.
IBindCtx::RegisterObjectParam()
,
IEnumString()
- Returns the binding options stored in this bind context.
IBindCtx::GetBindOptions()
HRESULT GetBindOptions(
#include <objidl.h>
BIND_OPTS * pbindopts
);
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.
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.
[in, out] Pointer to an initialized
BIND_OPTS
structure
on entry that receives the current binding parameters on return.
This method supports the standard return value
E_UNEXPECTED
, as well as
the following:
S_OK
The stored binding options were successfully returned.
- Retrieves the pointer associated with the specified key in the
bind context's string-keyed table of pointers.
IBindCtx::GetObjectParam()
HRESULT GetObjectParam(
#include <objidl.h>
LPOLESTR pszKey,
IUnknown ** ppunk
);
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.
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).
[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.
[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
.
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.
IBindCtx::RegisterObjectParam()
,
IBindCtx::EnumObjectParam()
- Provides an interface pointer to the Running Object Table (ROT)
for the machine on which this bind context is running.
IBindCtx::GetRunningObjectTable()
HRESULT GetRunningObjectTable((
#include <objidl.h>
IRunningObjectTable ** pprot
);
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.
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.
[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()
.
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.
IMoniker()
,
IRunningObjectTable()
- Calls
IBindCtx::RegisterObjectBound()
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.
HRESULT RegisterObjectBound(
#include <objidl.h>
IUnknown * punk
);
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.
[in] Pointer to the
IUnknown()
interface
on the object
that is being registered as bound.
This method supports the standard return value
E_OUTOFMEMORY
, as well as
the following:
S_OK
The object was successfully registered.
IBindCtx::ReleaseBoundObjects()
,
IBindCtx::RevokeObjectBound()
,
IRunningObjectTable::GetObject()
- Stores an
IBindCtx::RegisterObjectParam()
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.
HRESULT RegisterObjectParam(
#include <objidl.h>
LPOLESTR pszKey,
IUnknown * punk
);
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.
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:
It is replaced in the table by another object with the same key.
It is removed from the table by a call to
IBindCtx::RevokeObjectParam()
.
The bind context is released. All registered objects are released when the bind context is released.
[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.
[in] Pointer to the
IUnknown()
interface
on the object
that is to be registered.
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.
IBindCtx::GetObjectParam()
,
IBindCtx::RevokeObjectParam()
,
IBindCtx::EnumObjectParam()
- Releases all pointers to all objects that were previously registered
by calls to
IBindCtx::ReleaseBoundObjects()
IBindCtx::RegisterObjectBound()
.
HRESULT ReleaseBoundObjects(
#include <objidl.h>
void
);
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.
S_OK
The objects were released successfully.
IBindCtx::RegisterObjectBound()
- Releases the
IBindCtx::RevokeObjectBound()
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.
HRESULT RevokeObjectBound(
#include <objidl.h>
IUnknown * punk
);
You rarely call this method. This method is included for completeness.
[in] Pointer to the
IUnknown()
interface
on the object
to be released.
S_OK
The object was released successfully.
MK_E_NOTBOUND
Indicates that
punk
was not previously
registered
with a call to
IBindCtx::RegisterObjectBound()
.
IBindCtx::RegisterObjectBound()
- 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::RevokeObjectParam()
IBindCtx::RegisterObjectParam()
.
HRESULT RevokeObjectParam(
#include <objidl.h>
LPOLESTR pszKey
);
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.
[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the key to remove. Key string comparison is case-sensitive.
S_OK
The specified key was successfully removed from the table.
S_FALSE
No object has been registered with the specified key.
IBindCtx::RegisterObjectParam()
- Specifies new values for the binding parameters stored in the
bind context.
Subsequent binding operations can call
IBindCtx::SetBindOptions()
IBindCtx::GetBindOptions()
to retrieve the parameters.
HRESULT SetBindOptions(
#include <objidl.h>
BIND_OPTS * pbindopts
);
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.
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.
[in] Pointer to a
BIND_OPTS2
or a
BIND_OPTS
structure containing the binding parameters.
This method supports the standard return value
E_OUTOFMEMORY
, as well as
the following:
S_OK
The parameters were stored successfully.
Bind_OPTS2
,
IBindCtx::GetBindOptions()
IClassActivator()
Specifies a method that retrieves
a class object.
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()
.
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.
IUnknown Methods
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments the reference count. |
Release()
|
Decrements the reference count. |
|
Description
|
GetClassObject
|
Retrieves a class object. |
- Retrieves a class object.
Similar to
IClassActivator::GetClassObject()
CoGetClassObject()
,
HRESULT GetClassObject(
#include <objidl.h>
REFCLSID * pClassID,
DWORD dwClsContext,
LCID locale,
REFIID riid,
void ** ppv
);
This method returns the class identifier (CLSID) for an object, used in later operations to load object-specific code into the caller's context.
[in] Points to the CLSID that Identifies the class whose class object is to be retrieved.
[in] The context in which the class is expected to run; values
are taken
from the
CLSCTX
enumeration.
[in] Any LCID constant as defined in
WINNLS.H
.
[in] IID of the interface on the object to which a pointer is desired.
[out] On successful return, an indirect pointer to the requested interface.
This method supports the standard return value
E_FAIL
,
as well as the
following:
S_OK
The CLSID was successfully returned.
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()
.
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.
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
IMoniker::Enum()
method gets a pointer
to an
IEnumMoniker()
implementation that can enumerate forwards
or backwards
through the components of the moniker.
For a description of how two of the
system-supplied types of monikers enumerate their components, see
Section
Section 16.2.9
and Section
Section 16.2.10.
The
IRunningObjectTable::EnumRunning()
method returns a
pointer to an
IEnumMoniker()
implementation that can enumerate
the
monikers registered in a Running Object Table.
The prototypes of the methods are as follows:
HRESULT Next(
#include <objidl.h>
ULONG celt,
IMoniker * rgelt,
ULONG * pceltFetched
);
HRESULT Skip(
#include <objidl.h>
ULONG celt
);
HRESULT Reset(
#include <objidl.h>
void
);
HRESULT Clone(
#include <objidl.h>
IEnumMoniker ** ppenum
);
IEnum
XXXX,
IMoniker::Enum()
,
IRunningObjectTable::EnumRunning()
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()
.
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.
Call the methods of
IEnumString()
to enumerate through
a set of
strings.
The prototypes of the member functions are as follows:
HRESULT Next(
#include <objidl.h>
ULONG celt,
LPOLESTR * rgelt,
ULONG * pceltFetched
);
HRESULT Skip(
#include <objidl.h>
ULONG celt
);
HRESULT Reset(
#include <objidl.h>
void
);
HRESULT Clone(
#include <objidl.h>
IEnumString ** ppenum
);
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()
.
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
.
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:
HRESULT Next(
#include <objidl.h>
ULONG celt,
IUnknown ** rgelt,
ULONG * pceltFetched
);
HRESULT Skip(
#include <objidl.h>
ULONG celt
);
HRESULT Reset(
#include <objidl.h>
void
);
HRESULT Clone(
#include <objidl.h>
IEnumUnknown ** ppenum
);
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 can be saved to a persistent storage. When a moniker is loaded back into memory, it still identifies the same object.
Monikers support an operation called ``binding,'' which is the process of locating the object named by the moniker, activating it (loading it into memory) if it is not already active, and returning a pointer to a requested interface on that object.
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.
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).
Two kinds of objects call the methods of
IMoniker
:
A component that contains one or more objects to be identified with a moniker and must provide the moniker to other objects
A client object that must bind to the object identified by the moniker
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.
File monikers
-- based on a path in
the file system.
File
monikers can be used to identify objects that are saved as files.
The
associated creation function is
CreateFileMoniker
.
Item monikers
-- based on a string
that identifies an object
in a container.
Item monikers can be used to identify objects smaller than
a
file, such as embedded objects in a compound document and pseudo-objects (like
a range of cells in a spreadsheet).
The associated creation function is
CreateItemMoniker()
.
Generic composite monikers
-- consists
of two or more
monikers of arbitrary type that have been composed together.
Generic composite
monikers allow monikers of different classes to be used in combination.
The
associated creation function is
CreateGenericComposite()
.
Anti-monikers
-- the inverse of file,
item, or pointer
monikers.
Anti-monikers are used primarily for constructing relative monikers,
which are analogous to relative path (such as ``..\backup\report.old''), and
which specify a location of an object
relative
to the
location of
another object).
The associated creation function is
CreateAntiMoniker()
.
Pointer monikers
-- a non-persistent
moniker that wraps an
interface pointer to an object loaded in memory.
Whereas most monikers identify
objects that can be saved to persistent storage, pointer monikers identify
objects that cannot.
The associated creation function is
CreatePointerMoniker()
.
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.
Class monikers
-- these represent
an object class.
Class
monikers bind to the class object of the class for which they are created.
The
associated creation function is
CreateClassComposite
.
IUnknown Methods
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments reference count. |
Release()
|
Decrements reference count. |
IPersist Methods
|
Description
|
GetClassID()
|
Returns the object's CLSID. |
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. |
|
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. |
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
- 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.
IMoniker::BindToObject()
HRESULT BindToObject(
#include <objidl.h>
IBindCtx * pbc,
IMoniker * pmkToLeft,
REFIID riidResult,
void ** ppvResult
);
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.
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:
Create a bind context object with a call to the
CreateBindCtx()
function.
Call
IMoniker::BindToObject()
using the
moniker, retrieving a pointer
to a desired interface on the identified object.
Release()
the bind context.
Through the acquired interface pointer, perform the desired operations on the object.
When finished with the object, release the object's interface pointer.
The following code fragment illustrates these steps:
// pMnk is anIMoniker()
* 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.
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).
[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.
[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
.
[in] IID of the interface the client wishes to use to communicate with the object that the moniker identifies.
[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
.
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()
errorsIf the moniker used to bind to an object contains an item moniker, errors associated with this method can be returned.
BindMoniker()
,
IMoniker::BindToStorage()
- Retrieves an interface pointer to the storage that contains the
object identified by the moniker.
Unlike the
IMoniker::BindToStorage()
IMoniker::BindToObject()
method, this method does not activate the object identified by
the moniker.
HRESULT BindToStorage(
#include <objidl.h>
IBindCtx * pbc,
IMoniker * pmkToLeft,
REFIID riid,
void ** ppvObj
);
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.
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.
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).
[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()
.
[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
.
[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()
.
[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.
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()
errorsBinding to a moniker containing an item moniker can return any of the errors associated with this function.
- 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.
IMoniker::CommonPrefixWith()
HRESULT CommonPrefixWith(
#include <objidl.h>
IMoniker * pmkOther,
IMoniker ** ppmkPrefix
);
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.''
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.
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.
[in] Pointer to the
IMoniker()
interface
on another
moniker to be compared with this one to determine whether there is a common
prefix.
[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
.
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.
IMoniker::RelativePathTo()
,
MonikerCommonPrefixWith()
- Combines the current moniker with another moniker, creating a
new composite moniker.
IMoniker::ComposeWith()
HRESULT ComposeWith(
#include <objidl.h>
IMoniker * pmkRight,
BOOL fOnlyIfNotGeneric,
IMoniker ** ppmkComposite
);
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 ) )
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:
Create an item moniker identifying an object.
Get a moniker that identifies the object's container.
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
.
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.
[in] Pointer to the
IMoniker()
interface
on the moniker
to compose onto the end of this moniker.
[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.
[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
.
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.
CreateGenericComposite()
,
IMoniker::Inverse()
- Supplies a pointer to an enumerator that can enumerate the components of a
composite moniker.
IMoniker::Enum()
HRESULT Enum(
#include <objidl.h>
BOOL fForward,
IEnumMoniker ** ppenumMoniker
);
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.
Call this method to examine the components that make up a composite moniker.
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
.
[in] If
TRUE
, enumerates the monikers from
left to
right.
If
FALSE
, enumerates from right to left.
[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
.
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
).
- Gets the display name , which is a user-readable representation
of this moniker.
IMoniker::GetDisplayName()
HRESULT GetDisplayName(
#include <objidl.h>
IBindCtx * pbc,
IMoniker * pmkToLeft,
LPOLESTR * ppszDisplayName
);
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.
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.
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.
[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()
.
[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
.
[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
.
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.
IMoniker::ParseDisplayName()
,
MkParseDisplayName()
- 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.
IMoniker::GetTimeOfLastChange()
HRESULT GetTimeOfLastChange(
#include <objidl.h>
IBindCtx * pbc,
IMoniker * pmkToLeft,
FILETIME * pFileTime
);
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.
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:
For many types of monikers, the
pmkToLeft
parameter identifies the
container of the object identified by this moniker.
If this is true of your
moniker class, you can simply call
IMoniker::GetTimeOfLastChange()
on the
pmkToLeft
parameter, since an object cannot have changed
at a date later
than its container.
You can get a pointer to the Running Object Table (ROT) by
calling
IBindCtx::GetRunningObjectTable()
on the
pbc
parameter, and
then calling
IRunningObjectTable::GetTimeOfLastChange()
,
since the
ROT generally records the time of last change.
You can get the storage associated with this moniker (or the
pmkToLeft
moniker) and return the storage's last modification
time with
a call to
IStorage::Stat()
.
[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()
.
[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
.
[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).
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.
IBindCtx::GetRunningObjectTable()
,
IRunningObjectTable::GetTimeOfLastChange()
- Calculates a 32-bit integer using the internal state of the moniker.
IMoniker::Hash()
HRESULT Hash(
#include <objidl.h>
DWORD * pdwHash
);
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()
.
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.
[out] Pointer to the hash value.
S_OK
Successfully received a 32-bit integer hash value.
- 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).
IMoniker::Inverse()
HRESULT Inverse(
#include <objidl.h>
IMoniker ** ppmk
);
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 ) )
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.
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.
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()
.
[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
.
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.
CreateAntiMoniker()
,
IMoniker::ComposeWith()
,
IMoniker::RelativePathTo()
- Compares this moniker with a specified moniker and indicates whether they
are identical.
IMoniker::IsEqual()
HRESULT IsEqual(
#include <objidl.h>
IMoniker * pmkOtherMoniker
);
Previous implementations of the Running Object Table (ROT) called this
method.
The current implementation of the ROT uses the
IROTData()
interface instead.
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.
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()
.
[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).
S_OK
The two monikers are identical.
S_FALSE
The two monikers are not identical.
IMoniker::Reduce()
,
IMoniker::Hash()
,
IROTData()
- Determines whether the object identified by this moniker is currently loaded
and running.
IMoniker::IsRunning()
HRESULT IsRunning((
#include <objidl.h>
IBindCtx * pbc,
IMoniker * pmkToLeft,
IMoniker * pmkNewlyRunning
);
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
.
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.
[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()
.
[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
.
[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.
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.
IBindCtx::GetRunningObjectTable()
,
IRunningObjectTable::IsRunning()
- Indicates whether this moniker is of one of the system-supplied
moniker classes.
IMoniker::IsSystemMoniker()
HRESULT IsSystemMoniker(
#include <objidl.h>
DWORD * pdwMksys
);
New values of the
MKSYS
enumeration may be defined
in the
future; therefore you should explicitly test for each value you are interested
in.
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.
[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
.
S_OK
The moniker is a system moniker.
S_FALSE
The moniker is not a system moniker.
- 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.
IMoniker::ParseDisplayName()
HRESULT ParseDisplayName(
#include <objidl.h>
IBindCtx * pbc,
IMoniker * pmkToLeft,
LPOLESTR pszDisplayName,
ULONG * pchEaten,
IMoniker ** ppmkOut
);
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.
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:
You can try to get the object's CLSID (by calling
IPersist::GetClassID()
on the object), and then call the
CoGetClassObject()
function, requesting the
IParseDisplayName()
interface on the class factory associated
with that
CLSID.
You can try to bind to the object itself to get an
IParseDisplayName()
pointer.
You can try binding to the object identified by
pmkToLeft
to get an
IOleItemContainer()
pointer, and then call
IOleItemContainer::GetObject()
to get an
IParseDisplayName()
pointer for the item.
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.
[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()
.
[in] Pointer to the
IMoniker()
interface
on the moniker
that has been built out of the display name up to this point.
[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.
[out] Pointer to the number of characters in pszDisplayName that were consumed in this step.
[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
.
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()
errorsParsing display names may cause binding. Thus, any error associated with this function may be returned.
IParseDisplayName()
,
MkParseDisplayName()
- 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.
IMoniker::Reduce()
HRESULT Reduce(
#include <objidl.h>
IBindCtx * pbc,
DWORD dwReduceHowFar,
IMoniker ** ppmkToLeft,
IMoniker ** ppmkReduced
);
IMoniker::Reduce()
is intended for the following
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 that tracks data as it moves about. When reduced, the moniker of the data in its current location is returned.
On file systems that support an identifier-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 identifiers.
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.
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.
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.
[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()
.
[in]
DWORD
that specifies how far this
moniker should
be reduced.
This parameter must be one of the values from the
MKRREDUCE
enumeration.
[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.
[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.)
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.
IMoniker::IsEqual()
,
MKRREDUCE
- Supplies a moniker that, when composed onto the end of this moniker
(or one with a similar structure), yields the specified moniker.
IMoniker::RelativePathTo()
HRESULT RelativePathTo(
#include <objidl.h>
IMoniker * pmkOther,
IMoniker ** ppmkRelPath
);
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.''
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.
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
.
[in] Pointer to the
IMoniker()
interface
on the moniker
to which a relative path should be taken.
[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
.
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.
IMoniker::Inverse()
,
IMoniker::CommonPrefixWith()
,
MonikerRelativePathTo()
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.
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.
IMoniker::BindToObject()
This method is not implemented.
It returns
E_NOTIMPL
.
IMoniker::BindToStorage()
This method is not implemented.
It returns
E_NOTIMPL
.
IMoniker::Reduce()
This method returns
MK_S_REDUCED_TO_SELF
and passes
back the same
moniker.
IMoniker::ComposeWith()
If
fOnlyIfNotGeneric
is
TRUE
,
this method sets
ppmkComposite
to
NULL
moniker and
returns
MK_E_NEEDGENERIC
; otherwise,
the method returns the result of combining the two monikers into a generic
composite.
Note that composing a file, item, or pointer moniker to the right
of
an anti-moniker produces a generic composite rather than composing to nothing,
as would be the case if the order of composition were reversed.
IMoniker::Enum()
This method returns
S_OK
and sets *ppenumMoniker
to
NULL
.
IMoniker::IsEqual()
This method returns
S_OK
if both are anti-monikers;
otherwise, it
returns
S_FALSE
.
IMoniker::Hash()
This method calculates a hash value for the moniker.
IMoniker::IsRunning()
This method checks the ROT to see if the object is running.
IMoniker::GetTimeOfLastChange()
This method is not implemented (that is, it returns
E_NOTIMPL
).
IMoniker::Inverse()
This method returns
MK_E_NOINVERSE
and sets *ppmk
to
NULL
.
IMoniker::CommonPrefixWith()
If the other moniker is also an anti-moniker, the method returns
MK_S_US
and sets
ppmkPrefix
to this moniker.
Otherwise, the method
calls the
MonikerCommonPrefixWith()
function.
This function correctly
handles
the case where the other moniker is a generic composite.
IMoniker::RelativePathTo()
This method returns
MK_S_HIM
and sets *ppmkRelPath
to the other
moniker.
IMoniker::GetDisplayName()
For each anti-moniker contained in this moniker, this method return one instance of ``\..''
IMoniker::ParseDisplayName()
This method is not implemented (that is, it returns
E_NOTIMPL
).
IMoniker::IsSystemMoniker()
This method returns
S_OK
and indicates
MKSYS_ANTIMONIKER
.
CreateAntiMoniker()
,
IMoniker()
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.
To use class monikers, you must use the
CreateClassMoniker()
function to create the monikers.
IMoniker::BindToObject()
If
pmkLeft
is
NULL
, calls
CoGetClassObject()
using
the CLSID the class moniker was initialized with (in
CreateClassMoniker()
or through
MkParseDisplayName()
) and the
CLSCTX
of the current pbc
(IBindContext
).
If
pmkLeft
is non-NULL
, calls
pmkLeft->BindToObject
for
IClassActivator()
and calls
IClassActivator::GetClassObject
with the CLSID it
was initialized with and the
CLSCTX
and
LOCALE
parameters from of the current
pbc
(IBindContext
).
This process is very roughly sketched out in the following code:
BIND_OPTS2 bindOpts;
IClassActivator()
*pActivate;
bindOpts.cbStruct = sizeof(bindOpts);
pbc->GetBindOptions(&bindOpts);
if (NULL == pmkToLeft)
return CoGetClassObject(<clsid>,
bindOpts.dwClassContext, NULL, riid, ppvResult);
pmkToLeft->BindToObject(pbc, NULL, IID_IClassActivator, (void **)
&pActivate);
hr = pActivate->GetClassObject(<clsid>,
bindOpts.dwClassContext, bindOpts.locale, iid, ppvResult);
pActivate->Release();
return hr;
IMoniker::BindToStorage()
This method forwards to the class moniker's
BindToObject
.
IMoniker::Reduce()
This method returns
MK_S_REDUCED_TO_SELF
and passes
back the same
moniker.
IMoniker::ComposeWith()
Follows the contract, and behaves like an Item Moniker in that it can
return
E_INVALIDARG
and
MK_E_NEEDGENERIC
,
etc.
IMoniker::Enum()
This method returns
S_OK
and sets
ppenumMoniker
to
NULL
.
May
return
E_INVALIDARG
if
ppenumMoniker
is an invalid pointer.
IMoniker::IsEqual()
This method returns
S_OK
if
pmkOther
is a class moniker
constructed with the same CLSID information as itself.
Otherwise, the method
returns
S_FALSE
.
May return
E_INVALIDARG
if
pmkOther
is an invalid
pointer.
IMoniker::Hash()
This method calculates a hash value for the moniker and returns
S_OK
.
may return
E_INVALIDARG
if
pdwHash
is an invalid pointer.
IMoniker::IsRunning()
Returns
E_NOTIMPL
.
IMoniker::GetTimeOfLastChange()
Returns
MK_E_UNAVAILABLE
.
IMoniker::Inverse()
This method returns an anti-moniker (i.e., the results of calling
CreateAntiMoniker()
).
IMoniker::CommonPrefixWith()
If
pmkOther
IsEqual
to this
moniker, retrives a pointer to
this moniker and returns
MK_S_US
.
If
pmkOther
is a class moniker but is
not equal to this moniker, returns
MK_E_NOPREFIX
.
Otherwise
returns the result
of calling
MonikerCommonPrefixWith()
with itself as
pmkThis,
pmkOther
and
ppmkPrefix, which handles
the case whre
pmkOther
is a generic composite moniker.
IMoniker::RelativePathTo()
This method returns the result of calling This method returns the result
of calling
MonikerRelativePathTo()
with
pmkSrc
equal to this
moniker,
pmkOther,
ppmkRelPath,
and
TRUE
as
dwReserved.
IMoniker::GetDisplayName()
The display name for class monikers is of the form:
display-name = "CLSID:" string-clsid-no-curly-braces *[";" clsid-options] ":" clsid-options = clsid-param ``='' value clsid-param = none currently defined
clsid:a7b90590-36fd-11cf-857d-00aa006d2ea4:
IMoniker::ParseDisplayName()
This method parses the display name by binding to itself for
IParseDisplayName()
and asking the bound object to parse
the display name into a
moniker, as follows:
hr = BindToObject(pbc, pmkToLeft, IID_IParseDisplayName, (void**)&ppdn); if (SUCCEEDED(hr)) { hr = ppdn->ParseDisplayName(pbc, lpszDisplayName, pchEaten, ppmkOut); ppdn->Release(); } return hr;
The method tries to acquire an
IParseDisplayName()
pointer,
first by binding to the class factory for the object identified by the moniker,
and then by binding to the object itself.
If either of these binding operations
is successful, the file moniker passes the unparsed portion of the display
name
to the
IParseDisplayName::ParseDisplayName()
method.
This method returns
MK_E_SYNTAX
if
pmkToLeft
is non-NULL
.
IMoniker::IsSystemMoniker()
This method returns
S_OK
, and passes back
MKSYS_CLASSMONIKER
.
CreateClassMoniker()
,
IMoniker()
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.
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.
IMoniker::BindToObject()
When
pmkToLeft
is
NULL
, the
method looks for the moniker in the
ROT, and if found, queries the retrieved object for the requested interface
pointer.
If the moniker is not found in the ROT, the method loads the object
from the file system and retrieves the requested interface pointer.
If
pmkLeft
is not
NULL
, then
instead of determining the class to
instantiate and initialize with the contents of the file referred to by the
file moniker using
GetClassFile()
(or other means), call
pmkLeft
->BindToObject
for
IClassFactory()
and
IClassActivator()
, retrieve this pointer in
pcf.
If this fails with
E_NOINTERFACE
, return
MK_E_INTERMEDIATEINTERFACENOTSUPPORTED
.
If the
IClassFactory()
pointer is successfully retrieved,
call
pcf->CreateInstance
(IID_IPersistFile
,
(void**)
&ppf) to get
a fresh
instance of the class to be initialized and initialize it using
IPersistFile()
or other appropriate means per the existing
initialization
paths of File moniker.
IMoniker::BindToStorage()
This method opens the file specified by the path represented by the
moniker and returns an
IStorage()
pointer to that file.
The method
supports binding to
IStorage()
interface only; if
IStream()
or
ILockBytes()
is requested in
riid,
the method returns
E_UNSPEC, and if other interfaces are requested, this method returns
E_NOINTERFACE
.
IStream()
and
ILockBytes()
will be supported in future
releases.
Unless
pmkToLeft
is a class moniker,
pmkToLeft
should
be
NULL
, as in the implementation of
IMoniker::BindToObject()
.
For
situations where
pmkToLeft
is non-NULL
,
see the above description.
IMoniker::Reduce()
This method returns MK_S_REDUCED_TO_SELF and passes back the same moniker.
IMoniker::ComposeWith()
If
pmkRight
is an anti-moniker, the returned moniker
is
NULL
.
If
pmkRight
is a composite whose leftmost component is an
anti-moniker, the
returned moniker is the composite with the leftmost anti-moniker removed.
If
pmkRight
is a file moniker, this method collapses the
two monikers into
a single file moniker, if possible.
If not possible (e.g., if both file
monikers represent absolute paths, as in
d:\work
and
e:\reports),
then the returned moniker is
NULL
and the return value
is
MK_E_SYNTAX
.
If
pmkRight
is neither an anti-moniker nor a file moniker,
then the method
checks the
fOnlyIfNotGeneric
parameter; if it is
FALSE
, the method
combines the two monikers into a generic composite; if it is
TRUE
, the method
sets *ppmkComposite
to
NULL
and returns
MK_E_NEEDGENERIC
.
IMoniker::Enum()
This method returns
S_OK
and sets
ppenumMoniker
to
NULL
.
IMoniker::IsEqual()
This method returns
S_OK
if *pmkOther
is a file moniker and the
paths for both monikers are identical (using a case-insensitive comparison).
Otherwise, the method returns
S_FALSE
.
IMoniker::Hash()
This method calculates a hash value for the moniker.
IMoniker::IsRunning()
If
pmkNewlyRunning
is non-NULL
,
this method returns
TRUE
if that
moniker is equal to this moniker.
Otherwise, the method asks the ROT whether
this moniker is running.
The method ignores
pmkToLeft.
IMoniker::GetTimeOfLastChange()
If this moniker is in the ROT, this method returns the last change time
registered there; otherwise, it returns the last write time for the file.
If
the file cannot be found, this method returns
MK_E_NOOBJECT
.
IMoniker::Inverse()
This method returns an anti-moniker (i.e., the results of calling
CreateAntiMoniker()
).
IMoniker::CommonPrefixWith()
If both monikers are file monikers, this method returns a file moniker that is based on the common components at the beginning of two file monikers. Components of a file moniker can be:
A machine name of the form \\server\share. A machine name is treated as a single component, so two monikers representing the paths ``\\myserver\public\work'' and ``\\myserver\private\games'' do not have ``\\myserver'' as a common prefix.
A drive designation (for example, ``C:'').
A directory or file name.
If the other moniker is not a file moniker, this method passes both
monikers in a call to the
MonikerCommonPrefixWith()
function.
This
function correctly handles the case where the other moniker is a generic
composite.
This method returns
MK_E_NOPREFIX
if there is no
common prefix.
IMoniker::RelativePathTo()
This method computes a moniker which when composed to the right of this moniker yields the other moniker. For example, if the path of this moniker is ``C:\work\docs\report.doc'' and if the other moniker is ``C:\work\art\picture.bmp,'' then the path of the computed moniker would be ``..\..\art\picture.bmp.''
IMoniker::GetDisplayName()
This method returns the path that the moniker represents. If this method is called by a 16-bit application, the method checks to see whether the specified file exists and, if so, returns a short name for that file because 16-bit applications are not equipped to handle long file names.
IMoniker::ParseDisplayName()
This method tries to acquire an
IParseDisplayName()
pointer,
first by binding to the class factory for the object identified by the moniker,
and then by binding to the object itself.
If either of these binding operations
is successful, the file moniker passes the unparsed portion of the display
name
to the
IParseDisplayName::ParseDisplayName()
method.
This method returns
MK_E_SYNTAX
if
pmkToLeft
is non-NULL
.
IMoniker::IsSystemMoniker()
This method returns
S_OK
, and passes back
MKSYS_FILEMONIKER
.
CreateFileMoniker
,
IMoniker()
,
IPersistFile()
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.
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.
IMoniker::BindToObject()
If
pmkToLeft
is
NULL
, this method
looks for the moniker in the
ROT, and if found, queries the retrieved object for the requested interface
pointer.
If
pmkToLeft
is not
NULL
,
the method recursively calls
IMoniker::BindToObject()
on the rightmost component of
the
composite, passing the rest of the composite as the
pmkToLeft
parameter
for that call.
IMoniker::BindToStorage()
This method recursively calls
BindToStorage
on the
rightmost
component of the composite, passing the rest of the composite as the
pmkToLeft
parameter for that call.
IMoniker::Reduce()
This method recursively calls
Reduce
for each of
its component
monikers.
If any of the components reduces itself, the method returns
S_OK
and
passes back a composite of the reduced components.
If no reduction occurred,
the method passes back the same moniker and returns
MK_S_REDUCED_TO_SELF
.
IMoniker::ComposeWith()
If
fOnlyIfNotGeneric
is
TRUE
,
this method sets
*pmkComposite
to
NULL
and returns
MK_E_NEEDGENERIC
; otherwise, the
method returns the result of combining the two monikers by calling the
CreateGenericComposite()
function.
IMoniker::Enum()
If successful, this method returns
S_OK
and passes
back an enumerator
that enumerates the component monikers that make up the composite; otherwise,
the method returns
E_OUTOFMEMORY
.
IMoniker::IsEqual()
This method returns
S_OK
if the components of both
monikers are equal
when compared in the left-to-right order.
IMoniker::Hash()
This method calculates a hash value for the moniker.
IMoniker::IsRunning()
If
pmkToLeft
is non-NULL
, this
method composes
pmkToLeft
with this moniker and calls
IsRunning()
on the result.
If
pmkToLeft
is
NULL
, this method
returns
TRUE
if
pmkNewlyRunning
is non-NULL
and is equal to this moniker.
If
pmkToLeft
and
pmkNewlyRunning
are
both
NULL
, this method
checks the ROT to see whether the moniker is running.
If so, the method returns
S_OK
; otherwise, it recursively calls
IMoniker::IsRunning()
on the
rightmost component of the composite, passing the remainder of the composite
as
the
pmkToLeft
parameter for that call.
This handles the
case where the
moniker identifies a pseudo-object that is not registered as running; see
the
Item Moniker implementation of
IMoniker::IsRunning()
.
IMoniker::GetTimeOfLastChange()
This method creates a composite of
pmkToLeft
(if
non-NULL
) and
this moniker and uses the ROT to retrieve the time of last change.
If the
object is not in the ROT, the method recursively calls
IMoniker::GetTimeOfLastChange()
on the rightmost component
of the
composite, passing the remainder of the composite as the
pmkToLeft
parameter for that call.
IMoniker::Inverse()
This method returns a composite moniker that consists of the inverses of each of the components of the original composite, stored in reverse order. For example, if the inverse of A is A -1 , then the inverse of the composite A · B · C is C -1 · B -1 · A -1.
IMoniker::CommonPrefixWith()
If the other moniker is a composite, this method compares the components of each composite from left to right. The returned common prefix moniker might also be a composite moniker, depending on how many of the leftmost components were common to both monikers. If the other moniker is not a composite, the method simply compares it to the leftmost component of this moniker.
If the monikers are equal, the method returns
MK_S_US
and sets
ppmkPrefix
to this moniker.
If the other moniker is a
prefix of this
moniker, the method returns
MK_S_HIM
and sets
ppmkPrefix
to the other
moniker.
If this moniker is a prefix of the other, this method returns
MK_S_ME
and sets
ppmkPrefix
to this moniker.
If there is no common prefix, this method returns
MK_E_NOPREFIX
and sets
ppmkPrefix
to
NULL
.
IMoniker::RelativePathTo()
This method finds the common prefix of the two monikers and creates two monikers that consist of the remainder when the common prefix is removed. Then it creates the inverse for the remainder of this moniker and composes the remainder of the other moniker on the right of it.
IMoniker::GetDisplayName()
This method returns the concatenation of the display names returned by each component moniker of the composite.
IMoniker::ParseDisplayName()
This method recursively calls
IMoniker::ParseDisplayName()
on the rightmost component of the composite, passing everything else as the
pmkToLeft
parameter for that call.
IMoniker::IsSystemMoniker()
This method returns
S_OK
and indicates
MKSYS_GENERICCOMPOSITE
.
CreateGenericComposite()
,
IMoniker()
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.
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.
IMoniker::BindToObject()
If
pmkToLeft
is
NULL
, this method
returns
E_INVALIDARG
.
Otherwise, the method calls
IMoniker::BindToObject()
on
the
pmkToLeft
parameter, requesting an
IOleItemContainer()
interface
pointer.
The method then calls
IOleItemContainer::GetObject()
,
passing the
string contained within the moniker, and returns the requested interface
pointer.
IMoniker::BindToStorage()
If
pmkToLeft
is
NULL
, this method
returns
E_INVALIDARG
.
Otherwise, the method calls
IMoniker::BindToObject()
on
the
pmkToLeft
parameter, requesting an
IOleItemContainer()
interface
pointer.
The method then calls
IOleItemContainer::GetObjectStorage()
for
the requested interface.
IMoniker::Reduce()
This method returns
MK_S_REDUCED_TO_SELF
and passes
back the same
moniker.
IMoniker::ComposeWith()
If
pmkRight
is an anti-moniker, the returned moniker
is
NULL
; if
pmkRight
is a composite whose leftmost component is an
anti-moniker, the
returned moniker is the composite after the leftmost anti-moniker is removed.
If
pmkRight
is not an anti-moniker, the method combines
the two monikers
into a generic composite if
fOnlyIfNotGeneric
is
FALSE
; if
fOnlyIfNotGeneric
is
TRUE
, the method
returns a
NULL
moniker and a
return value of
MK_E_NEEDGENERIC
.
IMoniker::Enum()
This method returns
S_OK
and sets *ppenumMoniker
to
NULL
.
IMoniker::IsEqual()
This method returns
S_OK
if both monikers are item
monikers and their
display names are identical (using a case-insensitive comparison); otherwise,
the method returns
S_FALSE
.
IMoniker::Hash()
This method calculates a hash value for the moniker.
IMoniker::IsRunning()
If
pmkToLeft
is
NULL
, this method
returns
TRUE
if
pmkNewlyRunning
is non-NULL
and is
equal to this moniker.
Otherwise, the
method checks the ROT to see whether this moniker is running.
If
pmkToLeft
is non-NULL
, the
method calls
IMoniker::BindToObject()
on the
pmkToLeft
parameter,
requesting an
IOleItemContainer()
interface pointer.
The
method then calls
IOleItemContainer::IsRunning()
, passing the string contained
within this
moniker.
IMoniker::GetTimeOfLastChange()
If
pmkToLeft
is
NULL
, this method
returns
MK_E_NOTBINDABLE
.
Otherwise, the method creates a composite of
pmkToLeft
and this moniker
and uses the ROT to access the time of last change.
If the object is not in
the
ROT, the method calls
IMoniker::GetTimeOfLastChange()
on
the
pmkToLeft
parameter.
IMoniker::Inverse()
This method returns an anti-moniker (i.e., the results of calling
CreateAntiMoniker()
).
IMoniker::CommonPrefixWith()
If the other moniker is an item moniker that is equal to this moniker,
this method sets *ppmkPrefix
to this moniker and returns
MK_S_US
;
otherwise, the method calls the
MonikerCommonPrefixWith()
function.
This function correctly handles the case where the other moniker is a generic
composite.
IMoniker::RelativePathTo()
This method returns
MK_E_NOTBINDABLE
and sets *ppmkRelPath
to
NULL
.
IMoniker::GetDisplayName()
This method returns the concatenation of the delimiter and the item name that were specified when the item moniker was created.
IMoniker::ParseDisplayName()
If
pmkToLeft
is
NULL
, this method
returns
MK_E_SYNTAX
.
Otherwise,
the method calls
IMoniker::BindToObject()
on the
pmkToLeft
parameter, requesting an
IOleItemContainer()
interface
pointer.
The method
then calls
IOleItemContainer::GetObject()
, requesting an
IParseDisplayName()
interface pointer to the object identified
by
the moniker, and passes the display name to
IParseDisplayName::ParseDisplayName()
.
IMoniker::IsSystemMoniker()
This method returns
S_OK
and indicates
MKSYS_ITEMMONIKER
.
CreateItemMoniker()
,
IMoniker()
,
IOleItemContainer()
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.
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.
IMoniker::BindToObject()
This method queries the wrapped pointer for the requested interface.
IMoniker::BindToStorage()
This method queries the wrapped pointer for the requested interface.
IMoniker::Reduce()
This method returns
MK_S_REDUCED_TO_SELF
and passes
back the same
moniker.
IMoniker::ComposeWith()
If
pmkRight
is an anti-moniker, the returned moniker
is
NULL
; if
pmkRight
is a composite whose leftmost component is an
anti-moniker, the
returned moniker is the composite after the leftmost anti-moniker is removed.
If
fOnlyIfNotGeneric
is
FALSE
, the
returned moniker is a generic
composite of the two monikers; otherwise, the method sets *ppmkComposite
to
NULL
and returns
MK_E_NEEDGENERIC
.
IMoniker::Enum()
This method is not implemented (that is, it returns
E_NOTIMPL
).
IMoniker::IsEqual()
This method returns
S_OK
only if both are pointer
monikers and the
interface pointers that they wrap are identical.
IMoniker::Hash()
This method calculates a hash value for the moniker.
IMoniker::IsRunning()
This method always returns
S_OK
, because the object
identified by a
pointer moniker must always be running.
IMoniker::GetTimeOfLastChange()
This method is not implemented (that is, it returns
E_NOTIMPL
).
IMoniker::Inverse()
This method returns an anti-moniker (i.e., the results of calling
CreateAntiMoniker()
).
IMoniker::CommonPrefixWith()
If the two monikers are equal, this method returns
MK_S_US
and sets
*ppmkPrefix
to this moniker.
Otherwise, the method returns
MK_E_NOPREFIX
and sets *ppmkPrefix
to
NULL
.
IMoniker::RelativePathTo()
This method is not implemented (that is, it returns
E_NOTIMPL
).
IMoniker::GetDisplayName()
This method is not implemented (that is, it returns
E_NOTIMPL
).
IMoniker::ParseDisplayName()
This method queries the wrapped pointer for the
IParseDisplayName()
interface and passes the display name
to
IParseDisplayName::ParseDisplayName()
.
IMoniker::IsSystemMoniker()
This method returns
S_OK
and indicates
MKSYS_POINTERMONIKER
.
IMoniker()
,
CreatePointerMoniker()
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.
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.
Applications typically do not call
IOleItemContainer()
methods
directly.
The item moniker implementation of
IMoniker()
is the
primary caller of
IOleItemContainer()
methods.
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments the reference count. |
Release()
|
Decrements the reference count. |
IParseDisplayName
Method
|
Description
|
ParseDisplayName
|
Parses object's display name to form moniker. |
IOleContainer
Methods
|
Description
|
EnumObjects
|
Enumerates objects in a container. |
LockContainer
|
Keeps container running until explicitly released. |
|
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. |
CreateItemMoniker()
,
IMoniker - Item Moniker
Implementation
- Returns a pointer to the object identified by the specified name.
IOleItemContainer::GetObject()
HRESULT GetObject(
#include <oleidl.h>
LPOLESTR pszItem,
DWORD dwSpeedNeeded,
IBindCtx * pbc,
REFIID riid,
void ** ppvObject
);
The item moniker implementation of
IMoniker::BindToObject()
calls this method, passing the name stored within the item moniker as the
pszItem
parameter.
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.
[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.
[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.
[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()
.
[in] Reference to the identifier of the interface pointer requested.
[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
.
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.
IMoniker::BindToObject()
,
IBindCtx::GetBindOptions()
- Returns a pointer to the storage for the object identified by
the specified name.
IOleItemContainer::GetObjectStorage()
HRESULT GetObjectStorage(
#include <oleidl.h>
LPOLESTR pszItem,
IBindCtx * pbc,
REFIID riid,
void ** ppvStorage
);
The item moniker implementation of
IMoniker::BindToStorage()
calls this method.
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.
[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.
[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()
.
[in] Reference to the identifier of the interface to be used
to communicate
with the object, usually
IStorage()
.
[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
.
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.
IMoniker - Item Moniker Implementation
- Indicates whether the object identified by the specified name
is running.
IOleItemContainer::IsRunning()
HRESULT IsRunning((
#include <oleidl.h>
LPOLESTR pszItem
);
The item moniker implementation of
IMoniker::IsRunning()
calls this method.
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.
[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the container's name for the object.
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.
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.
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.
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.
IUnknown Methods
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments reference count. |
Release()
|
Decrements reference count. |
|
Description
|
ParseDisplayName
|
Parses the display name returning a moniker corresponding to it. |
IMoniker::ParseDisplayName()
,
IOleItemContainer()
,
MkParseDisplayName()
,
MkParseDisplayNameEx
- 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.
IParseDisplayName::ParseDisplayName()
HRESULT ParseDisplayName(
#include <oleidl.h>
IBindCtx * pbc,
LPOLESTR pszDisplayName,
ULONG * pchEaten,
IMoniker ** ppmkOut
);
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.
[in] Pointer to the bind context to be used in this binding operation.
[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.
[out Pointer to the number of characters in the display name that correspond to the ppmkOut moniker.
[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
.
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.
MkParseDisplayName()
,
MkParseDisplayNameEx
IMoniker::ParseDisplayName()
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.
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.
You typically do not need to use this interface. This interface is used by the system's implementation of the ROT.
IUnknown()
Methods
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments reference count. |
Release()
|
Decrements reference count. |
|
Description
|
GetComparisonData
|
Retrieve data to allow moniker to be compared with another. |
IMoniker()
,
IRunningObjectTable()
- Retrieves data from a moniker that can be used to test the moniker
for equality against another moniker.
IROTData::GetComparisonData()
HRESULT GetComparisonData(
#include <objidl.h>
PVOID * ppvData,
ULONG cbMax,
PULONG pcbData
);
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.
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.
[out] Indirect pointer to a buffer that receives the comparison data.
[in] Length of the buffer specified in ppvData.
[out] Pointer to the length of the comparison data.
This method supports the standard return value
E_OUTOFMEMORY
, as well as
the following:
S_OK
The comparison data was successfully returned.
IMoniker()
,
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.
You do not need to implement this interface. The system provides an implementation of the Running Object Table that is suitable for all situations.
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.
IUnknown Methods
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments reference count. |
Release()
|
Decrements reference count. |
|
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. |
IBindCtx::GetRunningObjectTable()
,
IROTData()
,
GetRunningObjectTable()
- 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).
IRunningObjectTable::EnumRunning()
HRESULT EnumRunning(
#include <objidl.h>
IEnumMoniker ** ppenumMoniker
);
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.
[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
.
This method supports the standard return value
E_OUTOFMEMORY
, as well as
the following:
S_OK
An enumerator was successfully returned.
- 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.
IRunningObjectTable::GetObject()
HRESULT GetObject(
#include <objidl.h>
IMoniker * pmkObjectName,
IUnknown ** ppunkObject
);
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.
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).
[in] Pointer to the moniker to search for in the Running Object Table.
[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
.
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).
- 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.
IRunningObjectTable::GetTimeOfLastChange()
HRESULT GetTimeOfLastChange(
#include <objidl.h>
IMoniker * pmkObjectName,
FILETIME * pfiletime
);
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()
.
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.
[in] Pointer to the
IMoniker()
interface
on the moniker
to search for in the ROT.
[out] Pointer to a
FILETIME
structure that
receives
the object's last change time.
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).
IMoniker::GetTimeOfLastChange()
,
IRunningObjectTable::NoteChangeTime()
- Determines whether the object identified by the specified moniker
is currently running.
This method looks for the moniker in the Running Object
Table (ROT).
IRunningObjectTable::IsRunning()
HRESULT IsRunning((
#include <objidl.h>
IMoniker * pmkObjectName
);
This method simply indicates whether a object is running.
To retrieve
a
pointer to a running object, use the
IRunningObjectTable::GetObject()
method.
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.
[in] Pointer to the
IMoniker()
interface
on the moniker
to search for in the Running Object Table.
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).
- 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.
IRunningObjectTable::NoteChangeTime()
HRESULT NoteChangeTime(
#include <objidl.h>
DWORD dwRegister,
FILETIME * pfiletime
);
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()
.
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.
[in] Value identifying the ROT entry of the changed object.
This value
was previously returned by
IRunningObjectTable::Register()
.
[in] Pointer to a
FILETIME
structure containing
the
object's last change time.
This method supports the standard return value
E_INVALIDARG
, as well as
the following:
S_OK
The change time was recorded successfully.
IRunningObjectTable::GetTimeOfLastChange()
,
IMoniker::GetTimeOfLastChange()
- Registers an object and its identifying moniker in the Running
Object Table (ROT).
IRunningObjectTable::Register()
HRESULT Register(
#include <objidl.h>
DWORD grfFlags,
IUnknown * punkObject,
IMoniker * pmkObjectName,
DWORD * pdwRegister
);
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()
.
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.
[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.
[in] Pointer to the object that is being registered as running.
[in] Pointer to the moniker that identifies punkObject.
[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.
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.
IMoniker::Reduce()
,
IRunningObjectTable::IsRunning()
,
IRunningObjectTable::Revoke()
- Removes from the Running Object Table (ROT) an entry that was
previously registered by a call to
IRunningObjectTable::Revoke()
IRunningObjectTable::Register()
.
HRESULT Revoke(
#include <objidl.h>
DWORD dwRegister
);
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.
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.
[in] Value identifying the ROT entry to revoke.
This value
was previously
returned by
IRunningObjectTable::Register()
.
This method supports the standard return value
E_INVALIDARG
, as well as
the following:
S_OK
The object's registration was successfully revoked.
IRunningObjectTable::Register()
- 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.
BindMoniker()
HRESULT BindMoniker((
#include <objbase.h>
LPMONIKER pmk,
DWORD grfOpt,
REFIID iidResult,
LPVOID FAR * ppvResult
);
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.
[in] Pointer to the object's moniker.
[in] Reserved for future use; must be zero.
[in] Interface identifier to be used to communicate with the object.
[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()
.
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.
CreateBindCtx()
,
IMoniker::BindToObject()
- Converts a string into a moniker that identifies the object named by the string.
This is the inverse of the
MkParseDisplayName()
IMoniker::GetDisplayName()
operation,
which retrieves the display name associated with a moniker.
WINOLEAPI MkParseDisplayName((
#include <objbase.h>
LPBC pbc,
LPCOLESTR szUserName,
ULONG FAR * pchEaten,
LPMONIKER FAR * ppmk
);
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:
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.
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.
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.
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.
[in] Pointer to the
IBindCtx()
interface
on the bind
context object to be used in this binding operation.
[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the display name to be parsed.
[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.
[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.
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()
.
IMoniker::ParseDisplayName()
,
IMoniker::GetDisplayName()
,
IParseDisplayName()
- Given a string, this function returns a moniker of the object that the string
denotes.
MkParseDisplayNameEx()
HRESULT MkParseDisplayNameEx(
#include <urlmon.h>
IBindCtx * pbc,
LPWSTR szDisplayName,
ULONG * pcchEaten,
IMoniker ** ppmk
);
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.
``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()
.
ROT Case:
All prefixes of
szDisplayName
that consist
solely of valid file name characters are consulted as file monikers in the
Running Object Table.
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.
``@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.
[in] Pointer to the bind context in which to accumulate bound objects.
[in] Display name to be parsed.
[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.
[out] Address of
IMoniker*
pointer variable
that
receives the interface pointer
to the resulting moniker.
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.
- 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
MonikerCommonPrefixWith()
IMoniker::CommonPrefixWith()
.
WINOLEAPI MonikerCommonPrefixWith((
#include <objbase.h>
LPMONIKER pmkThis,
LPMONIKER pmkOther,
LPMONIKER FAR * ppmkCommon
);
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.
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
.
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.
- 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
MonikerRelativePathTo()
IMoniker::RelativePathTo()
implementations.
WINOLEAPI MonikerRelativePathTo((
#include <objbase.h>
LPMONIKER pmkSrc,
LPMONIKER pmkDest,
LPMONIKER FAR * ppmkRelPath,
BOOL dwReserved
);
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.
[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.
[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.
[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
.
[in] Reserved; must be non-zero.
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.
- Creates and supplies a new anti-moniker.
CreateAntiMoniker()
WINOLEAPI CreateAntiMoniker((
#include <objbase.h>
LPMONIKER FAR * ppmk
);
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:
Call
IMoniker::Enum()
on the composite,
specifying
FALSE
as
the first parameter.
This creates an enumerator that returns the component
monikers in reverse order.
Use the enumerator to retrieve the last piece of the composite.
Call
IMoniker::Inverse()
on that moniker.
The moniker returned by
IMoniker::Inverse()
will remove the last piece of the
composite.
[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
.
This function supports the standard return value
E_OUTOFMEMORY
, as well
as the following:
S_OK
The anti-moniker has been created successfully.
IMoniker::Inverse()
,
IMoniker::ComposeWith
,
IMoniker - Anti-Moniker Implementation
,
ISequentialStream::Read
storage and stream access errors.
- Supplies a pointer to an implementation of
CreateBindCtx()
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.
WINOLEAPI CreateBindCtx((
#include <objbase.h>
DWORD reserved,
LPBC FAR * ppbc
);
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:
Get a pointer to a bind context by calling the
CreateBindCtx()
function.
Call the
IMoniker::BindToObject()
method
on the moniker,
retrieving an interface pointer to the object to which the moniker refers.
Release()
the bind context.
Use the interface pointer.
Release()
the interface pointer.
The following code fragment illustrates these steps:
// pMnk is anIMoniker()
* 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.
[in] Reserved for future use; must be zero.
[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.
This function supports the standard return value
E_OUTOFMEMORY
, as well
as the following:
S_OK
The bind context was allocated and initialized successfully.
BIND_OPTS
,
IBindCtx
,IMoniker
,
MkParseDisplayName
- Creates a file moniker based on the specified path.
CreateClassMoniker()
WINOLEAPI CreateClassMoniker((
#include <objbase.h>
REFCLSID rclsid,
IMoniker ** ppmk
);
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..
[in] Reference to the CLSID of the object type to which this moniker binds.
[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
.
S_OK
The moniker has been created successfully.
E_INVALIDARG
One or more arguments are invalid.
IMoniker - Class Moniker Implementation
- Creates a file moniker based on the specified path.
CreateFileMoniker()
WINOLEAPI CreateFileMoniker(
#include <objbase.h>
LPCOLESTR lpszPathName,
LPMONIKER FAR * ppmk
);
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.
[in] Pointer to a zero-terminated wide character string (two bytes per character) containing the path on which this moniker is based.
[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
.
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.
IMoniker - File Moniker Implementation
- Performs a generic composition of two monikers and supplies a
pointer to the resulting composite moniker.
CreateGenericComposite()
WINOLEAPI CreateGenericComposite((
#include <objbase.h>
LPMONIKER pmkFirst,
LPMONIKER pmkRest,
LPMONIKER FAR * ppmkComposite
);
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.
[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.
[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.
[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
.
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).
IMoniker::ComposeWith()
,
IMoniker - Generic
Composite Moniker
Implementation
- Creates an item moniker that identifies an object within a containing object
(typically a compound document).
CreateItemMoniker()
WINOLEAPI CreateItemMoniker((
#include <objbase.h>
LPCOLESTR lpszDelim,
LPCOLESTR lpszItem,
LPMONIKER FAR * ppmk
);
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.
[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.
[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()
.
[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.
This function supports the standard return value
E_OUTOFMEMORY
, as well
as the following:
S_OK
The moniker was created successfully.
IMoniker::ComposeWith()
,
IOleItemContainer
,
IMoniker()
- Item Moniker Implementation
- Creates a pointer moniker based on a pointer to an object.
CreatePointerMoniker()
WINOLEAPI CreatePointerMoniker((
#include <objbase.h>
LPUNKNOWN punk,
LPMONIKER FAR * ppmk
);
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.
[in] Pointer to an
IUnknown()
interface
on the object
to be identified by the resulting moniker.
[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.
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.
IMoniker - Pointer Moniker Implementation
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;
Size of this structure in bytes (that is, the size of the
BIND_OPTS
structure).
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.
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
.
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).
BIND_OPTS2
,
BIND_FLAGS
,
CreateBindCtx()
,
IBindCtx::SetBindOptions()
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;
Size of this structure in bytes (that is, the size of the
BIND_OPTS2
structure).
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.
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
.
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).
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
.
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()
.
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()
.
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.
BIND_OPTS
,
BIND_FLAGS
,
CreateBindCtx()
,
IBindCtx::SetBindOptions()
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;
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.
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;
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.
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;
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.
IMoniker::IsSystemMoniker()