CWinThread有两种用法,一种是辅助线程,又叫工作线程(Worker_Thread),另外一种是交互线程(User_Interface_Thread)。其中第一种用法简单,而第二种就相对复杂了。我们来具体看一下。(笔者用的是VC2010)
例一:
我们建立一个Win32控制台程序空项目,右键点击项目,选择【属性】,
对项目做如上修改。
输入下面的代码:
#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程序,选择对话框程序直接点完成。
这样,系统会给我们生成一个对话框,直接将对话框资源修改成下面的样子:
双击【确定】,得到
点击【项目】菜单,选择【添加类】
选择MFC类。
【类名】:CMyThread 【基类名】:CWinThread 直接【完成】。
系统自动生成CMyThread类,一共两个文件MyThread.h和MyThread.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 消息处理程序
在Dlg的cpp类中,添加如下代码:
// 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的使用方法。我们可以将以上两端代码中的粗体代码,换成我们想要的任何代码。