能显示文字的进度条 CTextProgressCtrl重载CProgressCtrl(作者: Written by Chris Maunder ([email protected]))

进度条控制的类,这个类最重要的功能就是允许在进度条中显示文字。void setshowtext(bool bshow); 

   你可以通过这个函数来设置是否能显示文字。设置文字你可以用cwnd::setwindowtext,如果你用函数setshowtext(true)来设置能显示文字,但是你没有用cwnd::setwindowtext来设置要显示的文字是什么,那么该类就会用默认的设置,只显示进度百分比,这点大家还是要注意的。 
    

    下面是添加该类的详细步骤:
    一、在VC工程的菜单栏中点击“View”选项,选择其中的“ClassWizard”.
    

 

二、在弹出的“MFC ClassWizard”对话框中点击“Add  Class”中的“New”选项。

 

三、在弹出的New Class对话框中,写入新加类的名称为CTextProgressCtrl,选择其基类为“CProgressCtrl”,最后点击“OK”按钮。如此一来,工程中会增加“TextProgressCtrl.cpp”、“TextProgressCtrl.h”两个文件。

 

四、编写CMemDC类如下:

#ifndef _MEMDC_H_
//////////////////////////////////////////////////
// CMemDC - memory DC
//
// Author: Keith Rule
// Email:  [email protected]
// Copyright 1996-1997, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// History - 10/3/97 Fixed scrolling bug.
//                   Added print support.
//
// This class implements a memory Device Context

class CMemDC : public CDC
{
public:

    // constructor sets up the memory DC
    CMemDC(CDC* pDC) : CDC()
    {
        ASSERT(pDC != NULL);

        m_pDC = pDC;
        m_pOldBitmap = NULL;
        m_bMemDC = !pDC->IsPrinting();
              
        if (m_bMemDC)    // Create a Memory DC
        {
            pDC->GetClipBox(&m_rect);
            CreateCompatibleDC(pDC);
            m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
            m_pOldBitmap = SelectObject(&m_bitmap);
            SetWindowOrg(m_rect.left, m_rect.top);
        }
        else        // Make a copy of the relevent parts of the current DC for printing
        {
            m_bPrinting = pDC->m_bPrinting;
            m_hDC       = pDC->m_hDC;
            m_hAttribDC = pDC->m_hAttribDC;
        }
    }
    
    // Destructor copies the contents of the mem DC to the original DC
    ~CMemDC()
    {
        if (m_bMemDC) 
        {    
            // Copy the offscreen bitmap onto the screen.
            m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
                          this, m_rect.left, m_rect.top, SRCCOPY);

            //Swap back the original bitmap.
            SelectObject(m_pOldBitmap);
        } else {
            // All we need to do is replace the DC with an illegal value,
            // this keeps us from accidently deleting the handles associated with
            // the CDC that was passed to the constructor.
            m_hDC = m_hAttribDC = NULL;
        }
    }

    // Allow usage as a pointer
    CMemDC* operator->() {return this;}
        
    // Allow usage as a pointer
    operator CMemDC*() {return this;}

private:
    CBitmap  m_bitmap;      // Offscreen bitmap
    CBitmap* m_pOldBitmap;  // bitmap originally found in CMemDC
    CDC*     m_pDC;         // Saves CDC passed in constructor
    CRect    m_rect;        // Rectangle of drawing area.
    BOOL     m_bMemDC;      // TRUE if CDC really is a Memory DC.
};

#endif

 

五、为该类添加以下私有变量

protected:
    int   m_nPos, 
    m_nStepSize, 
    m_nMax, 
    m_nMin;
    CString  m_strText;
    BOOL  m_bShowText;
    int   m_nBarWidth;
    COLORREF m_colFore,
    m_colBk,
    m_colTextFore,
    m_colTextBk;

 

