MFC实现一个通用模态进度条窗口

#include "afxwin.h"
#include "afxcmn.h"

// CModelProgressDlg 对话框
class CModelProgressDlg : public CDialogEx
{
	DECLARE_DYNAMIC(CModelProgressDlg)

public:
	CModelProgressDlg(CWnd* pParent = NULL);   // 标准构造函数
	virtual ~CModelProgressDlg();
	typedef UINT(*ThreadFun)(LPVOID pParam);
	struct Thread
	{
		Thread():fun(NULL), data(NULL), progress(NULL) {}
		ThreadFun fun;
		LPVOID data;
		const CModelProgressDlg* GetProgress() { return progress; }
	private:
		CModelProgressDlg* progress;
		friend class CModelProgressDlg;
	}m_threadData;
// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum {
		IDD = IDD_DIALOG_MODEL_PROGRESS
};
#endif
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	HANDLE GetFinishEventHandle() { return m_finishEvt; }
	void SetRange(short range);
private:
	int m_nCount;
	HANDLE m_finishEvt;
	CString m_strTip;
	CStatic m_tip;
	short m_range;
	CProgressCtrl m_progress;
	static const UINT REFRESH_PROGRESS_TIMER_ID = 240129;
	static const UINT REFRESH_PROGRESS_ELAPSE = 500;
private:
	afx_msg void OnBnClickedBreak();
	afx_msg LRESULT OnUpdateText(WPARAM wParam, LPARAM lParam);
	virtual BOOL OnInitDialog();
	afx_msg void OnTimer(UINT_PTR nIDEvent);
	afx_msg void OnClose();
	virtual BOOL PreTranslateMessage(MSG* pMsg) override;
};

  

#include "stdafx.h"
#include "DlgModelProgress.h"
#include "afxdialogex.h"
#include "WinMessageID/GlobalMessageID.h"

// CModelProgressDlg 对话框

IMPLEMENT_DYNAMIC(CModelProgressDlg, CDialogEx)

CModelProgressDlg::CModelProgressDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(IDD_DIALOG_MODEL_PROGRESS, pParent), m_range(100), m_nCount(0)
{	
	m_threadData.progress = this;
	m_finishEvt = CreateEvent(NULL, TRUE, FALSE, NULL);//无信号
}

CModelProgressDlg::~CModelProgressDlg()
{
}

void CModelProgressDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STATIC_TIP, m_tip);
	DDX_Control(pDX, IDC_PROGRESS_TASK, m_progress);
}

BEGIN_MESSAGE_MAP(CModelProgressDlg, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_BREAK, &CModelProgressDlg::OnBnClickedBreak)
	ON_WM_SHOWWINDOW()
	ON_MESSAGE(WM_UPDATE_REPORT_WINDOW_POS, &CModelProgressDlg::OnUpdateText)
	ON_WM_CLOSE()
	ON_WM_TIMER()
END_MESSAGE_MAP()

void CModelProgressDlg::SetRange(short range) 
{
	m_range = range;
	m_progress.SetRange(0, m_range);
}

// CModelProgressDlg 消息处理程序
BOOL CModelProgressDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	GetDlgItem(IDC_BUTTON_BREAK)->SetWindowText(XTPResourceManager()->LoadString(IDS_CANCEL));

	SetTimer(REFRESH_PROGRESS_TIMER_ID, REFRESH_PROGRESS_ELAPSE, NULL);
	
	AfxBeginThread(m_threadData.fun, &m_threadData);
	
	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}

BOOL CModelProgressDlg::PreTranslateMessage(MSG* pMsg)
{
	BOOL bAlt = GetKeyState(VK_MENU) & 0x8000;
	if (pMsg->message == WM_KEYDOWN)
	{
		if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
		{
			return TRUE;
		}

	}
	else if (pMsg->message == WM_SYSKEYDOWN)
	{
		if (pMsg->wParam == VK_F4 && bAlt)
		{
			return TRUE;
		}

	}
	return CDialogEx::PreTranslateMessage(pMsg);
}

void CModelProgressDlg::OnTimer(UINT_PTR nIDEvent)
{
	if (REFRESH_PROGRESS_TIMER_ID == nIDEvent)
	{
		static tstring arrState[] = { _UC("."), _UC(".."), _UC("...") };
		SetDlgItemText(IDC_STATIC_TIP, m_strTip + arrState[m_nCount++%_countof(arrState)].c_str());
	}
}

void CModelProgressDlg::OnBnClickedBreak()
{
	// TODO: 在此添加控件通知处理程序代码
	LOG(INFO) << "Stop generate report!";
	SetEvent(m_finishEvt);
	m_strTip = CSLoadString(IDS_WAIT_STOPING).c_str();
	m_tip.SetWindowText(m_strTip);
	GetDlgItem(IDC_BUTTON_BREAK)->EnableWindow(FALSE);
}


LRESULT CModelProgressDlg::OnUpdateText(WPARAM wParam, LPARAM lParam)
{
	m_progress.SetPos(wParam);
	CString percent;
	percent.Format(_T("%.2f%%"), (wParam / (double)m_range) * 100);
	SetDlgItemText(IDC_STATIC_PERCENT, percent);

	if (lParam != NULL)
	{
		m_strTip = (TCHAR*)lParam;
		m_tip.SetWindowText(m_strTip);
		free((void*)lParam);
	}

	UpdateData(FALSE);

	return 0;
}

void CModelProgressDlg::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	KillTimer(REFRESH_PROGRESS_TIMER_ID);

	CDialogEx::OnClose();
}

  

image

 

UINT DlgPrintProject::GenerateStationThread(LPVOID pParam)
{
	//生成报表数据
	CModelProgressDlg::Thread *threadData = (CModelProgressDlg::Thread*)pParam;//获取线程相关数据

	CModelProgressDlg* progress = (CModelProgressDlg*)threadData->GetProgress();//获取进度条指针
	DlgPrintProject* _this = (DlgPrintProject*)threadData->data;//获取当前类this指针
   progress->SetRange(ReportManager::GetInstance()->GetProgressRange());//设置进度条范围 }

  

代码有缺失,请参考思路!

posted @ 2025-11-05 16:19  快雪  阅读(4)  评论(0)    收藏  举报