【问题标题】:How to show Windows Explorer context (right click) menu?如何显示 Windows 资源管理器上下文(右键单击)菜单?
【发布时间】:2012-05-19 19:57:52
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: c++ windows windows-explorer


    【解决方案1】:

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

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

    还有一些非 C++ 示例:

    以及相关的 SO 问题:

    【讨论】:

      【解决方案2】:

      你有两个选择:

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

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

      【讨论】:

      • 2) 这是有人发明#ifdef 的原因之一;)
      【解决方案3】:

      我是这样做的:

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

      【讨论】:

        【解决方案4】:

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

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

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

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

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

        关键是实现这两个 Windows shell 接口:

        • IContextMenu

        • IShellExtInt

        【讨论】:

        • 感谢您的回复,但我知道如何显示上下文菜单 :) 您所指的文章解释了如何将项目添加到资源管理器上下文菜单。同样,我只需要显示它(默认项目是打开、打印、编辑、打开方式...等
        猜你喜欢
        • 1970-01-01
        • 2014-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-21
        相关资源
        最近更新 更多