开发手册 欢迎您!
软件开发者资料库

MFC - 多线程

MFC多线程 - 从简单和简单的步骤学习MFC,从基本到高级概念,包括概述,环境设置,VC ++项目,入门,Windows基础,对话框,Windows资源,属性表,Windows布局,控件管理,Windows控件,消息和事件,Activex控件,文件系统,标准I / O,文档视图,字符串,Carray,链接列表,数据库类,序列化,多线程,Internet编程,GDI,库。

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

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

让我们通过创建一个新的基于MFC对话框的应用程序来查看一个简单的例子.

第1步 : 将静态控件的标题和ID更改为分别单击开始线程按钮 IDC_STATIC_TEXT .

步骤2 : 拖动两个按钮并为这些按钮添加单击事件处理程序.

启动线程按钮

第3步 : 为静态文本控件添加控制变量.

步骤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 times per second   AfxBeginThread(MyThreadProc, 0); // <<== START THE THREAD}


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

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 dialogint 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 handlersBOOL CMFCMultithreadingDlg::OnInitDialog() {   CDialogEx::OnInitDialog();   // Set the icon for this dialog. The framework does this automatically   // when the application's main window is not a dialog   SetIcon(m_hIcon, TRUE);        // Set big icon   SetIcon(m_hIcon, FALSE);       // Set small icon   // TODO: Add extra initialization here   return TRUE; // return TRUE unless you set the focus to a control}// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.void CMFCMultithreadingDlg::OnPaint() {   if (IsIconic()) {      CPaintDC dc(this); // device context for painting      SendMessage(WM_ICONERASEBKGND,         reinterpret_cast(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();   }}// The system calls this function to obtain the cursor to display while the user drags// the minimized window.HCURSOR CMFCMultithreadingDlg::OnQueryDragIcon() {   return static_cast(m_hIcon);}UINT /*CThreadDlg::*/MyThreadProc(LPVOID Param) //Sample function for using inAfxBeginThread {   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"); m_ctrlStatus.SetWindowText(L"已停止"); }


第10步 : 编译并执行上面的代码时,您将看到以下输出.

Multithreading

步骤11 : 现在点击Start Thread按钮.

Start Thread

第12步 : 单击"停止线程"按钮.它将停止该线程.

停止线程