首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

MFC 無模式進度對話框與進程調用、目錄遞刪、磁碟資訊查詢綜合實作

     編輯:關於VC++

一、無模式進度對話框架構

核心模式:主視窗持有對話框指標,Create() 建立無模式對話框,DestroyWindow() 關閉,PostNcDestroy 自刪。

對話框類別 CModel


class CModel : public CDialog {
    CWnd* m_pParent; int m_nID;
public:
    CModel(CWnd* pParent = NULL) : CDialog(IDD, pParent) {
        m_pParent = pParent; m_nID = IDD;
    }
    BOOL Create() { return CDialog::Create(m_nID, m_pParent); }
    virtual void PostNcDestroy() { delete this; CDialog::PostNcDestroy(); }
};

主視窗調用


// 開啟
if (!m_pDlg) {
    m_pDlg = new CModel(this);
    m_pDlg->Create();
    GetDlgItem(IDC_EXPORT)->EnableWindow(FALSE); // 禁用觸發按鈕
} else {
    m_pDlg->SetActiveWindow();
}

// 關閉
if (m_pDlg) { m_pDlg->DestroyWindow(); m_pDlg = NULL; }

優點:主視窗保持可操作、進度對話框可拖動、支援取消按鈕 (對話框內設 OnCancel 呼叫 DestroyWindow)。

二、進程調用壓縮/解壓縮 (ARJ 範例)

策略:批次檔 + CreateProcess + 計時器輪詢完成旗標。

產生批次檔


void CMyCompress::CreateBat(CString BatPath, CString ArjPath, CString BatName,
                            CString ArjFile, CString TempPath, CString ExitFlag, BOOL bCompress) {
    CStdioFile f; f.Open(BatPath + BatName, CFile::modeCreate|CFile::modeWrite);
    CString cmd = bCompress ? "arj a -v" : "arj e -v";
    cmd += m_TotalBytes; // 分卷大小
    cmd += " ..\\" + ArjPath + "\\" + ArjFile + " ";
    cmd += bCompress ? "..\\" + TempPath + "\\*.* " : "..\\" + TempPath + "\\ ";
    cmd += "-y -jm\n";
    f.WriteString(cmd);
    f.WriteString("dir > " + ExitFlag + "\n"); // 完成旗標檔
    f.Close();
}

啟動進程並輪詢


void CMyCompress::RunBat(CString BatPath, CString BatName, CString ExitFlag) {
    STARTUPINFO si = {sizeof(si)}; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;
    PROCESS_INFORMATION pi;
    CreateProcess(BatPath + BatName, NULL, NULL, NULL, FALSE,
                  CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi);

    DeleteFile(ExitFlag); SetTimer(1, 100, NULL); m_bSearching = TRUE;
    // OnTimer 每 100ms 檢查 ExitFlag 是否存在
    // 存在 → KillTimer → TerminateProcess/CloseHandle → 後續處理
}

OnTimer:


void CMyCompress::OnTimer(UINT) {
    CFile f; if (f.Open(m_ExitFlag, CFile::modeRead)) { m_bSearching = FALSE; f.Close(); }
}

三、遞迴刪除目錄樹 DeleteTree

Win32 無對應 API,自行實作:


BOOL DeleteTree(CString Dir) {
    return PreRemoveDirectory(Dir) && RemoveDirectory(Dir);
}
BOOL PreRemoveDirectory(CString Dir) {
    SetCurrentDirectory(Dir);
    HANDLE h = FindFirstFile("*.*", &fd);
    if (h != INVALID_HANDLE_VALUE) {
        do {
            if (fd.cFileName[0]=='.') continue;
            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                PreRemoveDirectory(fd.cFileName), RemoveDirectory(fd.cFileName);
            else
                DeleteFile(fd.cFileName);
        } while (FindNextFile(h, &fd));
        FindClose(h);
    }
    SetCurrentDirectory(m_OriginalDir);
    return TRUE;
}

優於進程調用:無外部相依、效率高、易維護、可精細錯誤處理。

四、磁碟機資訊查詢與清空


// 列舉可移動磁碟
GetLogicalDriveStrings → GetDriveType == DRIVE_REMOVABLE → 加入下拉清單

// 查詢容量/序號/清空
GetDiskFreeSpace → 總/可用空間
GetVolumeInformation → 序號、檔案系統、磁碟標籤
PreRemoveDirectory(Drive) → 清空內容 (含寫保護檢查對話框)
SetVolumeLabel(Drive, NewLabel) → 設定磁碟標籤

架構比較與選擇指南

功能內部函式進程調用建議
壓縮/解壓演算法複雜、維護成本高成熟工具 (ARJ/7z)、一行命令進程調用
刪除目錄樹API 簡單、可控需外部命令、參數麻煩內部函式
磁碟資訊Win32 API 完整無標準命令列工具內部函式

原則:**演算法複雜/有成熟工具 → 進程調用;OS API 完整/邏輯簡單 → 內部函式**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved