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

VC++ 進度條控件多線程應用實作:CProgressDialog 封裝類

     編輯:關於VC++

前言

進度條控件(CProgressCtrl)廣泛用於長時間操作的視覺化回饋。傳統單執行緒實作會阻塞 UI,導致介面凍結。本文提供一個支援多執行緒、可取消、可自訂進度邏輯的 CProgressDialog 封裝類,適用於 VC++ 6.0 / Windows 98/NT 環境。

核心類別設計

1. 基底類別 CProgressDialog

class CProgressDialog : public CDialog
{
public:
    CProgressDialog(LPCSTR caption, BOOL enableCancel = TRUE, CWnd* pParent = NULL);
    virtual ~CProgressDialog();

    // 進度控制介面
    void SetProgress(int percent) { m_ProgressCtrl.SetPos(percent); }
    void SetMessage(LPCSTR msg) { m_MessageStatic.SetWindowText(msg); }
    BOOL IsCancel() { return m_IsCancel; }

    // 純虛函數:衍生類實作具體工作邏輯
    virtual DWORD ProgressProc() = 0;

protected:
    // 對話框資料成員
    CStatic m_MessageStatic;   // 訊息標籤
    CButton m_CancelButton;    // 取消按鈕
    CProgressCtrl m_ProgressCtrl; // 進度條
    CString m_Caption;         // 對話框標題
    BOOL m_EnableCancel;       // 是否啟用取消
    BOOL m_IsCancel;           // 取消旗標
    HANDLE m_Thread;           // 工作執行緒控制代碼

    // 靜態執行緒入口函數
    static DWORD WINAPI ThreadProc(CProgressDialog* dlg);

    // 訊息映射
    virtual BOOL OnInitDialog();
    virtual void OnCancel();
    virtual void OnOK();
    DECLARE_MESSAGE_MAP()
};

2. 關鍵實作細節

執行緒啟動與同步

BOOL CProgressDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    m_ProgressCtrl.SetRange(0, 100);
    m_ProgressCtrl.SetPos(0);
    SetWindowText(m_Caption);

    if (!m_EnableCancel)
        m_CancelButton.ShowWindow(SW_HIDE);

    DWORD threadID;
    m_Thread = CreateThread(
        NULL, 0,
        (LPTHREAD_START_ROUTINE)ThreadProc,
        (LPVOID)this, 0, &threadID
    );
    return TRUE;
}

DWORD WINAPI CProgressDialog::ThreadProc(CProgressDialog* dlg)
{
    DWORD ret = dlg->ProgressProc(); // 呼叫衍生類實作
    dlg->PostMessage(WM_COMMAND, IDOK); // 工作完成通知 UI
    return ret;
}

取消與關閉處理

void CProgressDialog::OnCancel()
{
    if (m_EnableCancel) m_IsCancel = TRUE; // 只設旗標,不直接關閉
}

void CProgressDialog::OnOK()
{
    WaitForSingleObject(m_Thread, INFINITE); // 等待執行緒結束
    CDialog::OnOK();
}

CProgressDialog::~CProgressDialog()
{
    if (m_Thread) CloseHandle(m_Thread);
}

3. 衍生類實作範例

class CMyProgressDialog : public CProgressDialog
{
public:
    CMyProgressDialog(LPCSTR caption) : CProgressDialog(caption) {}
    virtual DWORD ProgressProc();
};

DWORD CMyProgressDialog::ProgressProc()
{
    SetMessage("Progress...");
    for (int i = 0; i < 100; i++)
    {
        if (IsCancel()) break; // 檢查取消旗標
        Sleep(100);            // 模擬工作負載
        SetProgress(i);        // 更新進度
    }
    return 0;
}

使用方式

void CMainDlg::OnStartTask()
{
    CMyProgressDialog dlg("資料處理中...");
    dlg.DoModal(); // 模態對話框,自動管理執行緒生命週期
}

設計優勢

  • 非阻塞 UI:工作在背景執行緒,主執行緒保持響應
  • 支援取消:輪詢 IsCancel() 實作優雅中止
  • 介面分離:基底類處理 UI/執行緒,衍生類專注業務邏輯
  • 資源安全:建構/解構函數自動管理執行緒控制代碼

擴充建議

  1. 新增 SetRange(min, max) 支援非 0-100 進度範圍
  2. 支援 PostMessage 自訂訊息回報詳細狀態
  3. 整合 CWinThread 替代原生 CreateThread 以利 MFC 同步物件
  4. 加入例外處理機制,確保執行緒異常時正確清理

結語

此封裝類展示了 MFC 中結合 Worker Thread 與 UI 控件的經典模式。透過純虛函數隔離業務邏輯,開發者只需專注 ProgressProc() 實作,即可快速建立專業級進度對話框。

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