MFC - 多线程

MFC - 多线程 首页 / MFC入门教程 / MFC - 多线程

Microsoft基础类(MFC)库提供对多线程应用程序的支持,当您启动记事本时,操作系统将创建一个进程并开始执行该进程的主线程。当该线程终止时,该过程也终止。

您可以根据需要在应用程序中创建其他线程, MFC应用程序中的所有线程均由CWinThread对象表示,在大多数情况下,您甚至不必显式创建这些对象,而是调用框架帮助器函数AfxBeginThread,该函数为您创建CWinThread对象。

让无涯教程通过创建一个新的基于MFC对话框的应用程序来研究一个简单的示例。

步骤1 - 将静态控件的标题和ID分别更改为单击"Start Thread"按钮和 IDC_STATIC_TEXT 。

步骤2 - 拖动两个按钮,并为这些按钮添加click事件处理程序。

Start Thread Button

步骤3 - 为Static text 控件添加控件变量。

步骤4 - 现在在CMFCMultithreadingDlg.cpp文件的开头添加以下三个全局变量。

int currValue;
int maxValue;
BOOL stopNow;

步骤5 - 在CMFCMultithreadingDlg类中添加WM_TIMER消息。

无涯教程网

这是OnTimer()的实现

void CMFCMultithreadingDlg::OnTimer(UINT_PTR nIDEvent) {
   //TODO: Add your message handler code here and/or call default
   CString sStatusMsg;
   sStatusMsg.Format(L"Running: %d", currValue);
   m_ctrlStatus.SetWindowText(sStatusMsg);

   CDialogEx::OnTimer(nIDEvent);
}

步骤6 - 现在在CMFCMultithreadingDlg类的AfxBeginThread中添加一个示例函数。

UINT MyThreadProc(LPVOID Param) {
   while (!stopNow && (currValue < maxValue)) {
      currValue++;
      Sleep(50);     //would do some work here
   }
   
   return TRUE;
}

步骤7 - 这是"Start thread"按钮的事件处理程序的实现,它将启动线程。

void CMFCMultithreadingDlg::OnBnClickedButtonStart() {
   //TODO: Add your control notification handler code here
   currValue = 0;
   maxValue = 5000;
   stopNow = 0;
   m_ctrlStatus.SetWindowText(L"Starting...");
   SetTimer(1234, 333, 0); //每秒 3 次

   AfxBeginThread(MyThreadProc, 0); //<<== START THE THREAD
}

步骤8 - 这是Stop Thread按钮的事件处理程序的实现,它将停止线程。

链接:https://www.learnfk.comhttps://www.learnfk.com/mfc/mfc-multithreading.html

来源:LearnFk无涯教程网

void CMFCMultithreadingDlg::OnBnClickedButtonStop() {
   
   //TODO: Add your control notification handler code here
   stopNow = TRUE;
   KillTimer(1234);
   m_ctrlStatus.SetWindowText(L"Stopped");
}

步骤9 - 这是完整的源文件。

//MFCMultithreadingDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MFCMultithreading.h"
#include "MFCMultithreadingDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//CMFCMultithreadingDlg dialog

int currValue;
int maxValue;
BOOL stopNow;

CMFCMultithreadingDlg::CMFCMultithreadingDlg(CWnd* pParent /*=NULL*/)
   : CDialogEx(IDD_MFCMULTITHREADING_DIALOG, pParent) {
   m_hIcon = AfxGetApp() -> LoadIcon(IDR_MAINFRAME);
}
void CMFCMultithreadingDlg::DoDataExchange(CDataExchange* pDX) {
   CDialogEx::DoDataExchange(pDX);
   DDX_Control(pDX, IDC_STATIC_TEXT, m_ctrlStatus);
}

BEGIN_MESSAGE_MAP(CMFCMultithreadingDlg, CDialogEx)
   ON_WM_PAINT()
   ON_WM_QUERYDRAGICON()
   ON_BN_CLICKED(IDC_BUTTON_START,
      &CMFCMultithreadingDlg::OnBnClickedButtonStart)
   ON_WM_TIMER()
   ON_BN_CLICKED(IDC_BUTTON_STOP,
      &CMFCMultithreadingDlg::OnBnClickedButtonStop)
END_MESSAGE_MAP()

//CMFCMultithreadingDlg message handlers

BOOL CMFCMultithreadingDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   //设置此对话框的图标。该框架会自动执行此操作当应用程序的主窗口不是对话框时
   SetIcon(m_hIcon, TRUE);        //Set big icon
   SetIcon(m_hIcon, FALSE);       //Set small icon

   //TODO: Add extra initialization here

   return TRUE; //除非您将焦点设置为控件,否则返回 TRUE
}

//除非您将焦点设置为控件,否则返回 TRUE绘制图标。对于使用文档/视图模型的 MFC 应用程序,
//这是由框架自动为您完成的。

void CMFCMultithreadingDlg::OnPaint() {
   if (IsIconic()) {
      CPaintDC dc(this); //device context for painting
      SendMessage(WM_ICONERASEBKGND,
         reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
			
      //Center icon in client rectangle
      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;

      //Draw the icon
      dc.DrawIcon(x, y, m_hIcon);
   }else {
      CDialogEx::OnPaint();
   }
}
//系统调用该函数获取用户拖动时要显示的光标
//最小化的窗口。
HCURSOR CMFCMultithreadingDlg::OnQueryDragIcon() {
   return static_cast<HCURSOR>(m_hIcon);
}

UINT /*CThreadDlg::*/MyThreadProc(LPVOID Param) //Sample function for using in
AfxBeginThread {
   while (!stopNow && (currValue < maxValue)) {
      currValue++;
      Sleep(50); //would do some work here
   }
   return TRUE;
}
void CMFCMultithreadingDlg::OnBnClickedButtonStart() {
   //TODO: Add your control notification handler code here
   currValue = 0;
   maxValue = 5000;
   stopNow = 0;
   m_ctrlStatus.SetWindowText(L"Starting...");
   SetTimer(1234, 333, 0); //3 times per second

   AfxBeginThread(MyThreadProc, 0); //<<== START THE THREAD
}

void CMFCMultithreadingDlg::OnTimer(UINT_PTR nIDEvent) {
   //TODO: Add your message handler code here and/or call default
   CString sStatusMsg;
   sStatusMsg.Format(L"Running: %d", currValue);
   m_ctrlStatus.SetWindowText(sStatusMsg);

   CDialogEx::OnTimer(nIDEvent);
}

void CMFCMultithreadingDlg::OnBnClickedButtonStop() {
   //TODO: Add your control notification handler code here
   stopNow = TRUE;
   KillTimer(1234);
   m_ctrlStatus.SetWindowText(L"Stopped");
}

步骤10 - 编译并执行上述代码后,您将看到以下输出。

Multithreading

步骤11 - 现在,单击"Start Thread"按钮。

Start Thread

步骤12 - 单击"Stop Thread"按钮。它将停止线程。

Stop Thread

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

如何设计一个秒杀系统 -〔许令波〕

玩转webpack -〔程柳锋〕

Linux实战技能100讲 -〔尹会生〕

消息队列高手课 -〔李玥〕

Linux内核技术实战课 -〔邵亚方〕

说透数字化转型 -〔付晓岩〕

如何成为学习高手 -〔高冷冷〕

超级访谈:对话张雪峰 -〔张雪峰〕

深入剖析Java新特性 -〔范学雷〕

好记忆不如烂笔头。留下您的足迹吧 :)