xpr_bool_t ShellEnumerator::enumerate(HWND aHwnd, LPSHELLFOLDER aShellFolder, xpr_sint_t aListType, xpr_sint_t aAttributes) { DWORD sFlags = 0; HRESULT sComResult; switch (aListType) { case ListTypeAll: sFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS; break; case ListTypeOnlyFile: sFlags = SHCONTF_NONFOLDERS; break; case ListTypeOnlyFolder: sFlags = SHCONTF_FOLDERS; break; } if (XPR_TEST_BITS(aAttributes, AttributeHidden)) { sFlags |= SHCONTF_INCLUDEHIDDEN; } if (XPR_TEST_BITS(aAttributes, AttributeSystem)) { sFlags |= SHCONTF_STORAGE; } LPENUMIDLIST sEnumIdList = XPR_NULL; sComResult = aShellFolder->EnumObjects(aHwnd, sFlags, &sEnumIdList); if (FAILED(sComResult)) { if (XPR_IS_NOT_NULL(sEnumIdList)) { COM_RELEASE(sEnumIdList); } return XPR_FALSE; } COM_RELEASE(mEnumIdList); mEnumIdList = sEnumIdList; return XPR_TRUE; }
/* #FN# Fills a branch of the TreeView control. Given the shell folder, enumerate the subitems of this folder, and add the appropriate items to the tree. This function enumerates the items in the folder identifed by lpsf. Note that since we are filling the left hand pane, we will only add items that are folders and/or have sub-folders. We *could* put all items in here if we wanted, but that's not the intent. */ void /* #AS# Nothing */ CShellTree:: FillTreeView( LPSHELLFOLDER lpsf, /* #IN# Pointer to shell folder that we want to enumerate items */ LPITEMIDLIST lpifq, /* #IN# Fully qualified item id list to the item that we are enumerating items for; in other words, this is the PIDL to the item identified by the lpsf parameter */ HTREEITEM hParent /* #IN# Parent node */ ) { TV_ITEM tvi; /* TreeView Item */ TV_INSERTSTRUCT tvins; /* TreeView Insert Struct */ HTREEITEM hPrev = NULL; /* Previous Item Added */ LPSHELLFOLDER lpsf2 = NULL; LPENUMIDLIST lpe = NULL; LPITEMIDLIST lpi = NULL; LPITEMIDLIST lpifqThisItem = NULL; LPTVITEMDATA lptvid = NULL; LPMALLOC lpMalloc = NULL; ULONG ulFetched = 0; HWND hwnd = ::GetParent( m_hWnd ); char szBuff[ MAX_PATH + 1 ]; char szPath[ MAX_PATH + 1 ]; HRESULT hr; /* Allocate a shell memory object */ hr = ::SHGetMalloc( &lpMalloc ); if( FAILED(hr) ) return; if( SUCCEEDED(hr) ) { /* Get the IEnumIDList object for the given folder */ hr = lpsf->EnumObjects( hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &lpe ); if( S_OK == hr && lpe ) { /* Enumerate throught the list of folder and non-folder objects */ while( S_OK == lpe->Next( 1, &lpi, &ulFetched ) ) { /* Create a fully qualified path to the current item. The SH* shell API's take a fully qualified path pidl, (see GetIcon above where I call SHGetFileInfo) whereas the interface methods take a relative path pidl */ ULONG ulAttrs = SFGAO_FOLDER | SFGAO_HASSUBFOLDER; if( !m_bFolderMode ) ulAttrs |= SFGAO_FILESYSTEM | SFGAO_LINK; /* Determine what type of object we have */ lpsf->GetAttributesOf( 1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs ); if( m_bFolderMode && ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER) || (!m_bFolderMode && ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_FILESYSTEM) && !(ulAttrs & SFGAO_LINK)) ) { tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; /* We need this next if statement so that we don't add things like the MSN to our tree. MSN is not a folder, but according to the shell it has subfolders */ /* OK, let's get some memory for our ITEMDATA struct */ lptvid = (LPTVITEMDATA)lpMalloc->Alloc( sizeof(TVITEMDATA) ); if( !lptvid ) goto Done; /* Error - could not allocate memory */ /* Now get the friendly name that we'll put in the treeview */ if( !GetName( lpsf, lpi, SHGDN_NORMAL, szBuff ) ) goto Done; /* Error - could not get friendly name */ tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH; /* Allocate/create the fully qualified PIDL, consisting of the parents full PIDL and our relative PIDL */ lpifqThisItem = ConcatPidls( lpifq, lpi ); if( ulAttrs & SFGAO_FOLDER && (ulAttrs & SFGAO_HASSUBFOLDER || /* There are not any subfolders but what about files? */ (!m_bFolderMode && SHGetPathFromIDList( lpifqThisItem, szPath ) && !IsFolderEmpty( szPath ))) ) { /* This item has sub-folders, so let's put the + in the TreeView. The first time the user clicks on the item, we'll populate the sub-folders */ tvi.cChildren = 1; tvi.mask |= TVIF_CHILDREN; } /* Now, make a copy of the ITEMIDLIST (non-qualified) */ lptvid->lpi = CopyITEMID( lpMalloc, lpi ); tvi.iImage = GetItemIcon( lpifqThisItem, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON ); tvi.iSelectedImage = GetItemIcon( lpifqThisItem, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON ); lptvid->lpsfParent = lpsf; /* Store the parent folders SF */ lpsf->AddRef(); /* Increment our saved reference */ /* Now create another PIDL from our Full parents PIDL and the releative one that we'll save */ lptvid->lpifq = ConcatPidls( lpifq, lpi ); /* Populate the TreeView Insert Struct. The item is the one filled above. Insert it after the last item inserted at this level. And indicate this is a root entry */ tvi.lParam = (LPARAM)lptvid; tvins.item = tvi; tvins.hInsertAfter = hPrev; tvins.hParent = hParent; /* Add the item to the tree */ hPrev = InsertItem( &tvins ); /* Free this item with task allocator */ lpMalloc->Free( lpifqThisItem ); lpifqThisItem = 0; } lpMalloc->Free( lpi ); /* Free the pidl that the shell gave us */ lpi = 0; } } } else return; Done: if( lpe ) lpe->Release(); /* The following 2 if statements will only be TRUE if we got here on an error condition from the "goto" statement. Otherwise, we free this memory at the end of the while loop above */ if( lpi && lpMalloc ) lpMalloc->Free( lpi ); if( lpifqThisItem && lpMalloc ) lpMalloc->Free( lpifqThisItem ); if( lpMalloc ) lpMalloc->Release(); } /* #OF# CShellTree::FillTreeView */
/**************************************************************************** * * FUNCTION: FillTreeView( LPSHELLFOLDER lpsf, * LPITEMIDLIST lpifq, * HTREEITEM hParent) * * PURPOSE: Fills a branch of the TreeView control. Given the * shell folder, enumerate the subitems of this folder, * and add the appropriate items to the tree. * * PARAMETERS: * lpsf - Pointer to shell folder that we want to enumerate items * lpifq - Fully qualified item id list to the item that we are enumerating * items for. In other words, this is the PIDL to the item * identified by the lpsf parameter. * hParent - Parent node * * COMMENTS: * This function enumerates the items in the folder identifed by lpsf. * Note that since we are filling the left hand pane, we will only add * items that are folders and/or have sub-folders. We *could* put all * items in here if we wanted, but that's not the intent. * ****************************************************************************/ void CShellTreeCtrl::FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent) { TV_ITEM tvi; // TreeView Item. TV_INSERTSTRUCT tvins; // TreeView Insert Struct. HTREEITEM hPrev = NULL; // Previous Item Added. LPSHELLFOLDER lpsf2=NULL; LPENUMIDLIST lpe=NULL; LPITEMIDLIST lpi=NULL, lpiTemp=NULL, lpifqThisItem=NULL; LPTVITEMDATA lptvid=NULL; LPMALLOC lpMalloc=NULL; ULONG ulFetched; UINT uCount=0; HRESULT hr; char szBuff[256]; char szFileName[2048]; HWND hwnd=::GetParent(m_hWnd); // Allocate a shell memory object. hr=::SHGetMalloc(&lpMalloc); if (FAILED(hr)) return; if (SUCCEEDED(hr)) { // Get the IEnumIDList object for the given folder. hr=lpsf->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN , &lpe); if (SUCCEEDED(hr)) { // Enumerate throught the list of folder and non-folder objects. while (S_OK==lpe->Next(1, &lpi, &ulFetched)) { //Create a fully qualified path to the current item //The SH* shell api's take a fully qualified path pidl, //(see GetIcon above where I call SHGetFileInfo) whereas the //interface methods take a relative path pidl. ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER; // Determine what type of object we have. lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs); if (m_bDispFile || (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER))) { //We need this next if statement so that we don't add things like //the MSN to our tree. MSN is not a folder, but according to the //shell it has subfolders. if (m_bDispFile || (ulAttrs & SFGAO_FOLDER )) { tvi.mask= TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; if (ulAttrs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER) )// { //This item has sub-folders, so let's put the + in the TreeView. //The first time the user clicks on the item, we'll populate the //sub-folders. tvi.cChildren=1; tvi.mask |= TVIF_CHILDREN; } //OK, let's get some memory for our ITEMDATA struct lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA)); if (!lptvid) goto Done; // Error - could not allocate memory. //Now get the friendly name that we'll put in the treeview. if (!GetName(lpsf, lpi, SHGDN_NORMAL, szBuff)) goto Done; // Error - could not get friendly name. // if (!GetName(lpsf, lpi, SHGDN_FORPARSING, szFileName)) if(SHGetPathFromIDList(lpi,szFileName)) { if(!(ulAttrs & SFGAO_FOLDER) && m_bDispFile) if(!MatchExtensionFilter(szFileName)) continue; } else if(!(ulAttrs & SFGAO_FOLDER) && m_bDispFile) if(!MatchExtensionFilter(szBuff)) continue; tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH; lpifqThisItem=ConcatPidls(lpifq, lpi); //Now, make a copy of the ITEMIDLIST lptvid->lpi=CopyITEMID(lpMalloc, lpi); GetNormalAndSelectedIcons(lpifqThisItem, &tvi); lptvid->lpsfParent=lpsf; //Store the parent folders SF lpsf->AddRef(); lptvid->lpifq=ConcatPidls(lpifq, lpi); tvi.lParam = (LPARAM)lptvid; // Populate the TreeVeiw Insert Struct // The item is the one filled above. // Insert it after the last item inserted at this level. // And indicate this is a root entry. tvins.item = tvi; tvins.hInsertAfter = hPrev; tvins.hParent = hParent; // Add the item to the tree hPrev = InsertItem(&tvins); } // Free this items task allocator. lpMalloc->Free(lpifqThisItem); lpifqThisItem=0; } lpMalloc->Free(lpi); //Free the pidl that the shell gave us. lpi=0; } } } else return; Done: if (lpe) lpe->Release(); //The following 2 if statements will only be TRUE if we got here on an //error condition from the "goto" statement. Otherwise, we free this memory //at the end of the while loop above. if (lpi && lpMalloc) lpMalloc->Free(lpi); if (lpifqThisItem && lpMalloc) lpMalloc->Free(lpifqThisItem); if (lpMalloc) lpMalloc->Release(); }
void CCJShellTree::FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent) { TV_ITEM tvi; // TreeView Item. TV_INSERTSTRUCT tvins; // TreeView Insert Struct. HTREEITEM hPrev = NULL; // Previous Item Added. LPENUMIDLIST lpe=0; LPITEMIDLIST lpi=0, lpifqThisItem=0; LPTVITEMDATA lptvid=0; LPMALLOC lpMalloc=0; ULONG ulFetched; HRESULT hr; TCHAR szBuff[256]; HWND hwnd=GetParent()->GetSafeHwnd(); hr=SHGetMalloc(&lpMalloc); if (FAILED(hr)) return; // Hourglass on! SetCapture(); CWaitCursor wait; // display wait cursor if (SUCCEEDED(hr)) { SetRedraw(FALSE); hr=lpsf->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &lpe); if (SUCCEEDED(hr)) { while (S_OK==lpe->Next(1, &lpi, &ulFetched)) { //Create a fully qualified path to the current item //The SH* shell api's take a fully qualified path pidl, //(see GetIcon above where I call SHGetFileInfo) whereas the //interface methods take a relative path pidl. ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER; lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs); if (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER)) { //We need this next if statement so that we don't add things like //the MSN to our tree. MSN is not a folder, but according to the //shell is has subfolders.... if (ulAttrs & SFGAO_FOLDER) { tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; if (ulAttrs & SFGAO_HASSUBFOLDER) { //This item has sub-folders, so let's put the + in the TreeView. //The first time the user clicks on the item, we'll populate the //sub-folders then. tvi.cChildren=1; tvi.mask |= TVIF_CHILDREN; } //OK, let's get some memory for our ITEMDATA struct lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA)); if (!lptvid) goto Done; //Now get the friendly name that we'll put in the treeview... if( m_shell.GetName(lpsf, lpi, SHGDN_NORMAL, szBuff) == FALSE ) { goto Done; } tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH; lpifqThisItem=m_shell.ConcatPidls(lpifq, lpi); //Now, make a copy of the ITEMIDLIST lptvid->lpi=m_shell.CopyITEMID(lpMalloc, lpi); m_shell.GetNormalAndSelectedIcons(lpifqThisItem, &tvi); lptvid->lpsfParent=lpsf; //Store the parent folders SF lpsf->AddRef(); //So, you ask, what's the story here? Why do we have 2 //functions that apparently do the same thing? Well, //ParseDisplayName() (used in GetFullyQualPidl) does not //work well for non-file system objects such as the My //Computer and Net Hood. So, since we know that these //guys will only show up when we are enumerating the root //of the namespace (as identified by an hParent of TVI_ROOT), //we special case this here. You *could* use ConcatPidls() //in ALL cases, but the GetFullyQualPidl() is shown for //demonstration purposes, since it's the more intuative way. //Commented out for now, since we need ConcatPidls for *any* non-file system object. //This includes things like Control Panel, et al. // if (hParent==TVI_ROOT) lptvid->lpifq=m_shell.ConcatPidls(lpifq, lpi); // else // lptvid->lpifq=GetFullyQualPidl(lpsf, lpi); tvi.lParam = (LPARAM)lptvid; // Populate the TreeVeiw Insert Struct // The item is the one filled above. // Insert it after the last item inserted at this level. // And indicate this is a root entry. tvins.item = tvi; tvins.hInsertAfter = hPrev; tvins.hParent = hParent; // Add the item to the tree hPrev = InsertItem(&tvins); } lpMalloc->Free(lpifqThisItem); lpifqThisItem=0; } lpMalloc->Free(lpi); //Finally, free the pidl that the shell gave us... lpi=0; } } } else { SetRedraw(); return; } Done: // Hourglass off! ReleaseCapture(); if (lpe) lpe->Release(); //The following 2 if statements will only be TRUE if we got here on an //error condition from the "goto" statement. Otherwise, we free this memory //at the end of the while loop above. if (lpi && lpMalloc) lpMalloc->Free(lpi); if (lpifqThisItem && lpMalloc) lpMalloc->Free(lpifqThisItem); if (lpMalloc) lpMalloc->Release(); SetRedraw(); }
int DriveBox_Fill(HWND hwnd) { LPSHELLFOLDER lpsfDesktop; LPSHELLFOLDER lpsf; // Workspace == CSIDL_DRIVES LPITEMIDLIST pidl; LPITEMIDLIST pidlEntry; LPENUMIDLIST lpe; COMBOBOXEXITEM cbei; LPDC_ITEMDATA lpdcid; ULONG dwAttributes = 0; DWORD grfFlags = SHCONTF_FOLDERS; // Init ComboBox SendMessage(hwnd, WM_SETREDRAW, 0, 0); SendMessage(hwnd, CB_RESETCONTENT, 0, 0); ZeroMemory(&cbei, sizeof(COMBOBOXEXITEM)); cbei.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_LPARAM; cbei.pszText = LPSTR_TEXTCALLBACK; cbei.cchTextMax = MAX_PATH; cbei.iImage = I_IMAGECALLBACK; cbei.iSelectedImage = I_IMAGECALLBACK; // Get pidl to [My Computer] if (NOERROR == SHGetSpecialFolderLocation(hwnd, CSIDL_DRIVES, &pidl)) { // Get Desktop Folder if (NOERROR == SHGetDesktopFolder(&lpsfDesktop)) { // Bind pidl to IShellFolder if (NOERROR == lpsfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&lpsf)) { // Create an Enumeration object for lpsf if (NOERROR == lpsf->EnumObjects(hwnd, grfFlags, &lpe)) { // Enumerate the contents of [My Computer] while (NOERROR == lpe->Next(1, &pidlEntry, NULL)) { // Add item to the List if it is part of the // Filesystem dwAttributes = SFGAO_FILESYSTEM; lpsf->GetAttributesOf(1, (LPCITEMIDLIST*)&pidlEntry, &dwAttributes); if (dwAttributes & SFGAO_FILESYSTEM) { // Windows XP: check if pidlEntry is a drive SHDESCRIPTIONID di; HRESULT hr; hr = SHGetDataFromIDList(lpsf, pidlEntry, SHGDFIL_DESCRIPTIONID, &di, sizeof(SHDESCRIPTIONID)); if (hr != NOERROR || (di.dwDescriptionId >= SHDID_COMPUTER_DRIVE35 && di.dwDescriptionId <= SHDID_COMPUTER_OTHER)) { lpdcid = (DC_ITEMDATA*)CoTaskMemAlloc(sizeof(DC_ITEMDATA)); // lpdcid->pidl = IL_Copy(pidlEntry); lpdcid->pidl = pidlEntry; lpdcid->lpsf = lpsf; lpsf->AddRef(); // Insert sorted ... { COMBOBOXEXITEM cbei2; LPDC_ITEMDATA lpdcid2; HRESULT hr; cbei2.mask = CBEIF_LPARAM; cbei2.iItem = 0; while ((SendMessage(hwnd, CBEM_GETITEM, 0, (LPARAM)&cbei2))) { lpdcid2 = (LPDC_ITEMDATA)cbei2.lParam; hr = (lpdcid->lpsf->CompareIDs(0, lpdcid->pidl, lpdcid2->pidl)); if ((short)(SCODE_CODE(GetScode(hr))) < 0) break; else cbei2.iItem++; } cbei.iItem = cbei2.iItem; cbei.lParam = (LPARAM)lpdcid; SendMessage(hwnd, CBEM_INSERTITEM, 0, (LPARAM)&cbei); } } } } // IEnumIDList::Next() lpe->Release(); } // IShellFolder::EnumObjects() lpsf->Release(); } // IShellFolder::BindToObject() CoTaskMemFree(pidl); } // SHGetSpecialFolderLocation() lpsfDesktop->Release(); } // SHGetDesktopFolder() SendMessage(hwnd, WM_SETREDRAW, 1, 0); // Return number of items added to combo box return ((int)SendMessage(hwnd, CB_GETCOUNT, 0, 0)); }
// Snapshots a directory and displays the items in the listview control int DirList_Fill(HWND hwnd, const WCHAR* lpszDir, DWORD grfFlags, const WCHAR* lpszFileSpec, BOOL bExcludeFilter, BOOL bNoFadeHidden, int iSortFlags, BOOL fSortRev) { WCHAR wszDir[MAX_PATH]; LPSHELLFOLDER lpsfDesktop = NULL; LPSHELLFOLDER lpsf = NULL; LPITEMIDLIST pidl = NULL; LPITEMIDLIST pidlEntry = NULL; LPENUMIDLIST lpe = NULL; LV_ITEM lvi; LPLV_ITEMDATA lplvid; ULONG chParsed = 0; ULONG dwAttributes = 0; DL_FILTER dlf; SHFILEINFO shfi = { 0 }; DLDATA* lpdl = (DLDATA*)GetProp(hwnd, pDirListProp); // Initialize default icons SHGetFileInfo(L"Icon", FILE_ATTRIBUTE_DIRECTORY, &shfi, sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON | SHGFI_SYSICONINDEX); lpdl->iDefIconFolder = shfi.iIcon; SHGetFileInfo(L"Icon", FILE_ATTRIBUTE_NORMAL, &shfi, sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON | SHGFI_SYSICONINDEX); lpdl->iDefIconFile = shfi.iIcon; // First of all terminate running icon thread DirList_TerminateIconThread(hwnd); // A Directory is strongly required if (!lpszDir || !*lpszDir) return (-1); lstrcpy(lpdl->szPath, lpszDir); // Init ListView SendMessage(hwnd, WM_SETREDRAW, 0, 0); ListView_DeleteAllItems(hwnd); // Init Filter DirList_CreateFilter(&dlf, lpszFileSpec, bExcludeFilter); // Init lvi lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; lvi.iItem = 0; lvi.iSubItem = 0; lvi.pszText = LPSTR_TEXTCALLBACK; lvi.cchTextMax = MAX_PATH; lvi.iImage = I_IMAGECALLBACK; // Convert Directory to a UNICODE string /*MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpszDir, -1, wszDir, MAX_PATH);*/ lstrcpy(wszDir, lpszDir); // Get Desktop Folder if (NOERROR == SHGetDesktopFolder(&lpsfDesktop)) { // Convert wszDir into a pidl if (NOERROR == lpsfDesktop->ParseDisplayName(hwnd, NULL, wszDir, &chParsed, &pidl, &dwAttributes)) { // Bind pidl to IShellFolder if (NOERROR == lpsfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&lpsf)) { // Create an Enumeration object for lpsf if (NOERROR == lpsf->EnumObjects(hwnd, grfFlags, &lpe)) { // Enumerate the contents of lpsf while (NOERROR == lpe->Next(1, &pidlEntry, NULL)) { // Add found item to the List // Check if it's part of the Filesystem dwAttributes = SFGAO_FILESYSTEM | SFGAO_FOLDER; lpsf->GetAttributesOf(1, (LPCITEMIDLIST*)pidlEntry, &dwAttributes); if (dwAttributes & SFGAO_FILESYSTEM) { // Check if item matches specified filter if (DirList_MatchFilter(lpsf, pidlEntry, &dlf)) { lplvid = (LV_ITEMDATA*)CoTaskMemAlloc(sizeof(LV_ITEMDATA)); lplvid->pidl = pidlEntry; lplvid->lpsf = lpsf; lpsf->AddRef(); lvi.lParam = (LPARAM)lplvid; // Setup default Icon - Folder or File lvi.iImage = (dwAttributes & SFGAO_FOLDER) ? lpdl->iDefIconFolder : lpdl->iDefIconFile; ListView_InsertItem(hwnd, &lvi); lvi.iItem++; } } } // IEnumIDList::Next() lpe->Release(); } // IShellFolder::EnumObjects() } // IShellFolder::BindToObject() } // IShellFolder::ParseDisplayName() lpsfDesktop->Release(); } // SHGetDesktopFolder() if (lpdl->pidl) CoTaskMemFree(lpdl->pidl); if (lpdl->lpsf) lpdl->lpsf->Release(); // Set lpdl lpdl->cbidl = IL_GetSize(pidl); lpdl->pidl = pidl; lpdl->lpsf = lpsf; lpdl->bNoFadeHidden = bNoFadeHidden; // Set column width to fit window ListView_SetColumnWidth(hwnd, 0, LVSCW_AUTOSIZE_USEHEADER); // Sort before display is updated DirList_Sort(hwnd, iSortFlags, fSortRev); // Redraw Listview SendMessage(hwnd, WM_SETREDRAW, 1, 0); // Return number of items in the control return (ListView_GetItemCount(hwnd)); }
void FillTreeView(HWND hwndTreeView,LPSHELLFOLDER lpsf,LPITEMIDLIST lpifq,HTREEITEM hParent) { TV_ITEM tvi; // TreeView Item. TV_INSERTSTRUCT tvins; // TreeView Insert Struct. HTREEITEM hPrev = NULL; // Previous Item Added. LPSHELLFOLDER lpsf2=0; LPENUMIDLIST lpe=0; LPITEMIDLIST lpi=0,lpifqThisItem;// lpiTemp=0, lpifqThisItem; LPTVITEMDATA lptvid=0; LPMALLOC lpMalloc=0; ULONG ulFetched; HRESULT hr; char szBuff[256]; HWND hwnd=GetParent(hwndTreeView); hr=SHGetMalloc(&lpMalloc); if(FAILED(hr)) return; SetCapture(GetParent(hwndTreeView)); SetCursor(LoadCursor(NULL,IDC_WAIT)); hr=lpsf->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &lpe) ; if(SUCCEEDED(hr)) { while (S_OK==lpe->Next(1,&lpi,&ulFetched)) { ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER; lpsf->GetAttributesOf(1,(LPCITEMIDLIST*)&lpi, &ulAttrs) ; if( ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER)) { if( ulAttrs & SFGAO_FOLDER) { tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; if( ulAttrs & SFGAO_HASSUBFOLDER) { tvi.cChildren=1; tvi.mask |= TVIF_CHILDREN; } lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA)); if( !lptvid) goto Done; if(!GetName(lpsf, lpi, SHGDN_NORMAL, szBuff)) goto Done; tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH; lpifqThisItem=ConcatPidls(lpifq, lpi) ; lptvid -> lpi=CopyITEMID(lpMalloc, lpi) ; GetNormalAndSelectedIcons(lpifqThisItem, &tvi) ; lptvid -> lpsfParent=lpsf; //Store the parent folders SF lpsf->AddRef() ; if( hParent==TVI_ROOT) lptvid -> lpifq=ConcatPidls(lpifq, lpi) ; else lptvid -> lpifq=GetFullyQualPidl(lpsf, lpi) ; tvi.lParam = (LPARAM)lptvid; tvins./*DUMMYUNIONNAME.*/item = tvi; tvins.hInsertAfter = hPrev; tvins.hParent = hParent; hPrev = TreeView_InsertItem(hwndTreeView, &tvins) ; //////the next code expand all item but CD-ROM in Tree view///////// // //TreeView_Expand(hwndTreeView,hPrev,TVE_TOGGLE); // /////code end////////////////////////////////////////////////////// } lpMalloc->Free(lpifqThisItem) ; lpifqThisItem=0; } lpMalloc->Free(lpi) ; //Finally, free the pidl that the shell gave us... lpi=0; } } Done: ReleaseCapture() ; SetCursor( LoadCursor( NULL, IDC_ARROW)) ; if(lpe) lpe->Release() ; if(lpi && lpMalloc) lpMalloc->Free(lpi) ; if(lpifqThisItem && lpMalloc) lpMalloc->Free(lpifqThisItem) ; if(lpMalloc) lpMalloc->Release() ; }
//*************************************************************************************** HRESULT CBCGPShellList::EnumObjects (LPSHELLFOLDER pParentFolder, LPITEMIDLIST pidlParent) { ASSERT_VALID (this); ASSERT_VALID (g_pShellManager); LPENUMIDLIST pEnum; HRESULT hRes = pParentFolder->EnumObjects (NULL, m_nTypes, &pEnum); if (SUCCEEDED (hRes)) { LPITEMIDLIST pidlTemp; DWORD dwFetched = 1; LPBCGCBITEMINFO pItem; //enumerate the item's PIDLs while (pEnum->Next(1, &pidlTemp, &dwFetched) == S_OK && dwFetched) { LVITEM lvItem; ZeroMemory(&lvItem, sizeof(lvItem)); //fill in the TV_ITEM structure for this item lvItem.mask = LVIF_PARAM | LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; //AddRef the parent folder so it's pointer stays valid pParentFolder->AddRef(); //put the private information in the lParam pItem = (LPBCGCBITEMINFO)GlobalAlloc(GPTR, sizeof(BCGCBITEMINFO)); pItem->pidlRel = pidlTemp; pItem->pidlFQ = g_pShellManager->ConcatenateItem (pidlParent, pidlTemp); pItem->pParentFolder = pParentFolder; if (!IsItemMatchedToFilter(pItem)) { ReleaseItem(pItem); dwFetched = 0; continue; } lvItem.lParam = (LPARAM)pItem; lvItem.pszText = _T(""); lvItem.iImage = OnGetItemIcon (GetItemCount (), pItem); //determine if the item is shared DWORD dwAttr = SFGAO_DISPLAYATTRMASK; pParentFolder->GetAttributesOf (1, (LPCITEMIDLIST*)&pidlTemp, &dwAttr); if (dwAttr & SFGAO_SHARE) { lvItem.mask |= LVIF_STATE; lvItem.stateMask |= LVIS_OVERLAYMASK; lvItem.state |= INDEXTOOVERLAYMASK(1); //1 is the index for the shared overlay image } if (dwAttr & SFGAO_GHOSTED) { lvItem.mask |= LVIF_STATE; lvItem.stateMask |= LVIS_CUT; lvItem.state |= LVIS_CUT; } int iItem = InsertItem (&lvItem); if (iItem >= 0) { //------------- // Set columns: //------------- const int nColumns = (GetStyle () & LVS_TYPEMASK) == LVS_REPORT ? m_wndHeader.GetItemCount () : 1; for (int iColumn = 0; iColumn < nColumns; iColumn++) { SetItemText (iItem, iColumn, OnGetItemText (iItem, iColumn, pItem)); } } dwFetched = 0; } pEnum->Release (); } return hRes; }