六、在构造函数中为私有变量赋值

 CTextProgressCtrl::CTextProgressCtrl()
{
    m_nPos   = 0;
    m_nStepSize  = 1;
    m_nMax   = 100;
    m_nMin   = 0;
    m_bShowText  = TRUE;
    m_strText.Empty();
    m_colFore  = ::GetSysColor(COLOR_HIGHLIGHT);
    m_colBk   = ::GetSysColor(COLOR_MENU/*COLOR_WINDOW*/);
    m_colTextFore = ::GetSysColor(COLOR_HIGHLIGHT);
    m_colTextBk  = ::GetSysColor(COLOR_WINDOW);
 
    m_nBarWidth = -1;
}

 

七、在VC工程的菜单栏中点击“View”选项,选择其中的“ClassWizard”.依次为CTextProgressCtrl类添加以下消息:

       ON_WM_PAINT

       ON_WM_SIZE

       ON_WM_ERASEBKGND

       代码如下:

 /***********************************************ON_WM_PAINT消息代码********************************************************/

void CTextProgressCtrl::OnPaint() 
{
 if (m_nMin >= m_nMax) 
        return;

    CRect LeftRect, RightRect, ClientRect;
    GetClientRect(ClientRect);

    double Fraction = (double)(m_nPos - m_nMin) / ((double)(m_nMax - m_nMin));

 CPaintDC PaintDC(this); // device context for painting
    CMemDC dc(&PaintDC);
 //CPaintDC dc(this);    // device context for painting (if not double buffering)

    LeftRect = RightRect = ClientRect;

    LeftRect.right = LeftRect.left + (int)((LeftRect.right - LeftRect.left)*Fraction);
    dc.FillSolidRect(LeftRect, m_colFore);

    RightRect.left = LeftRect.right;
    dc.FillSolidRect(RightRect, m_colBk);

    if (m_bShowText)
    {
        CString str;
        if (m_strText.GetLength())
            str = m_strText;
        else
            str.Format("%d%%", (int)(Fraction*100.0));

        dc.SetBkMode(TRANSPARENT);

        CRgn rgn;
        rgn.CreateRectRgn(LeftRect.left, LeftRect.top, LeftRect.right, LeftRect.bottom);
        dc.SelectClipRgn(&rgn);
        dc.SetTextColor(m_colTextBk);

        dc.DrawText(str, ClientRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

        rgn.DeleteObject();
        rgn.CreateRectRgn(RightRect.left, RightRect.top, RightRect.right, RightRect.bottom);
        dc.SelectClipRgn(&rgn);
        dc.SetTextColor(m_colTextFore);

        dc.DrawText(str, ClientRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    }
}

 /********************************************************************************************************************************/

 /*********************************************ON_WM_SIZE消息代码**********************************************************/

void CTextProgressCtrl::OnSize(UINT nType, int cx, int cy) 
{
 CProgressCtrl::OnSize(nType, cx, cy);
 
 // TODO: Add your message handler code here
 m_nBarWidth = -1;   // Force update if SetPos called
}

 /*********************************************************************************************************************************/

 /**************************************ON_WM_ERASEBKGND消息代码******************************************************/

BOOL CTextProgressCtrl::OnEraseBkgnd(CDC* /*pDC*/) 
{
 // TODO: Add your message handler code here and/or call default
 
 return TRUE;
}

 /*******************************************************************************************************/

 

      

 

八,手动在代码中添加WM_SETTEXT、WM_GETTEXT消息

      TextProgressCtrl.cpp中添加代码如下:

     BEGIN_MESSAGE_MAP(CTextProgressCtrl, CProgressCtrl)
 //{{AFX_MSG_MAP(CTextProgressCtrl)
 ON_WM_PAINT()
 ON_WM_SIZE()
 ON_WM_ERASEBKGND()
 //}}AFX_MSG_MAP
 ON_MESSAGE(WM_SETTEXT, OnSetText)
    ON_MESSAGE(WM_GETTEXT, OnGetText)
END_MESSAGE_MAP()

LRESULT CTextProgressCtrl::OnSetText(UINT, LPCTSTR szText)
{
    LRESULT result = Default();

    if ( (!szText && m_strText.GetLength()) ||
         (szText && (m_strText != szText))   )
    {
        m_strText = szText;
        Invalidate();
    }

    return result;
}

LRESULT CTextProgressCtrl::OnGetText(UINT cchTextMax, LPTSTR szText)
{
    if (!_tcsncpy(szText, m_strText, cchTextMax))
        return 0;
    else 
        return min(cchTextMax, (UINT) m_strText.GetLength());
}

 

TextProgressCtrl.h中添加代码如下:

//{{AFX_MSG(CTextProgressCtrl)
 afx_msg void OnPaint();
 afx_msg void OnSize(UINT nType, int cx, int cy);
 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
 //}}AFX_MSG
    afx_msg LRESULT OnSetText(UINT, LPCTSTR szText);
    afx_msg LRESULT OnGetText(UINT cchTextMax, LPTSTR szText);

 

九、依次为CTextProgressCtrl类添加如下函数:

 
  void SetForeColour(colorref col) 设置进度条中的条的颜色 
  void SetBkColour(colorref col) 设置进度条的背景色 
  void SetTextForeColour(colorref col) 当进度条没有覆盖文本时,文本的颜色 
  void SetTextBkColour(colorref col) 当进度条覆盖文本时,文本的颜色 
  CORLORREF GetForeColour() 得到进度条中条的颜色 
  CORLORREF GetBkColour() 得到进度条的背景色 
  CORLORREF GetTextForeColour() 当进度条没有覆盖文本时,得到文本的颜色 
  CORLORREF GetTextBkColour() 当进度条覆盖文本时,得到文本的颜色

        int SetStep(int nStep);       设置进度条步进
        int OffsetPos(int nPos);    指定增量来增加进度条的当前位置
        int StepIt(); 用每一步的增量来增加进度条的当前位置
        int SetPos(int nPos); 设置进度条的当前位置
        void SetRange(int nLower, int nUpper); 设置进度条范围
        void SetShowText(BOOL bShow);    设置是否能显示文字

 

以下是上述函数的具体代码:

void CTextProgressCtrl::SetForeColour(COLORREF col)
{
    m_colFore = col;
}

void CTextProgressCtrl::SetBkColour(COLORREF col)
{
    m_colBk = col;
}

void CTextProgressCtrl::SetTextForeColour(COLORREF col)
{
    m_colTextFore = col;
}

void CTextProgressCtrl::SetTextBkColour(COLORREF col)
{
    m_colTextBk = col;
}

COLORREF CTextProgressCtrl::GetForeColour()
{
    return m_colFore;
}

COLORREF CTextProgressCtrl::GetBkColour()
{
    return m_colBk;
}

COLORREF CTextProgressCtrl::GetTextForeColour()
{
    return m_colTextFore;
}

COLORREF CTextProgressCtrl::GetTextBkColour()
{
    return m_colTextBk;
}

void CTextProgressCtrl::SetShowText(BOOL bShow)
{
    if (::IsWindow(m_hWnd) && m_bShowText != bShow)
        Invalidate();

    m_bShowText = bShow;
}

void CTextProgressCtrl::SetRange(int nLower, int nUpper)
{
    m_nMax = nUpper;
    m_nMin = nLower;
}

int CTextProgressCtrl::SetPos(int nPos)
{
    if (!::IsWindow(m_hWnd))
        return -1;

    int nOldPos = m_nPos;
    m_nPos = nPos;

    CRect rect;
    GetClientRect(rect);

    double Fraction = (double)(m_nPos - m_nMin) / ((double)(m_nMax - m_nMin));
    int nBarWidth = (int) (Fraction * rect.Width());

    if (nBarWidth != m_nBarWidth)
    {
        m_nBarWidth = nBarWidth;
        RedrawWindow();
    }

    return nOldPos;
}

int CTextProgressCtrl::StepIt()
{
    return SetPos(m_nPos + m_nStepSize);
}

int CTextProgressCtrl::OffsetPos(int nPos)
{
    return SetPos(m_nPos + nPos);
}

int CTextProgressCtrl::SetStep(int nStep)
{
    int nOldStep = nStep;
    m_nStepSize = nStep;
    return nOldStep;

}

代码:链接

猜你喜欢

转载自blog.csdn.net/eric_e/article/details/80671645
今日推荐