[轉]MFC子線程中更新控制項內容的兩種辦法

來源:互聯網
上載者:User

標籤: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子線程中更新控制項內容的兩種辦法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.