Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Is it possible to call system shell context menu for a file / folder from Qt app?
Forum Updated to NodeBB v4.3 + New Features

Is it possible to call system shell context menu for a file / folder from Qt app?

Scheduled Pinned Locked Moved General and Desktop
2 Posts 1 Posters 2.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    Violet Giraffe
    wrote on 10 Jul 2013, 07:23 last edited by
    #1

    I have a path to a file system object (file / folder), and I want to all a system context (right-click) menu for it. For example, on Windows I need Windows Explorer menu.
    Is it possible?

    1 Reply Last reply
    0
    • V Offline
      V Offline
      Violet Giraffe
      wrote on 11 Jul 2013, 05:14 last edited by
      #2

      It appears there's no wrapper for this in Qt, so on Windows one has to use WinAPI. Here's how it works:

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

      If I manage to do the same on Mac, I'll try to tidy up a wrapper class and opensource it.

      1 Reply Last reply
      0

      1/2

      10 Jul 2013, 07:23

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved