C++ 關(guān)于MFC多線程編程的注意事項(xiàng)
在多線程編程中,最簡單的方法,無非就是利用 AfxBeginThread 來創(chuàng)建一個工作線程,看一下這個函數(shù)的說明:
CWinThread* AFXAPI AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
在這個說明中,除第1和第2兩個參數(shù)外,余下的參數(shù)都有默認(rèn)值。所以,我們在使用的時候,是必須要指定前兩個參數(shù)的。
其中 第一個參數(shù)是 要運(yùn)行的函數(shù)的名稱,光寫函數(shù)名就可以了,不能加引號。
第二個參數(shù),是指定 運(yùn)行函數(shù)的 參數(shù),這個參數(shù)的類型為 LPVOID 。所以要運(yùn)行的函數(shù)的在傳遞過去后,要轉(zhuǎn)化為LPVOID類型才可以。
而要運(yùn)行的參數(shù)還有一個限制,那就是必須返回一個UINT類型的結(jié)果。所以要運(yùn)行的函數(shù)的就有一個基本上固定的格式。
UINT RunProce(LPVOID lpParam)
在這里還需要特別說明一下,這個函數(shù)不能是實(shí)例函數(shù),也就是函數(shù)前面是不能有 類限定符:: 的。如果是靜態(tài)函數(shù)也是可以的。
在這個函數(shù)中,我們只能使用一個參數(shù),而參數(shù)的類型只能是 LPVOID ,可以用一個結(jié)構(gòu)體來封閉多個參數(shù)。
余下的問題,就不是很多了。
關(guān)于 多線程,就寫到這里吧!
在多線程編程中,一個很重要的問題就是,要將線程的運(yùn)行過程通知界面線程,做一些顯示方面的更新。如下載線程,在適當(dāng)?shù)臅r候,可以更新界面,現(xiàn)在下載到什么進(jìn)度了。等等的情況。但是在工作線程中,是不是直接操作界面線程的控件的。那怎么辦呢,只能通過自定義一個消息來解決。
工作流程,就是 在自定義線程中 通過發(fā)送一個界面上的 消息,來通知界面做一些更新操作。在這個自定義消息中,有一個細(xì)節(jié)要解決,那就是自定義消息,必須要指定接收消息的控件句柄。當(dāng)然你中以使用m_pApp 直接通知主框架來解決,但是這樣解決似乎繞了一個很大的圈。其實(shí)解決的方法很簡單,那就是直接將接收消息的控件的句柄傳給自定義線程,就可以了。我們直接在線程中使用此句柄就可以解決了。
我們知道控件的基類都是 CWnd。所以我們傳遞一個CWnd的指針進(jìn)去。當(dāng)然還有一些其它的參數(shù)要一塊傳遞進(jìn)去,那就做一個結(jié)構(gòu)吧
typedef struct{
CString srcString;
CString DesString;
CWnd* hander;
}Param;
這里我們傳遞了三個參數(shù) 兩個字符串一個指針。
我們先造一個自定義線程函數(shù)
UINT RunProce(LPVOID lpParam)
{
Param* par;
CWnd* hander;
par = (Param*)lpParam;
hander = par->hander;
myCopyDirectory(lpParam);
CString str;
str = "復(fù)制完成";
hander->SendMessage(WM_USERMESSAGE,0,(LPARAM)&str);
return 0;
}
在這個函數(shù)中,我們要運(yùn)行由此函數(shù)組成的一個線程的話,就需要傳遞一個參數(shù)lpParam,而這個參數(shù)是由 Param 的結(jié)構(gòu)體來指定。實(shí)際上是傳遞了三個參數(shù)進(jìn)去。
Param* par;
par = (Param*)lpParam;
我們會用上在的強(qiáng)制類型轉(zhuǎn)換的方法,就可以還原參數(shù)的值。根據(jù)這三個參數(shù)就 自定主的線程函數(shù)就可以運(yùn)行了。那如何通知界面線程呢。看一下自定義函數(shù)里面的這一句
hander->SendMessage(WM_USERMESSAGE,0,(LPARAM)&str);
這一句中 hander 是由結(jié)構(gòu)體轉(zhuǎn)換而來的 接收消息的控件的句柄。然后調(diào)用這個控件的 SendMessage 方法,就可以向此控件發(fā)消息了。消息的內(nèi)容由后面的參數(shù)來決定
第一個參數(shù) WM_USERMESSAGE 這是一個消息的名稱。這個名稱實(shí)際上是一個數(shù)字。我們需要在 .h 文件中 指定一下如下面的格式
#define WM_USERMESSAGE 11130
后面的數(shù)字造的大一點(diǎn),哈哈
第二個與第三個參數(shù),就是這個消息傳遞具體的值,如果不需要傳遞值的話,那就直接寫0吧
在這里我們想在傳遞參數(shù)的第三個參數(shù)上傳遞一個 字符串,那就是上面的寫法了。
這樣的話,在線程中發(fā)送消息的部分,就全部講完了。消息發(fā)送出去了,怎么接收呢?
這真是一個重要的問題
首先,要將消息做一下映射。消息映射的目的,就是告訴程序,當(dāng)出現(xiàn)這個消息的時候,使用哪個函數(shù)進(jìn)行處理。這樣的話,就首先需要一個消息映射的函數(shù)。這個消息映射的函數(shù)不是亂寫,因?yàn)橐獋鬟f兩個參數(shù),所以這個函數(shù)需要能夠接收這兩個參數(shù)。處理函數(shù)一般這樣子寫
LRESULT CCopyfileDlg::OnProcName(WPARAM wParam, LPARAM lParam)
他奶奶的,太神奇了。返回值只能是 LRESULT 。這個不用討論吧,照著抄吧。函數(shù)名稱后面有參數(shù)兩個,這是一個實(shí)例函數(shù)。因?yàn)榍懊嬗校海?br />
兩個參數(shù)一般也寫成這個樣子的。
函數(shù)內(nèi)容,就由你的程序的功能決定了。我這里直接抄一段我自己的代碼吧
LRESULT CCopyfileDlg::OnProcName(WPARAM wParam, LPARAM lParam) { // TODO: 處理用戶自定義消息 CString* str = (CString*)lParam; SetDlgItemText(IDC_STATIC,*str); if(*str == "復(fù)制完成") { (CButton*)GetDlgItem(IDC_COPYBUT)->EnableWindow(true); } return 0; }
這段程序是根據(jù)得到的傳遞過來的參數(shù),在界面上顯示具體的參數(shù)內(nèi)容。
SetDlgItemText(IDC_STATIC,*str); //在靜態(tài)文本框中顯示消息。
備注:
如果要讓按鈕變成灰色的,那就使用控件的 EnableWindow 方法。
這個方法,我們說,是專門的消息處理函數(shù),那么它的聲明也比較特殊。需要這么寫
afx_msg LRESULT OnProcName(WPARAM wParam, LPARAM lParam);
將上面的內(nèi)容放在 h文件的合理位置就可以了。
現(xiàn)在消息處理函數(shù)也有了。但是怎么將映射呢?
其實(shí)在 CPP文件中,有一個由 BEGIN_MESSAGE_MAP(CCopyfileDlg, CDialog) 和END_MESSAGE_MAP() 包括的區(qū)域。這個區(qū)域就是用來定義消息映射的。
將這么一句話放在他們中間,就OK了
ON_MESSAGE(WM_USERMESSAGE,OnProcName)
這么一句話,就將 WM_USERMESSAGE 與 OnProcName 與消息處理函數(shù)結(jié)合在一起了。是不是超級簡單呀!
這樣我們的界面線程中的消息處理部分也主做好了。
當(dāng)消息發(fā)送過來后,就會通過消息映射放在對應(yīng)的函數(shù)中加以處理。
以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。
上一篇:C++訪問Redis的mset 二進(jìn)制數(shù)據(jù)接口封裝方案
欄 目:C語言
下一篇:常用的STL查找算法
本文標(biāo)題:C++ 關(guān)于MFC多線程編程的注意事項(xiàng)
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3015.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery
- 08-05織夢dedecms什么時候用欄目交叉功能?