欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于MFC實現(xiàn)多線程進度條

 更新時間:2025年01月22日 11:08:49   作者:秋月的私語  
這篇文章主要為大家詳細介紹了如何基于MFC實現(xiàn)多線程進度條效果,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

先看下效果,MFC對話框中實現(xiàn)多線程進度條,對話框支持拖拽不卡死。

直接上代碼

我這里提供完整的對話框代碼:

 
// MultiThreadProgressDlg.h: 頭文件
//
 
#pragma once
 
 
// CMultiThreadProgressDlg 對話框
class CMultiThreadProgressDlg : public CDialogEx
{
// 構(gòu)造
public:
	CMultiThreadProgressDlg(CWnd* pParent = nullptr);	// 標準構(gòu)造函數(shù)
 
// 對話框數(shù)據(jù)
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_MULTITHREADPROGRESS_DIALOG };
#endif
 
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
 
 
// 實現(xiàn)
protected:
	HICON m_hIcon;
 
	// 生成的消息映射函數(shù)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedOk();
	CProgressCtrl m_hThread1;
	CProgressCtrl m_hThread2;
	CProgressCtrl m_hThread3;
 
	static DWORD _stdcall ThreadOne(LPVOID IpParameter);
	static DWORD _stdcall ThreadTwo(LPVOID IpParameter);
	static DWORD _stdcall ThreadThree(LPVOID IpParameter);
 
	HANDLE m_hThreadOne;
	HANDLE m_hThreadTwo;
	HANDLE m_hThreadThree;
};

然后是實現(xiàn)文件

 
// MultiThreadProgressDlg.cpp: 實現(xiàn)文件
//
 
#include "pch.h"
#include "framework.h"
#include "MultiThreadProgress.h"
#include "MultiThreadProgressDlg.h"
#include "afxdialogex.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
 
 
// 用于應(yīng)用程序“關(guān)于”菜單項的 CAboutDlg 對話框
 
class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();
 
// 對話框數(shù)據(jù)
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif
 
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
 
// 實現(xiàn)
protected:
	DECLARE_MESSAGE_MAP()
};
 
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
 
 
// CMultiThreadProgressDlg 對話框
 
 
 
CMultiThreadProgressDlg::CMultiThreadProgressDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MULTITHREADPROGRESS_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
 
void CMultiThreadProgressDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_PROGRESS1, m_hThread1);
	DDX_Control(pDX, IDC_PROGRESS2, m_hThread2);
	DDX_Control(pDX, IDC_PROGRESS3, m_hThread3);
}
 
BEGIN_MESSAGE_MAP(CMultiThreadProgressDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &CMultiThreadProgressDlg::OnBnClickedOk)
END_MESSAGE_MAP()
 
 
// CMultiThreadProgressDlg 消息處理程序
 
BOOL CMultiThreadProgressDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
 
	// 將“關(guān)于...”菜單項添加到系統(tǒng)菜單中。
 
	// IDM_ABOUTBOX 必須在系統(tǒng)命令范圍內(nèi)。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
 
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
 
	// 設(shè)置此對話框的圖標。  當應(yīng)用程序主窗口不是對話框時,框架將自動
	//  執(zhí)行此操作
	SetIcon(m_hIcon, TRUE);			// 設(shè)置大圖標
	SetIcon(m_hIcon, FALSE);		// 設(shè)置小圖標
 
	// TODO: 在此添加額外的初始化代碼
	m_hThread1.SetRange(0, 100000);
	m_hThread2.SetRange(0, 100000);
	m_hThread3.SetRange(0, 100000);
 
	//創(chuàng)建線程
	m_hThreadOne = CreateThread(NULL, 100, ThreadOne, (void*)this, CREATE_SUSPENDED, NULL); // CREATE_SUSPENDED標識創(chuàng)建的線程可以被掛起的
 
	SetThreadPriority(m_hThreadOne, THREAD_PRIORITY_ABOVE_NORMAL); //標識創(chuàng)建的線程具有的優(yōu)先級別
 
	m_hThreadTwo = CreateThread(NULL, 100, ThreadTwo, (void*)this, CREATE_SUSPENDED, NULL);
 
	SetThreadPriority(m_hThreadTwo, THREAD_PRIORITY_NORMAL);
 
	m_hThreadThree = CreateThread(NULL, 100, ThreadThree, (void*)this, CREATE_SUSPENDED, NULL);
 
	SetThreadPriority(m_hThreadThree, THREAD_PRIORITY_BELOW_NORMAL);
 
	//啟動線程
	ResumeThread(m_hThreadOne);
 
	ResumeThread(m_hThreadTwo);
 
	ResumeThread(m_hThreadThree);
 
	return TRUE;  // 除非將焦點設(shè)置到控件,否則返回 TRUE
}
 
void CMultiThreadProgressDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}
 
// 如果向?qū)υ捒蛱砑幼钚』粹o,則需要下面的代碼
//  來繪制該圖標。  對于使用文檔/視圖模型的 MFC 應(yīng)用程序,
//  這將由框架自動完成。
 
void CMultiThreadProgressDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于繪制的設(shè)備上下文
 
		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
 
		// 使圖標在工作區(qū)矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
 
		// 繪制圖標
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}
 
//當用戶拖動最小化窗口時系統(tǒng)調(diào)用此函數(shù)取得光標
//顯示。
HCURSOR CMultiThreadProgressDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}
 
 
void CMultiThreadProgressDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知處理程序代碼
	CDialogEx::OnOK();
}
 
DWORD _stdcall CMultiThreadProgressDlg::ThreadOne(LPVOID IpParameter)
{
	CMultiThreadProgressDlg* pDlg = (CMultiThreadProgressDlg*)IpParameter;
 
	int low, high, pos;
 
	pos = pDlg->m_hThread1.GetPos();
 
	pDlg->m_hThread1.GetRange(low, high);
 
	while (pos < high)
 
	{
 
		pos = pDlg->m_hThread1.GetPos();
		Sleep(10);
		pDlg->m_hThread1.SetPos(pos + 1);
 
	}
 
	pDlg->m_hThread1.SetPos(0);
 
	return 0;
}
 
DWORD _stdcall CMultiThreadProgressDlg::ThreadTwo(LPVOID IpParameter)
{
	CMultiThreadProgressDlg* pDlg = (CMultiThreadProgressDlg*)IpParameter;
 
	int low, high, pos;
 
	pos = pDlg->m_hThread2.GetPos();
 
	pDlg->m_hThread2.GetRange(low, high);
 
	while (pos < high)
 
	{
 
		pos = pDlg->m_hThread2.GetPos();
 
		Sleep(10);
 
		pDlg->m_hThread2.SetPos(pos + 1);
 
	}
 
	pDlg->m_hThread2.SetPos(0);
 
	return 0;
}
 
DWORD _stdcall CMultiThreadProgressDlg::ThreadThree(LPVOID IpParameter)
{
	CMultiThreadProgressDlg* pDlg = (CMultiThreadProgressDlg*)IpParameter;
 
	int low, high, pos;
 
	pos = pDlg->m_hThread3.GetPos();
 
	pDlg->m_hThread3.GetRange(low, high);
 
	while (pos < high)
 
	{
 
		pos = pDlg->m_hThread3.GetPos();
 
		Sleep(10);
 
		pDlg->m_hThread3.SetPos(pos + 1);
 
	}
 
	pDlg->m_hThread3.SetPos(0);
 
	return 0;
}

直接編譯運行,即可看到效果。

為了進一步研究動態(tài)添加進度條,于是我寫了下面這個小程序,可以根據(jù)對話框的大小,動態(tài)增減進度條的個數(shù),其中寬度為當前對話框的寬度:

直接上完整代碼:

 
// DynamicProgressBarsDlg.h: 頭文件
//
 
#pragma once
#include <vector>
 
