示例#1
0
HRESULT CDataObject::_CollectFiles(IShellFolder* pShellFolder, PCIDLIST_RELATIVE pidlFolder, LPCWSTR pstrFolder, CPidl& pidls)
{
   ATLASSERT(pShellFolder);
   UINT nCount = pidls.GetItemCount();
   for( UINT i = 0; i < nCount; i++ ) 
   {
      CPidl pidlItem = pidls.GetItem(i);

      WIN32_FIND_DATA wfd = { 0 };
      HRESULT Hr = ::SHGetDataFromIDList(pShellFolder, pidlItem.GetItem(0), SHGDFIL_FINDDATA, &wfd, sizeof(wfd));
      if( FAILED(Hr) ) return Hr;

      FILEDESCRIPTOR fd = { 0 };
      fd.dwFlags = (DWORD)(FD_FILESIZE | FD_ATTRIBUTES | FD_UNICODE);
      if( _ShellModule.GetConfigBool(VFS_CAN_PROGRESSUI) ) fd.dwFlags |= FD_PROGRESSUI;
      wcscpy_s(fd.cFileName, lengthof(fd.cFileName), pstrFolder);
      wcscat_s(fd.cFileName, lengthof(fd.cFileName), wfd.cFileName);
      fd.nFileSizeLow = wfd.nFileSizeLow;
      if( IsFileTimeValid(wfd.ftCreationTime) ) fd.ftCreationTime = wfd.ftCreationTime, fd.dwFlags |= FD_CREATETIME;
      if( IsFileTimeValid(wfd.ftLastWriteTime) ) fd.ftLastWriteTime = wfd.ftLastWriteTime, fd.dwFlags |= FD_WRITESTIME;
      if( IsFileTimeValid(wfd.ftLastAccessTime) ) fd.ftLastAccessTime = wfd.ftLastAccessTime, fd.dwFlags |= FD_ACCESSTIME;
      fd.dwFileAttributes = wfd.dwFileAttributes;

      // Setup item info into <sizel>
      NSEFILEPIDLDATA * pNseInfo = (NSEFILEPIDLDATA *)pidlItem.GetItem(0);
      if (pNseInfo && pNseInfo->magic == TARFILE_MAGIC_ID && pNseInfo->cb == sizeof(NSEFILEPIDLDATA)){
            fd.sizel.cx = pNseInfo->wfd.dwId.category; fd.sizel.cy = pNseInfo->wfd.dwId.id;
      }      

	  // Setup parent info into <pointl>
      if (m_spFolder && m_spFolder->m_spFolderItem){
            VFS_FIND_DATA vfd = m_spFolder->m_spFolderItem->GetFindData();
            fd.pointl.x = vfd.dwId.category; fd.pointl.y = vfd.dwId.id;
      }      

      if( !m_aFiles.Add(fd) ) return E_OUTOFMEMORY;

      // Recurse into sub-folders...
      // HarryWu, 2014.7.21
      // it is high-cost and terrible, and not need for non-http mode.
      if( FALSE && IsBitSet(wfd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) )
      {
         CComPtr<IShellFolder> spSubFolder;
         HR( pShellFolder->BindToObject(pidlItem, NULL, IID_PPV_ARGS(&spSubFolder)) );
         CComPtr<IEnumIDList> spEnum;
         HR( spSubFolder->EnumObjects(m_hwndOwner, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_STORAGE, &spEnum) );
         ULONG uFetched = 0;
         CPidl pidlSubItems;
         PITEMID_CHILD pidlChild = NULL;
         while( spEnum->Next(1, &pidlChild, &uFetched), uFetched > 0 ) {
            pidlSubItems.Append(pidlChild);
            ::CoTaskMemFree(pidlChild);
            uFetched = 0;
         }
         WCHAR wszSubFolder[MAX_PATH] = { 0 };
         ::wnsprintf(wszSubFolder, lengthof(wszSubFolder) - 1, L"%s%s\\", pstrFolder, wfd.cFileName);
         CPidl pidlSubFolder = pidlFolder + pidlItem;
         HR( _CollectFiles(spSubFolder, pidlSubFolder, wszSubFolder, pidlSubItems) );
      }
   }
   return S_OK;
}