VC++中的Progress控件如何使用

字號:

Progress控件能讓人們感受到一個應(yīng)用程序執(zhí)行的進度,在很多應(yīng)用程序中都能用到它,但通常只支持在單任務(wù)中,在Windows98/NT中文操作系統(tǒng)下,在VC++6.0環(huán)境下,利用線程編制了一個非常小巧的應(yīng)用程序來實現(xiàn)Progress控件的使用。它可以支持多線程,使用起來很方便。
    以下是這個應(yīng)用程序的源代碼:
    //ProgressDialog.h
    class CProgressDialog : public CDialog
    {
    // Construction
    public:
    CProgressDialog(LPCSTR caption, BOOL
    enableCancel=TRUE, CWnd* pParent = NULL);
    // standard constructor
    virtual ~CProgressDialog(void);
    // Dialog Data
    //{{AFX_DATA(CProgressDialog)
    enum { IDD = IDD_PROGRESS_DIALOG };
    CStatic
    m_MessageStatic; //進程條標題
    CButton m_CancelButton; //中止按鈕控鍵
    CProgressCtrl
    m_ProgressCtrl;
    //}}AFX_DATA
    CString m_Caption;
     //對話框標題
    BOOL m_EnableCancel; //中止按鈕顯示開關(guān)
    BOOL m_IsCancel; //中止按鈕是否按下開關(guān)
    HANDLE m_Thread;
     //線程句柄
    static DWORD WINAPI ThreadProc(CProgressDialog* dlg); //靜態(tài)線程
    void SetProgress(int percent) //設(shè)置進程位置
    { m_ProgressCtrl.SetPos(percent);}
    void SetMessage(LPCSTR msg) //設(shè)置進程條標題
    { m_MessageStatic.SetWindowText(msg);}
    BOOL IsCancel(void)
    { return m_IsCancel;}
    virtual DWORD ProgressProc()=0;//線程過程純虛函數(shù)
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CProgressDialog)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);
    // DDX/DDV support
    //}}AFX_VIRTUAL
    // Implementation
    protected:
    // Generated message map functions
    //{{AFX_MSG(CProgressDialog)
    virtual BOOL OnInitDialog();
    virtual void OnCancel();
    virtual void OnOK();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    };
    class CMyProgressDialog:public CProgressDialog {
    public:
    CMyProgressDialog(LPCSTR caption):CProgressDialog(caption) {}
    virtual DWORD ProgressProc(); //繼承過程
    };
    // ProgressDialog.cpp
    #include "stdafx.h"
    #include "ProgressTest.h"
    #include "ProgressDialog.h"
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    CProgressDialog::CProgressDialog(LPCSTR caption, BOOL enableCancel, CWnd* pParent /*=NULL*/) :
    CDialog(CProgressDialog::IDD, pParent)
    {
    //{{AFX_DATA_INIT(CProgressDialog)
    m_Caption=caption;
    m_EnableCancel=enableCancel;
    m_IsCancel=FALSE;
    m_Thread=NULL;
    //}}AFX_DATA_INIT
    }
    CProgressDialog::~CProgressDialog(void)
    {
    if (m_Thread) {
    CloseHandle(m_Thread);
    }}
    void
    CProgressDialog::DoDataExchange(CDataExchange* pDX)
    {CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CProgressDialog)
    DDX_Control (pDX IDC_MESSAGE_STATIC, m_MessageStatic);
    DDX_Control(pDX, IDCANCEL, m_CancelButton);
    DDX_Control(pDX, IDC_PROGRESS, m_ProgressCtrl);
    //}}AFX_DATA_MAP
    }
    BEGIN_MESSAGE_MAP(CProgressDialog, CDialog)
    //{{AFX_MSG_MAP(CProgressDialog)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    // CProgressDialog message handlersBOOL CProgressDialog::OnInitDialog()
    {
    CDialog::OnInitDialog();
    // TODO: Add extra initialization here
    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)CProgressDialog::Thread
    Proc,(LPVOID)this,0,&threadID);
    return TRUE; // return TRUE unless you set the focus to a control
     // EXCEPTION: OCX Property Pages should return
    FALSE
    }
    DWORD WINAPI
    CProgressDialog::ThreadProc(CProgressDialog* dlg)
    {DWORD ret=dlg->ProgressProc();
    dlg->PostMessage(WM_COMMAND, IDOK);
    return ret;
    }
    void CProgressDialog::OnCancel()
    {
    // TODO: Add extra cleanup here
    if (m_EnableCancel) m_IsCancel=TRUE;
    }
    void CProgressDialog::OnOK()
    {
    // TODO: Add extra validation here
    WaitForSingleObject(m_Thread, INFINITE);
    CDialog::OnOK();
    }DWORD CMyProgressDialog::ProgressProc()
    {SetMessage("Progress...");
    for (int i=0;i<100;i++) {
    if (IsCancel()) break;
    Sleep(100);
    SetProgress(i);
    }
    return 0;
    }
    只需在應(yīng)用Progress控件的地方調(diào)用CMyProgressDialog類的對象即可??筛鶕?jù)不同的應(yīng)用程序修改DWORD CMyProgressDialog::ProgressProc()這個繼承函數(shù)的函數(shù)體來適應(yīng)相應(yīng)的程序。