MkParseDisplayName

HRESULT MkParseDisplayName(pbc, lpszDisplayName, pcchEaten, ppmk)

Recall from IMoniker::GetDisplayName that most monikers have a textual name which is meaningful to the user. The function MkParseDisplayName does the logical inverse operation: given a string, it returns a moniker of 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, than 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.

Argument

Type

Description

pbc

IBindCtx*

The binding context in which to accumulate bound objects.

lpszDisplayName

LPSTR

The display name to be parsed.

pcchEaten

ULONG*

On exit the number of characters of the display name that was successfully parsed. Most useful on syntax error.

ppmk

IMoniker*

The resulting moniker.

return value

HRESULT

S_OK, MK_E_SYNTAX.


Parsing a display name may in some cases be as expensive as binding to the object that it denotes, since along the way various non-trivial name space managers (such as a spreadsheet application that can parse into ranges in its sheets) need to be connected to by the parsing mechanism to succeed. As might be expected, objects are not released by the parsing operation itself, but are instead handed over to the passed-in binding context (via IBindCtx::RegisterObjectBound). Thus, if the moniker resulting from the parse is immediately bound using this same binding 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 naïve URL moniker which parsed from any valid URL strings (such as, "http: . . . ", "file: . . . ", and so forth) and only during binding took time to resolve against the Internet server, a potentially expensive operation.

An important use of MkParseDisplayName worth noting lies in textual programming languages which permit remote references as syntactic elements. The expression language of a spreadsheet is a good example of such a language.

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 lpszDisplayName has been parsed into a moniker, and a suffix of the display name remains not understood. This is illustrated in Figure 4

Figure 4. Intermediate stage in parsing a display name into a moniker.

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-so-far, 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, and so they can carry out the processes completely within IMoniker::ParseDisplayName. The common case, however, is that the moniker-so-far 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 MkParseDisplayName 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 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-so-far. MkParseDisplayName 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. 1. All prefixes of lpszDisplayName that consist solely of valid file name characters are consulted as file monikers in the Running Object Table.
  2. 2. The file system is consulted to check if a prefix of lpszDisplayName 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.
  3. 3. If the initial character of lpszDisplayName is '@', then the maximal string immediately following the '@' which conforms to the legal ProgID syntax6. 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.