The IAssociationElement methods of an association element all query the element about an association setting. The IAssociationArray methods of a QueryAssociations object do the same but for an ordered list of elements. In both interfaces, each method has as its first argument a value from the ASSOCQUERY enumeration. This value describes the setting that is sought. For some ASSOCQUERY values, the description must be completed by a string which is given as the method’s second argument. For consistency with Microsoft’s documentation of the IQueryAssociations methods, this second argument is here called pszExtra.

Every association element has a query source, which is in general a registry key. Most ASSOCQUERY values map simply to a value on some relative path (subkey) with respect to the key that acts as the element’s query source. The result of such a query is the data from the value. The path may be absent, to indicate that the value is in the key represented by the query source itself rather than in any subkey. The value may be absent to stand for the default value of whatever key is represented by the path.

Formatting Bits

The ASSOCQUERY values have some interpretation in bit fields, to specify general behaviour, the nature of the pszExtra argument, and the formatting of any data produced by the query:

Bit Flag Interpretation
0x00010000 responds to QueryString method
0x00020000 responds to QueryExists method
0x00040000 responds to QueryDirect method
0x00080000 responds to QueryDword method
0x00100000 obtains resource string when data from QueryString is indirect string
0x00200000 responds to QueryObject method
0x00400000 responds to QueryGuid method
0x01000000 expects pszExtra for path or value
0x02000000 expects pszExtra for verb
0x04000000 significance unknown
0x80000000 fall-back to secondary query source

The meaning of bits for responsiveness to various methods is more complicated than suggested by the brief descriptions above. As actually implemented, most queries cannot respond successfully to QueryString, QueryDword, QueryGuid or QueryExists unless the bit for responding to QueryDirect is also set.

By indirect string is here meant the standard form supported by the SHLWAPI function SHLoadIndirectString for naming a string resource in an executable. Briefly, the form is an @ sign, a pathname for the executable, a comma, a minus sign and a resource number. If the 0x00100000 bit is set for the query and the string data for the queried association is an indirect string, then the data produced by the QueryString method is the string resource, not the indirect string. SHELL32 is presently limited to 1024 characters for loading the string resource.

Queries for Arbitrary Values

All association elements, of whatever type, can be queried for any value in the element’s query source. The pszExtra argument to the method names the value.

Query Path Value Remarks
0x010F0000   extra  
extra   if failed with extra as value, but extra is DocObject or BrowseInPlace
0x01170001   extra obtains resource string when data from QueryString is indirect string

The only bit field that matters in the numerical values for these queries is 0x00100000. Both queries therefore respond to all of QueryString, QueryDword, QueryGuid, QueryExists and QueryDirect.

Note that the 0x010F0000 query allows that two particular values may instead be present as subkeys. In these cases, the data is from the default value of the subkey. It is not enough that DocObject or BrowseInPlace exists as a subkey: it must have a default value.

Shell Queries

Most shell elements can be queried for all the following. All respond to QueryString, QueryExists and QueryDirect.

Query Path Value Remarks
0x00170000   FriendlyTypeName obtains resource string when data from QueryString is indirect string
0x00070001 DefaultIcon    
0x81470002 ShellEx\extra   also responds to QueryGuid
0x00470003 Clsid   also responds to QueryGuid
0x00070004 Progid    

Some types of shell element are more particular.


Shell Verb Queries

All shell elements recognise the following queries in which the pszExtra argument supplies a verb. All these queries respond to QueryString, QueryExists and QueryDirect except where otherwise noted.

