Фильтрация типов файлов с помощью CMFCShellTreeCtrl

Я использую производный класс CMFCShellTreeCtrl с именем CShellTreeCtrl в объекте CMFCOutlookBar для отображения файлов, и я хотел бы отфильтровать типы файлов и позже иметь возможность перетаскивать файлы из него.

Мне удалось отобразить как файлы, так и папки, но я не мог понять, как использовать IEnumIDList для фильтрации типов файлов.

int CBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMFCOutlookBar::OnCreate(lpCreateStruct) == -1)
return -1;

CMFCOutlookBarTabCtrl* pOutlookBar = (CMFCOutlookBarTabCtrl*)GetUnderlyingWindow();

if (pOutlookBar != NULL)
{
pOutlookBar->SetImageList(IDB_PAGES_HC, 24);
pOutlookBar->SetToolbarImageList(IDB_PAGES_SMALL_HC, 16);
pOutlookBar->EnableInPlaceEdit(FALSE);
RecalcLayout();
}

RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);

// can float, can autohide, can resize, CAN NOT CLOSE
DWORD dwStyle = AFX_CBRS_AUTOHIDE | AFX_CBRS_RESIZE;CRect rectDummy(0, 0, 0, 0);
const DWORD dwTreeStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_INFOTIP;
m_pDirList = new CShellTreeCtrl;
m_pDirList->Create(dwTreeStyle, rectDummy, this, ID_SHELLDRILL);
m_pDirList->SetFlags(m_pDirList->GetFlags() | SHCONTF_NONFOLDERS);
pOutlookBar->AddControl(m_pDirList, _T("Folders"), 2, FALSE, dwStyle);
}

0

Решение

Получил работу со следующим кодом, адаптированным из этот похожий вопрос

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

string str = strItem;

if (tvItem.cChildren & SFGAO_HASSUBFOLDER)
{
InsertItem(&tvInsert);
}
else
{
if ((str.substr(str.find_last_of(".") + 1) == "pdf"))
{
InsertItem(&tvInsert);
}
}
dwFetched = 0;
}

pEnum->Release();
return S_OK;
}
0

Другие решения


По вопросам рекламы [email protected]