If the target system is Windows Vista, Windows Server 2008 or newer, enumerating known folders (formerly known as special folders) like Desktop, Documents, Program Files, etc is quite easy by calling GetFolderIds method of IKnownFolderManager interface. It gets an array of all registered known folder IDs (KNOWNFOLDERID). Once having a folder ID, we can call IKnownFolderManager::GetFolder to get an instance of IKnownFolder interface and further get more details.
To make things even easier, I wrote two MFC-extension classes CKnownFolderManager and CKnownFolder, which are wrappers over IKnownFolderManager and IKnownFolder, respectively. Here, let’s just see brief code examples. The implementation details can be found in the attached demo project.
Using CKnownFolderManager to get an array of known folders IDs
// Fills an array of KNOWNFOLDERID void CDemoDlg::_FillKnownFolderIdsArray() { try { CKnownFolderManager kfManager; kfManager.GetFolderIds(m_arrKnownFolderIds); } catch(COleException* e) { e->ReportError(); // show what's going wrong e->Delete(); } }
Using CKnownFolder to fill a lisbox with known folder names
void CDemoDlg::_FillKnownFolderList() { // ... try { // instantiate a CKnownFolderManager object CKnownFolderManager kfManager; const INT_PTR nSize = m_arrKnownFolderIds.GetSize(); for(INT_PTR nIndex = 0; nIndex < nSize; nIndex++) { // get KNOWNFOLDERID and instantiate a CKnownFolder object const KNOWNFOLDERID& knownFolderId = m_arrKnownFolderIds.ElementAt(nIndex); CKnownFolder knownFolder(kfManager, knownFolderId); CString strName = knownFolder.GetName(); // add known folder name to the listbox control int nItem = m_listKnownFolders.AddString(strName); // keep in mind the index in KNOWNFOLDERID array, for further use m_listKnownFolders.SetItemData(nItem, (DWORD_PTR)nIndex); } } catch(COleException* e) { e->ReportError(); // show what's going wrong e->Delete(); } }
Using CKnownFolder to get special folder details
// LBN_SELCHANGE notification handler void CDemoDlg::OnLbnSelchangeListKnownFolders() { int nCurSel = m_listKnownFolders.GetCurSel(); if(LB_ERR == nCurSel) return; // get current KNOWNFOLDERID from the array INT_PTR nArrIndex = (INT_PTR)m_listKnownFolders.GetItemData(nCurSel); const KNOWNFOLDERID& knownFolderId = m_arrKnownFolderIds.ElementAt(nArrIndex); try { // instantiate CKnownFolder object based on current KNOWNFOLDERID CKnownFolderManager kfManager; CKnownFolder knownFolder(kfManager, knownFolderId); // get special folder details CString strName = knownFolder.GetName(); CString strCategory = knownFolder.GetCategoryStr(); CString strFolderType = knownFolder.GetFolderTypeStr(); CString strId = knownFolder.GetIdStr(); CString strPath = knownFolder.GetPathStr(); // ... } catch(COleException* e) { e->ReportError(); e->Delete(); } }
Demo project
Download: Listing Known Folders Demo.zip (308)
The demo project is a simple MFC dialog-based application that uses CKnownFolderManager and CKnownFolder. In the left side is a lisbox which displays the list of known folders names. For each selected listbox item, the edit control from the right side displays the details (name, category, path, etc). Additionally, if the user pushes the “Browse…” button, a browse for folder dialog is shown, having the selected known folder in the root.
Resources
- MSDN: Known Folders
- MSDN: IKnownFolderManager interface
- MSDN: IKnownFolder interface
- MSDN: Known Folders Sample