| 類型 | 訊息迴路 | 典型用途 |
|---|---|---|
| 工作者執行緒 | 無 | 後台運算、列印、資料處理等非 UI 任務 |
| 使用者介面執行緒 | 有 (獨立訊息隊列) | 處理獨立 UI、輸入回應、獨立視窗 |
Win32 API 層面兩者無差別,MFC 透過 AfxBeginThread() 兩種多載封裝差異。
// 1. 建立工作者執行緒
CWinThread* AfxBeginThread(
AFX_THREADPROC pfnThreadProc, // 執行函數:UINT Func(LPVOID)
LPVOID pParam, // 傳遞參數
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0, // 0=立即執行, CREATE_SUSPENDED=建立後暫停
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
// 2. 建立 UI 執行行緒
CWinThread* AfxBeginThread(
CRuntimeClass* pThreadClass, // CWinThread 衍生類的 RUNTIME_CLASS
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
m_hThread:執行緒核心物件句柄m_nThreadID:執行緒 IDm_pMainWnd:主視窗指標 (UI 執行緒)virtual BOOL InitInstance():UI 執行緒初始化 (建立視窗等),成功回傳 TRUEvirtual int ExitInstance():UI 執行緒清理,回傳結束碼BOOL CreateThread(...):兩階段建立 (先建物件再啟動)專案 MultiThread5,對話框含編輯框 (間隔毫秒)、按鈕、進度條。
// 共用結構體
struct ThreadInfo {
UINT nMilliSecond;
CProgressCtrl* pProgress;
};
// 執行函數 (全域或靜態)
UINT ThreadFunc(LPVOID pParam) {
ThreadInfo* pInfo = (ThreadInfo*)pParam;
for (int i=0; i<100; i++) {
pInfo->pProgress->SetPos(i);
Sleep(pInfo->nMilliSecond);
}
return 0;
}
// 啟動按鈕
void CMultiThread5Dlg::OnStart() {
UpdateData(TRUE);
m_info.nMilliSecond = m_nMilliSecond;
m_info.pProgress = &m_ctrlProgress;
m_pThread = AfxBeginThread(ThreadFunc, &m_info);
}
步驟:
CWinThread 衍生類 CUIThreadIDD_UITHREADDLG 及類別 CUIThreadDlgCUIThread 成員加入 CUIThreadDlg m_dlgInitInstance/ExitInstance:BOOL CUIThread::InitInstance() {
m_dlg.Create(IDD_UITHREADDLG);
m_dlg.ShowWindow(SW_SHOW);
m_pMainWnd = &m_dlg;
return TRUE;
}
int CUIThread::ExitInstance() {
m_dlg.DestroyWindow();
return CWinThread::ExitInstance();
}
啟動:
void CMultiThread6Dlg::OnUiThread() {
AfxBeginThread(RUNTIME_CLASS(CUIThread));
}
每次點擊按鈕彈出獨立對話框,擁有獨立訊息迴路,滑鼠左鍵彈出訊息框互不干擾。
InitInstance() → 回傳 TRUE 才繼續Run():標準訊息迴路 (GetMessage/DispatchMessage),空閒時呼叫 OnIdle()WM_QUIT 退出迴路ExitInstance() 清理資源InitInstance() 執行特定任務後回傳 FALSE,不進入 Run(),可作為帶訊息處理能力的工作者執行緒。
MFC AfxBeginThread 封裝了執行緒建立細節,工作者執行緒適合純計算,UI 執行緒適合獨立視窗。理解 CWinThread 生命週期與虛擬函數,能靈活構建多執行緒架構。