Exemplo n.º 1
0
/* #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 */
Exemplo n.º 2
0
BOOL AddUserMenu(HMENU hMenu, LPMALLOC pMalloc, LPCTSTR path)
{
	int nResult = 0;
	char itemName[1024], tmpPath[MAX_PATH];
	OLECHAR ochPath[MAX_PATH];
	STRRET strret;
	SHFILEINFO    tSHFileInfo;
	LPITEMIDLIST  pItemID, pItemIDFile, pItemIDFolder;
	LPSHELLFOLDER pFolder = NULL, pDesktop = NULL;
	LPENUMIDLIST  pEnumIDFolder = NULL, pEnumIDFile = NULL;
	PLISTIDL      *pptListIDL    = &g_ptListIDL;
	PUSERMENU     *ppUserMenu    = &g_ptUserMenu;
	PODMENUITEM   *pptODMenuItem = &g_ptODMenuItem;

	//構造体連結リストの最後までいく。
	while((*pptODMenuItem) != NULL)
		pptODMenuItem = &(*pptODMenuItem)->next;
	while((*pptListIDL) != NULL)
		pptListIDL = &(*pptListIDL)->next;
	while((*ppUserMenu) != NULL)
		ppUserMenu = &(*ppUserMenu)->next;

	if(SHGetDesktopFolder(&pFolder) != NOERROR)
		return FALSE;
	if(SHGetDesktopFolder(&pDesktop) != NOERROR)
	{
		pFolder->lpVtbl->Release(pFolder);
		return FALSE;
	}

	MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,path,-1,ochPath,MAX_PATH);

	if (pDesktop->lpVtbl->ParseDisplayName(pDesktop, NULL, NULL, ochPath, NULL, &pItemIDFolder, NULL)!=NOERROR)
	{
		pItemIDFolder = NULL;
		pFolder->lpVtbl->Release(pFolder);
		pDesktop->lpVtbl->Release(pDesktop);
		return FALSE;
	}

	if (pDesktop->lpVtbl->BindToObject(pDesktop, pItemIDFolder, 0, &IID_IShellFolder, (LPVOID *)&pFolder)!=NOERROR)
	{
		pFolder->lpVtbl->Release(pFolder);
		pDesktop->lpVtbl->Release(pDesktop);
		return FALSE;
	}
	pDesktop->lpVtbl->Release(pDesktop);

	//フォルダをすべて取得
	if(pFolder->lpVtbl->EnumObjects(pFolder, NULL, SHCONTF_FOLDERS, &pEnumIDFolder) != NOERROR)
	{
		pFolder->lpVtbl->Release(pFolder);
		return FALSE;
	}

	while(pEnumIDFolder->lpVtbl->Next(pEnumIDFolder, 1, &pItemIDFile, NULL) == NOERROR)
	{
		if(pFolder->lpVtbl->GetDisplayNameOf(pFolder, pItemIDFile, SHGDN_NORMAL, &strret) == NOERROR)
		{
			if(strret.uType == STRRET_CSTR)
				strcpy(itemName, strret.cStr);
			else if(strret.uType == STRRET_OFFSET)
				strcpy(itemName, (char *)pItemIDFile + strret.uOffset);
			else if(strret.uType == STRRET_WSTR)
			{
				char *pStr = Unicode2Ansi(strret.pOleStr);
				pMalloc->lpVtbl->Free(pMalloc, strret.pOleStr);
				if(pStr != NULL){
					strcpy(itemName, pStr);
					free(pStr);
				}
				else{
					nResult = -1;
					break;
				}
			}
			pItemID = ConcatPidls(pItemIDFolder,pItemIDFile);
			if(!(SHGetPathFromIDList(pItemID,tmpPath)))
			{
				nResult = -1;
				break;
			}

			*pptListIDL = (PLISTIDL)malloc(sizeof(LISTIDL));
			if(*pptListIDL == NULL)
			{
				nResult = -1;
				break;
			}
			else
			{
				if(g_ptListIDL == NULL)
					g_ptListIDL = *pptListIDL;
			}
			(*pptListIDL)->uMenuID = uItemID;
			(*pptListIDL)->next = NULL;
			strcpy((*pptListIDL)->path,tmpPath);

			*pptODMenuItem = (PODMENUITEM)malloc(sizeof(ODMENUITEM));
			ZeroMemory(*pptODMenuItem, sizeof(ODMENUITEM));
			if(*pptODMenuItem == NULL)
			{
				nResult = -1;
				break;
			}
			else
			{
				if(g_ptODMenuItem == NULL)
					g_ptODMenuItem = *pptODMenuItem;
			}
			(*pptODMenuItem)->uMenuID = uItemID;
			(*pptODMenuItem)->next = NULL;

			ZeroMemory(&tSHFileInfo, sizeof(tSHFileInfo));

			SHGetFileInfo((LPCTSTR)pItemID, 0, &tSHFileInfo, sizeof(tSHFileInfo),
							SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON);

			(*pptODMenuItem)->hMenuIcon = tSHFileInfo.hIcon;

			// サブメニュー作成
			*ppUserMenu = (PUSERMENU)malloc(sizeof(USERMENU));
			if(*ppUserMenu == NULL){
				nResult = -1;
				break;
			}
			else
			{
				if (g_ptUserMenu == NULL)
					g_ptUserMenu = *ppUserMenu;
			}
			(*ppUserMenu)->hMenu = CreatePopupMenu();
			if((*ppUserMenu)->hMenu == NULL)
			{
				nResult = -1;
				break;
			}
			(*ppUserMenu)->uID   = uItemID;
			(*ppUserMenu)->flg   = FALSE;
			(*ppUserMenu)->next  = NULL;
			strcpy((*ppUserMenu)->path,tmpPath);

			AddMenuItem((*ppUserMenu)->hMenu, uItemID, MFT_STRING, "フォルダを開く", NULL);
			AddMenuItem(hMenu, uItemID, MFT_OWNERDRAW, itemName, (*ppUserMenu)->hMenu);
			strcpy((*pptODMenuItem)->sMenuStr, itemName);
		}
		else
		{
			nResult = -1;
			break;
		}

		pMalloc->lpVtbl->Free(pMalloc, pItemID);
		pMalloc->lpVtbl->Free(pMalloc, pItemIDFile);
		pptListIDL    = &(*pptListIDL)->next;
		ppUserMenu    = &(*ppUserMenu)->next;
		pptODMenuItem = &(*pptODMenuItem)->next;
		uItemID++;
	}
	if(pEnumIDFolder != NULL){
		pEnumIDFolder->lpVtbl->Release(pEnumIDFolder);
	}

	if (path[0] != 0)
	{
		//隠しファイル以外のファイルのみ
		if(pFolder->lpVtbl->EnumObjects(pFolder, NULL, SHCONTF_NONFOLDERS, &pEnumIDFile) != NOERROR){
			pFolder->lpVtbl->Release(pFolder);
			return FALSE;
		}

		while(pEnumIDFile->lpVtbl->Next(pEnumIDFile, 1, &pItemIDFile, NULL) == NOERROR){
			if(pFolder->lpVtbl->GetDisplayNameOf(pFolder, pItemIDFile, SHGDN_NORMAL, &strret) == NOERROR)
			{
				if(strret.uType == STRRET_CSTR)
					strcpy(itemName, strret.cStr);
				else if(strret.uType == STRRET_OFFSET)
					strcpy(itemName, (char *)pItemIDFile + strret.uOffset);
				else if(strret.uType == STRRET_WSTR)
				{
					char *pStr = Unicode2Ansi(strret.pOleStr);
					pMalloc->lpVtbl->Free(pMalloc, strret.pOleStr);
					if(pStr != NULL){
						strcpy(itemName, pStr);
						free(pStr);
					}
					else{
						nResult = -1;
						break;
					}
				}

				pItemID = ConcatPidls(pItemIDFolder,pItemIDFile);
				if(!(SHGetPathFromIDList(pItemID,tmpPath)))
				{
					nResult = -1;
					break;
				}

				*pptListIDL = (PLISTIDL)malloc(sizeof(LISTIDL));
				if(*pptListIDL == NULL)
				{
					nResult = -1;
					break;
				}
				(*pptListIDL)->uMenuID = uItemID;
				(*pptListIDL)->next = NULL;
				strcpy((*pptListIDL)->path,tmpPath);

				*pptODMenuItem = (PODMENUITEM)malloc(sizeof(ODMENUITEM));
				ZeroMemory(*pptODMenuItem, sizeof(ODMENUITEM));
				if(*pptODMenuItem == NULL)
				{
					nResult = -1;
					break;
				}
				else
				{
					if(g_ptODMenuItem == NULL)
						g_ptODMenuItem = *pptODMenuItem;
				}
				(*pptODMenuItem)->uMenuID = uItemID;
				(*pptODMenuItem)->next = NULL;

				ZeroMemory(&tSHFileInfo, sizeof(tSHFileInfo));

				SHGetFileInfo((LPCTSTR)pItemID, 0, &tSHFileInfo, sizeof(tSHFileInfo),
								SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON);
				(*pptODMenuItem)->hMenuIcon = tSHFileInfo.hIcon;

				AddMenuItem(hMenu, uItemID, MFT_OWNERDRAW, itemName, NULL);
				strcpy((*pptODMenuItem)->sMenuStr, itemName);
			}
			else{
				nResult = -1;
				break;
			}

			pMalloc->lpVtbl->Free(pMalloc, pItemID);
			pMalloc->lpVtbl->Free(pMalloc, pItemIDFile);
			pptListIDL    = &(*pptListIDL)->next;
			pptODMenuItem = &(*pptODMenuItem)->next;
			uItemID++;
		}
	}

	if(pEnumIDFile != NULL)
		pEnumIDFile->lpVtbl->Release(pEnumIDFile);

	if(pFolder != NULL)
		pFolder->lpVtbl->Release(pFolder);

	pMalloc->lpVtbl->Free(pMalloc, pItemIDFolder);

	if(nResult != 0)
		return FALSE;
	return TRUE;
}
Exemplo n.º 3
0
/****************************************************************************
*
*  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();
}
Exemplo n.º 4
0
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() ;
}