Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何显示Windows资源管理器上下文(右键单击)菜单?_C++_Windows_Windows Explorer - Fatal编程技术网

C++ 如何显示Windows资源管理器上下文(右键单击)菜单?

C++ 如何显示Windows资源管理器上下文(右键单击)菜单?,c++,windows,windows-explorer,C++,Windows,Windows Explorer,我想显示Windows资源管理器上下文菜单 我不想将我的应用程序添加到其中,我只想在我的应用程序中显示它。 我需要的一个很好的实现示例是Total Commander 如果按住鼠标右键,TC将显示与Windows资源管理器中完全相同的上下文菜单 我使用的是C++/Qt,但语言在这里并不重要。 用鼠标右键点击弹出上下文菜单非常简单 在Qt。有几件事需要注意 另一方面,如果您正在寻找类似“Windows资源管理器集成”或“Windows Shell集成”的东西,那么下面是一个很好的(尽管不是特定于Q

我想显示Windows资源管理器上下文菜单

我不想将我的应用程序添加到其中,我只想在我的应用程序中显示它。

我需要的一个很好的实现示例是Total Commander

如果按住鼠标右键,TC将显示与Windows资源管理器中完全相同的上下文菜单

我使用的是C++/Qt,但语言在这里并不重要。

用鼠标右键点击弹出上下文菜单非常简单 在Qt。有几件事需要注意

另一方面,如果您正在寻找类似“Windows资源管理器集成”或“Windows Shell集成”的东西,那么下面是一个很好的(尽管不是特定于QT的)示例:

关键在于实现这两个Windows shell界面:

  • IContextMenu

  • IShellExtInt


我找到了一些可能对您有所帮助的样品。单独使用Qt不太可能做到这一点,因为shell上下文菜单是高度特定于操作系统的;可能还需要一些Win32调用

还有一些非C++示例:

及相关问题:

您有两种选择:

1) 自行实现每个功能,在自定义上下文菜单上创建相应的操作,或

2) 访问Windows API。。。考虑到Qt是跨平台的,这正是Qt不打算做的。

我是这样做的:

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;
}

感谢您的回复,但我知道如何显示上下文菜单:)您所指的文章解释了如何将项目添加到资源管理器上下文菜单。同样,我只需要显示它(默认项是Open、Print、Edit、Open with…etc2),这也是有人发明ifdef的原因之一。)
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;
}