Query Path Value Remarks
0x02070000 shell\verb\command    
0x02070001 shell\verb\ddeexec    
0x02070002 shell\verb\ddeexec\ifexec    
0x02070003 shell\verb\ddeexec\application   has fall back for QueryString (see notes after table)
0x02070004 shell\verb\ddeexec\topic   has fall back for QueryString (see notes after table)
0x02060005 shell\verb\ddeexec NoActivateHandler responds to QueryExists and QueryDirect only
0x02060006 shell\verb\command command responds to QueryExists and QueryDirect only
0x02010007     responds to QueryString only;
obtains pathname of executable (see notes after table)
0x02170008 shell\verb FriendlyAppName translates when data from QueryString is indirect string;
has fallback for QueryString (see notes after table)
0x02070009 shell\verb\ddeexec WindowClassName  
0x0207000A shell\verb\ddeexec WindowName  
0x0207000B     responds to QueryString only;
obtains verb
0x0247000C shell\verb\DropTarget Clsid also responds to QueryGuid
0x0247000D shell\verb\command DelegateExecute also responds to QueryGuid
0x0220000E     responds to QueryObject only;
creates verb delegate (see notes after table)
0x0220000F     responds to QueryObject only;
creates application delegate (see notes after table)
0x02200010     responds to QueryObject only;
creates execution association (see notes after table)
0x02020011 shell\verb Elevate responds only to QueryExists;
actually checks for whether verb is “runas” (see notes after table)
0x02070012 shell\verb\command IsolatedCommand has fallback for QueryString (see notes after table)
0x02070013 shell\verb icon  

In general, query 0x02010007 extracts an executable’s pathname from the result of query 0x02070000 (meaning typically the default value of the command subkey). However, if the verb is “runas”, the data obtained is the whole of the default value. The latter behaviour is plausibly a coding error (a missing break in a switch), but may be deliberate.

When query 0x0207000B is directed at a shell element, it has some small merit in testing whether the given verb is well-defined for the element, i.e., that its query source has a usable shell\verb subkey. The query is arguably more useful when directed at a verb delegate, to discover which verb was specified when creating the verb delegate.

Query 0x0220000E creates a shell verb element, called the verb delegate, from the queried element and the given verb. The query source for the verb delegate is the shell\verb subkey. All the other shell verb queries can be put to this verb delegate, with the shell\verb part of the path taken as granted. When multiple shell verb queries for the same verb are to be put to the one shell element, it is much more efficient to create a verb delegate and put the queries to the verb delegate rather than the orginal element.

Query 0x0220000F creates an application element, called the application delegate, from the queried element and the given verb. The initialisation string for this application element is the result of query 0x02010007, i.e., is the executable’s pathname as extracted from the default value of the shell\verb\command subkey.

Query 0x02200010 creates an ExecuteAssociation object. Details are presently beyond the scope of this work.

Although tables map query 0x02020011 to the Elevate value in the query source, the query never actually can check this value. This is perhaps a coding error which may eventually be corrected. Without the 0x00400000 bit set, query 0x02020011 is always failed (returning E_INVALIDARG) by the code for interpreting the bits that determine responsiveness to the IAssociationElement methods. One case is allowed for correcting this result: if the verb is “runas”, then QueryExists succeeds independently of whether an Elevate value exists.

For several queries, the QueryString method has a fall back if string data cannot be obtained from the designated registry value:

Query Fall Back
0x02070003 extract executable’s filename, i.e., with no path or extension, from the result of query 0x02010007
0x02070004 answer with the hard-coded string System
0x02170008 answer from the application delegate unless the queried element is already an application element
0x02070012 if the verb is “runas”, redo as query 0x02070000

Documented Equivalents

In ordinary practice, association elements are accessed through a QueryAssociations object, also called an association array. Such objects can be created, initialised and queried using documented functions and methods. Many, but nowhere near all, lower-level queries with an ASSOCQUERY value can be put to an association array as one or another case of an IQueryAssociations method:

Query IQueryAssociations Method Case
0x010F0000 GetData ASSOCDATA_VALUE
0x010F0000 specialised for EditFlags value GetData ASSOCDATA_EDITFLAGS
0x01170001 specialised for NoOpen value GetString ASSOCSTR_NOOPEN
0x01170001 specialised for InfoTip value GetString ASSOCSTR_INFOTIP
0x01170001 specialised for QuickTip value GetString ASSOCSTR_QUICKTIP
0x01170001 specialised for TileInfo value GetString ASSOCSTR_TILEINFO
0x02070000 GetString ASSOCSTR_COMMAND
0x02070001 GetString ASSOCSTR_DDECOMMAND
0x02070002 GetString ASSOCSTR_DDEIFEXEC
0x02070004 GetString ASSOCSTR_DDETOPIC
0x02010007 GetString ASSOCSTR_EXECUTABLE
0x0220000F GetKey ASSOCKEY_APP

For query 0x0220000F, which obtains an interface to an object, the corresponding case with the GetKey method is not truly equivalent but merely obtains the registry key that the object uses as its query source.