How can I register my context menu command for all file types *except* one, or other complex conditionals?


We saw that you can register your context menu under * to make it apply to all files. But what if you want it to apply to all files except one? For example, your command might be "Convert to Widget" but you don't want it to appear for .widget files because that would be redundant.

I mentioned how to do this as an afterthought in an earlier discussion of advanced context menu registration, but I'm going to elevate to its own topic because it's probably even more useful than the base article!

Starting in Windows 7, you can conditionalize your context menu declaratively. This is explained in the documentation for context menus in the section Getting Dynamic Behavior for Static Verbs by Using Advanced Query Syntax. Let's try it out. Of course, I don't actually have a "Widgetizer" program, so I'll just use Calc.

[HKEY_CLASSES_ROOT\*\shell\Widgetize]
"AppliesTo"="NOT System.FileExtension:=.widget"

[HKEY_CLASSES_ROOT\*\shell\Widgetize\Command]
@="calc.exe"

The Widgetize command appears only for files whose extension is not .widget.

You have access to the shell property system and Advanced Query Syntax here, so you can create more complex conditionals. Here's how you can Widgetize only files that are smaller than 32KB, and ignore zero-byte files.

"AppliesTo"="System.Size:1..32kb AND NOT System.FileExtension:=.widget"
Comments (12)
  1. Anonymous says:

    I'm waiting eagerly for the next installment where Raymond describes the Orvanced Query Syntax. :-)

    [Nice one. Fixed. (For those who missed it: I misspelled Advanced as Andvanced in one location.) -Raymond]
  2. IMHO, the last example is a really bad idea. I know it's just an example, but in my experience designing user interfaces, arbitrarily enabling/disabling items (or, even worse, hiding them) based in complex rules makes users unsure and customer support staff crazy. If the rules are complex (i.e., not a simple "the file is not a widget"), it's better to let the item enabled, and when it's selected, show an alert telling the user why s/he can't use the command.

  3. Anonymous says:

    @Antonio Rodríguez 'Grijan', that would be even worse. I'd be confused by the huge amount of options and unsure if clicking any of them would work or punish me with an informative message box or an insidious beep. Then, I'd still be confused about the number of options and afraid to click any, resiliently giving up on using those pesky and useless context menus.

  4. Anonymous says:

    Ha. The only reason I could have come up with for this was config.sys and for that we're now almost 20 years too late.

  5. GregM says:

    Very nice Erik.  I noticed the misspelling, but didn't come up with anything witty in response.  When I saw your response, it took me a few seconds to figure out what you meant by Orvanced, as I didn't read the original typo as "And"-vanced, just as Advanced with an extra n.  :)

  6. xpclient says:

    Wow cool! Purely enhanced shell functionality. :)

    How do you add a context menu item for Windows 7's Control Panel items which are not hosted by Explorer.exe? Say "Pin to something" for Keyboard Control Panel?

  7. Anonymous says:

    Nice one! First time I've ever seen a good use for Advanced Query Syntax, for I sure don't use it for searching. (Good search programs supporting regex FTW.)

  8. Anonymous says:

    I didn't know you could search like that, very nice. Now, if I put "System.Size:1..32kb AND NOT System.FileExtension:=.widget" into the Windows 7 Explorer search bar, it returns files of size 132kb. Is this due to some localization settings affecting the parsing?

  9. Anonymous says:

    Pity there's no documented API to actually run those tests programmatically (as in, given an IShellItem, how can I tell if it matches a given AQS query).

  10. Anonymous says:

    @Drafi: It's due to the display roundoff.

    Filler text to get past spam filter. Short comment is short.

  11. Anonymous says:

    @Antonio Rodríguez 'Grijan'

    But in UI design, isn't this standard practice? Especially if you have an application that performs different kinds of actions on different kinds of files? Another example: You display different kinds of multimedia files, and alter the visibility of commands based on selection. View image files/play video files/convert video files and so on.

    It would be a huge confusing mess if all commands were enabled all the time for all types, regardless of their applicability.

    This is what I get for being in South Africa… my comment is so long after the one I'm replying to, I doubt it will ever be read by the intended commenter.

  12. @Jerome, @John Doe: Of course, for commands that apply only to a *simple* and *reduced* set (for example, JPEG images), it's better to just show it when needed. I was talking about *complex* or *confusing* rules, like showing the command for all files but not for Word documents, or files with a extension longer than three characters. These complex rules, in practice, aren't used very often. So if they will apply most of the time, they will add to the clutter anyway. You don't lose much showing the command in the few cases where they don't apply, and you can gain a lot in usability and cut in product support costs.

    The idea isn't mine, and isn't new. That's why many applications disable menu commands when not applicable instead of hiding them. It traces back to the first volume of Inside Macintosh, where Apple explains the best practices of the then revolutionary Macintosh user interface, and the reasons behind them. It was published in 1984, but is generic enough that it can be applied today – you will be surprised how much of that is still in use after 30 years!

Comments are closed.