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

后端 未结 4 901
无人及你
无人及你 2020-12-10 08:50

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.

相关标签:
4条回答
  • 2020-12-10 09:25

    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;
    }
    
    0 讨论(0)
  • 2020-12-10 09:33

    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.

    • Use Shell ContextMenu in your applications
    • Explorer Shell Context Menu

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

    And some non-C++ samples also:

    • C# File Browser
    • Shell context menu sample in C#

    And related SO questions:

    • How to access Windows shell context menu items?
    • How to obtain full shell context menu of right-click a folder background
    0 讨论(0)
  • 2020-12-10 09:35

    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.

    0 讨论(0)
  • 2020-12-10 09:36

    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

    0 讨论(0)
提交回复
热议问题