對於windows來說,所有的線程都是一樣的,但MFC卻把線程區分為兩種:用戶界面(UI)線程和工作者線程。用戶界面線程具有消息循環而工作者線程沒有。UI線程可以創建窗口並給這些窗口發送消息,工作者線程執行后台任務,因其不接受用戶直接輸入蘑菇不需要窗口和消息循環。
創建UI線程需要首先從CWinThread派生一個線程類,改類與CWinApp類派生額應用程序類很相似(CwinApp繼承自CWinThread)。派生類必須重載InitInstance,在其中創建一個對話框。關於對話框的創建可以參見上博文MFC中的模態對話框與非模態對話框.
首先在MFC類向導中添加繼承自CWinThread的一個線程類CUIThread。
重載InitInstance如下(此處創建模態對話框):
BOOL CUIThread::InitInstance() { // TODO: 在此執行任意逐線程初始化 MyDialog mydlg; m_pMainWnd = &mydlg; mydlg.DoModal(); return TRUE; }
其中m_pMainWnd= &mydlg;是指定線程主窗口,m_pMainWnd的作用MSDN的解釋如下:
The Microsoft Foundation Class Library will automaticallyterminate your thread when the window referred to by m_pMainWnd isclosed. If this thread is the primary thread for an application, theapplication will also be terminated. If this data member is NULL,the main window for the application's CWinApp object will beused to determine when to terminate the thread. m_pMainWnd isa public variable of type CWnd*.
Typically, you set this member variable when you override InitInstance.In a worker thread, the value of this data member is inherited from its parentthread.
也就是說當和m_pMainWnd相關的窗口被關閉后,MFC會自動終止你的線程。
接着在主對話框中添加按鈕響應函數用於調用AfxBeginThread。
void CModalUIDlg::OnBnClickedOk() { // TODO: 在此添加控件通知處理程序代碼 //CDialogEx::OnOK(); CWinThread* pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread)); }
函數AfxBeginThread可用於創建工作者線程和UI線程,他們的調用方式不同,對於工作者線程:
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc,//線程回調函數 LPVOID pParam, //傳遞給回調函數的參數 int nPriority = THREAD_PRIORITY_NORMAL,//線程優先級 UINT nStackSize = 0,//指定堆棧大小 DWORD dwCreateFlags = 0,//創建表示(CREATE_SUSPENDED:掛起,0:立即執行) LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL //安全屬性 );
對於UI線程:
CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass,//CWinThread派生的RUNTIME_CLASS類 int nPriority = THREAD_PRIORITY_NORMAL,//線程優先級 UINT nStackSize = 0,//指定堆棧大小 DWORD dwCreateFlags = 0,//創建表示(CREATE_SUSPENDED:掛起,0:立即執行) LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL //安全屬性 );
對應於之前討論的模態與非模態對話框,這里也分別實現使用UI線程創建者兩類對話框。
參考: