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; };