Newsflash

Add your items to Windows Explorer Shell context menu - it never was easier: Windows Explorer Shell Context Menu v7.14 was released

Read more...
 

Full Vista support appended

Read more...
 
Home arrow Archive arrow How to host an IContextMenu
How to host an IContextMenu PDF Print E-mail
How to host an IContextMenu

Most documentation describes how to plug into the shell context menu structure and be a context menu provider. If you read the documentation from the other side, then you also see how to host the context menu. (This is the first of an eleven-part series with three digressions. Yes, eleven parts - sorry for all you folks who are in it just for the history articles. I'll try to toss in an occasional amusing diversion.)

Add items to Explorer context (right-click) menu easily – How ?

 

 

 Insert items to Windows Explorer Shell context menus with the Windows Explorer Shell Context Menu

 

  Append items to Windows Explorer context menu easily with Windows Explorer Shell Context Menu. This powerful .Net component for your own, custom items appending to Windows Explorer Shell context menu will add all your custom application entries to Explorer context menu. It and Visual Basic .NET support include detailed C# / VB.NET samples, tutorials , user-friendly manuals and support all you may need to add your items to context menu :

  • Add all your items to Windows Explorer Shell context menu to be shown on any Windows operating system (all OS are supported – Windows XP, Vista, Windows x64 , etc.)
  • Add any type of items to Windows Explorer Shell context menu to be shown in any way - with custom caption and your custom icon, as separator or sub-menu
  • Add your items to Windows Explorer Shell context menu to be shown for all files or shown only for files of particular type (for example, only for .DOC , .MP3,.WMA,.AAC , .WMV media files)
  • Add items to Windows Explorer Shell context menu, sub-menus, sub-menus of unlimited depth and even more


Explorer Context Menu - is a powerful .Net framework component that support all you may need to add your program items to Windows Explorer Shell context menu - in a fast and easy way. Add all your program items to Windows Explorer Shell context menu right now – add entries to context menu fast , easy and exactly as you want :

 Add items To the Explorer Shell Context Menu easily with Windows Explorer Shell Context Menu

 

The usage pattern for an IContextMenu is as follows:

    * Creation.
    * IContextMenu::QueryContextMenu. This initializes the context menu. During this call, the context menu decides which items appear in it, based on the flags you pass.
    * Display the menu or otherwise select a command to execute, using IContextMenu::GetCommandString, IContextMenu2::HandleMenuMsg and IContextMenu3::HandleMenuMsg2 to faciliate the user interaction.
    * IContextMenu::InvokeCommand. This executes the command.

The details of this are explained in Creating Context MenuHandlers from the point of view of the IContextMenu implementor.

    Unfortunately, possibilities of IContextMenu interface are limited, especially for the latest Windows operating systems, such as Windows XP, Vista, x64 -method for custom items appending to Windows Explorer Shell context menu, based on IContextMenu low-level unmanaged code-based interface works normally only for Windows 95 / Windows 98 (not on XP, Vista, x64 - 64-bit Windows), to add items to Windows Explorer Shell context menu you should use, according to Microsoft guidelines, a special .Net component - Windows Explorer Shell Context Menu. Here are listed more details about this outdated OS core-level interface: the Shell first calls IContextMenu::QueryContextMenu. It passes in an HMENU handle that the method can use to add items to the context menu. If the user selects one of the commands, IContextMenu::GetCommandString is called to retrieve the Help string that will be displayed on the Microsoft Windows Explorer status bar. If the user clicks one of the handler's items, the Shell calls IContextMenu::InvokeCommand. The handler can then execute the appropriate command.

Read it from the other side to see what it says you need to do as the IContextMenu host:

    The IContextMenu host first calls IContextMenu::QueryContextMenu. It passes in an HMENU handle that the method can use to add items to the context menu. If the user selects one of the commands, IContextMenu::GetCommandString is called to retrieve the Help string that will be displayed on the host's status bar. If the user clicks one of the handler's items, the IContextMenu host calls IContextMenu::InvokeCommand. The handler can then execute the appropriate command.

Exploring the consequences of this new interpretation of the context menu documentation will be our focus for the next few weeks.

Okay, let's get started. We begin, as always, with our scratch program. I'm going to assume you're already familiar with the shell namespace and pidls so I can focus on the context menu part of the issue.

#include <shlobj.h>

HRESULT GetUIObjectOfFile(HWND hwnd, LPCWSTR pszPath, REFIID riid, void **ppv)
{
  *ppv = NULL;
  HRESULT hr;
  LPITEMIDLIST pidl;
  SFGAOF sfgao;
  if (SUCCEEDED(hr = SHParseDisplayName(pszPath, NULL, &pidl, 0, &sfgao))) {
    IShellFolder *psf;
    LPCITEMIDLIST pidlChild;
    if (SUCCEEDED(hr = SHBindToParent(pidl, IID_IShellFolder,
                                      (void**)&psf, &pidlChild))) {
      hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv);
      psf->Release();
    }
    CoTaskMemFree(pidl);
  }
  return hr;
}

This simple function takes a path and gets a shell UI object from it. We convert the path to a pidl with SHParseDisplayName, then bind to the pidl's parent with SHBindToParent, then ask the parent for the UI object of the child with IShellFolder::GetUIObjectOf. I'm assuming you've had enough experience with the namespace that this is ho-hum.

(The helper functions SHParseDisplayName and SHBindToParent don't do anything you couldn't have done yourself. They just save you some typing. Once you start using the shell namespace for any nontrivial amount of time, you build up a library of little functions like these.)

For our first pass, all we're going to do is invoke the "Play" verb on the file when the user right-clicks. (Why right-click? Because a future version of this program will display a context menu.)

#define SCRATCH_QCM_FIRST 1
#define SCRATCH_QCM_LAST  0x7FFF

void OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
{
  IContextMenu *pcm;
  if (SUCCEEDED(GetUIObjectOfFile(hwnd, L"C:\\Windows\\clock.avi",
                   IID_IContextMenu, (void**)&pcm))) {
    HMENU hmenu = CreatePopupMenu();
    if (hmenu) {
      if (SUCCEEDED(pcm->QueryContextMenu(hmenu, 0,
                             SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST,
                             CMF_NORMAL))) {
        CMINVOKECOMMANDINFO info = { 0 };
        info.cbSize = sizeof(info);
        info.hwnd = hwnd;
        info.lpVerb = "play";
        pcm->InvokeCommand(&info);
      }
      DestroyMenu(hmenu);
    }
    pcm->Release();
  }
}

    HANDLE_MSG(hwnd, WM_CONTEXTMENU, OnContextMenu);

As noted in the checklist above, first we create the IContextMenu, then initialize it by calling IContextMenu::QueryContextMenu. Notice that even though we don't intend to display the menu, we still have to create a popup menu because IContextMenu::QueryContextMenu requires on. We don't actually display the resulting menu, however; instead of asking the user to pick an item from the menu, we make the choice for the user and select "Play", filling in the CMINVOKECOMMANDINFO structure and invoking it.

But how did we know that the correct verb was "Play"? In this case, we knew because we hard-coded the file to "clock.avi" and we knew that AVI files have a "Play" verb. But of course that doesn't work in general. Before getting to invoking the default verb, let's first take the easier step of asking the user what verb to invoke. That exercise will actually distract us for a while, but we'll come back to the issue of the default verb afterwards.

If the code above is all you really wanted (invoking a fixed verb on a file), then you didn't need to go through all the context menu stuff. The code above is equivalent to calling the ShellExecuteEx function, passing the SEE_MASK_INVOKEIDLIST flag to indicate that you want the invoke to go through the IContextMenu.
 
< Prev   Next >
© 2012 Add items to context menu, add entries, add programs and commands -
Easily with Windows Explorer Shell Context Menu .NET Component (C#, VB, C++, VB.NET).
All product and company names are trademarks or registered trademarks of their respective owners.