谈VC++中的Progress 控件的使用

发表于:2007-07-04来源:作者:点击数: 标签:
大连捷通电脑技术有限公司 王 淼 Progress 控件能让人们感受到一个应用程序执行的进度,在很多应用程序中都能用到它,但通常只支持在单任务中,我在 Windows 98/NT 中文操作系统下,在VC ++6.0 环境下,利用线程编制了一个非常小巧的应用程序来实现Progress
大连捷通电脑技术有限公司 王 淼

  Progress 控件能让人们感受到一个应用程序执行的进度,在很多应用程序中都能用到它,但通常只支持在单任务中,我在Windows98/NT 中文操作系统下,在VC ++6.0 环境下,利用线程编制了一个非常小巧的应用程序来实现Progress 控件的使用。它可以支持多线程,使用起来很方便。

  以下是这个应用程序的源代码:

//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;
    // 中止按钮显示开关
   BOOL m_IsCancel; 
    // 中止按钮是否按下开关
   HANDLE m_Thread;    // 线程句柄
   static DWORD WINAPI ThreadProc(CProgress
Dialog *dlg); // 静态线程
   void SetProgress(int percent) // 设置进程位置
   { m_ProgressCtrl.SetPos(percent);}
   void SetMessage(LPCSTR msg)
    // 设置进程条标题
   { m_MessageStatic.SetWindowText(msg);}
   BOOL IsCancel(void)
   { return m_IsCancel;}
   virtual DWORD ProgressProc()=0;
    // 线程过程纯虚函数
// 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 handlers
BOOL 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::ThreadProc,
      (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;
}
  只需在应用Progress 控件的地方调用CMyProgressDialog 类的对象即可。可根据不同的应用程序修改DWORD CMyProgressDialog::ProgressProc() 这个继承函数的函数体来适应相应的程序。  

原文转自:http://www.ltesting.net