www.pudn.com > CDlgProgress.zip > CDlgProgress.h


 
#pragma once 
#pragma warning(disable:4311) 
#pragma warning(disable:4312) 
#pragma comment(lib, "gdiplus.lib") 
#include  
using namespace Gdiplus; 
 
#ifndef CS_DROPSHADOW 
#define CS_DROPSHADOW 0x00020000 
#endif 
#ifndef LWA_ALPHA 
#define LWA_ALPHA 0x00000002 
#endif 
#ifndef WS_EX_LAYERED 
#define WS_EX_LAYERED 0x00080000 
#endif 
 
#define WM_PROGRESSUPDATE WM_USER + 100 
 
//A helper class that constructs a modal dialog from a template in memory 
class CMemDialog 
{ 
public: 
	CMemDialog(const wchar_t* szClassName, DWORD classStyle, DWORD style, DWORD dwExtendedStyle, void* pParam, DLGPROC dlgProc, HWND hParent) 
	{ 
		HLOCAL hDlgTemplate = NULL; 
		void FAR* lpDlgTemplate = NULL; 
		DLGTEMPLATE dlgTemplate; 
   		UINT nMenuNameLength = NULL; 
		UINT nClassNameLength = NULL; 
		void* pMenuName = NULL; 
		void* pClassName = NULL; 
 
		WNDCLASS wc; 
		GetClassInfo(AfxGetInstanceHandle(), L"#32770", &wc); 
		wc.lpszClassName = szClassName; 
		wc.style = CS_HREDRAW | CS_VREDRAW | classStyle; 
		AfxRegisterClass(&wc); 
 
		memset(&dlgTemplate, 0, sizeof(dlgTemplate)); 
 
		//Menu 
		nMenuNameLength = sizeof(WORD); 
		pMenuName = new BYTE[nMenuNameLength]; 
		*((WORD*)pMenuName) = 0x0000; 
 
		//Class 
		nClassNameLength = sizeof(WORD); 
		nClassNameLength += ((UINT)wcslen(szClassName)) * sizeof(WCHAR); 
		pClassName = new BYTE[nClassNameLength]; 
		*((WORD*) pClassName) = 0x0000; 
		wcscpy((WCHAR*)pClassName, szClassName); 
 
		dlgTemplate.style = style | DS_CENTER | DS_MODALFRAME; 
		dlgTemplate.dwExtendedStyle = dwExtendedStyle; 
		dlgTemplate.x = 0; 
		dlgTemplate.y = 0; 
		dlgTemplate.cx = 0; 
		dlgTemplate.cy = 0; 
 
		hDlgTemplate = LocalAlloc(LHND, (((sizeof(DLGTEMPLATE) +  nMenuNameLength + nClassNameLength) + 3) & ~3)); 
		lpDlgTemplate = LocalLock(hDlgTemplate); 
 
		BYTE* pMain = (BYTE*)lpDlgTemplate; 
		DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)lpDlgTemplate; 
		*pTemplate = dlgTemplate; 
 
		pMain += sizeof(dlgTemplate); 
 
		int nLenght = nMenuNameLength; 
		BYTE* p = (BYTE*) pMenuName; 
		for(; nLenght--; *pMain++ = *p++); 
 
		nLenght = nClassNameLength; 
		p = (BYTE*) pClassName; 
		for(; nLenght--; *pMain++ = *p++); 
 
		DialogBoxIndirectParam(NULL, (LPCDLGTEMPLATE)lpDlgTemplate, hParent, dlgProc,(LPARAM)pParam); 
 
		LocalUnlock(hDlgTemplate); 
		LocalFree(hDlgTemplate); 
 
		delete pClassName; 
		delete pMenuName; 
	} 
 
	~CMemDialog() 
	{ 
	} 
}; 
 
class CDlgProgress 
{ 
	typedef bool (*PROGRESSFUNC)(CDlgProgress*); 
 
