Как определить, является ли данный PIDL файлом .zip или аналогичным?

VS2010 представил CMFCShellTreeCtrl, который позволяет вводить дерево ctrl для браузера папок в наши приложения MFC.

Однако в этом классе, похоже, существует серьезная нехватка возможностей фильтрации. то есть он создаст список объектов-контейнеров (IShellFolder). Но, похоже, нет способа указать, что контейнеры .zip не должны отображаться в дереве папок.

Он предоставляет виртуальный, который может быть использовангрубо для этого:

HRESULT CMFCShellTreeCtrl::EnumObjects(HTREEITEM hParentItem, LPSHELLFOLDER pParentFolder, LPITEMIDLIST pidlParent)
{
  ASSERT_VALID(this);
  ASSERT_VALID(afxShellManager);

  LPENUMIDLIST pEnum = NULL;

  HRESULT hr = pParentFolder->EnumObjects(NULL, m_dwFlags, &pEnum);
  if (FAILED(hr) || pEnum == NULL)
  {
      return hr;
  }

  LPITEMIDLIST pidlTemp;
  DWORD dwFetched = 1;

  // Enumerate the item's PIDLs:
  while (SUCCEEDED(pEnum->Next(1, &pidlTemp, &dwFetched)) && dwFetched)
  {
      TVITEM tvItem;
      ZeroMemory(&tvItem, sizeof(tvItem));

      // Fill in the TV_ITEM structure for this item:
      tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;

      // AddRef the parent folder so it's pointer stays valid:
      pParentFolder->AddRef();

      // Put the private information in the lParam:
      LPAFX_SHELLITEMINFO pItem = (LPAFX_SHELLITEMINFO)GlobalAlloc(GPTR, sizeof(AFX_SHELLITEMINFO));
      ENSURE(pItem != NULL);

      pItem->pidlRel = pidlTemp;
      pItem->pidlFQ = afxShellManager->ConcatenateItem(pidlParent, pidlTemp);

      pItem->pParentFolder = pParentFolder;
      tvItem.lParam = (LPARAM)pItem;

      CString strItem = OnGetItemText(pItem);
      tvItem.pszText = strItem.GetBuffer(strItem.GetLength());
      tvItem.iImage = OnGetItemIcon(pItem, FALSE);
      tvItem.iSelectedImage = OnGetItemIcon(pItem, TRUE);

      // Determine if the item has children:
      DWORD dwAttribs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DISPLAYATTRMASK | SFGAO_CANRENAME | SFGAO_FILESYSANCESTOR;

      pParentFolder->GetAttributesOf(1, (LPCITEMIDLIST*) &pidlTemp, &dwAttribs);
      tvItem.cChildren = (dwAttribs & (SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR));

      // Determine if the item is shared:
      if (dwAttribs & SFGAO_SHARE)
      {
          tvItem.mask |= TVIF_STATE;
          tvItem.stateMask |= TVIS_OVERLAYMASK;
          tvItem.state |= INDEXTOOVERLAYMASK(1); //1 is the index for the shared overlay image
      }

      // Fill in the TV_INSERTSTRUCT structure for this item:
      TVINSERTSTRUCT tvInsert;

      tvInsert.item = tvItem;
      tvInsert.hInsertAfter = TVI_LAST;
      tvInsert.hParent = hParentItem;

      InsertItem(&tvInsert);
      dwFetched = 0;
  }

  pEnum->Release();
  return S_OK;
}

Что меня смущает, так это отсутствие способности различать, какой это тип объекта, который перечисляется (или, во-первых, лучший способ управления перечислением, чтобы отфильтровать объекты, не являющиеся файловой системой, подобные этим).

Можно посмотреть на текст перечисляемого элемента и просто исключить его, если он заканчивается на «.zip». Тем не менее, это кажется мне вялым. В конце концов, произвольная папка может быть названа XYZ.zip (которая по-прежнему является папкой, а не zip-архивом). Точно так же, вероятно, существуют другие типы архивов, кроме .zip, которые могут быть поддержаны в будущем, или другие типы контейнеров, которые, тем не менее, не являются папками.

Я не хочу исключать такие вещи, как «Сеть» и «Компьютер» из допустимых узлов. Только те, которые являются проблемными, такие как "Downloads \ Foobar.zip"

Я прошу прощения за этот бессвязный вопрос. Будем благодарны за любую помощь в улучшении моего понимания и творческих подходов к пониманию того, какие объекты являются частью пространства имен оболочки Microsoft и как их можно с пользой использовать!

Ответы на вопрос(1)

Ваш ответ на вопрос