MSDN Documentation

Shell Extensions

Shell extensions are COM objects that allow you to customize and extend the functionality of the Windows Shell. They enable you to add new features to the Windows Explorer, such as custom context menu items, property sheet pages, icons, and more. By implementing shell extensions, developers can deeply integrate their applications with the Windows user interface.

Types of Shell Extensions

The Windows Shell supports a variety of shell extension interfaces, each designed for a specific purpose:

Key Interfaces and Concepts

Developing shell extensions involves working with Component Object Model (COM) interfaces. Some of the fundamental COM interfaces you'll interact with include:

Registering Shell Extensions

Shell extensions are registered in the Windows Registry. The registration process typically involves:

  1. Creating a unique Class Identifier (CLSID) for your COM object.
  2. Registering the COM object under HKEY_CLASSES_ROOT\CLSID\ with its InprocServer32 key pointing to your DLL.
  3. Associating the shell extension with specific file types or shell objects by adding entries under the appropriate registry keys (e.g., HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\ for context menu extensions).

Example: Basic Context Menu Extension

Here's a simplified C++ code snippet demonstrating the structure of a context menu handler:


// Assume necessary headers and COM initialization are done.

class CMyContextMenu : public IContextMenu {
public:
    // IUnknown methods (QueryInterface, AddRef, Release)
    STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) {
        // ... implementation ...
        return E_NOINTERFACE;
    }
    STDMETHODIMP_(ULONG) AddRef() {
        // ... implementation ...
        return ++m_cRef;
    }
    STDMETHODIMP_(ULONG) Release() {
        // ... implementation ...
        return --m_cRef;
    }

    // IContextMenu methods
    STDMETHODIMP QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) {
        // Add your menu item here
        InsertMenu(hmenu, indexMenu, MF_STRING, idCmdFirst, L"My Custom Action");
        return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(idCmdLast - idCmdFirst + 1));
    }

    STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo) {
        // Handle the command invocation
        if (LOWORD(pCmdInfo- >wID) == 0) { // Check if it's your custom command ID
            // Perform your action here
            MessageBox(pCmdInfo- >hwnd, L"Custom action invoked!", L"Shell Extension", MB_OK);
        }
        return S_OK;
    }

    STDMETHODIMP GetCommandString(UINT_PTR idCmd, UINT uFlags, LPUINT pReserved, LPSTR pszName, UINT cchMax) {
        // ... implementation ...
        return E_NOTIMPL;
    }

private:
    ULONG m_cRef = 1;
};
            

Best Practices