home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / filefind.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  8KB  |  364 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. ////////////////////////////////////////////////////////////////////////////
  14. // CFileFind implementation
  15.  
  16. CFileFind::CFileFind()
  17. {
  18.     m_pFoundInfo = NULL;
  19.     m_pNextInfo = NULL;
  20.     m_hContext = NULL;
  21.     m_chDirSeparator = '\\';
  22. }
  23.  
  24. CFileFind::~CFileFind()
  25. {
  26.     Close();
  27. }
  28.  
  29. void CFileFind::Close()
  30. {
  31.     if (m_pFoundInfo != NULL)
  32.     {
  33.         delete m_pFoundInfo;
  34.         m_pFoundInfo = NULL;
  35.     }
  36.  
  37.     if (m_pNextInfo != NULL)
  38.     {
  39.         delete m_pNextInfo;
  40.         m_pNextInfo = NULL;
  41.     }
  42.  
  43.     if (m_hContext != NULL && m_hContext != INVALID_HANDLE_VALUE)
  44.     {
  45.         CloseContext();
  46.         m_hContext = NULL;
  47.     }
  48. }
  49.  
  50. void CFileFind::CloseContext()
  51. {
  52.     ::FindClose(m_hContext);
  53.     return;
  54. }
  55.  
  56. BOOL CFileFind::FindFile(LPCTSTR pstrName /* = NULL */,
  57.     DWORD dwUnused /* = 0 */)
  58. {
  59.     UNUSED_ALWAYS(dwUnused);
  60.     Close();
  61.     m_pNextInfo = new WIN32_FIND_DATA;
  62.     m_bGotLast = FALSE;
  63.  
  64.     if (pstrName == NULL)
  65.         pstrName = _T("*.*");
  66.     lstrcpy(((WIN32_FIND_DATA*) m_pNextInfo)->cFileName, pstrName);
  67.  
  68.     m_hContext = ::FindFirstFile(pstrName, (WIN32_FIND_DATA*) m_pNextInfo);
  69.  
  70.     if (m_hContext == INVALID_HANDLE_VALUE)
  71.     {
  72.         DWORD dwTemp = ::GetLastError();
  73.         Close();
  74.         ::SetLastError(dwTemp);
  75.         return FALSE;
  76.     }
  77.  
  78.     LPTSTR pstrRoot = m_strRoot.GetBufferSetLength(_MAX_PATH);
  79.     LPCTSTR pstr = _tfullpath(pstrRoot, pstrName, _MAX_PATH);
  80.  
  81.     // passed name isn't a valid path but was found by the API
  82.     ASSERT(pstr != NULL);
  83.     if (pstr == NULL)
  84.     {
  85.         m_strRoot.ReleaseBuffer(-1);
  86.         Close();
  87.         ::SetLastError(ERROR_INVALID_NAME);
  88.         return FALSE;
  89.     }
  90.     else
  91.     {
  92.         // find the last forward or backward whack
  93.         LPTSTR pstrBack  = _tcsrchr(pstrRoot, '\\');
  94.         LPTSTR pstrFront = _tcsrchr(pstrRoot, '/');
  95.  
  96.         if (pstrFront != NULL || pstrBack != NULL)
  97.         {
  98.             if (pstrFront == NULL)
  99.                 pstrFront = pstrRoot;
  100.             if (pstrBack == NULL)
  101.                 pstrBack = pstrRoot;
  102.  
  103.             // from the start to the last whack is the root
  104.  
  105.             if (pstrFront >= pstrBack)
  106.                 *pstrFront = '\0';
  107.             else
  108.                 *pstrBack = '\0';
  109.         }
  110.         m_strRoot.ReleaseBuffer(-1);
  111.     }
  112.  
  113.     return TRUE;
  114. }
  115.  
  116. BOOL CFileFind::MatchesMask(DWORD dwMask) const
  117. {
  118.     ASSERT(m_hContext != NULL);
  119.     ASSERT_VALID(this);
  120.  
  121.     if (m_pFoundInfo != NULL)
  122.         return (!!(((LPWIN32_FIND_DATA) m_pFoundInfo)->dwFileAttributes & dwMask));
  123.     else
  124.         return FALSE;
  125. }
  126.  
  127. BOOL CFileFind::GetLastAccessTime(FILETIME* pTimeStamp) const
  128. {
  129.     ASSERT(m_hContext != NULL);
  130.     ASSERT(pTimeStamp != NULL);
  131.     ASSERT_VALID(this);
  132.  
  133.     if (m_pFoundInfo != NULL && pTimeStamp != NULL)
  134.     {
  135.         *pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastAccessTime;
  136.         return TRUE;
  137.     }
  138.     else
  139.         return FALSE;
  140. }
  141.  
  142. BOOL CFileFind::GetLastWriteTime(FILETIME* pTimeStamp) const
  143. {
  144.     ASSERT(m_hContext != NULL);
  145.     ASSERT(pTimeStamp != NULL);
  146.     ASSERT_VALID(this);
  147.  
  148.     if (m_pFoundInfo != NULL && pTimeStamp != NULL)
  149.     {
  150.         *pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastWriteTime;
  151.         return TRUE;
  152.     }
  153.     else
  154.         return FALSE;
  155. }
  156.  
  157. BOOL CFileFind::GetCreationTime(FILETIME* pTimeStamp) const
  158. {
  159.     ASSERT(m_hContext != NULL);
  160.     ASSERT_VALID(this);
  161.  
  162.     if (m_pFoundInfo != NULL && pTimeStamp != NULL)
  163.     {
  164.         *pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftCreationTime;
  165.         return TRUE;
  166.     }
  167.     else
  168.         return FALSE;
  169. }
  170.  
  171. BOOL CFileFind::GetLastAccessTime(CTime& refTime) const
  172. {
  173.     ASSERT(m_hContext != NULL);
  174.     ASSERT_VALID(this);
  175.  
  176.     if (m_pFoundInfo != NULL)
  177.     {
  178.         refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastAccessTime);
  179.         return TRUE;
  180.     }
  181.     else
  182.         return FALSE;
  183. }
  184.  
  185. BOOL CFileFind::GetLastWriteTime(CTime& refTime) const
  186. {
  187.     ASSERT(m_hContext != NULL);
  188.     ASSERT_VALID(this);
  189.  
  190.     if (m_pFoundInfo != NULL)
  191.     {
  192.         refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastWriteTime);
  193.         return TRUE;
  194.     }
  195.     else
  196.         return FALSE;
  197. }
  198.  
  199. BOOL CFileFind::GetCreationTime(CTime& refTime) const
  200. {
  201.     ASSERT(m_hContext != NULL);
  202.     ASSERT_VALID(this);
  203.  
  204.     if (m_pFoundInfo != NULL)
  205.     {
  206.         refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftCreationTime);
  207.         return TRUE;
  208.     }
  209.     else
  210.         return FALSE;
  211. }
  212.  
  213. BOOL CFileFind::IsDots() const
  214. {
  215.     ASSERT(m_hContext != NULL);
  216.     ASSERT_VALID(this);
  217.  
  218.     // return TRUE if the file name is "." or ".." and
  219.     // the file is a directory
  220.  
  221.     BOOL bResult = FALSE;
  222.     if (m_pFoundInfo != NULL && IsDirectory())
  223.     {
  224.         LPWIN32_FIND_DATA pFindData = (LPWIN32_FIND_DATA) m_pFoundInfo;
  225.         if (pFindData->cFileName[0] == '.')
  226.         {
  227.             if (pFindData->cFileName[1] == '\0' ||
  228.                 (pFindData->cFileName[1] == '.' &&
  229.                  pFindData->cFileName[2] == '\0'))
  230.             {
  231.                 bResult = TRUE;
  232.             }
  233.         }
  234.     }
  235.  
  236.     return bResult;
  237. }
  238.  
  239. BOOL CFileFind::FindNextFile()
  240. {
  241.     ASSERT(m_hContext != NULL);
  242.  
  243.     if (m_hContext == NULL)
  244.         return FALSE;
  245.     if (m_pFoundInfo == NULL)
  246.         m_pFoundInfo = new WIN32_FIND_DATA;
  247.  
  248.     ASSERT_VALID(this);
  249.  
  250.     void* pTemp = m_pFoundInfo;
  251.     m_pFoundInfo = m_pNextInfo;
  252.     m_pNextInfo = pTemp;
  253.  
  254.     return ::FindNextFile(m_hContext, (LPWIN32_FIND_DATA) m_pNextInfo);
  255. }
  256.  
  257. CString CFileFind::GetFileURL() const
  258. {
  259.     ASSERT(m_hContext != NULL);
  260.     ASSERT_VALID(this);
  261.  
  262.     CString strResult("file://");
  263.     strResult += GetFilePath();
  264.     return strResult;
  265. }
  266.  
  267. CString CFileFind::GetRoot() const
  268. {
  269.     ASSERT(m_hContext != NULL);
  270.     ASSERT_VALID(this);
  271.  
  272.     return m_strRoot;
  273. }
  274.  
  275. CString CFileFind::GetFilePath() const
  276. {
  277.     ASSERT(m_hContext != NULL);
  278.     ASSERT_VALID(this);
  279.  
  280.     CString strResult = m_strRoot;
  281.     if (strResult[strResult.GetLength()-1] != '\\' &&
  282.         strResult[strResult.GetLength()-1] != '/')
  283.         strResult += m_chDirSeparator;
  284.     strResult += GetFileName();
  285.     return strResult;
  286. }
  287.  
  288. CString CFileFind::GetFileTitle() const
  289. {
  290.     ASSERT(m_hContext != NULL);
  291.     ASSERT_VALID(this);
  292.  
  293.     CString strFullName = GetFileName();
  294.     CString strResult;
  295.  
  296.     _tsplitpath(strFullName, NULL, NULL, strResult.GetBuffer(_MAX_PATH), NULL);
  297.     strResult.ReleaseBuffer();
  298.     return strResult;
  299. }
  300.  
  301. CString CFileFind::GetFileName() const
  302. {
  303.     ASSERT(m_hContext != NULL);
  304.     ASSERT_VALID(this);
  305.  
  306.     CString ret;
  307.  
  308.     if (m_pFoundInfo != NULL)
  309.         ret = ((LPWIN32_FIND_DATA) m_pFoundInfo)->cFileName;
  310.     return ret;
  311. }
  312.  
  313. DWORD CFileFind::GetLength() const
  314. {
  315.     ASSERT(m_hContext != NULL);
  316.     ASSERT_VALID(this);
  317.  
  318.     if (m_pFoundInfo != NULL)
  319.         return ((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeLow;
  320.     else
  321.         return 0;
  322. }
  323.  
  324. #if defined(_X86_) || defined(_ALPHA_)
  325. __int64 CFileFind::GetLength64() const
  326. {
  327.     ASSERT(m_hContext != NULL);
  328.     ASSERT_VALID(this);
  329.  
  330.     if (m_pFoundInfo != NULL)
  331.         return ((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeLow +
  332.                 (((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeHigh << 32);
  333.     else
  334.         return 0;
  335. }
  336. #endif
  337.  
  338. #ifdef _DEBUG
  339. void CFileFind::Dump(CDumpContext& dc) const
  340. {
  341.     CObject::Dump(dc);
  342.     dc << "\nm_hContext = " << (UINT) m_hContext;
  343. }
  344.  
  345. void CFileFind::AssertValid() const
  346. {
  347.     // if you trip the ASSERT in the else side, you've called
  348.     // a Get() function without having done at least one
  349.     // FindNext() call
  350.  
  351.     if (m_hContext == NULL)
  352.         ASSERT(m_pFoundInfo == NULL && m_pNextInfo == NULL);
  353.     else
  354.         ASSERT(m_pFoundInfo != NULL && m_pNextInfo != NULL);
  355.  
  356. }
  357. #endif
  358.  
  359. #ifdef AFX_INIT_SEG
  360. #pragma code_seg(AFX_INIT_SEG)
  361. #endif
  362.  
  363. IMPLEMENT_DYNAMIC(CFileFind, CObject)
  364.