// CDynamicProgressBarsDlg 對話框
class CDynamicProgressBarsDlg : public CDialogEx
{
// 構(gòu)造
public:
	CDynamicProgressBarsDlg(CWnd* pParent = nullptr);	// 標準構(gòu)造函數(shù)
 
// 對話框數(shù)據(jù)
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_DYNAMICPROGRESSBARS_DIALOG };
#endif
 
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
 
	//創(chuàng)建一個進度條
	CProgressCtrl* CreateProgressBar(const CRect rect);
 
	//進度條指針
	std::vector<CProgressCtrl*> m_vpPrgoressCtrl;
	int m_nShowCount = 0;
 
// 實現(xiàn)
protected:
	HICON m_hIcon;
 
	// 生成的消息映射函數(shù)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnSize(UINT nType, int cx, int cy);
};

實現(xiàn)文件:

 
// DynamicProgressBarsDlg.cpp: 實現(xiàn)文件
//
 
#include "pch.h"
#include "framework.h"
#include "DynamicProgressBars.h"
#include "DynamicProgressBarsDlg.h"
#include "afxdialogex.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
 
#define IDC_PRG_START   1000
 
// 用于應(yīng)用程序“關(guān)于”菜單項的 CAboutDlg 對話框
 
class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();
 
// 對話框數(shù)據(jù)
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif
 
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
 
// 實現(xiàn)
protected:
	DECLARE_MESSAGE_MAP()
};
 
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
 
 
// CDynamicProgressBarsDlg 對話框
 
 
 
CDynamicProgressBarsDlg::CDynamicProgressBarsDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DYNAMICPROGRESSBARS_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
 
void CDynamicProgressBarsDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}
 
CProgressCtrl* CDynamicProgressBarsDlg::CreateProgressBar(const CRect rect)
{
	//創(chuàng)建一個進度條
	CProgressCtrl* pProgress = new CProgressCtrl;
 
	// 創(chuàng)建進度條
	if (!pProgress->Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH, rect, this, IDC_PRG_START))
	{
		TRACE(_T("創(chuàng)建進度條失敗!\n"));
		delete pProgress;
		return NULL;
	}
 
	// 設(shè)置進度條范圍和初始位置
	pProgress->SetRange(0, 100);
	pProgress->SetPos(60);
 
	return pProgress;
}
 
BEGIN_MESSAGE_MAP(CDynamicProgressBarsDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_SIZE()
END_MESSAGE_MAP()
 
 
// CDynamicProgressBarsDlg 消息處理程序
 
BOOL CDynamicProgressBarsDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
 
	// 將“關(guān)于...”菜單項添加到系統(tǒng)菜單中。
 
	// IDM_ABOUTBOX 必須在系統(tǒng)命令范圍內(nèi)。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
 
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
 
	// 設(shè)置此對話框的圖標。  當應(yīng)用程序主窗口不是對話框時,框架將自動
	//  執(zhí)行此操作
	SetIcon(m_hIcon, TRUE);			// 設(shè)置大圖標
	SetIcon(m_hIcon, FALSE);		// 設(shè)置小圖標
 
	// TODO: 在此添加額外的初始化代碼
 
	return TRUE;  // 除非將焦點設(shè)置到控件,否則返回 TRUE
}
 
void CDynamicProgressBarsDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}
 
// 如果向?qū)υ捒蛱砑幼钚』粹o,則需要下面的代碼
//  來繪制該圖標。  對于使用文檔/視圖模型的 MFC 應(yīng)用程序,
//  這將由框架自動完成。
 
void CDynamicProgressBarsDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于繪制的設(shè)備上下文
 
		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
 
		// 使圖標在工作區(qū)矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
 
		// 繪制圖標
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}
 