	HWND m_hWnd; 
	bool m_bAllowCancel; 
	CWinThread*	m_hThread; 
	PROGRESSFUNC m_hThreadProc; 
	ULONG_PTR m_gdiplusToken; 
	double m_dPos; 
	wchar_t* m_strTitle; 
	bool m_bContinue; 
	 
	friend INT_PTR CALLBACK ProgressDlgProc(HWND, UINT, WPARAM, LPARAM); 
	friend UINT ThreadProc(LPVOID pData); 
 
public: 
	bool Continue() 
	{ 
		return m_bContinue; 
	} 
 
	HWND GetWindowHandle() 
	{ 
		return m_hWnd; 
	} 
 
	CDlgProgress(HWND hParentWnd, PROGRESSFUNC hThreadProc, const wchar_t* strTitle, bool bAllowCancel = false) 
	{ 
		GdiplusStartupInput gdiplusStartupInput; 
		GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); 
 
		m_hThread = NULL; 
		m_bAllowCancel = bAllowCancel; 
		m_hThreadProc = hThreadProc; 
 
		m_strTitle = new wchar_t[wcslen(strTitle) + 1]; 
		wcscpy(m_strTitle, strTitle); 
		m_strTitle[wcslen(strTitle)] = 0;	 
 
		CMemDialog dlg(L"CDlgProgress", CS_DROPSHADOW, WS_POPUP | WS_DISABLED, WS_EX_LAYERED, this, ProgressDlgProc, hParentWnd); 
	} 
 
	virtual ~CDlgProgress(void) 
	{ 
		GdiplusShutdown(m_gdiplusToken); 
		delete m_strTitle; 
	} 
 
	inline void SetProgress(CString strText, double dPos) 
	{ 
		m_dPos = dPos; 
		::SendMessage(m_hWnd, WM_PROGRESSUPDATE, (WPARAM)strText.GetBuffer(), 0); 
	} 
}; 
 
static UINT ThreadProc(LPVOID pData) 
{ 
	CDlgProgress* pDlgProgress = (CDlgProgress*) pData; 
	bool bRet = pDlgProgress->m_hThreadProc(pDlgProgress); 
 
	EndDialog(pDlgProgress->m_hWnd, 2); 
 
	return bRet; 
} 
 
