# MkParseDisplayNameEx

Given a string, this function returns a moniker of the object that the string denotes.

HRESULT MkParseDisplayNameEx(

IBindCtx*pbc, | //Pointer to the bind context
LPWSTR szDisplayName, | //Display name to be parsed
ULONG *pcchEaten, | //Pointer to the number of characters of the display name successfully parsed
IMoniker **ppmk | //Indirect pointer to a moniker
); |

Parameters

pbc
  [in] Pointer to the bind context in which to accumulate bound objects.
szDisplayName
  [in] Display name to be parsed.
pcchEaten
  [out] Pointer to the number of characters of the display name that were successfully parsed. Most useful on syntax error, when a non-zero value is often returned and therefore a subsequent call to MkParseDisplayNameEx with the same pbc and a shortened szDisplayName should return a valid moniker.
ppmk
  [out] Indirect pointer to the resulting moniker.

Return Values

S_OK
  The operation was successful.
MK_E_SYNTAX
  Parsing failed because szDisplayName could only be partially resolved into a moniker. In this case, *pcchEaten has the number of characters that were successfully parsed into a moniker prefix.
E_OUTOFMEMORY
  The operation ran out of memory.

Remarks

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

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

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

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

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

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

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

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

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

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

\ / : ! [

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

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

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

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

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

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

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

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

See Also

IParseDisplayName