WTL 绘制的进度条,逻辑清晰明了,代码函数清晰易懂:基本思路就是 首先绘制 进度条背景图,然后根据动态进度不断重绘前景进度条,绘制操作在OnPaint函数里画。该类可以直接用于项目中。
使用示例:
MyProgress* pMyProgress = new MyProgress;
CRect rcProgress;
rcProgress.top = 500;
rcProgress.left = 240;
rcProgress.right = rcProgress.left + 500;
rcProgress.bottom = rcProgress.top + 20;
CString strFore = Util::GetCurrentDir();
strFore += L"\img\ui\progress_fore.png";
CString strBgnd = Util::GetCurrentDir();
strBgnd += L"\img\ui\progress_bgnd.png";
pMyProgress->SetRange(0,100);
pMyProgress->SetProgressBmp(strFore,strBgnd);
pMyProgress->Create(m_hWnd,rcProgress,NULL,WS_CHILD|WS_VISIBLE);
效果图如下:

进度条自定义类代码如下:
#pragma once
#pragma comment(lib, "gdiplus.lib")
static ULONG_PTR s_gdiplusToken3=0;
class MyProgress:public CWindowImpl<MyProgress>
{
public:
MyProgress()
{
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&s_gdiplusToken3, &gdiplusStartupInput, NULL);
}
~MyProgress()
{
GdiplusShutdown(s_gdiplusToken3);
}
protected:
BEGIN_MSG_MAP(MyProgress)
MESSAGE_HANDLER(WM_CREATE,OnCreate)
MESSAGE_HANDLER(WM_PAINT,OnPaint)
MESSAGE_HANDLER(WM_DESTROY,OnDestroy)
MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBkgnd)
END_MSG_MAP()
HBITMAP GetBitmapFromFile( LPCWSTR pFile )
{
std::auto_ptr<Bitmap> pBmp(new Bitmap(pFile));
if(!pBmp.get())
return NULL;
HBITMAP hBmp = NULL;
Color backColor = Color(255,0,0,0);
if(Ok!=pBmp->GetHBITMAP(backColor,&hBmp))
return NULL;
return hBmp;
}
void SetProgressBmp(CString strFore,CString strBgnd)
{
m_btm_fore.Attach(GetBitmapFromFile(strFore));
m_btm_bgnd.Attach(GetBitmapFromFile(strBgnd));
}
BOOL DrawBmp( HDC hdc, CRect rect, HBITMAP hBitmap )
{
BITMAP bm;
GetObject(hBitmap,sizeof(bm),(VOID*)&bm);
INT nWidth = bm.bmWidth;
INT nHeight = bm.bmHeight;
CDC memdc;
memdc.CreateCompatibleDC(hdc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(hdc,nWidth,nHeight);
memdc.SelectBitmap(hBitmap);
//BLENDFUNCTION bf = {AC_SRC_OVER,0,255,1};
//return ::AlphaBlend(hdc,rect.left,rect.top,nWidth,nHeight,memdc,0,0,nWidth,nHeight,bf);
return ::StretchBlt(hdc,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,
memdc,0,0,nWidth,nHeight,SRCCOPY );
}
void SetPos(int nPos)
{
m_nPos = nPos;
m_nPercent = GetPercent();
RedrawWindow();
}
void SetRange(int nMin,int nMax)
{
if(nMin > nMin)
return;
m_nMin = nMin;
m_nMax = nMax;
}
int GetRange()
{
return m_nMax - m_nMin;
}
int GetPercent()
{
return (m_nPos * 100)/GetRange();
}
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
m_nMin = 0;
m_nMax = 100;
m_nPos = 0;
m_nPercent =0;
m_bHasDrawBgnd = FALSE;
GetClientRect(&m_rcWindow);
GetClientRect(&m_rcProgress);
SetWindowPos(HWND_TOPMOST,m_rcWindow,SWP_SHOWWINDOW);
return TRUE;
}
LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return TRUE;
}
LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return TRUE;
}
LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CPaintDC dc(m_hWnd);
int nWidth = m_rcWindow.right - m_rcWindow.left;
int nHeight = m_rcWindow.bottom - m_rcWindow.top;
if(!m_bHasDrawBgnd)
{
//画背景
DrawBmp(dc,m_rcWindow,m_btm_bgnd);
m_bHasDrawBgnd = TRUE;
}
//画动态进度条部分
m_rcProgress.right = m_rcProgress.left + nWidth*GetPercent()/100;
DrawBmp(dc,m_rcProgress,m_btm_fore);
return TRUE;
}
private:
int m_nMin;
int m_nMax;
int m_nPos;
int m_nPercent;
BOOL m_bHasDrawBgnd;
CBitmap m_btm_fore;
CBitmap m_btm_bgnd;
CRect m_rcWindow;
CRect m_rcProgress;
};