Microsoft基础类(MFC)库提供对多线程应用程序的支持,当您启动记事本时,操作系统将创建一个进程并开始执行该进程的主线程。当该线程终止时,该过程也终止。
您可以根据需要在应用程序中创建其他线程, MFC应用程序中的所有线程均由CWinThread对象表示,在大多数情况下,您甚至不必显式创建这些对象,而是调用框架帮助器函数AfxBeginThread,该函数为您创建CWinThread对象。
让无涯教程通过创建一个新的基于MFC对话框的应用程序来研究一个简单的示例。
步骤1 - 将静态控件的标题和ID分别更改为单击"Start Thread"按钮和 IDC_STATIC_TEXT 。
步骤2 - 拖动两个按钮,并为这些按钮添加click事件处理程序。

步骤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按钮的事件处理程序的实现,它将停止线程。
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);
</span><span class="com">//Center icon in client rectangle</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> cxIcon </span><span class="pun">=</span><span class="pln"> </span><span class="typ">GetSystemMetrics</span><span class="pun">(</span><span class="pln">SM_CXICON</span><span class="pun">);</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> cyIcon </span><span class="pun">=</span><span class="pln"> </span><span class="typ">GetSystemMetrics</span><span class="pun">(</span><span class="pln">SM_CYICON</span><span class="pun">);</span><span class="pln">
</span><span class="typ">CRect</span><span class="pln"> rect</span><span class="pun">;</span><span class="pln">
</span><span class="typ">GetClientRect</span><span class="pun">(&</span><span class="pln">rect</span><span class="pun">);</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> x </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="typ">Width</span><span class="pun">()</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> cxIcon </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)/</span><span class="lit">2</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> y </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">()</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> cyIcon </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)/</span><span class="lit">2</span><span class="pun">;</span><span class="pln">
</span><span class="com">//Draw the icon</span><span class="pln">
dc</span><span class="pun">.</span><span class="typ">DrawIcon</span><span class="pun">(</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> m_hIcon</span><span class="pun">);</span><span class="pln">
}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 - 编译并执行上述代码后,您将看到以下输出。

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

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