Today, let's teach you how to make a self-made file resource manager (・).
compiler:Visual Studio 2019
Objectives:
1. Learn to use multithreading
2. Learn to recursively traverse all folders
Here are the teaching hours:
- Open the compiler and create an MFC application
- Draw bed mouth
- Create a thread
Note: because the workload is large when traversing the file, multithreading should be used to prevent the interface from faking death.
Write under / / CFileTreeDlg message handler
DWORD WINAPI EnumFileThread(LPARAM lParam) { CFileTreeDlg* dlg = (CFileTreeDlg*)lParam; return 0; }
Then create a thread in OnInitDialog():
BOOL CFileTreeDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Set the icon for this dialog box. When the main window of the application is not a dialog box, the frame will automatically // Do this SetIcon(m_hIcon, TRUE); // Set large icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: add additional initialization code here //Prevent interface fake death CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)EnumFileThread, this, 0, NULL); return TRUE; // Returns TRUE unless the focus is set to the control }
- Get drive letter
When inserting a file, we need to know where to insert it, so add a member variable:
HTREEITEM m_hTreeItem;
In OnInitDialog() / / TODO: add additional initialization code here. Write below
//Tree Root control operation m_hRootItem = m_tree.InsertItem(L"My computer");
Now let's get the drive letter.
We will use this function: GetLogicalDriveStrings
DWORD GetLogicalDriveStrings( DWORD nBufferLength, LPTSTR lpBuffer );
Parameters:
-
nBufferLength
[in]lpBuffer indicates the maximum size of the buffer, in TCHARS. This size does not include terminating null characters. If this parameter is zero, lpBuffer is not used. -
lpBuffer.
[out] pointer to a buffer that receives a series of null terminated strings, one for each valid dnive in the system, plus an additional null character. Each string is a device name.
Then CFileTreeDlg* dlg = (CFileTreeDlg*)lParam; Write below
wchar_t szBuffer[256] = { 0 }; DWORD dwLength = GetLogicalDriveStrings(sizeof szBuffer, szBuffer); //Cycle display drive letter for (int i = 0; i < dwLength / 4/*Here we should pay attention to divide by 4*/; i++) { CString strPANFU = szBuffer + 4 * i; //Insert tree control HTREEITEM hRootItem = dlg->m_FileTree.InsertItem(strPANFU, dlg->m_hRootItem); } return 0;
- Traversal file
The next step is the most important step of the file tree.
First define a member function FindFile();
void FindFile( /*route*/ CString strFileRootPath, /*Temp Tree node*/ HTREEITEM hRootItem);
In a multithreaded function, htreeitem hroottitem = DLG - > m_ FileTree. InsertItem(strPANFU, dlg->m_hRootItem); Write below
dlg->FindFile(strPANFU, hRootItem);
The function looks like this:
void CFileTreeDlg::FindFile( /*File directory*/ CString strFileRootPath, /*Temp Tree node*/ HTREEITEM hRootItem) { CFileFind finder; CString strFilePath; strFilePath = strFileRootPath + L"*.*";//*. * ☞ all documents //Record current node HTREEITEM hTemp; BOOL bRes; bRes = finder.FindFile(strFilePath);//See if this path exists while (bRes) { bRes = finder.FindNextFile();//Find the next file along the if (!finder.IsDots())//Whether IsDots is Or { if (finder.IsDirectory()) { CString strFileName = finder.GetFileName(); CString strFilePath = finder.GetFilePath() + L"\\*.*"; hTemp = m_tree.InsertItem(strFileName, hRootItem); FindFile(strFilePath, hTemp); } else { CString strFileName = finder.GetFileName(); m_tree.InsertItem(strFileName, hRootItem); } } } }
Here we traverse the file using a class called CFileFind
- MFC class CFileFind performs local file search and is the base class of CGopherFileFind and CFtpFileFind; The latter two categories are used for Internet File lookup. CFileFind includes member functions to start searching, locate files, and return Title names or paths. For Internet lookup, GetFileURL returns the URL of the file.
CFileFind is the base class of MFC class designed for other two kinds of special servers. CGopherFileFind works on Gopher server and CFtpFileFind works on FTP server. These classes provide a seamless mechanism for users to find files, which is independent of server protocol, file type, location, local machine or remote server.
First, enter the drive letter, like this:
CFileFind finder; CString strFilePath; strFilePath = strFileRootPath + L"*.*";//*. * ☞ all documents //Record current node HTREEITEM hTemp; BOOL bRes; bRes = finder.FindFile(strFilePath);//See if this path exists
After successful entry, traverse the file:
while (bRes) { bRes = finder.FindNextFile(); if (finder.IsDirectory())//If it is a folder, go into the folder and find it { CString strFileName = finder.GetFileName(); CString strFilePath = finder.GetFilePath() + L"\\*.*"; hTemp/*Mark the path this time*/ = m_tree.InsertItem(strFileName, hRootItem); /*Recursive search*/FindFile(strFilePath, hTemp); } else//If a file is found, a tree control is inserted { CString strFileName = finder.GetFileName(); m_tree.InsertItem(strFileName, hRootItem); } }
Now let's try to run
Therefore, when traversing the file, we should avoid "." And "..."
Modification code:
while (bRes) { bRes = finder.FindNextFile(); if (!finder.IsDots())//Whether IsDots is Or { if (finder.IsDirectory()) { CString strFileName = finder.GetFileName(); CString strFilePath = finder.GetFilePath() + L"\\*.*"; hTemp = m_tree.InsertItem(strFileName, hRootItem); FindFile(strFilePath, hTemp); } else { CString strFileName = finder.GetFileName(); m_tree.InsertItem(strFileName, hRootItem); } } }
Try in one run:
Success!!!!
If it's not easy to make comments in this tutorial area (・ if it's not easy to make comments.). Bye bye!