static INT_PTR CALLBACK ProgressDlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam) 
{ 
	switch(Message) 
	{ 
		case WM_INITDIALOG: 
		{ 
			CDlgProgress *pProgressDialog = (CDlgProgress*) lParam; 
 
			typedef BOOL (WINAPI* lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags); 
			 
			HMODULE hDll = ::LoadLibrary(_T("USER32.dll")); 
 
			if(hDll) 
			{ 
				lpfnSetLayeredWindowAttributes pFn = NULL; 
				pFn = (lpfnSetLayeredWindowAttributes)GetProcAddress(hDll, "SetLayeredWindowAttributes"); 
				 
				if(pFn) 
					pFn(hDlg, NULL, 200, LWA_ALPHA); 
 
				::FreeLibrary(hDll); 
			} 
 
			pProgressDialog->m_hWnd = hDlg; 
 
			SetWindowLongPtr(hDlg, GWL_USERDATA,(LONG)pProgressDialog); 
			SendMessage(hDlg, WM_PROGRESSUPDATE, 0, 0); 
 
			RECT rc; 
			GetWindowRect(GetParent(hDlg), &rc); 
 
			if(rc.right - rc.left < 400 || rc.bottom - rc.top < 200) 
				GetWindowRect(GetDesktopWindow(), &rc); 
 
			rc.left = rc.left + (rc.right - rc.left - 400) / 2; 
			rc.top = rc.top  + (rc.bottom - rc.top  - 200) / 2; 
			rc.right = rc.left + 400; 
			rc.bottom = rc.top  + 200; 
 
			SetWindowPos(hDlg, NULL, rc.left, rc.top, 400, 200, SWP_NOZORDER | SWP_SHOWWINDOW); 
			pProgressDialog->m_hThread = AfxBeginThread(ThreadProc, pProgressDialog); 
		} 
		case WM_COMMAND: 
		{ 
			if(IDCANCEL == LOWORD(wParam)) 
			{ 
				CDlgProgress* pProgressDialog = (CDlgProgress*)GetWindowLongPtr(hDlg, GWL_USERDATA); 
				 
				if(pProgressDialog->m_bAllowCancel) 
				{ 
					pProgressDialog->m_bContinue = false; 
 
					if(pProgressDialog->m_hThread) 
						WaitForSingleObject(pProgressDialog->m_hThread, 5000); 
 
					EndDialog(hDlg, 2); 
				} 
				 
				return TRUE; 
			} 
 
			break; 
		}		 
		case WM_PROGRESSUPDATE: 
		{ 
			CDlgProgress* pProgressDialog = (CDlgProgress*)GetWindowLongPtr(hDlg, GWL_USERDATA); 
			wchar_t* strStatus = (wchar_t*)wParam; 
			double dProgress = pProgressDialog->m_dPos; 
 
			HDC dc = GetDC(hDlg); 
			HDC dcMem; 
			HBITMAP bm; 
			 
			bm = CreateCompatibleBitmap(dc, 400, 200); 
			dcMem = CreateCompatibleDC(dc); 
			SelectObject(dcMem, bm); 
 
			////////////////////////// 
			Graphics graphics(dcMem); 
			graphics.SetSmoothingMode(SmoothingModeAntiAlias); 
 
			GraphicsPath path; 
			path.AddEllipse(25, 25, 150, 150); 
			INT num = 1; 
 
			PathGradientBrush pthGrBrush(&path); 
			pthGrBrush.SetGammaCorrection(TRUE); 
			pthGrBrush.SetSurroundColors(&Color(255, 64, 64, 64), &num); 
			pthGrBrush.SetCenterColor(Color(255, 128, 128, 128)); 
 
			PathGradientBrush pthGrBrush2(&path); 
			pthGrBrush2.SetGammaCorrection(TRUE); 
			pthGrBrush2.SetSurroundColors(&Color(255, 64, 64, 64), &num); 
			pthGrBrush2.SetCenterColor(Color(255, 255, 128, 64)); 
 
			graphics.FillRectangle(&SolidBrush(Color(255, 128, 128, 128)), -5, -5, 410, 210); 
			graphics.FillPie(&pthGrBrush, 25, 25, 150, 150, 0, 360); 
			graphics.FillPie(&pthGrBrush2, 25, 25, 150, 150, 0, (365 * (REAL)dProgress) / 100); 
			//graphics.DrawRectangle(&Pen(Color(255, 255, 255, 255), 2), 0, 0, 399, 199); 
			graphics.DrawPie(&Pen(Color(255, 100, 100, 100)), 25, 25, 150, 150, 0, 360); 
			graphics.DrawPie(&Pen(Color(255, 100, 100, 100)), 25, 25, 150, 150, 0, (365 * (REAL)dProgress) / 100); 
 
			StringFormat format; 
			format.SetAlignment(StringAlignmentNear); 
			Font fontBold(L"Tahoma", 10, FontStyleBold); 
			Font fontNormal(L"Tahoma", 8); 
 
			graphics.DrawString(pProgressDialog->m_strTitle, -1, &fontBold, RectF(201, 26, 176, 151), &format, &SolidBrush(Color(255, 0, 0, 0))); 
			graphics.DrawString(pProgressDialog->m_strTitle, -1, &fontBold, RectF(200, 25, 175, 150), &format, &SolidBrush(Color(255, 255, 255, 255))); 
			graphics.DrawString(strStatus, -1, &fontNormal, RectF(200, 70, 175, 105), &format, &SolidBrush(Color(255, 255, 255, 255))); 
			////////////////////////////// 
 
			BitBlt(dc, 0, 0, 400, 200, dcMem, 0, 0, SRCCOPY); 
			 
			DeleteObject(bm); 
			DeleteDC(dcMem); 
			ReleaseDC(hDlg, dc);  
 
			return TRUE; 
		} 
	} 
 
	return FALSE; 
} 
 
#pragma warning(default:4311) 
#pragma warning(default:4312)