- MFC教程
- MFC-首页
- MFC - 概述
- MFC - 环境设置
- MFC - VC++ 项目
- MFC - 入门
- MFC - Windows 基础知识
- MFC - 对话框
- MFC - Windows 资源
- MFC - 属性表
- MFC - 窗口布局
- MFC-控制管理
- MFC-Windows 控件
- MFC - 消息和事件
- MFC-Activex 控件
- MFC-文件系统
- MFC——标准I/O
- MFC - 文档视图
- MFC-字符串
- MFC-卡雷
- MFC - 链接列表
- MFC - 数据库类
- MFC-序列化
- MFC——多线程
- MFC-- 互联网编程
- MFC-GDI
- MFC - 库
- MFC 有用资源
- MFC - 快速指南
- MFC - 有用的资源
- MFC - 讨论
MFC——多线程
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 - 这是“启动线程”按钮的事件处理程序的实现,它将启动线程。
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 - 这是“停止线程”按钮的事件处理程序的实现,它将停止线程。
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();
// 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<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();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
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 - 现在单击“启动线程”按钮。
步骤 12 - 单击“停止线程”按钮。它会停止线程。
