| 控制項 | 類型 | ID | 變數名 | 說明 |
|---|---|---|---|---|
| 主目錄 | ComboBox | IDC_MAIN_DIR | m_cbMainDir | 下拉列表顯示常用根目錄 |
| 子目錄 | ListBox | IDC_SUB_DIRS | m_lbSubDirs | 列出當前目錄下的子目錄 |
| 所有文件 | ListBox | IDC_LIST_ALL_FILES | m_lbAllFiles | 列出當前目錄下的文件(含隱藏/系統/只讀) |
BOOL CMyDialog::OnInitDialog() {
CDialogEx::OnInitDialog();
char szBuf[MAX_PATH];
m_cbMainDir.AddString(_T("C:\\"));
GetWindowsDirectory(szBuf, MAX_PATH); m_cbMainDir.AddString(szBuf);
szBuf[2] = '\0'; m_cbMainDir.AddString(szBuf); // 根目錄 C:\
GetSystemDirectory(szBuf, MAX_PATH); m_cbMainDir.AddString(szBuf);
GetCurrentDirectory(MAX_PATH, szBuf); m_cbMainDir.AddString(szBuf);
return TRUE;
}
void CMyDialog::OnCbnSelchangeMainDir() {
CString strDir, strPath;
int nSel = m_cbMainDir.GetCurSel();
if (nSel == CB_ERR) return;
m_cbMainDir.GetLBText(nSel, strDir);
m_lbSubDirs.ResetContent();
m_lbAllFiles.ResetContent();
strPath = strDir + _T("\\*.*");
CFileFind finder;
BOOL bWorking = finder.FindFile(strPath);
while (bWorking) {
bWorking = finder.FindNextFile();
if (finder.IsDots()) continue; // 忽略 "." 與 ".."
if (finder.IsDirectory()) {
m_lbSubDirs.AddString(finder.GetFileName());
} else {
// 文件:檔案屬性位元組合判斷
DWORD attr = finder.GetFileAttributes();
if (attr & FILE_ATTRIBUTE_ARCHIVE ||
attr & FILE_ATTRIBUTE_HIDDEN ||
attr & FILE_ATTRIBUTE_READONLY ||
attr & FILE_ATTRIBUTE_SYSTEM) {
m_lbAllFiles.AddString(finder.GetFileName());
}
}
}
finder.Close();
}
WIN32_FIND_DATA::dwFileAttributes 為位元組合,常見常數(winnt.h):
| 常數 | 值 | 含義 |
|---|---|---|
| FILE_ATTRIBUTE_READONLY | 0x00000001 | 唯讀 |
| FILE_ATTRIBUTE_HIDDEN | 0x00000002 | 隱藏 |
| FILE_ATTRIBUTE_SYSTEM | 0x00000004 | 系統檔案 |
| FILE_ATTRIBUTE_DIRECTORY | 0x00000010 | 目錄 |
| FILE_ATTRIBUTE_ARCHIVE | 0x00000020 | 存檔標記(備份工具使用) |
| FILE_ATTRIBUTE_NORMAL | 0x00000080 | 標準檔案(無其他屬性) |
| FILE_ATTRIBUTE_TEMPORARY | 0x00000100 | 暫存檔案 |
| FILE_ATTRIBUTE_COMPRESSED | 0x00000800 | 壓縮 |
| FILE_ATTRIBUTE_ENCRYPTED | 0x00004000 | 加密 (EFS) |
正確判斷目錄:(attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY
正確判斷一般文件:(attr & FILE_ATTRIBUTE_DIRECTORY) == 0
void EnumAll(const CString& path, CStringArray& dirs, CStringArray& files) {
CFileFind finder;
CString spec = path + _T("\\*.*");
BOOL b = finder.FindFile(spec);
while (b) {
b = finder.FindNextFile();
if (finder.IsDots()) continue;
if (finder.IsDirectory()) {
dirs.Add(finder.GetFilePath());
EnumAll(finder.GetFilePath(), dirs, files); // 遞歸
} else {
files.Add(finder.GetFilePath());
}
}
finder.Close();
}
Close() 釋放句柄。== 比較完整值(一個文件通常同時擁有多個屬性)。CString、CFileFind 皆支援寬字元,無需手動轉碼。CListCtrl (Report 模式) + 虛擬模式 或 分頁載入。MFC CFileFind 封裝了 FindFirstFile/FindNextFile,配合位元屬性判斷,能輕鬆實現目錄/文件枚舉、遞歸遍歷與屬性過濾。掌握位元組合邏輯與資源釋放時機,是編寫健壯文件操作代碼的關鍵。