CWinThread有两种用法,一种是辅助线程,又叫工作线程(Worker_Thread,另外一种是交互线程(User_Interface_Thread)。其中第一种用法简单,而第二种就相对复杂了。我们来具体看一下。(笔者用的是VC2010

 

例一:

我们建立一个Win32控制台程序空项目,右键点击项目,选择【属性】,

CWinThread类用法详解+实例_MFC

 

对项目做如上修改。

 

输入下面的代码:

#define _AFXDLL
#include"afxwin.h"
class CMyThread:public CWinThread
{
public:
DECLARE_DYNCREATE(CMyThread)
protected:
virtual BOOL InitInstance();
};
IMPLEMENT_DYNCREATE(CMyThread,CWinThread)
BOOL CMyThread::InitInstance()
{
//这里可以添加线程处理代码,你想在这里做什么都可以!
_tprintf(L"Hello CWinThread as Worker Thread\n");
//注意,这里必须返回FALSE,这是区别于User_Interface_Thread的地方!如果这里返回
//TRUE,那么InitInstance函数执行完毕后,MFC框架将会调用CMyThread类的虚拟函数Run()
//Run函数执行的是消息循环,在工作线程中,没有窗口,何来消息循环呢,所以这里一定要返回FALSE,
//记住了!!!
return FALSE;
}
int _tmain()
{
//创建一个新线程
CWinThread* p=AfxBeginThread(RUNTIME_CLASS(CMyThread));
_gettchar();
return 0;
}



这里面应该注意的问题,已经在程序的注释中给出了。在真正的MFC中使用这个类,用法没有任何区别,我们重点看User_Interface_Thread的用法。

 

例子二:

首先创建一个MFC程序,选择对话框程序直接点完成。

CWinThread类用法详解+实例_MFC_02


这样,系统会给我们生成一个对话框,直接将对话框资源修改成下面的样子:


CWinThread类用法详解+实例_MFC_03


双击【确定】,得到

CWinThread类用法详解+实例_MFC_04

点击【项目】菜单,选择【添加类】

CWinThread类用法详解+实例_类_05

选择MFC类。



CWinThread类用法详解+实例_ CWinThread_06


 

【类名】:CMyThread     【基类名】:CWinThread  直接【完成】。

 

系统自动生成CMyThread类,一共两个文件MyThread.hMyThread.cpp

 

MyThread.cpp中,添加如下代码:

// MyThread.cpp : 实现文件
//
#include "stdafx.h"
#include "tt、.h"
#include "MyThread.h"
// CMyThread
LRESULT CALLBACK MainWndProc(
    HWND hwnd,        // handle to window
    UINT uMsg,        // message identifier
    WPARAM wParam,    // first message parameter
    LPARAM lParam)    // second message parameter
{ 
 
    switch (uMsg) 
    { 
        case WM_CREATE: 
            // Initialize the window. 
            return 0; 
 
        case WM_PAINT: 
            // Paint the window's client area. 
            return 0; 
 
        case WM_SIZE: 
            // Set the size and position of the window. 
            return 0; 
 
        case WM_DESTROY: 
            // Clean up window-specific data objects. 
PostQuitMessage(0);
            return 0; 
 
        // 
        // Process other messages. 
        // 
 
        default: 
            return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
    return 0; 
} 
// CMyThread
IMPLEMENT_DYNCREATE(CMyThread, CWinThread)
CMyThread::CMyThread()
{
}
CMyThread::~CMyThread()
{
}
BOOL CMyThread::InitInstance()
{
// TODO: 在此执行任意逐线程初始化
WNDCLASS wc,wc1; 
 
    // Register the main window class. 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = (WNDPROC) MainWndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
wc.hInstance = ::GetModuleHandle(NULL); 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName =NULL; 
    wc.lpszClassName = L"ydm"; 
 
if(!GetClassInfo(GetModuleHandle(NULL),L"ydm",&wc1))
{
if (!RegisterClass(&wc)) 
return FALSE; 
}
HWND hwnd=CreateWindow(L"ydm",NULL,WS_OVERLAPPEDWINDOW,0,0,500,300,NULL,NULL,
::GetModuleHandle(NULL),NULL);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
return TRUE;
}
int CMyThread::ExitInstance()
{
// TODO: 在此执行任意逐线程清理
return CWinThread::ExitInstance();
}
BEGIN_MESSAGE_MAP(CMyThread, CWinThread)
END_MESSAGE_MAP()
// CMyThread 消息处理程序

Dlgcpp类中,添加如下代码:

// tt、.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "tt、.h"
#include "tt、Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// Ctt、App
BEGIN_MESSAGE_MAP(Ctt、App, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// Ctt、App 构造
Ctt、App::Ctt、App()
{
// 支持重新启动管理器
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 Ctt、App 对象
Ctt、App theApp;
// Ctt、App 初始化
BOOL Ctt、App::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// 创建 shell 管理器,以防对话框包含
// 任何 shell 树视图控件或 shell 列表视图控件。
CShellManager *pShellManager = new CShellManager;
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
Ctt、Dlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
//  “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
//  “取消”来关闭对话框的代码
}
// 删除上面创建的 shell 管理器。
if (pShellManager != NULL)
{
delete pShellManager;
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
//  而不是启动应用程序的消息泵。
return FALSE;
}

编译并执行,在对话框上点击【确定】,会出来一个新的对话框。这是User_Interface_Thread的使用方法。我们可以将以上两端代码中的粗体代码,换成我们想要的任何代码。