⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 progressdialog.cpp

📁 虚拟打印机
💻 CPP
字号:
/* * * progressdialog.cpp *   Copyright (C) 2006 Michael H. Overlin   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Contact at poster_printer@yahoo.com * */#include "progressdialog.h"#include "progressdialog_rc.h"#include "dialogwindow.h"#include "gdiutils.h"#include "mathutils.h"#include <mmsystem.h>#include <strsafe.h>#include <process.h>#define TIMER_ID						100#define STATUSUPDATE_TIMER_MS			175#define PROGRESS_RADIOBUTTON_NUMBER		6#define PROGRESS_RADIOBUTTON_FIRST		IDC_RADIO_PROGRESS_1#define MAX_STATUS_CCH					128#define WAIT_TIMESLICE_MS				50BOOL ProgressDialogWindow::Status::operator ==(const ProgressDialogWindow::Status& st) const { return memcmp(this, &st, sizeof(*this)) == 0; }BOOL ProgressDialogWindow::Status::operator !=(const ProgressDialogWindow::Status& st) const { return ! (*this == st); }ProgressDialogWindow::ProgressDialogWindow(	IN HINSTANCE hinst, 	IN const tstring& tstrTitle, 	IN const tstring& tstrJobDescription,	IN BOOL bHideCancelButton)	: DialogWindow(hinst, IDD_DIALOG_PRINTPROGRESS){	m_bHideCancelButton = bHideCancelButton;	m_status.bErrors = FALSE;	m_status.bUserCanceled = FALSE;	m_status.bAllDone = FALSE;	m_statusOld = m_status;	m_tstrTitle = tstrTitle;	m_tstrJobDescription = tstrJobDescription;	m_hNewThread = NULL;	this->SetAutoDelete(FALSE);}ProgressDialogWindow::~ProgressDialogWindow() {	if (m_hNewThread != NULL) {		while( ::WaitForSingleObject(m_hNewThread, WAIT_TIMESLICE_MS) == WAIT_TIMEOUT ) {			// IN ORDER FOR MODAL DIALOG TO TERMINATE, IT MAY HAVE TO ENABLE WINDOWS IN THE CURRENT THREAD			// W/O THIS LOOP DEADLOCK RESULTS			MSG msg;			if (PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE)) { 				if ( ! ::DialogWindow::TheirIsDialogMessage(msg) ) {					TranslateMessage(&msg); 					DispatchMessage(&msg); 				} 			} 		}	}}ProgressDialogWindow::Status ProgressDialogWindow::GetStatus(void) {	ProgressDialogWindow::Status retValue;	Lock();	__try {		retValue = m_status;	} __finally {		UnLock();	}	return retValue;}void ProgressDialogWindow::SetStatus(const ProgressDialogWindow::Status& status) {	ProgressDialogWindow::Status statusBuff;	Lock();	__try {		statusBuff = m_status;	} __finally {		UnLock();	}	if (statusBuff != status) {		Lock();		__try {			m_status = status;		} __finally {			UnLock();		}		if (status.bAllDone) {			this->CenterWindowAboveParent();			this->ShowWindow(SW_NORMAL);			//::Beep(500, 100);			::PlaySound(TEXT("SystemAsterisk"), NULL, SND_ASYNC);			// MAKE USER HIT OK BUTTON ANYWAY			//if (status.bUserCanceled) {			//	this->EndDialog(0);			//}		}	}}tstring ProgressDialogWindow::GetStatusString(void) {	tstring retValue;	Lock();	try {		retValue = m_tstrStatus;	} catch(...) {		UnLock();		throw;	}	UnLock();	return retValue;}void ProgressDialogWindow::SetStatusString(const tstring& tstrStatus) {	Lock();	__try {		m_tstrStatus = tstrStatus;	} __finally {		UnLock();	}}BOOL  ProgressDialogWindow::DoNewThreadModalDialog(HWND hwndParent) {	ASSERT(m_hNewThread == NULL);	m_hwndDialogParent = hwndParent;	m_hNewThread = (HANDLE) ::_beginthread( ProgressDialogWindow::TheirThreadProc, 0,  this);		BOOL bRetValue = (m_hNewThread != NULL);	return bRetValue;}//INT_PTR ProgressDialogWindow::GetDialogResultCode(void) {//	INT_PTR resultCode;//	Lock();//	__try {//		resultCode = m_DialogResultCode;//	} __finally {//		UnLock();//	}//	return resultCode;//}// ****// **** private:  class ProgressDialogWindow// ****void ProgressDialogWindow::AnimateProgressRadioButtons(void) {	Lock();	__try {		BOOL bFound = FALSE;		for(uint ui = 0; ui < PROGRESS_RADIOBUTTON_NUMBER; ++ui) {			if (this->IsDlgButtonChecked(ui + PROGRESS_RADIOBUTTON_FIRST)) {				uint uiCheck = (ui + 1) % PROGRESS_RADIOBUTTON_NUMBER;				this->CheckDlgButton(ui + PROGRESS_RADIOBUTTON_FIRST, FALSE);				this->CheckDlgButton(uiCheck + PROGRESS_RADIOBUTTON_FIRST, TRUE);				bFound = TRUE;				break;			}		}		if (!bFound) {			this->CheckDlgButton(PROGRESS_RADIOBUTTON_FIRST, TRUE);		}	} __finally {		UnLock();	}}void ProgressDialogWindow::CheckAllProgressRadioButtons(void) {	Lock();	__try {		for(uint ui = 0; ui < PROGRESS_RADIOBUTTON_NUMBER; ++ui) {			if (!this->IsDlgButtonChecked(ui + PROGRESS_RADIOBUTTON_FIRST)) {				this->CheckDlgButton(ui + PROGRESS_RADIOBUTTON_FIRST, TRUE);			}		}	} __finally {		UnLock();	}}HWND ProgressDialogWindow::GetDialogParent(void) {	HWND hwndParent;	Lock();	__try {		hwndParent = m_hwndDialogParent;	} __finally {		UnLock();	}	return hwndParent;}void ProgressDialogWindow::DoStatusTick(void) {	tstring tstrStatus, tstrOldStatus;	Status status, statusOld;	Lock();	try {		tstrOldStatus = m_tstrOldStatus;		tstrStatus = m_tstrOldStatus = m_tstrStatus;		statusOld = m_statusOld;		status = m_statusOld = m_status;	} catch(...) {		UnLock();		throw;	}	UnLock();	if (tstrOldStatus != tstrStatus || statusOld != status) {		tstring tstrTemp;		tstrTemp = tstrStatus;		if (status.bAllDone) {			tstrTemp += TEXT("\nDONE.");		}		this->SetDlgItemText(IDC_STATIC_PRINT_PROGRESS, tstrTemp.c_str());	}	if (! status.bAllDone) {  // DEBUG / FIX: KILL TIMER WHEN ALL DONE?		this->AnimateProgressRadioButtons();	} else {		this->CheckAllProgressRadioButtons();		HWND hwndDismiss = this->GetDlgItem(IDC_BUTTON_DISMISS);		// 7/12		::CenterWindowHorizontallyInDialog(hwndDismiss, this->hdlg());		::SetWindowText(hwndDismiss, TEXT("OK"));		//RECT rDlg;		//::GetClientRect(this->hdlg(), &rDlg);		//RECT rButton;		//::GetWindowRect(hwndDismiss, &rButton);		//::ScreenToClient(rButton, this->hdlg());		//RECT rTemp = rButton;		//::CenterInRect(rTemp, rDlg);		//::MoveWindow(hwndDismiss, rTemp.left, rButton.top, RW(rButton), RH(rButton), TRUE);		::ShowWindow(hwndDismiss, SW_SHOW);		this->SetHasSystemMenu(TRUE);	}	//Lock();	//try {	//	if (m_tstrOldStatus != m_tstrStatus || m_statusOld != m_status) {	//		m_tstrOldStatus = m_tstrStatus;	//		m_statusOld = m_status;	//		tstring tstrTemp;	//		tstrTemp = m_tstrStatus;	//		if (m_status.bAllDone) {	//			tstrTemp += TEXT("\n\nDONE.");	//		}	//		this->SetDlgItemText(IDC_STATIC_PRINT_PROGRESS, tstrTemp.c_str());	//	}	//	if (! m_status.bAllDone) {  // DEBUG / FIX: KILL TIMER WHEN ALL DONE?	//		this->AnimateProgressRadioButtons();	//	} else {	//		this->CheckAllProgressRadioButtons();	//		this->SetDlgItemTextW(IDC_BUTTON_DISMISS, TEXT("OK"));	//	}	//} catch(...) {	//	UnLock();	//	throw;	//}	//UnLock();}void ProgressDialogWindow::SetDialogResultCode(INT_PTR resultCode) {	Lock();	__try {		m_DialogResultCode = resultCode;	} __finally {		UnLock();	}}BOOL ProgressDialogWindow::InitMsg(WPARAM wParam, LPARAM lParam) {	DialogWindow::InitMsg(wParam, lParam);	BOOL bHideCancelButton;	tstring tstrTitle, tstrJobDescription, tstrStatus;	Lock();	try {		bHideCancelButton = m_bHideCancelButton;		tstrTitle = m_tstrTitle;		tstrJobDescription = m_tstrJobDescription;		tstrStatus = m_tstrStatus;	} catch(...) {		UnLock();		throw;	}	UnLock();	this->CenterWindowAboveParent();	this->SetWindowText(tstrTitle.c_str());	this->SetDlgItemText(IDC_STATIC_PRINT_JOB_DESCRIPTION, tstrJobDescription.c_str());	this->SetDlgItemText(IDC_BUTTON_DISMISS, TEXT("Cancel"));	this->SetDlgItemText(IDC_STATIC_PRINT_PROGRESS, tstrStatus.c_str());		this->SetTimer(TIMER_ID, STATUSUPDATE_TIMER_MS);	if (bHideCancelButton) {		HWND hwndDismiss = this->GetDlgItem(IDC_BUTTON_DISMISS);		::ShowWindow(hwndDismiss, SW_HIDE);		this->SetHasSystemMenu(FALSE);	}	return TRUE;}BOOL ProgressDialogWindow::CommandMsg(WPARAM wParam, LPARAM lParam) {	Status status;	Lock();	__try {		status = m_status;	} __finally {		UnLock();	}	BOOL bRetValue = FALSE;	WORD wID = LOWORD(wParam);	switch(wID) {	case IDC_BUTTON_DISMISS: 		if (status.bAllDone) {			//this->DestroyWindow();			this->EndDialog(0);		} else {			status.bUserCanceled = TRUE;			status.bErrors = TRUE;			Lock();			__try {				m_status = status;			} __finally {				UnLock();			}		}		bRetValue = TRUE;		break;	default:		break;	}	return bRetValue;}BOOL ProgressDialogWindow::CommonControlColorNotifyMsg(UINT msg, WPARAM wParam, LPARAM lParam) {	Status status;	Lock();	__try {		status = m_status;	} __finally {		UnLock();	}	static BOOL bSkipRecursion = FALSE;	BOOL bRetValue = FALSE;	// I WANT TO CALL THE DEFDLGPROC TO GET THE BACKGROUND BRUSH	// BUT I WANT TO SET THE TEXT COLOR	switch(msg) {	case WM_CTLCOLORSTATIC:		if (!bSkipRecursion) {			if (status.bErrors) {				HWND hwndControl = (HWND) lParam;				int iCtrlID = ::GetDlgCtrlID(hwndControl);				if (iCtrlID == IDC_STATIC_PRINT_PROGRESS) {					HDC hdc = (HDC) wParam;					// DEBUG-FIX : THIS CODE HAS TO BE EXPLICITLY TESTED AT SOME POINT, IM NOT SURE THIS WILL WORK					// AVOID INFINITE RECURSIVE LOOP HERE - CALLING DEFDLGPROC RECURSES INTO THIS ROUTINE					bSkipRecursion = TRUE;					LRESULT lres = ::CallWindowProc(::DefDlgProc, this->hdlg(), WM_CTLCOLORSTATIC, wParam, lParam);					bSkipRecursion = FALSE;					bRetValue = (BOOL) lres;					// RED TEXT COLOR FOR FAILURE CONDITION					::SetTextColor(hdc, RGB(0xff, 0, 0));				}			}		}		break;	default:		break;	}	return bRetValue;}BOOL ProgressDialogWindow::NotificationMsg(UINT msg, WPARAM wParam, LPARAM lParam) {	BOOL bRetValue = FALSE;	switch(msg) {		case WM_CLOSE:			this->SendMessage(WM_COMMAND, (WPARAM) IDC_BUTTON_DISMISS, 0);			bRetValue = TRUE;			break;		default:			break;	}	return bRetValue;}BOOL ProgressDialogWindow::TimerMsg(WPARAM wParam, LPARAM lParam) {	BOOL bRetValue = FALSE;	switch(wParam) {		case TIMER_ID: {			this->DoStatusTick();			bRetValue = TRUE;		} break;		default:			break;	}	return bRetValue;}void __cdecl ProgressDialogWindow::TheirThreadProc(void *pv) {	ProgressDialogWindow *pdw = (ProgressDialogWindow *) pv;	HWND hwndParent = pdw->GetDialogParent();	INT_PTR resultCode = pdw->DoModalDialog(hwndParent);	pdw->SetDialogResultCode(resultCode);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -