进度条(CProgressCtrl)自绘

  1. 关键函数:GetRange(获取进度条范围)、GetPos(获取当前位置)。
  2. CProgresCtrl自绘比较简单,只要重写OnPaint。
  3. 代码:
    //CMyProgressCtrl头文件
    
    #pragma once
    
    
    
    // CMyProgressCtrl
    
    class CMyProgressCtrl : public CProgressCtrl
    
    {
    
    	DECLARE_DYNAMIC(CMyProgressCtrl)
    
    
    
    public:
    
    	CMyProgressCtrl();
    
    	virtual ~CMyProgressCtrl();
    
    	typedef enum _ALIGN_TEXT_
    
    	{
    
    		ALIGN_LEFT = 0x00,
    
    		ALIGN_CENTER,
    
    		ALIGN_RIGHT
    
    	}ALIGN_TEXT;
    
    
    
    protected:
    
    	DECLARE_MESSAGE_MAP()
    
    private:
    
    	COLORREF m_clrBarFgColor;//进度条前景色
    
    	COLORREF m_clrBarBkColor;//进度条背景色
    
    	COLORREF m_clrTextFgColor;//文本前景色
    
    	COLORREF m_clrTextBkColor;//文本背景色
    
    	ALIGN_TEXT m_AlignText;//文本对齐方式
    
    	BOOL m_bShowPercent;//是否显示百分比
    
    	CFont m_font;//文本字体
    
    public:
    
    	afx_msg void OnPaint();
    
    
    
    	inline void SetBarFgColor(COLORREF clr) {m_clrBarFgColor = clr;}
    
    	inline void SetBarBkColor(COLORREF clr) {m_clrBarBkColor = clr;}
    
    	inline void SetTextFgColor(COLORREF clr) {m_clrTextFgColor = clr;}
    
    	inline void SetTextBkColor(COLORREF clr) {m_clrTextBkColor = clr;}
    
    	inline void SetAlignText(ALIGN_TEXT AlignText) {m_AlignText = AlignText;}
    
    	inline void ShowPercent(BOOL bShowPercent = TRUE) {m_bShowPercent = bShowPercent;}
    
    	inline COLORREF GetBarFgColor() {return m_clrBarFgColor;}
    
    	inline COLORREF GetBarBkColor() {return m_clrBarBkColor;}
    
    	inline COLORREF GetTextFgColor() {return m_clrTextFgColor;}
    
    	inline COLORREF GetTextBkColor() {return m_clrTextBkColor;}
    
    	inline ALIGN_TEXT GetAlignText() {return m_AlignText;}
    
    	inline BOOL IsShowPercent(){return m_bShowPercent;}
    
    //	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    
    };
    
    
    // MyProgressCtrl.cpp : implementation file
    
    //
    
    #include "stdafx.h"
    
    #include "Progress_0100.h"
    
    #include "MyProgressCtrl.h"
    
    
    
    // CMyProgressCtrl
    
    IMPLEMENT_DYNAMIC(CMyProgressCtrl, CProgressCtrl)
    
    
    
    CMyProgressCtrl::CMyProgressCtrl() : m_clrBarFgColor(RGB(128, 128, 255)),
    
    				m_clrBarBkColor(RGB(235, 235, 235)),
    
    				m_clrTextFgColor(RGB(0, 0, 0)),
    
    				m_clrTextBkColor(RGB(255, 255, 255)),
    
    				m_AlignText(ALIGN_CENTER),
    
    				m_bShowPercent(TRUE)
    
    {
    
    }
    
    
    
    CMyProgressCtrl::~CMyProgressCtrl()
    
    {
    
    	if(m_font.GetSafeHandle())
    
    	{
    
    		m_font.DeleteObject();
    
    	}
    
    }
    
    
    
    BEGIN_MESSAGE_MAP(CMyProgressCtrl, CProgressCtrl)
    
    	ON_WM_PAINT()
    
    //	ON_WM_ERASEBKGND()
    
    END_MESSAGE_MAP()
    
    
    
    // CMyProgressCtrl message handlers
    
    void CMyProgressCtrl::OnPaint()
    
    {
    
    	CPaintDC paintDC(this); // device context for painting
    
    	// TODO: Add your message handler code here
    
    	//进度条范围
    
    	int nMin = 0;
    
    	int nMax = 0;
    
    
    
    	GetRange(nMin, nMax);
    
    	ASSERT(nMin <= nMax);
    
    	//当前位置
    
    	int nPos = GetPos();
    
    	ASSERT(nPos >= nMin && nPos <= nMax);
    
    
    
    	DWORD dwStyle = GetStyle();
    
    	BOOL bVertical = FALSE;
    
    	if(dwStyle & PBS_VERTICAL)
    
    	{//如果竖直的
    
    		bVertical = TRUE;
    
    	}
    
    
    
    	//创建兼容dc
    
    	CDC dc;
    
    	dc.CreateCompatibleDC(&paintDC);
    
    	ASSERT(dc.GetSafeHdc());
    
    
    
    	CRect rect;//客户端区域
    
    	GetClientRect(&rect);
    
    	//创建兼容位图
    
    	CBitmap bmp;
    
    	bmp.CreateCompatibleBitmap(&paintDC, rect.Width(), rect.Height());
    
    	ASSERT(bmp.GetSafeHandle());
    
    
    
    	CBitmap * pOldBitmap = dc.SelectObject(&bmp);
    
    
    
    	CFont *pOldFont = NULL;
    
    	CWnd *pParent = GetParent();
    
    	ASSERT(pParent);
    
    	//设置文本字体
    
    	CFont *pFont = pParent->GetFont();
    
    	ASSERT(pFont);
    
    	if(bVertical)
    
    	{
    
    		if(NULL == m_font.GetSafeHandle())
    
    		{
    
    			LOGFONT lf = {0};
    
    			pFont->GetLogFont(&lf);
    
    			lf.lfEscapement = 900;
    
    			m_font.CreateFontIndirectW(&lf);
    
    		}
    
    		ASSERT(m_font.GetSafeHandle());
    
    		pOldFont = dc.SelectObject(&m_font);
    
    	}
    
    	else
    
    	{
    
    		pOldFont = dc.SelectObject(&m_font);
    
    	}
    
    
    
    	double dPercent = 1.0 * (nPos - nMin) / (nMax - nMin);
    
    	//绘制进度条外边框
    
    	dc.DrawEdge(rect, EDGE_SUNKEN, BF_RECT | BF_FLAT);
    
    	//绘制进度条内矩形
    
    	CRect rc(rect);
    
    	rc.DeflateRect(CSize(2, 2));
    
    	dc.FillSolidRect(&rc, m_clrBarBkColor);
    
    
    
    	//获取要绘制的文本
    
    	CString strText(_T(""));
    
    	GetWindowTextW(strText);
    
    	if(m_bShowPercent)
    
    	{
    
    		strText.AppendFormat(_T("完成%.lf%%"), dPercent * 100.0);
    
    	}
    
    
    
    	dc.SetBkMode(TRANSPARENT);
    
    
    
    	CPoint pt(0, 0);//绘制文本的位置
    
    	CSize size = dc.GetOutputTextExtent(strText);//字体大小
    
    	CRect rcPos(rc);//进度条已前进的范围
    
    
    
    	if(!bVertical)
    
    	{
    
    		switch(m_AlignText)
    
    		{
    
    		case ALIGN_LEFT:
    
    			pt.x = rc.left;
    
    			break;
    
    		case ALIGN_RIGHT:
    
    			pt.x = rc.right - size.cx;
    
    			break;
    
    		case ALIGN_CENTER:
    
    		default:
    
    			pt.x = rc.left + (rc.Width() - size.cx) / 2;
    
    			break;
    
    		}
    
    		pt.y = rc.top + (rc.Height() - size.cy) / 2;
    
    
    
    		rcPos.right = rcPos.left + (int)(dPercent * rcPos.Width());
    
    	}
    
    	else
    
    	{
    
    		switch(m_AlignText)
    
    		{
    
    		case ALIGN_LEFT:
    
    			pt.y = rc.bottom;
    
    			break;
    
    		case ALIGN_RIGHT:
    
    			pt.y = rc.top + size.cx;
    
    			break;
    
    		case ALIGN_CENTER:
    
    		default:
    
    			pt.y = rc.top + rc.Height() / 2 + size.cx / 2;
    
    			break;
    
    		}
    
    		pt.x = rc.left + (rc.Width() - size.cy) / 2;
    
    
    
    		rcPos.top = rcPos.bottom - (int)(dPercent * rcPos.Height());
    
    	}
    
    	//绘制进度条已前进的矩形
    
    	dc.FillSolidRect(rcPos, m_clrBarFgColor);
    
    	//绘制文本
    
    	dc.SetTextColor(m_clrTextFgColor);
    
    	dc.ExtTextOutW(pt.x, pt.y, ETO_OPAQUE, rcPos, strText, NULL);
    
    
    
    	dc.SetTextColor(m_clrTextBkColor);
    
    	dc.ExtTextOutW(pt.x, pt.y, ETO_CLIPPED, &rcPos, strText, NULL);
    
    	//真正开始绘制
    
    	paintDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);
    
    
    
    	dc.SelectObject(pOldFont);
    
    	dc.SelectObject(pOldBitmap);
    
    	bmp.DeleteObject();
    
    
    
    	dc.DeleteDC();
    
    
    
    	// Do not call CProgressCtrl::OnPaint() for painting messages
    
    }
    
    
    
    //BOOL CMyProgressCtrl::OnEraseBkgnd(CDC* pDC)
    
    //{
    
    //	// TODO: Add your message handler code here and/or call default
    
    //	return TRUE;
    
    //	return CProgressCtrl::OnEraseBkgnd(pDC);
    
    //}
    
    
  4. 参考:
    http://blog.csdn.net/VisualEleven/article/details/6165007 
    http://hi.baidu.com/3582077/item/0491ea172298c858f1090e08

你可能感兴趣的:(progress)