標籤:dial 區別 use get 設定 body col 一個 wpa
一、概述
每個系統中都有線程(至少都有一個主線程),而線程最重要的作用就是平行處理,提高軟體的並發率。針對介面來說,還能提高介面的響應能力。一般的,為了應用的穩定性,在資料處理等耗時操作會單獨在一個線程中運行,而所有與主UI線程有關的控制項資料重新整理應該到主UI線程中處理。也就是資料處理線程發訊息,讓介面UI去更新控制項。在MFC中線程分為介面線程和工作者線程,介面實際就是一個線程畫出來的東西,這個線程維護一個“訊息佇列”,“訊息佇列”也是介面線程和工作者線程的最大區別,這個詞應該進到你的腦子裡,根深蒂固的!MFC中有兩類線程,分別稱之為工作者線程和使用介面執行緒。二者的主要區別在於工作者線程沒有訊息迴圈,而使用介面執行緒有自己的訊息佇列和訊息迴圈。
在MFC中,一般用全域函數AfxBeginThread()來建立並初始化一個線程(工作者線程,還有一個重載形式是用於建立使用介面執行緒)的運行。函數原型:
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
傳回值: 成功時返回一個指向新線程的線程對象的指標,否則NULL。
pfnThreadProc:線程的入口函數,聲明一定要如下: UINT MyThreadFunction(LPVOID pParam),不能設定為NULL。如果是類成員函數,一定要是靜態成員函數。
pParam:傳遞入線程的參數,注意它的類型為:LPVOID,所以我們可以傳遞一個結構體或者類對象到線程。一般傳遞this指標,以方便調用類的非靜態成員,因為線程函數是靜態函數。
nPriority:線程的優先順序,一般設定為0,讓它和主線程具有共同的優先順序。
nStackSize:指定新建立的線程的棧的大小。如果為 0,新建立的線程具有和主線程一樣的大小的棧。
dwCreateFlags:指定建立線程以後,線程有怎麼樣的標誌。可以指定兩個值:CREATE_SUSPENDED:線程建立以後,會處於掛起狀態,直到調用:ResumeThread。0 : 建立線程後就開始運行。
lpSecurityAttrs:指向一個 SECURITY_ATTRIBUTES 的結構體,用它來標誌新建立線程的安全性。如果為 NULL,那麼新建立的線程就具有和主線程一樣的安全性。
常見用法:
AfxBeginThread(MyThreadFunction, this);
傳遞線程參數為this,即類本身,是為了能線上程函數中獲得類中非靜態成員變數,因為線程函數是靜態函數。
MFC子線程中更新控制項內容有兩種方法,一種是在子線程中通過全域函數更新控制項內容,一種是在子線程中通過發送自訂訊息來更新控制項內容。
二、通過全域函數更新控制項內容
1.在對話方塊類CThreadDemoDlg中新增成員變數——線程對象的指標和線程函數
CWinThread *m_pThread; static UINT ThreadFunction(LPVOID pParam);
2.實現線程函數,使用全域函數::SetWindowText、::GetDlgItem更新控制項內容
UINT CThreadDemoDlg::ThreadFunction(LPVOID pParam) { CThreadDemoDlg *pDlg = (CThreadDemoDlg *)pParam; while (TRUE) { ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_STATIC), L"Hello World"); Sleep(1000); ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_STATIC), L"Hello Android"); Sleep(1000); } return 0; }
3.在成員函數OnInitDialog建立線程並啟動
m_pThread = AfxBeginThread((AFX_THREADPROC)ThreadFunction, this);
三、通過發送自訂訊息更新控制項內容
1.在標頭檔中定義訊息ID
#define WM_UPDATE_STATIC (WM_USER + 100)
2.在對話方塊類CThreadDemoDlg中新增成員——線程對象的指標和線程函數
CWinThread *m_pThread; static UINT ThreadFunction(LPVOID pParam);
3.聲明自訂的訊息函數
afx_msg LRESULT OnUpdateStatic(WPARAM wParam, LPARAM lParam);
4.在CPP檔案中添加訊息映射
BEGIN_MESSAGE_MAP(CThreadDemoDlg, CDialog) //...... ON_MESSAGE(WM_UPDATE_STATIC, &CThreadDemoDlg::OnUpdateStatic) //...... END_MESSAGE_MAP()
5.實現自訂訊息響應函數
LRESULT CThreadDemoDlg::OnUpdateStatic(WPARAM wParam, LPARAM lParam) { if (wParam == 0) { GetDlgItem(IDC_STATIC)->SetWindowText(L"Hello Linux"); } else { GetDlgItem(IDC_STATIC)->SetWindowText(L"Hello Windows"); } return 0; }
6.實現線程函數,並通過PostMessage發送自訂訊息
UINT CThreadDemoDlg::ThreadFunction(LPVOID pParam) { CThreadDemoDlg *pDlg = (CThreadDemoDlg *)pParam; while (TRUE) { ::PostMessage(pDlg->m_hWnd, WM_UPDATE_STATIC, 0, 0); Sleep(1000); ::PostMessage(pDlg->m_hWnd, WM_UPDATE_STATIC, 1, 0); Sleep(1000); } return 0; }
7.在成員函數OnInitDialog建立線程並啟動
m_pThread = AfxBeginThread((AFX_THREADPROC)ThreadFunction, this);
通過發送自訂訊息更新控制項內容總體思路:在主介面所在的主線程中建立線程--->將線程的起始函數綁定到類的靜態成員方法--->在靜態成員方法中調用PostMessage()或SendMessage()發送自訂訊息--->在自訂訊息的訊息響應函數中更新主介面上控制項的狀態顯示。
原文連結:MFC子線程中更新控制項內容的兩種辦法
[轉]MFC子線程中更新控制項內容的兩種辦法