MFC子執行緒中更新控制元件內容的兩種辦法
一、概述
每個系統中都有執行緒(至少都有一個主執行緒),而執行緒最重要的作用就是並行處理,提高軟體的併發率。針對介面來說,還能提高介面的響應能力。一般的,為了應用的穩定性,在資料處理等耗時操作會單獨在一個執行緒中執行,而所有與主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);
轉載,原文連結:https://blog.csdn.net/dezhihuang/article/details/73499998