1、CProgressBar.h
class CProgressBar : public CProgressCtrl
{
// Construction
public:
CProgressBar();
CProgressBar(LPCTSTR strMessage, int nSize=100, int MaxValue=100,
BOOL bSmooth=FALSE, int nPane=0);
virtual ~CProgressBar();
BOOL Create(LPCTSTR strMessage, int nSize=100, int MaxValue=100,
BOOL bSmooth=FALSE, int nPane=0);
//DECLARE_DYNCREATE(CProgressBar)
// Attributes
public:
BOOL SetRange(int nLower, int nUpper, int nStep = 1);
BOOL SetText(LPCTSTR strMessage);
BOOL SetSize(int nSize);
COLORREF SetBarColour(COLORREF clrBar);
COLORREF SetBkColour(COLORREF clrBk);
int SetPos(int nPos);
int OffsetPos(int nPos);
int SetStep(int nStep);
int StepIt();
void Clear();
// Operations
public:
int m_nSize; // Percentage size of control
int m_nPane; // ID of status bar pane progress bar is to appear in
CString m_strMessage; // Message to display to left of control
CString m_strPrevText; // Previous text in status bar
CRect m_Rect; // Dimensions of the whole thing
CStatusBar *GetStatusBar();
BOOL Resize();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CProgressBar)
//}}AFX_VIRTUAL
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CProgressBar)
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
2、CProgressBar.cpp
// ProgressBar.cpp : implementation file
//
#include "stdafx.h"
#include "StateBar.h"
#include "ProgressBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/**//////////////////////////////////////////////////////////////////////////////// CProgressBar
CProgressBar::CProgressBar()
{
m_Rect.SetRect(0,0,0,0);
}
CProgressBar::CProgressBar(LPCTSTR strMessage, int nSize/**//* =100 */, int MaxValue/**//* =100 */, BOOL bSmooth/**//* =FALSE */, int nPane/**//* =0 */)
{
Create(strMessage,nSize,MaxValue,bSmooth,nPane);
}
CProgressBar::~CProgressBar()
{
Clear();
}
BEGIN_MESSAGE_MAP(CProgressBar, CProgressCtrl)
//{{AFX_MSG_MAP(CProgressBar)
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/**//////////////////////////////////////////////////////////////////////////////// CProgressBar message handlers
void CProgressBar::Clear()
{
if(!IsWindow(GetSafeHwnd()))
return;
ModifyStyle(WS_VISIBLE,0);
CString str;
if(m_nPane==0)
str.LoadString(AFX_IDS_IDLEMESSAGE);
else
str=m_strPrevText;
CStatusBar* pStatusBar=GetStatusBar();
if(pStatusBar)
{
pStatusBar->SetPaneText(m_nPane,str);
pStatusBar->UpdateWindow();
}
}
BOOL CProgressBar::Create(LPCTSTR strMessage, int nSize/**//* =100 */, int MaxValue/**//* =100 */, BOOL bSmooth/**//* =FALSE */, int nPane/**//* =0 */)
{
BOOL bSuccess = FALSE;
CStatusBar * pStatusBar = GetStatusBar();
if(!pStatusBar)
return FALSE;
DWORD dwStyle=WS_CHILD|WS_VISIBLE;
#ifdef PBS_SMOOTH
if(bSmooth)
dwStyle|=PBS_SMOOTH;
#endif
CRect PaneRect;
pStatusBar->GetItemRect(nPane,&PaneRect);
bSuccess=CProgressCtrl::Create(dwStyle,PaneRect,pStatusBar,1);
ASSERT(bSuccess);
if(!bSuccess)
return FALSE;
SetRange(0,MaxValue);
SetStep(1);
m_strMessage=strMessage;
m_nPane=nPane;
m_nSize=nSize;
m_strPrevText=pStatusBar->GetPaneText(m_nPane);
Resize();
return TRUE;
}
CStatusBar* CProgressBar::GetStatusBar()
{
CWnd *pMainWnd = AfxGetMainWnd();
//主窗口指针。多文档、单文档返回的是CMainFrame指针,对话框的是主对话框的CDialog指针
if (!pMainWnd)
return NULL;
// If main window is a frame window, use normal methods
if (pMainWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd)))//如果对象对应于该类
{
CWnd* pMessageBar = ((CFrameWnd*)pMainWnd)->GetMessageBar();
return DYNAMIC_DOWNCAST(CStatusBar, pMessageBar);
}
// otherwise traverse children to try and find the status bar
else
return DYNAMIC_DOWNCAST(CStatusBar,
pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR));
}
BOOL CProgressBar::SetText(LPCTSTR strMessage)
{
m_strMessage = strMessage;
return Resize();
}
BOOL CProgressBar::SetSize(int nSize)
{
m_nSize = nSize;
return Resize();
}
COLORREF CProgressBar::SetBarColour(COLORREF clrBar)
{
#ifdef PBM_SETBKCOLOR
if (!IsWindow(GetSafeHwnd()))
return CLR_DEFAULT;
return SendMessage(PBM_SETBARCOLOR, 0, (LPARAM) clrBar);
#else
UNUSED(clrBar);
return CLR_DEFAULT;
#endif
}
COLORREF CProgressBar::SetBkColour(COLORREF clrBk)
{
#ifdef PBM_SETBKCOLOR
if (!IsWindow(GetSafeHwnd()))
return CLR_DEFAULT;
return SendMessage(PBM_SETBKCOLOR, 0, (LPARAM) clrBk);
#else
UNUSED(clrBk);
return CLR_DEFAULT;
#endif
}
BOOL CProgressBar::SetRange(int nLower, int nUpper, int nStep /**//* = 1 */)
{
if (!IsWindow(GetSafeHwnd()))
return FALSE;
// To take advantage of the Extended Range Values we use the PBM_SETRANGE32
// message intead of calling CProgressCtrl::SetRange directly. If this is
// being compiled under something less than VC 5.0, the necessary defines
// may not be available.
#ifdef PBM_SETRANGE32
ASSERT(-0x7FFFFFFF <= nLower && nLower <= 0x7FFFFFFF);
ASSERT(-0x7FFFFFFF <= nUpper && nUpper <= 0x7FFFFFFF);
SendMessage(PBM_SETRANGE32, (WPARAM) nLower, (LPARAM) nUpper);
#else
ASSERT(0 <= nLower && nLower <= 65535);
ASSERT(0 <= nUpper && nUpper <= 65535);
CProgressCtrl::SetRange(nLower, nUpper);
#endif
CProgressCtrl::SetStep(nStep);
return TRUE;
}
int CProgressBar::SetPos(int nPos)
{
if (!IsWindow(GetSafeHwnd()))
return 0;
#ifdef PBM_SETRANGE32
ASSERT(-0x7FFFFFFF <= nPos && nPos <= 0x7FFFFFFF);
#else
ASSERT(0 <= nPos && nPos <= 65535);
#endif
ModifyStyle(0,WS_VISIBLE);
return CProgressCtrl::SetPos(nPos);
}
int CProgressBar::OffsetPos(int nPos)
{
if (!IsWindow(GetSafeHwnd()))
return 0;
ModifyStyle(0,WS_VISIBLE);
return CProgressCtrl::OffsetPos(nPos);
}
int CProgressBar::SetStep(int nStep)
{
if (!IsWindow(GetSafeHwnd()))
return 0;
ModifyStyle(0,WS_VISIBLE);
return CProgressCtrl::SetStep(nStep);
}
int CProgressBar::StepIt()
{
if (!IsWindow(GetSafeHwnd()))
return 0;
ModifyStyle(0,WS_VISIBLE);
return CProgressCtrl::StepIt();
}
BOOL CProgressBar::Resize()
{
if (!IsWindow(GetSafeHwnd()))
//IsWindow:该函数确定给定的窗口句柄是否识别一个已存在的窗口。
//当我们想得到一个窗口对象(CWnd的派生对象)指针的句柄(HWND)时,最安全的方法是使用GetSafeHwnd()函数
return FALSE;
CStatusBar *pStatusBar = GetStatusBar();
if (!pStatusBar)
return FALSE;
// Redraw the window text
if (IsWindowVisible())//该函数获得给定窗口的可视状态
{
pStatusBar->SetPaneText(m_nPane, m_strMessage);//设置StatusBar的文本
pStatusBar->UpdateWindow();
}
// Calculate how much space the text takes up
CClientDC dc(pStatusBar);
CFont *pOldFont = dc.SelectObject(pStatusBar->GetFont());
CSize size = dc.GetTextExtent(m_strMessage);
//使用该函数获得所选字体中指定字符串的高度和宽度
int margin = dc.GetTextExtent(_T(" ")).cx * 2; // Text margin
dc.SelectObject(pOldFont);
// Now calculate the rectangle in which we will draw the progress bar
CRect rc;
pStatusBar->GetItemRect(m_nPane, rc);
// Position left of progress bar after text and right of progress bar
// to requested percentage of status bar pane
if (!m_strMessage.IsEmpty())
rc.left += (size.cx + 2*margin);
rc.right -= (rc.right - rc.left) * (100 - m_nSize) / 100;
if (rc.right < rc.left) rc.right = rc.left;
// Leave a litle vertical margin (10%) between the top and bottom of the bar
int Height = rc.bottom - rc.top;
rc.bottom -= Height/10;
rc.top += Height/10;
// If the window size has changed, resize the window
if (rc != m_Rect)
{
MoveWindow(&rc);
m_Rect = rc;
}
return TRUE;
}
BOOL CProgressBar::OnEraseBkgnd(CDC* pDC)
{
Resize();
return CProgressCtrl::OnEraseBkgnd(pDC);
}
3、关于CProgressBar类的简单应用
成员函数 |
说明 |
BOOL Success() |
用于确定该类的构造是否成功 |
COLORREF SetBarColour(COLORREF clrBar) |
设置进度条的填充色 |
COLORREF SetBkColour(COLORREF clrBar) |
设置进度条的背景色 |
int SetPos(int nPos) |
把进度条的当前位置设置为指定的值并重绘新位置 |
int OffsetPos(int nPos) |
通过在当前位置基础上加上由nPos指定的值,并使进度条控件的当前位置向前移动,然后重绘进度条,以反映新的位置 |
int SetStep(int nStep) |
设置进度条控件的步长增量(和StepIt函数一起使用)。在CProgressBar创建时,这个值默认为1 |
int StepIt() |
按通过SetStep函数指定的量使进度条的当前位置向前移动 |
void Clear() |
清除进度条 |
void SetRange(int nLower,int nUpper,int nStep=1) |
设置低限、高限以及步长值 |
void SetText(LPCTSTR strMessage) |
指定与进度条控件一起出现的文本消息,通常类似于“x%”,其中,x表示进度条的当前位置 |
void SetSize(int nSize) |
设置进度条的水平大小 |
void CMainFrame::OnSmooth()
{
// TODO: Add your command handler code here
CProgressBar bar(_T("Progress"), 40, 10000,TRUE);
for (int i = 0; i < 10000; i++) {
CString str;
str.Format("%d%% complete", i*100/10000);
bar.SetText(str);
bar.StepIt();
PeekAndPump();
}
}
void CMainFrame::OnNsmooth()
{
// TODO: Add your command handler code here
CProgressBar bar(_T("Progress"), 40, 10000);
for (int i = 0; i < 10000; i++) {
CString str;
str.Format("%d%% complete", i*100/10000);
bar.SetText(str);
bar.StepIt();
PeekAndPump();
}
}
1)CProgressBar bar(_T(
"Progress"), 40, 10000,TRUE);创建一个进度条,Progress为其开始的文本,40表示进度条的大小,10000是进度条的最大值,TRUE表示是否平滑。
2) str.Format("%d%% complete", i*100/10000);bar.SetText(str);设置进度条前面的文本,表示进度读条的百分比
3)PeekAndPump();加入该函数则进度条滚动时可以与窗口进行交互(比如改变窗口大小)
posted on 2009-07-03 20:18
The_Moment 阅读(1943)
评论(0) 编辑 收藏 引用 所属分类:
VC实践