//當用戶拖動最小化窗口時系統(tǒng)調(diào)用此函數(shù)取得光標
//顯示。
HCURSOR CDynamicProgressBarsDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}
 
 
void CDynamicProgressBarsDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);
 
	// TODO: 在此處添加消息處理程序代碼
	CRect rectWindow;
	GetWindowRect(&rectWindow);
 
	int nWidth = rectWindow.Width();
	int nHeight = rectWindow.Height();
 
	int nNewCount = nHeight / 60;
	size_t nProgressBarCount = m_vpPrgoressCtrl.size();
 
	if (nProgressBarCount < nNewCount)
	{
		for (size_t i = m_nShowCount; i < nNewCount; ++i)
		{
			CRect rect(0, i * 60, nWidth, i * 60 + 55);
			if (CProgressCtrl* pCtrl = CreateProgressBar(rect))
			{
				m_vpPrgoressCtrl.emplace_back(pCtrl);
			}
		}
 
		m_nShowCount = nNewCount;
	}
	else
	{
		for (size_t i = 0; i < m_nShowCount; ++i)
		{
			if (CProgressCtrl* pCtrl = m_vpPrgoressCtrl[i])
			{
				pCtrl->ShowWindow(SW_SHOW);
			}
		}
 
		for (size_t i = nNewCount; i < nProgressBarCount; ++i)
		{
			if (CProgressCtrl * pCtrl = m_vpPrgoressCtrl[i])
			{
				pCtrl->ShowWindow(SW_HIDE);
			}
		}
	}
 
}

關(guān)鍵代碼在OnSize()函數(shù)中。

到此這篇關(guān)于基于MFC實現(xiàn)多線程進度條的文章就介紹到這了,更多相關(guān)MFC多線程進度條內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言計算大數(shù)階乘的方法

    C語言計算大數(shù)階乘的方法

    這篇文章主要為大家詳細介紹了C語言計算大數(shù)階乘的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 用代碼和UML圖化解設(shè)計模式之橋接模式的深入分析

    用代碼和UML圖化解設(shè)計模式之橋接模式的深入分析

    本篇文章是對橋接模式進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 在Visual Studio 2019中修改項目名的方法

    在Visual Studio 2019中修改項目名的方法

    這篇文章主要介紹了在Visual Studio 2019中修改項目名的方法,文中通過示例介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • Opencv處理圖像之輪廓提取

    Opencv處理圖像之輪廓提取

    這篇文章主要為大家詳細介紹了Opencv處理圖像之輪廓提取,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C語言一看就懂的選擇與循環(huán)語句及函數(shù)介紹

    C語言一看就懂的選擇與循環(huán)語句及函數(shù)介紹

    函數(shù)是一個功能模塊,它把實現(xiàn)某個功能的代碼塊包含起來,并起一個函數(shù)名,供別人調(diào)用,如printf函數(shù),如system函數(shù)。是程序運行當中包裝起來的一個步驟;選擇與循環(huán)是編程中最常用的結(jié)構(gòu),本篇文章用最簡單的文字帶你了解它們
    2022-04-04
  • C語言面試常見考點排序總結(jié)

    C語言面試常見考點排序總結(jié)

    深處開發(fā)崗,其實排序也是繞不開的環(huán)節(jié),其中冒泡排序,選擇排序,插入排序,歸并排序,快速排序,堆排序也是我在秋招以來頻繁問到的技術(shù)點,今天我們來重點聊聊排序
    2021-11-11
  • C++ 指向類成員的指針

    C++ 指向類成員的指針

    指向類成員的指針總的來講可以分為兩大類四小類(指向數(shù)據(jù)成員還是成員函數(shù),指向普通成員還是靜態(tài)成員)
    2020-03-03
  • 基于C語言實現(xiàn)井字棋游戲

    基于C語言實現(xiàn)井字棋游戲

    這篇文章主要為大家詳細介紹了基于C語言實現(xiàn)井字棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 枚舉窗口句柄后關(guān)閉所有窗口示例

    枚舉窗口句柄后關(guān)閉所有窗口示例

    這篇文章主要介紹了關(guān)閉所有窗口的方法,原理是枚舉所有窗口句柄,然后發(fā)送WM_CLOSE消息來關(guān)閉窗口,需要的朋友可以參考下
    2014-01-01
  • 使用C++獲取邏輯執(zhí)行毫秒數(shù)的方法

    使用C++獲取邏輯執(zhí)行毫秒數(shù)的方法

    這篇文章主要為大家詳細介紹了如何使用C++獲取邏輯執(zhí)行毫秒數(shù)的方法,文中借助c++11提供的steady_clock,實現(xiàn)了精確獲取邏輯執(zhí)行時間的方法,需要的可以參考下
    2024-02-02

最新評論