简体   繁体   中英

How to show Windows Explorer context (right click) menu?

I want to show the Windows Explorer context menu.

I don't want to add my application to it, I just want to display it inside my application.

A good example of the implementation that I need is Total Commander.

If you press and hold right mouse button, TC will show the context menu, which is exactly the same as in Windows explorer.

I'm using C++/Qt, but language is not important here.

I found several samples that may help you. You're not likely to be able to do this with Qt alone, since the shell context menu is highly OS-specific; probably some Win32 calls will be needed also.

A Raymond Chen blog series "How to host an IContextMenu"

And some non-C++ samples also:

And related SO questions:

You have two options:

1) Implement each functionality on your own, creating the corresponing actions on a custom context menu, or

2) Access the Windows API... and this is just what Qt is not intended to considering that Qt is cross-platform.

Here's how I do it:

bool CShellMenu::openShellContextMenuForObject(const std::wstring &path, int xPos, int yPos, void * parentWindow)
{
    assert (parentWindow);
    ITEMIDLIST * id = 0;
    std::wstring windowsPath = path;
    std::replace(windowsPath.begin(), windowsPath.end(), '/', '\\');
    HRESULT result = SHParseDisplayName(windowsPath.c_str(), 0, &id, 0, 0);
    if (!SUCCEEDED(result) || !id)
        return false;
    CItemIdListReleaser idReleaser (id);

    IShellFolder * ifolder = 0;

    LPCITEMIDLIST idChild = 0;
    result = SHBindToParent(id, IID_IShellFolder, (void**)&ifolder, &idChild);
    if (!SUCCEEDED(result) || !ifolder)
        return false;
    CComInterfaceReleaser ifolderReleaser (ifolder);

    IContextMenu * imenu = 0;
    result = ifolder->GetUIObjectOf((HWND)parentWindow, 1, (const ITEMIDLIST **)&idChild, IID_IContextMenu, 0, (void**)&imenu);
    if (!SUCCEEDED(result) || !ifolder)
        return false;
    CComInterfaceReleaser menuReleaser(imenu);

    HMENU hMenu = CreatePopupMenu();
    if (!hMenu)
        return false;
    if (SUCCEEDED(imenu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_NORMAL)))
    {
        int iCmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, xPos, yPos, (HWND)parentWindow, NULL);
        if (iCmd > 0)
        {
            CMINVOKECOMMANDINFOEX info = { 0 };
            info.cbSize = sizeof(info);
            info.fMask = CMIC_MASK_UNICODE;
            info.hwnd = (HWND)parentWindow;
            info.lpVerb  = MAKEINTRESOURCEA(iCmd - 1);
            info.lpVerbW = MAKEINTRESOURCEW(iCmd - 1);
            info.nShow = SW_SHOWNORMAL;
            imenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
        }
    }
    DestroyMenu(hMenu);

    return true;
}

http://www.ffuts.org/blog/right-click-context-menus-with-qt/

Getting right-clicks to popup a context menu is pretty straightforward in Qt. There are just a couple of things to watch out for…

 // myWidget is any QWidget-derived class
 myWidget->setContextMenuPolicy(Qt::CustomContextMenu);
 connect(myWidget, SIGNAL(customContextMenuRequested(const QPoint&)),
     this, SLOT(ShowContextMenu(const QPoint&)));

If, on the other hand, you're looking for something like "Windows explorer integration" or "Windows Shell integration", here's a good (albeit non-QT specific) example:

http://www.codeproject.com/Articles/15171/Simple-shell-context-menu

The key is implementing these two Windows shell interfaces:

  • IContextMenu

  • IShellExtInt

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM