惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
博客园_首页
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
大猫的无限游戏
大猫的无限游戏
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
Jina AI
Jina AI
月光博客
月光博客
小众软件
小众软件
S
SegmentFault 最新的问题
量子位
阮一峰的网络日志
阮一峰的网络日志
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

博客园 - StationaryTraveller

如何查找微软VS软件中的图标 SQLite 的自增(AUTOINCREMENT)强制要求列的数据类型必须是INTEGER Qt动态获取翻译文本 Windows判断某窗口是否被其他窗口完全覆盖 如何批量修改“后期生成事件”为“预生成事件” MFC对话框中如何给一个控件发送消息 Window剪切板 C语言根据函数指针偏移实现函数动态调用 Qt程序系统文本翻译 SVN创建分支 Qt多版本如何共存 Qt6编译的程序在某些win10系统报错 电脑忘机了用户名密码怎么办 Qt事件过滤器实现空闲检测 CMFCToolTipCtrl的AddTool导致内存增加 MFC中CBitmap、CBrush、CFont、CPalette、CPen、CRgn删除GDI对象问题 实现从QListWidgett拖拽项到QTableWidget Windows系统下通过命令行获取进程指标 命令模式实现撤销和重做机制 避免溢出求平均值的算法 字节流转16进制字符串 PImpl:Pointer to Implementation C++单例
MFC实现一个通用模态进度条窗口
StationaryTraveller · 2025-11-05 · via 博客园 - StationaryTraveller
#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());//设置进度条范围 }

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