C++_MFC 基礎(chǔ)教程_(初學(xué)者)_第1頁(yè)
C++_MFC 基礎(chǔ)教程_(初學(xué)者)_第2頁(yè)
C++_MFC 基礎(chǔ)教程_(初學(xué)者)_第3頁(yè)
C++_MFC 基礎(chǔ)教程_(初學(xué)者)_第4頁(yè)
C++_MFC 基礎(chǔ)教程_(初學(xué)者)_第5頁(yè)
已閱讀5頁(yè),還剩438頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 好好學(xué)習(xí),天天向上! ppt簡(jiǎn)介共14章、442頁(yè),涵蓋了vc的基礎(chǔ)介紹,以及mfc程序的創(chuàng)建,控件的使用、多線程、多媒體編程、網(wǎng)絡(luò)編程、動(dòng)態(tài)鏈接庫(kù)的使用等等,是那些喜歡MFC但是不知道從何學(xué)起的MFC愛好者的最佳的基礎(chǔ)教材!第1章 Visual C+集成開發(fā)環(huán)境Visual C+是一個(gè)功能強(qiáng)大的可視化應(yīng)用程序開發(fā)工具。其憑借強(qiáng)大功能,受大了廣大程序員的歡迎。當(dāng)今流行的Visual C+的開發(fā)工具是6.0版本。下面來(lái)介紹Visual C+ 6.0的一些基本情況。1.1 Visual C+ 6.0概述Visual C+是一種C/C+語(yǔ)言的集成開發(fā)環(huán)境(IDE)。當(dāng)最初還處于DOS時(shí)代的Borl

2、and公司推出了Turbo Pascal和Turbo C,讓程序員感受到了把編譯器和編輯器集成在一起使用時(shí)的方便。Microsoft公司也看到了這一點(diǎn),于是,兩個(gè)公司開始合作,推出了Quick C和Microsoft C/C+等多個(gè)DOS版本的C/C+集成開發(fā)環(huán)境。隨著Windows的不斷成熟,于是Microsoft開始開發(fā)Windows下的Visual C+。經(jīng)過(guò)多次版本的修訂與更新,現(xiàn)在大多數(shù)程序員使用的是Visual C+ 6.0版本。Visual C+是一個(gè)可視化的C+的集成開發(fā)環(huán)境。在使用Visual C+時(shí),開發(fā)人員可以通過(guò)鼠標(biāo)拖動(dòng)方便地設(shè)計(jì)程序的界面,相應(yīng)的代碼系統(tǒng)會(huì)自動(dòng)生成。M

3、FC(Microsoft Fundermental Classes)是微軟提供的Visual C+可以調(diào)用的類庫(kù),其中封裝了開發(fā)人員常用的類。使用MFC可以大大提高編程人員的工作效率。1.2 Visual C+6.0界面介紹安裝好Visual C+開發(fā)環(huán)境后,桌面上并沒(méi)有其快捷圖標(biāo),需讀者自己修改。選擇“開始”菜單,從所有程序中,找到Microsoft Visual Studio 6.0級(jí)聯(lián)菜單下的Microsoft Visual C+菜單項(xiàng)。選擇該菜單項(xiàng),并將其拖動(dòng)到桌面上,則在桌面上創(chuàng)建了Microsoft Visual Studio的快捷圖標(biāo)。雙擊快捷圖標(biāo),即可啟動(dòng)Visual C+6.

4、0集成開發(fā)環(huán)境。每次運(yùn)行Visual C+6.0時(shí),會(huì)彈出一個(gè)【Tip of the day】對(duì)話框,如下圖所示。1.2 Visual C+6.0界面介紹技巧:【Tip of the day】對(duì)話框中介紹了很多關(guān)于開發(fā)環(huán)境的使用方法以及編程方面的小技巧。如果想在下次啟動(dòng)Visual C+ 6.0時(shí)不再顯示該提示對(duì)話框,可以選擇下一次啟動(dòng)時(shí)不再顯示它。1.2 Visual C+6.0界面介紹為了便于說(shuō)明,首先創(chuàng)建一個(gè)IDE的MFC項(xiàng)目(具體創(chuàng)建步驟,后面會(huì)詳細(xì)介紹),如下圖所示。1.2 Visual C+6.0界面介紹從上圖中可以看出,Visual C+的界面被分成了7部分。上面依次標(biāo)題欄、菜單

5、欄和工具欄。中間左側(cè)部分是工作區(qū)窗口,右側(cè)部分是編輯區(qū)。最下方是輸出窗口和狀態(tài)欄。1.2.1 工作區(qū)窗口和輸出窗口工作區(qū)窗口和輸出窗口是在一個(gè)程序編譯時(shí)使用最多的停靠式窗口。工作區(qū)窗口中顯示了當(dāng)前程序中的所有類、資源和文件信息。工作區(qū)窗口分為3個(gè)部分:Class View(類視圖)、Resource View(資源視圖)和File View(文件視圖)。Class View:顯示當(dāng)前工作區(qū)中所有工程定義的C+類。雙擊某個(gè)類名,Visual C+會(huì)自動(dòng)打開這個(gè)類的文件,并將編輯區(qū)定位到該類的定義處。雙擊類中的成員函數(shù)和變量,編輯區(qū)則定位到該成員函數(shù)或變量的定義處。1.2.1 工作區(qū)窗口和輸出窗口

6、Resource View:顯示當(dāng)前工作區(qū)中所有的資源。這些資源包括快捷鍵、對(duì)話框、圖標(biāo)、菜單、字符條編輯器、工具欄和版本信息。雙擊其中的ID號(hào),會(huì)顯示相應(yīng)的資源信息。File View:顯示屬于當(dāng)前工程的所有文件,包括C/C+源文件、頭文件、資源文件等。輸出窗口與工作區(qū)一樣,分為多個(gè)選擇卡。其中最常用的選項(xiàng)卡被放在了最外面,分別為Build、Debug、Find in Files 1和Find in Files 2。1.2.1 工作區(qū)窗口和輸出窗口Build:Build顯示工程在創(chuàng)建中,經(jīng)過(guò)的每一個(gè)步驟及相應(yīng)信息。如果出現(xiàn)編譯鏈接錯(cuò)誤,那么出現(xiàn)錯(cuò)誤的文件、原因、行號(hào)等內(nèi)容會(huì)顯示在Build中

7、。雙擊該錯(cuò)誤信息行,編輯區(qū)則定位在該錯(cuò)誤出現(xiàn)的行。Debug:工程通過(guò)編譯后,運(yùn)行調(diào)試版本時(shí),Debug選項(xiàng)卡中會(huì)顯示具體的調(diào)試信息。1.2.1 工作區(qū)窗口和輸出窗口Find in Files 1和Find in Files 2:兩個(gè)選項(xiàng)卡的作用相同,用于顯示從多個(gè)文件中查找字符串的結(jié)果。當(dāng)用戶想要查看某個(gè)函數(shù)或變量出現(xiàn)在哪些文件中,單擊【Edit】|【Find in Files】命令,彈出【Find in Files】對(duì)話框,如下圖所示。在【Find in Files】對(duì)話框中的【Find what】后的編輯框中,輸入想要查找的內(nèi)容,單擊【Find】按鈕即可。查找到的內(nèi)容會(huì)輸出到Find i

8、n Files選項(xiàng)卡中。1.2.2 菜單欄和工具欄菜單欄位于集成開發(fā)環(huán)境的頂部。菜單欄由9個(gè)菜單項(xiàng)組成:File(文件)、Edit(編輯)、View(視圖)、Insert(插入)、Project(工程)、Build(編譯)、Tools(工具)、Windows(窗口)、Help(幫助)。每一個(gè)菜單項(xiàng)都有一個(gè)下拉式菜單,其中的菜單項(xiàng)用于完成特定的功能。工具欄位于菜單欄的下面。工具欄可以稱作是美化的菜單欄,其由許多按鈕構(gòu)成。其中的按鈕用于完成特定的功能。工具欄可以任意拖動(dòng),也可以成為一個(gè)浮動(dòng)窗口。1.2.3 編輯區(qū)在Visual C+中,編寫應(yīng)用程序代碼的位置就是編輯區(qū)。該編輯區(qū)的功能十分強(qiáng)大,智能

9、化程度也非常高。在編輯區(qū)內(nèi),除了能編寫C/C+語(yǔ)言外,還能編寫SQL、HTML和VBScript等其他編程語(yǔ)言。如下圖所示。1.2.4 聯(lián)機(jī)幫助Visual C+6.0不像其他集成開發(fā)環(huán)境一樣把幫助系統(tǒng)集成在開發(fā)環(huán)境內(nèi)部,而是提供了一個(gè)專門為Visual C+設(shè)計(jì)的MSDN類庫(kù)。MSDN雖然是一個(gè)獨(dú)立的幫助系統(tǒng),但卻能很好地和Visual C+6.0集成在一起。MSDN的使用方式有以下幾種:?jiǎn)螕簟綡elp】|【Contents】命令;單擊【Help】|【Search】命令;單擊【Help】|【Index】命令;按下【F2】鍵。通過(guò)上述幾種命令方式,即可運(yùn)行MSDN。1.2.4 Visual C

10、+中的文件擴(kuò)展名打開程序Hello World所在的文件夾,看到該文件夾自動(dòng)生成了許多擴(kuò)展名不同的文件,如下圖所示。1.2.6 Visual C+中的文件擴(kuò)展名了解這些不同的擴(kuò)展名文件,對(duì)于理解Visual C+6.0如何組織和管理項(xiàng)目文件是很有必要的。有關(guān)這些文件擴(kuò)展名及其說(shuō)明,如下表所示。第2章 MFC與應(yīng)用程序框架在Visual C+集成開發(fā)環(huán)境下,使用微軟基礎(chǔ)類庫(kù)MFC,可以開發(fā)出功能強(qiáng)大的Windows應(yīng)用程序。另外,通過(guò)MFC AppWizard自動(dòng)生成的MFC應(yīng)用程序框架,還可以很方便地開發(fā)自己想要實(shí)現(xiàn)的功能。本章將先介紹有關(guān)MFC的基礎(chǔ)知識(shí),然后對(duì)MFC應(yīng)用程序框架作具體介紹。

11、2.1 微軟基礎(chǔ)類庫(kù)MFCMFC是一種重要的編程方法,它是微軟公司的特定的應(yīng)用程序包裝接口。本節(jié)將講解MFC概述及其類庫(kù)結(jié)構(gòu)。2.1.1 MFC概述MFC的英文全稱是Microsoft Foundation Classes,即微軟的基礎(chǔ)類庫(kù)。MFC的本質(zhì)就是一個(gè)包含了許多微軟公司已經(jīng)定義好的對(duì)象的類庫(kù)。雖然開發(fā)人員要編寫的程序在功能上各有不同,但是從結(jié)構(gòu)上講,都可以化分為對(duì)用戶界面的設(shè)計(jì)、對(duì)文件的操作、對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)及對(duì)多媒體的使用等一些最主要的方面。這一點(diǎn)正是微軟提出MFC類庫(kù)最重要的原因。在MFC類庫(kù)中,大約有200個(gè)類。在進(jìn)行程序設(shè)計(jì)時(shí),只需簡(jiǎn)單地調(diào)用已有的類及類中的方法即可。另外,還可

12、以利用“繼承”方法從已有類中派生出自己想要的類。這時(shí),派生出來(lái)的類不但擁有父類中的方法和屬性,還可以根據(jù)自己的需求,自定義一些特殊的屬性和方法,使得派生類功能更加強(qiáng)大。MFC有較好的移植性,可應(yīng)用于眾多平臺(tái)。2.1.2 MFC類庫(kù)結(jié)構(gòu)MFC中類可劃分為基類、應(yīng)用程序結(jié)構(gòu)類、窗口類、OLE類、數(shù)據(jù)庫(kù)類等10大類,而且在其中的一些大類的基礎(chǔ)上又派生出許多子類。MFC的類庫(kù)結(jié)構(gòu)的層次圖如下圖所示。2.1.2 MFC類庫(kù)結(jié)構(gòu)從上圖中可以看出,CObject是一個(gè)原始基類。絕大多數(shù)MFC類的最終基類都是CObject。原始基類下面,主要包括以下幾種類:MFC應(yīng)用程序結(jié)構(gòu)類,窗口、對(duì)話框和控件類,輸出(設(shè)

13、備文本)和繪圖類,簡(jiǎn)單數(shù)據(jù)類型類,數(shù)組、列表和映射類,文件和數(shù)據(jù)庫(kù)類,Internet和網(wǎng)絡(luò)類,OLE類以及高度和異常類。MFC的應(yīng)用程序結(jié)構(gòu)類分為CWinApp和CWinThread。使用MFC創(chuàng)建的每一個(gè)應(yīng)用程序都包含一個(gè)由類CWinApp派生而來(lái)的應(yīng)用程序?qū)ο?。該?duì)象是一個(gè)全局對(duì)象。應(yīng)用程序?qū)ο笾饕糜谔幚響?yīng)用程序的初始化,同時(shí)也處理應(yīng)用程序事件的消息循環(huán)。CCmdTarget和CCmdUI為MFC中常用的有關(guān)發(fā)送命令的類。CDocument為MFC中常用的應(yīng)用程序文檔的基類。CDocTemplate為文檔模版類,通常是應(yīng)用程序的單文檔或多文檔的基類。CView類是常用的視圖類。2.2

14、MFC應(yīng)用程序框架分析在前面介紹過(guò)如何創(chuàng)建一個(gè)基于單文檔的應(yīng)用程序。對(duì)于如何選擇性地創(chuàng)建基于多文檔或是基于對(duì)話框的應(yīng)用程序,將會(huì)在后續(xù)章節(jié)詳細(xì)介紹。本節(jié)主要對(duì)MFC應(yīng)用程序框進(jìn)行簡(jiǎn)單的概括,使讀者了解MFC應(yīng)用程序框架的結(jié)構(gòu)與工作機(jī)制。2.2.1 入口函數(shù)入口函數(shù)就是指一個(gè)程序的入口點(diǎn)。WinMain函數(shù)是Windows程序的入口函數(shù)。為了便于講解,首先要?jiǎng)?chuàng)建一個(gè)MFC應(yīng)用程序,程序名命名為sample0201。具體創(chuàng)建步驟不再詳細(xì)介紹。從創(chuàng)建好的sample0201程序中,并不能找到WinMain函數(shù)。這是因?yàn)榈湫蚖indows程序的大部分初始化工作都是標(biāo)準(zhǔn)化的,因此把WinMain函數(shù)隱藏

15、在應(yīng)用程序的框架中。當(dāng)一個(gè)程序編譯時(shí),會(huì)自動(dòng)將該函數(shù)鏈接到程序中。在計(jì)算機(jī)中找到Visual C+的安裝目錄,筆者安裝在F盤,則按照下面這個(gè)路徑依次打開文件夾,“F:Program FilesMicrosoft Visual StudioVC98MFCSRC”。打開后,會(huì)發(fā)現(xiàn)一個(gè)源文件“WinMain.cpp”。該文件中則定義了MFC應(yīng)用程序的入口函數(shù)AfxWinMain。文件的源代碼如下:2.2.1 入口函數(shù)2.2.1 入口函數(shù)當(dāng)一個(gè)應(yīng)用程序啟動(dòng)時(shí),會(huì)自動(dòng)調(diào)用應(yīng)用程序框架內(nèi)部的AfxWinMain函數(shù)。根據(jù)其前綴Afx就知道WinMain是一個(gè)全局的MFC函數(shù)。從上述代碼中可以看出,WinM

16、ain函數(shù)會(huì)查找該應(yīng)用程序的一個(gè)全局構(gòu)造對(duì)象。該對(duì)象是由CWinApp的派生類創(chuàng)建,因此有程序啟動(dòng)時(shí),它就被創(chuàng)建好了。然后WinMain對(duì)該應(yīng)用程序進(jìn)行初始化,在此過(guò)程調(diào)用的是該程序全局構(gòu)造對(duì)象的InitApplication()和InitInstance()函數(shù)。完成初始化后,WinMain調(diào)用Run()函數(shù),運(yùn)行應(yīng)用程序的消息循環(huán)。最后結(jié)束應(yīng)用程序時(shí),WinMain調(diào)用AfxWinTerm()函數(shù),做一些清理工作。2.2.2 InitInstance()函數(shù)InitInstance()函數(shù)的作用是初始化程序。每次啟動(dòng)一個(gè)應(yīng)用程序時(shí),Winmain函數(shù)會(huì)自動(dòng)調(diào)用InitInstance()函

17、數(shù)。打開創(chuàng)建的程序sample0201,在該程序的CSample0201App類中,可以看到該程序?qū)nitInstance()函數(shù)進(jìn)行了重載。該重載代碼如下:2.2.2 InitInstance()函數(shù)從上述代碼中可以看出,在ShowWindow和UpdateWindos之前,程序要做兩個(gè)動(dòng)作,一個(gè)是注冊(cè)窗口類,另一個(gè)是構(gòu)建窗口類。InitInstance()函數(shù)規(guī)定了生成的應(yīng)用程序是基于單文檔的、基于多文檔的或是基于對(duì)話框的。因此在CWinApp中必須重載InitInstance()函數(shù)。2.2.3 應(yīng)用類Run()函數(shù)與查找WinMain函數(shù)類似,在Visual C+的安裝目錄下,按照下

18、面這個(gè)路徑依次打開文件夾,“F:Program FilesMicrosoft Visual StudioVC98MFCSRC”。打開后,會(huì)發(fā)現(xiàn)一個(gè)源文件“THRDCORE.CPP”。該文件中定義了應(yīng)用類Run()函數(shù),源代碼如下:2.2.3 應(yīng)用類Run()函數(shù)從上述代碼中可以看出,如果消息隊(duì)列沒(méi)有消息,則調(diào)用OnIdle( )函數(shù),并遞增iIdleCount計(jì)數(shù)標(biāo)志,該計(jì)數(shù)標(biāo)志表示在兩次消息處理過(guò)程只共調(diào)用了多少次OnIdle()函數(shù)。bIdle是消息隊(duì)列空閑的標(biāo)志,當(dāng)消息隊(duì)列有消息時(shí),則調(diào)用PumpMessage()函數(shù),進(jìn)行消息翻譯和消息派發(fā)。其中PreTranslateMessage(

19、&m_msgCur)對(duì)消息進(jìn)行翻譯,DispatchMessage(&m_msgCur)把消息m_madCur發(fā)送到應(yīng)用程序主框架窗口。注意:在應(yīng)用程序sample0201的CSample0201App的Run函數(shù)繼承了CWinApp的虛函數(shù)Run()。而CWinApp的Run()函數(shù)調(diào)用了CWinThread的Run()函數(shù)。2.2.4 消息映射表當(dāng)MFC應(yīng)用程序類中的Run()函數(shù)把消息交給主窗口的窗口函數(shù)后,窗口函數(shù)將如何處理這些消息。在Win32程序中,處理窗口消息的窗口函數(shù)WinProc()函數(shù)通過(guò)switchcase結(jié)構(gòu)對(duì)消息進(jìn)行判斷并分別進(jìn)行處理。但在MFC應(yīng)用程

20、序的主窗口類對(duì)消息的處理并沒(méi)有沿襲Win32程序的做法。MFC應(yīng)用程序中進(jìn)行消息處理,是為每一個(gè)要處理的消息添加一個(gè)消息處理函數(shù)。這種定義消息和消息處理函數(shù)的對(duì)照表,稱為消息映射表。MFC的消息映射表采用映射宏的方式,將消息和消息處理函數(shù)一一對(duì)應(yīng)起來(lái)。以應(yīng)用程序的主框架為例,在類的聲明文件MainFrame.h中添加聲明消息映射的宏。2.2.4 消息映射表在類的實(shí)現(xiàn)文件MainFrame.cpp中,添加消息映射宏的定義語(yǔ)句。其中,ID_MY_MESSAGE為自定義的菜單項(xiàng)命令I(lǐng)D號(hào),OnMymessage()為響應(yīng)菜單命令的成員函數(shù)。2.2.5 MFC消息分類MFC應(yīng)用程序?qū)ο⒌拿枋鲆话惴譃?/p>

21、3類:窗口消息、命令消息和控件消息。1窗口消息窗口消息一般與創(chuàng)建窗口、繪制窗口、移動(dòng)窗口和銷毀窗口等操作有關(guān)。另外,當(dāng)使用鼠標(biāo)、鍵盤等與操作窗口有關(guān)的動(dòng)作時(shí),也會(huì)產(chǎn)生窗口消息。窗口消息的一般的表示形式是以“WM_”開頭的消息。常見的窗口消息如下所述。WM_CHAR:使用鍵盤時(shí)產(chǎn)生的消息。其對(duì)應(yīng)的消息處理函數(shù)為OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)。WM_CREATE:創(chuàng)建窗口時(shí)產(chǎn)生的消息,用于窗口的初始化。其對(duì)應(yīng)的消息處理函數(shù)為OnCreate(LPCREATESTRUCT lpCreateStruct)。WM_PAINT:通知窗口對(duì)自身進(jìn)行

22、繪制。一般在移動(dòng)窗口、改變窗口大小、繪制圖形時(shí)使用。其對(duì)應(yīng)的消息處理函數(shù)為OnPaint()。1窗口消息WM_LBUTTONDOWM:使用鼠標(biāo)左鍵時(shí)產(chǎn)生的消息。通知窗口單擊了左鍵。其對(duì)應(yīng)的消息處理函數(shù)為OnLButtonDown(UINT nFlags, CPoint point)。WM_MOUSEMOVE:移動(dòng)鼠標(biāo)時(shí)產(chǎn)生的消息。其對(duì)應(yīng)的消息處理函數(shù)為OnMouseMove(UINT nFlags, CPoint point)。WM_CLOSE:關(guān)閉窗口時(shí)產(chǎn)生的消息。其對(duì)應(yīng)的消息處理函數(shù)為OnClose()。WM_DESTROY:銷毀窗口時(shí)產(chǎn)生的消息。其對(duì)應(yīng)的消息處理函數(shù)為OnDestroy(

23、)。2命令消息命令消息一般與處理用戶的某個(gè)請(qǐng)求或執(zhí)行用戶的某個(gè)命令有關(guān)。一般通過(guò)選擇菜單項(xiàng)、單擊工具欄按鈕和按加速鍵產(chǎn)生命令消息。在MFC應(yīng)用程序中,凡是從基類CCmdTarget派生出來(lái)的子類,都能處理命令消息。另外,文檔類、視圖類和應(yīng)用程序類都能處理命令消息。創(chuàng)建命令消息時(shí),可以使用MFC Class Wizard建立消息映射和消息處理函數(shù)之間的關(guān)系。例如,應(yīng)用程序類發(fā)出文件打開命令,假設(shè)打開文件對(duì)應(yīng)的菜單資源ID為ID_FILE_IPEN,則其命令消息如下:3控件消息普通的控件都是子窗口,因?yàn)槠涠祭^承自CWnd。它們通過(guò)向其父窗口(一般為對(duì)話框)發(fā)關(guān)消息,響應(yīng)用戶的動(dòng)作(如移動(dòng)鼠標(biāo),單擊

24、等)。控件消息一般是由按鈕(BN_)、編輯框(EN_)、下拉列表框(LBN_)和組合框(CBN_)等控件產(chǎn)生的。其消息映射宏是在消息名前加上ON_,例如:第3章 C+語(yǔ)言基礎(chǔ)要使用Visual C+進(jìn)行Windows應(yīng)用程序的開發(fā),就要掌握面向?qū)ο蟮乃枷牒虲+語(yǔ)言。本章先講述一個(gè)簡(jiǎn)單的C+程序,然后根據(jù)這個(gè)程序,向讀者介紹C+中語(yǔ)言基礎(chǔ)。3.2 C+的基本數(shù)據(jù)類型及數(shù)據(jù)數(shù)據(jù)類型是對(duì)數(shù)據(jù)的一種抽象描述。在計(jì)算機(jī)程序中能操作的數(shù)據(jù)有很多種,不同的數(shù)據(jù)所需要的存儲(chǔ)空間有所不同。將數(shù)據(jù)按照類型進(jìn)行分類,有助于程序員對(duì)于存儲(chǔ)空間的分配。本節(jié)將具體介紹有關(guān)C+中的數(shù)據(jù)及其所屬的數(shù)據(jù)類型。3.2.2 變量變

25、量是一種特殊的標(biāo)識(shí)符,在變量中可以存儲(chǔ)數(shù)據(jù)。變量中存儲(chǔ)的數(shù)據(jù)可以根據(jù)程序的需要而改變,因此稱為變量。1定義變量在C+中,使用一個(gè)變量必須先定義該變量。C+中定義變量的語(yǔ)法代碼如下:定義一個(gè)變量需要說(shuō)明兩點(diǎn),一是變量的類型,二是變量的名稱。其中,變量的類型是C+中的數(shù)據(jù)類型。變量名是用戶為變量起的名稱。3.2.2 變量C+的變量名由字符及數(shù)字等組成。變量名必須滿足以下幾個(gè)條件。變量名只能由字母、數(shù)字和下劃線(_)組成。變量名必須以字母或下劃線開頭。變量名不能包含空白字符(換行符、空格和制表符稱為空白字符)。變量名不能與保留字名相同。變量名區(qū)分大小寫。3.2.2 變量2變量賦值如果想要使用一個(gè)變量

26、,就要為其進(jìn)行賦值。如果沒(méi)有對(duì)定義的變量賦值,Visual C+會(huì)為該變量默認(rèn)一個(gè)值。例如,如果是一個(gè)int類型的變量且沒(méi)有賦值,Visual C+將默認(rèn)其值為0。C+中為變量賦值的方法有兩種:一種是在定義變量的同時(shí)賦值,另一種是在定義變量后賦值。在定義變量的同時(shí)賦值,代碼如下:在定義變量后賦值,代碼如下:3.2.3常量常量與變量相反,是一個(gè)不隨時(shí)間和程序變化而變化的值。C+中,常量的命名規(guī)則和變量的大體相同。不同的是,常量名稱中的字母都為大寫。C+中定義符號(hào)常量的語(yǔ)法代碼如下:例如,在計(jì)算圓形面積的時(shí)候,經(jīng)常用到PI。為了避免重復(fù)地輸入PI的實(shí)際取值,而用下面的形式聲明PI的取值。這樣,在程

27、序中編譯時(shí),會(huì)將程序中出現(xiàn)的所有字符串PI全部置換成3.14。如果想要修改程序中PI的值,只需在頭文件處修改,全部PI的取值都會(huì)發(fā)生變化。3.2.3常量C+中定義靜態(tài)常量的語(yǔ)法代碼如下:在C+中,同聲符號(hào)常量一樣,在聲明靜態(tài)常量時(shí),也要對(duì)其進(jìn)行初始化,代碼如下:注意:在符號(hào)常量中,PI沒(méi)有類型,不占有存儲(chǔ)單元,且容易出錯(cuò)。而在Const常量中,PI有數(shù)據(jù)類型,并且占有存儲(chǔ)單元,有地址,因此可以使用指針指向它。3.3 C+的運(yùn)算符及表達(dá)式運(yùn)算符和表達(dá)式是一種程序語(yǔ)言的基礎(chǔ)。運(yùn)算符的作用是操作變量或表達(dá)式。C+中的運(yùn)算符包括賦值運(yùn)算符、算術(shù)運(yùn)算符、邏輯運(yùn)算符、關(guān)系運(yùn)算符、位運(yùn)算符、逗號(hào)運(yùn)算符、條件

28、運(yùn)算符等。本節(jié)將介紹這些運(yùn)算符及其所組成的表達(dá)式。3.3.1 表達(dá)式表達(dá)式是C+程序中不可缺少的一部分。表達(dá)式是由運(yùn)算符、操作數(shù)(變量、常量或函數(shù)等)和標(biāo)點(diǎn)符號(hào),按照一定規(guī)則組成的一個(gè)有意義的語(yǔ)句。例如:3.3.2 運(yùn)算符C+中的運(yùn)算符就是一種符號(hào),該符號(hào)可以用于處理數(shù)據(jù)。平時(shí)有數(shù)學(xué)計(jì)算中所使用的“+”、“-”、“”、“”都屬于運(yùn)算符。只是這些運(yùn)算符在C+中的表現(xiàn)形式可能與日常生活中有所不同。下面將對(duì)C+中的運(yùn)算符作具體介紹。1賦值運(yùn)算符賦值運(yùn)算符是用于為變量或常量指定數(shù)值的運(yùn)算體符。其操作符號(hào)為“”,示例代碼如下:上述表達(dá)式的意義是,把b的值賦值給a。其中,b可以是一個(gè)單純的變量,也可以是一

29、個(gè)表達(dá)式。3.3.2 運(yùn)算符2算術(shù)運(yùn)算符算術(shù)運(yùn)算符是用于進(jìn)行數(shù)學(xué)運(yùn)算的運(yùn)算符。例如,加、減、乘、除等就是算術(shù)運(yùn)算符。操作完成后,返回一個(gè)數(shù)字型的值。算術(shù)運(yùn)算符包括加法運(yùn)算符(+)、減法運(yùn)算符(-)、乘法運(yùn)算符(*)、除法運(yùn)算符(/)、模運(yùn)算符()。上述算術(shù)運(yùn)算符都是二元運(yùn)算符,該運(yùn)算符兩端的數(shù)據(jù)必須是數(shù)字。3.3.2 運(yùn)算符3邏輯運(yùn)算符邏輯運(yùn)算符,即用于處理邏輯值的運(yùn)算符。邏輯運(yùn)算符通常用在條件判斷語(yǔ)句或循環(huán)語(yǔ)句中,如if、while語(yǔ)句等。C+中的邏輯運(yùn)算符包括邏輯與運(yùn)算符(&)、邏輯或運(yùn)算符(|)、邏輯非運(yùn)算符(!)。由邏輯運(yùn)算符構(gòu)成的表達(dá)式,稱為邏輯表達(dá)式。邏輯表達(dá)式的返回值為邏

30、輯值(true或false),一般情況下,1代表true,0代表false。邏輯與運(yùn)算符可以進(jìn)行與操作,其操作方法為:如果邏輯與運(yùn)算符前的數(shù)為false(或是可以得出false的邏輯表達(dá)式),則返回false,否則返回true;當(dāng)邏輯與運(yùn)算符前后兩個(gè)數(shù)都為true時(shí),才返回true。邏輯或運(yùn)算符可以進(jìn)行或操作,其操作方法為:只要邏輯或運(yùn)算符前后的數(shù)據(jù)中有一個(gè)為true(或是可以得出true的邏輯表達(dá)式),則返回true;當(dāng)邏輯或運(yùn)算符前后兩個(gè)數(shù)都為false時(shí),才返回false。邏輯非運(yùn)算符要求要操作的數(shù)據(jù)必須是邏輯值,或是能夠轉(zhuǎn)換成邏輯值的邏輯表達(dá)式。邏輯非運(yùn)算符可以進(jìn)行非操作,其操作方法為

31、:如果要操作的數(shù)據(jù)為true,則返回false;如果要操作的數(shù)據(jù)為false,則返回true。3.3.2 運(yùn)算符4關(guān)系運(yùn)算符關(guān)系運(yùn)算符,即用于比較兩個(gè)數(shù)據(jù)關(guān)系大小的運(yùn)算符,并根據(jù)比較的結(jié)果返回一個(gè)邏輯值。關(guān)系運(yùn)算符包括大于運(yùn)算符()、大于等于運(yùn)算符(=)、小于運(yùn)算符()、小于等于運(yùn)算符(”一起使用。使用cin的語(yǔ)法代碼如下:例如,想要從鍵盤輸入一些數(shù)據(jù),將使用下述代碼:如果想要一次性輸入多個(gè)數(shù)據(jù),不是使用逗號(hào)作為分隔符,而應(yīng)該用“”分隔,應(yīng)該寫成:3.4.1 C+的輸入輸出2輸出語(yǔ)句C+的輸出語(yǔ)句用cout表示。其中,cout必須和“”一起使用,使用cout的語(yǔ)法代碼如下:例如,想要從鍵盤輸出

32、一些數(shù)據(jù),將使用下述代碼:如果想要一次性的輸出多個(gè)數(shù)據(jù),同樣不是使用逗號(hào)作為分隔符,而是每項(xiàng)數(shù)據(jù)之間用“Close();/關(guān)閉記錄集m_pConnection-Close();/關(guān)閉連接第13章 多線程編程Windows是一個(gè)多任務(wù)的操作系統(tǒng)。多線程運(yùn)行可以提高系統(tǒng)的運(yùn)行效率,因此使用比較廣泛。本章將對(duì)進(jìn)程與線程進(jìn)行簡(jiǎn)單介紹。內(nèi)容包括:進(jìn)程與線程、線程的使用、線程的終止與通信等。通過(guò)本章的學(xué)習(xí),讀者可以在程序中調(diào)用其他應(yīng)用程序,可以實(shí)現(xiàn)進(jìn)程間的通信,可以實(shí)現(xiàn)線程的同步。下面對(duì)多線程技術(shù)進(jìn)行詳細(xì)介紹。 13.1 進(jìn)程與線程進(jìn)程(Process)是應(yīng)用程序的執(zhí)行實(shí)例。每個(gè)進(jìn)行都可以訪問(wèn)進(jìn)程中的所有

33、資源。一個(gè)進(jìn)程是由一個(gè)或多個(gè)進(jìn)行、代碼、數(shù)據(jù)和應(yīng)用程序在內(nèi)存中的其他資源組成。當(dāng)一個(gè)應(yīng)用程序啟動(dòng),相應(yīng)的一個(gè)進(jìn)程進(jìn)行也會(huì)啟動(dòng),這個(gè)進(jìn)行稱為父進(jìn)程。一個(gè)應(yīng)用程序還可以啟動(dòng)其他進(jìn)程,被啟動(dòng)的其他進(jìn)程稱為子進(jìn)程。想要查看進(jìn)程,可以打開Windows的任務(wù)管理器。單擊【進(jìn)程】標(biāo)簽,在【進(jìn)程】選擇卡中可以查看當(dāng)前系統(tǒng)中的各個(gè)進(jìn)程,如右圖所示。進(jìn)程是資源的分配單位,每個(gè)進(jìn)程都擁有自己的地址空間和上下文環(huán)境。13.1 進(jìn)程與線程進(jìn)程是線程的容器,線程是進(jìn)程內(nèi)部的一個(gè)執(zhí)行單元。一個(gè)進(jìn)程可以有一個(gè)或是多個(gè)線程,但這些線程僅生存于該進(jìn)程中。也就是說(shuō),線程是在它所屬的進(jìn)程地址空間里執(zhí)行代碼,并在進(jìn)程的地址空間對(duì)數(shù)據(jù)

34、進(jìn)行操作。線程用于描述進(jìn)程中的運(yùn)行路徑。當(dāng)一個(gè)進(jìn)程被啟動(dòng)時(shí),系統(tǒng)就要?jiǎng)?chuàng)建一個(gè)主線程。該主線程是應(yīng)用程序需要的唯一線程,但進(jìn)程也可以創(chuàng)建其他線程來(lái)完善進(jìn)程的其他操作。13.2 線程的分類在MFC中,線程分為兩類:用戶界面線程(User-Interface Thread)和工作者線程(Worker Thread)。用戶界面線程:該線程通常用來(lái)處理用戶的輸入并響應(yīng)用戶生成的事件和消息。用戶界面線程是從CWinThread類派生而來(lái)的。在MFC中,CWinApp對(duì)象就是一個(gè)用戶界面線程。通常情況下,用戶界面線程都是主線程。當(dāng)應(yīng)用程序啟動(dòng)時(shí),用戶界面線程隨之啟動(dòng)。當(dāng)應(yīng)用程序退出時(shí),用戶界面線程也會(huì)隨之終

35、止。工作者線程:該線程通常不需要用戶進(jìn)行輸入,由后臺(tái)進(jìn)行處理。因此,工作者線程又被稱為后臺(tái)線程。工作者線程和用戶界面線程的區(qū)別在于,工作者線程不用從CWinThread類派生。13.3 線程類(CWinThread)在MFC上,CWinThread類封裝了對(duì)線程的操作。下面對(duì)CWinThtead類中的成員函數(shù)和成員變量作具體介紹。其中,CWinThread類中常用的函數(shù)如下:(1)調(diào)用CreateThread()函數(shù)可以創(chuàng)建一個(gè)新的線程,該函數(shù)的原型如下:dwCreateFlags:表示線程創(chuàng)建的標(biāo)志。nStackSize:表示線程堆棧的大小。lpSecurityAttrs:表示線程的安全屬性

36、。13.3 線程類(CWinThread)(2)調(diào)用SetThreadPriority()函數(shù)可以設(shè)置線程的優(yōu)先級(jí),該函數(shù)的原型如下:其中,nPriority參數(shù)定義了線程的優(yōu)先級(jí)。其取值如下表所示。13.3 線程類(CWinThread)(3)調(diào)用GetThreadPriority()函數(shù)可以獲取線程的優(yōu)先級(jí),該函數(shù)原型如下:(4)調(diào)用PostThreadMessage()函數(shù)可以向另一個(gè)CWinThread對(duì)象發(fā)送消息,該函數(shù)的原型如下:message:表示用戶定義消息的標(biāo)識(shí)。wParam:表示消息的第一個(gè)參數(shù)。lParam:表示消息的第二個(gè)參數(shù)。13.3 線程類(CWinThread)(

37、5)調(diào)用SuspendThread()函數(shù)可以將線程的掛起計(jì)數(shù)加1,當(dāng)線程的掛起計(jì)數(shù)大于0時(shí),該線程將暫停執(zhí)行,稱之為掛起狀態(tài)。該函數(shù)的原型如下:(6)調(diào)用ResumeThread()函數(shù)可以將線程的掛起計(jì)數(shù)減1。當(dāng)線程的掛起計(jì)數(shù)減少到0時(shí),恢復(fù)線程的執(zhí)行。該函數(shù)的原型如下:13.3 線程類(CWinThread)在CWinThread類中,還需要重載一些函數(shù)來(lái)完成對(duì)線程的操作。(1)重載InitInstance()函數(shù)用于控制用戶界面線程實(shí)例的初始化工作,該函數(shù)的原型如下:(2)重載ExitInstance()函數(shù)用于控制清理操作,該函數(shù)的原型如下:(3)重載OnIdle()函數(shù)用于控制線程

38、空閑處理操作,該函數(shù)的原型如下:lCount:表示計(jì)數(shù)器。此外,CWinThread類中有以下幾個(gè)重要的成員變量。m_hThread:表示當(dāng)前線程的句柄。m_nThreadID:表示當(dāng)前線程的ID。m_pMainWnd:表示指向應(yīng)用程序主窗口的指針。13.4 線程的使用在MFC中,創(chuàng)建一個(gè)新的線程時(shí),可以使用全局函數(shù)AfxBeginThread()。AfxBeginThread()有兩種原型,分別用于創(chuàng)建用戶界面線程和工作者線程。13.4.1 啟用用戶界面線程當(dāng)啟用用戶界面線程時(shí),調(diào)用AfxBeginThread()的原型如下:pThreadClass:表示用戶界面線程對(duì)象運(yùn)程時(shí)類結(jié)構(gòu)指針。p

39、Param:表示傳遞給控制函數(shù)的參數(shù)。nPriority:表示線程的優(yōu)先級(jí)。nStackSize:表示線程堆棧的大小。dwCreateFlags:表示線程創(chuàng)建的標(biāo)志。lpSecurityAttrs:表示安全屬性(SECURITY_ATTRIBUTES)結(jié)構(gòu)指針。13.4.1 啟用用戶界面線程另外,啟用用戶界面線程還可以先創(chuàng)建一個(gè)CWinThread類的對(duì)象,然后調(diào)用CreateThread()函數(shù)。代碼如下:13.4.2 啟用工作者線程當(dāng)啟用工作者線程時(shí),調(diào)用AfxBeginThread()的原型如下:pfnThreadProc:表示工作者線程的控制函數(shù)指針。pParam:表示傳遞給控制函數(shù)的

40、參數(shù)。nPriority:表示線程的優(yōu)先級(jí)。nStackSize:表示線程堆棧的大小。dwCreateFlags:表示線程創(chuàng)建的標(biāo)志。lpSecurityAttrs:表示安全屬性(SECURITY_ATTRIBUTES)結(jié)構(gòu)指針。注意:函數(shù)的返回值是一個(gè)線程指針。一般情況下,需要保存該指針,以便于以后根據(jù)該指針來(lái)終止該線程。13.4.3 用戶界面線程在實(shí)際應(yīng)用過(guò)程中,有時(shí)需要在線程中創(chuàng)建對(duì)話框。此時(shí),可以使用用戶界面線程來(lái)實(shí)現(xiàn)。在MFC中,創(chuàng)建用戶界面線程的具體步驟如下:(1)從CWinThread類派生一個(gè)子類。(2)在子類的InitInstance()函數(shù)中設(shè)置線程的主窗口。(3)調(diào)用Af

41、xBeginThread()函數(shù)創(chuàng)建用戶界面線程。13.4.3 用戶界面線程【示例13-1】創(chuàng)建用戶界面線程。在一個(gè)基于對(duì)話框的MFC應(yīng)用程序中,創(chuàng)建一個(gè)用戶界面線程用來(lái)啟動(dòng)另外一個(gè)對(duì)話框。(1)創(chuàng)建一個(gè)基于對(duì)話框的MFC應(yīng)用程序sample1301。(2)設(shè)計(jì)對(duì)話框資源,如下圖所示。13.4.3 用戶界面線程(3)單擊【Insert】|【Resource】命令,彈出【Insert Resource】(插入資源)對(duì)話框。選擇Dialog結(jié)點(diǎn),如左圖所示。(4)設(shè)計(jì)新插入的對(duì)話框資源,如右圖所示。13.4.3 用戶界面線程(5)雙擊新添加的對(duì)話框資源,為其添加相應(yīng)的類CSubDlg,如左圖所示。

42、(6)單擊【Insert】|【New Class】命令,彈出【New Class】對(duì)話框。添加一個(gè)CWinThread類的子類CSubThread,如右圖所示。13.4.3 用戶界面線程(7)添加并修改CSubThread類中的數(shù)據(jù)成員和成員函數(shù)。其中,SubThread.h文件中的代碼如下:SubThread.cpp文件中的代碼如下:13.4.3 用戶界面線程(8)在對(duì)話框類CSample1301Dlg的【創(chuàng)建用戶界面線程】按鈕中添加如下代碼:在【取消】按鈕中添加如下代碼:13.4.3 用戶界面線程(9)運(yùn)行程序sample1301,彈出主對(duì)話框。單擊【創(chuàng)建用戶界面線程】按鈕,彈出【用戶界面

43、線程】對(duì)話框。當(dāng)運(yùn)行程序sample1301的同時(shí),可以打開系統(tǒng)的任務(wù)管理器進(jìn)行查看。當(dāng)主對(duì)話框彈出時(shí),進(jìn)程中多了一個(gè)sample1301.exe進(jìn)程。當(dāng)彈出【用戶界面線程】對(duì)話框時(shí),沒(méi)有相應(yīng)的進(jìn)程出現(xiàn)。從上述內(nèi)容中可以看出,本例成功地創(chuàng)建了一個(gè)用戶界面線程。13.4.4 工作者線程創(chuàng)建工作者線程不需要使用CWinThread類的派生類,而是需要實(shí)現(xiàn)控制函數(shù)。在工作者線程的控制函數(shù)中,定義了線程的生命周期。當(dāng)進(jìn)入控制函數(shù)時(shí),線程將被啟動(dòng)。而當(dāng)退出函數(shù)時(shí),線程將被終止。【示例13-2】創(chuàng)建工作者線程。在一個(gè)基于對(duì)話框的MFC應(yīng)用程序中,創(chuàng)建工作者線程,并在對(duì)話框進(jìn)行初始化時(shí)啟用。(1)創(chuàng)建一個(gè)基

44、于對(duì)話框的MFC應(yīng)用程序sample1302。(2)設(shè)計(jì)對(duì)話框資源,如下圖所示。13.4.4 工作者線程(3)添加成員變量。為兩個(gè)ListBox控件添加成員變量,分別為m_list1和m_list2。其中,類別為Control,類型為CListBox。(4)為CSample1302Dlg類添加兩個(gè)自定義函數(shù),分別如下:(5)為控制函數(shù)添加代碼。其中,F(xiàn)irstThread()函數(shù)中添加的代碼如下:SecondThread()函數(shù)中添加的代碼如下:13.4.4 工作者線程(6)在對(duì)話框類CSample1302Dlg的OnInitDialog()函數(shù)中添加如下代碼:(7)修改Sample1302D

45、lg.h文件中的函數(shù)聲明,將線程函數(shù)聲明為static函數(shù)。 13.4.4 工作者線程(8)運(yùn)行程序sample1302,結(jié)果如圖13.8所示。注意:如果不按照第(7)步驟對(duì)Sample1302Dlg.h文件進(jìn)行修改,會(huì)出現(xiàn)如下錯(cuò)誤提示:AfxBeginThread : none of the 2 overloads can convert parameter 1 from type unsigned int (void *)。13.5 線程的終止當(dāng)一個(gè)線程終止時(shí),關(guān)閉該線程所屬的所有對(duì)象句柄,將該線程對(duì)象狀態(tài)變?yōu)橛行畔⑻?hào)狀態(tài),并將該線程對(duì)象終止?fàn)顟B(tài)STILL_ACTIVE改為退出碼。通常情況

46、下,線程終止分為兩種:正常終止和異常終止。13.5.1 正常終止線程對(duì)于用戶界面線程而言,使其正常終止只需在用戶界面線程中調(diào)用PostQuitMessage()即可。該函數(shù)的原型如下:nExitCode:表示線程的退出碼。對(duì)于工作者線程而言,當(dāng)控制函數(shù)正常執(zhí)行到函數(shù)的結(jié)束點(diǎn)(return語(yǔ)句)后,該線程也就正常終止了。另外,用戶也可以選擇使用AfxEndThread()函數(shù)來(lái)終止該線程。AfxEndThread()函數(shù)的原型如下:13.5.2 異常終止線程異常終止是指線程內(nèi)部出現(xiàn)自身無(wú)法終止的情況,在其他線程中強(qiáng)行終止該線程。異常終止用于在緊急情況下安全退出控制。如果想要終止線程,可以使用Te

47、rminateThread()函數(shù)。該函數(shù)的原型如下:hThread:表示將要終止的線程句柄。該參數(shù)可以使用創(chuàng)建線程返回時(shí)返回的CWinThread從m_hThread成員變量中得到。dwExitCode:表示線程的退出碼。13.5.3 線程的退出碼根據(jù)線程的退出碼,可以判斷線程的執(zhí)行情況。使用GetExitCode()函數(shù)可以獲取工作者線程或用戶界面線程退出碼。該函數(shù)的原型如下:hThread:表示線程句柄。該參數(shù)可以使用創(chuàng)建線程返回時(shí)返回的CWinThread從m_hThread成員變量中得到。lpExitCode:表示接收返回的終止?fàn)顟B(tài)的地址。13.5.3 線程的退出碼如果線程沒(méi)有被終止

48、,則終止?fàn)顟B(tài)返回STILL_ACTIVE。如果線程已經(jīng)被終止,則返回的終止?fàn)顟B(tài)可以是以下取值中的一個(gè):在ExitThread()或TerminateThread()函數(shù)中指定的退出值。在線程函數(shù)的return語(yǔ)句中的返回值。線程所屬進(jìn)程中的退出值。13.5.3 線程的退出碼想要獲取線程的退出碼,還要做一些其他工作。一般線程終止后,線程對(duì)象將被刪除,用戶不能獲取m_hThread句柄。想要解決這個(gè)問(wèn)題,可以采用以下兩個(gè)辦法。(1)在創(chuàng)建線程后,設(shè)置線程對(duì)象的m_bAutoDelete成員變量為FALSE。這樣,CWinThread對(duì)象在線程終止后仍將存在。在退出應(yīng)用程序之前,還需要手動(dòng)添加刪除C

49、WinThread線程對(duì)象的代碼。(2)單獨(dú)選擇保存線程句柄。在創(chuàng)建線程后,使用Win32函數(shù)DuplicateHandle()將m_hThread復(fù)制到另一個(gè)句柄。這樣,盡管對(duì)象被自動(dòng)刪除了,但使用復(fù)制的句仍然可以獲取線程的退出碼。注意:采用第二種方法時(shí),在復(fù)制句柄之前,線程不能終止。最安全的方法是在創(chuàng)建線程進(jìn)使用CREATE_SUSPENDED掛起,復(fù)制好后,調(diào)用ResumeThread()函數(shù)恢復(fù)線程的執(zhí)行。13.6 線程的通信通常情況下,在次線程是為主線程服務(wù)的,這就預(yù)示著主線程和次線程之間會(huì)進(jìn)行及時(shí)的通信。下面對(duì)線程間的通信作簡(jiǎn)單介紹。13.6.1 通信原理在線程間進(jìn)行通信的過(guò)程中,

50、需要用到以下幾個(gè)函數(shù)。其中,調(diào)用PostMessage()函數(shù)可以進(jìn)行線程間的通信。該函數(shù)的原型如下:hWnd:表示消息發(fā)送的目的窗口句柄。Msg:表示將要發(fā)送的消息。wParam:表示消息的第1個(gè)參數(shù)。lParam:表示消息的第2個(gè)參數(shù)。13.6.1 通信原理調(diào)用PostThreadMessage()函數(shù)可以向某個(gè)線程發(fā)送消息,該函數(shù)的原型如下:idThread:表示線程標(biāo)識(shí)。Msg:表示將要發(fā)送的消息。wParam:表示消息的第1個(gè)參數(shù)。lParam:表示消息的第2個(gè)參數(shù)。13.6.1 通信原理如果想要對(duì)消息進(jìn)行外理,用戶界面線程和工作者線程的處理方式不同。在用戶界面線程中,有兩種方式對(duì)消

51、息進(jìn)行處理。(1)使用消息映射宏ON_THREAD_MESSAGE。該宏的定義格式如下:message:表示消息標(biāo)識(shí)ID。memberFxn:表示CWinThread消息處理函數(shù)的名稱。(2)使用PreTranslateMessage()函數(shù),直接對(duì)消息進(jìn)行處理。該函數(shù)的原型如下:pMeg:表示包含消息的MSG結(jié)構(gòu)指針。13.6.1 通信原理在工作者線程中,可以使用GetMessage()函數(shù)對(duì)消息進(jìn)行處理。該函數(shù)的原型如下:lpMsg:表示消息MSG結(jié)構(gòu)指針。hWnd:表示窗口句柄。wMsgFilterMin:表示第1個(gè)消息。wMsgFilterMax:表示最后一個(gè)消息。13.6.2 用戶界

52、面線程通信下面通過(guò)一個(gè)實(shí)例來(lái)介紹用戶界面線程間的通信?!臼纠?3-3】實(shí)現(xiàn)用戶界面線程間的通信。(1)創(chuàng)建一個(gè)基于對(duì)話框的MFC應(yīng)用程序sample1303。(2)設(shè)計(jì)對(duì)話框資源,如下圖所示。(3)添加成員變量。其中,從上到下,各文本框?qū)?yīng)的成員變量分別為m_edit1、m_edit2和m_edit3。其中,m_edit1、m_edit2的類別為Value,類型為int。m_edit3的類別為Control,類型為CEdit。13.6.2 用戶界面線程通信(4)添加CWinThread類的派生類。單擊【Insert】|【New Class】命令,彈出【New Class】對(duì)話框。添加一個(gè)CWi

53、nThread類的子類CWinThread,如圖13.10所示。13.6.2 用戶界面線程通信(5)在CompareThread.h文件中添加如下代碼:在CompareThread.cpp文件中添加如下代碼:(6)在CSample1303Dlg類中添加一條自定義消息,代碼如下:13.6.2 用戶界面線程通信(7)重載CCompareThread類的PreTranslateMessage()函數(shù)。右擊CCompareThread類,在彈出的彈出式菜單中選擇【Add Virtual Function】菜單項(xiàng),彈出【New Virtual Override for Class CCompareThr

54、ead】對(duì)話框。從左邊的列表框中雙擊【PreTranslateMessage】選項(xiàng),將其移動(dòng)到右邊的列表框中,如下圖所示。13.6.2 用戶界面線程通信(8)單擊【Add and Edit】按鈕,進(jìn)入編輯區(qū)。在PreTranslateMessage()函數(shù)中添加代碼如下:13.6.2 用戶界面線程通信(9)為對(duì)話框類CSample1303Dlg添加一個(gè)成員變量,如下圖所示。該變量用于保存線程的標(biāo)識(shí)。(10)在對(duì)話框類CSample1303Dlg的初始化函數(shù)中創(chuàng)建并啟動(dòng)用戶界面線程,代碼如下:13.6.2 用戶界面線程通信(11)在【比較】按鈕的消息響應(yīng)函數(shù)中添加如下代碼:(12)運(yùn)行程序sam

55、ple1303,結(jié)果如下圖所示。在運(yùn)行程序時(shí),單擊【比較】按鈕,并沒(méi)有直接對(duì)a、b的值進(jìn)行比較,而是發(fā)送一條WM_CPMPARE的消息,交由CCompareThread類的PreTranslateMessage()函數(shù)進(jìn)行處理。13.7 線程的同步在編寫多線程應(yīng)用程序時(shí),經(jīng)常會(huì)出現(xiàn)線程間同步訪問(wèn)共享資源的情況。多個(gè)線程同時(shí)訪問(wèn)同一個(gè)共享資源將可能發(fā)生無(wú)法預(yù)知的錯(cuò)誤。例如,一個(gè)線程正在更新數(shù)據(jù)集,而同時(shí)另外一個(gè)線程正在讀取數(shù)據(jù)。那么,第二個(gè)線程只會(huì)讀取一部分正確的數(shù)據(jù)。為了解決這個(gè)問(wèn)題,Visual C+6.0提供了同步類。同步類包括同步對(duì)象和同步訪問(wèn)對(duì)象。其中,同步對(duì)象分為4種,分別是CSem

56、aphore(信號(hào)量)、CCriticalSection(臨界區(qū))、CMutex(互斥量)和CEvent(事件)。下面對(duì)這些同步類分別進(jìn)行介紹。13.7.1 同步訪問(wèn)對(duì)象同步訪問(wèn)對(duì)象提供了對(duì)同步對(duì)象的封裝。同步訪問(wèn)對(duì)象分為兩種,分別是CSingleLock和CMultiLock。1CSingleLock如果一次只需要等待一個(gè)同步對(duì)象,可以使用CSingleLock類的對(duì)象。CSingleLock類的構(gòu)造函數(shù)如下:pObject:表示同步對(duì)象指針。該參數(shù)不能為NULL。bInitialLock:表示是否在初始化時(shí)對(duì)同步對(duì)象進(jìn)行訪問(wèn)。如果想要獲取同步對(duì)象,可以使用Lock()函數(shù)。該函數(shù)的原型如下

57、:dwTimeOut:表示同步對(duì)象等待的時(shí)間。13.7.1 同步訪問(wèn)對(duì)象如果想要釋放同步對(duì)象,可以使用Unlock()函數(shù)。該函數(shù)的原型如下:lCount:表示要釋放的對(duì)象數(shù)。lPrevCount:表示同步對(duì)象接收的前一次的個(gè)數(shù)。如果想要判斷等待的同步對(duì)象是否被鎖定,可以使用IsLocked()函數(shù)。該函數(shù)的原型如下:13.7.1 同步訪問(wèn)對(duì)象2CMultiLock如果在某個(gè)特定的時(shí)刻要使用多個(gè)同步對(duì)象,可以使用CMultiLock類的對(duì)象。CMultiLock類的構(gòu)造函數(shù)原型如下:ppObjects:表示同步對(duì)象數(shù)組指針。dwCount:表示同步對(duì)象數(shù)組元素的個(gè)數(shù)。bInitialLock:

58、表示是否在初始化時(shí)對(duì)同步對(duì)象進(jìn)行訪問(wèn)。13.7.1 同步訪問(wèn)對(duì)象如果想要獲取同步對(duì)象,可以使用Lock()函數(shù)。該函數(shù)的原型如下:dwTimeOut:表示同步對(duì)象等待的時(shí)間。bWaitForAll:表示是否等待所有的同步對(duì)象。dwWakeMask:指定其他放棄等待的條件。13.7.1 同步訪問(wèn)對(duì)象如果想要釋放同步對(duì)象,可以使用Unlock()函數(shù)。該函數(shù)的原型如下:lCount:表示要師范的對(duì)象數(shù),該參數(shù)必須大于0。lPrevCount:表示同步對(duì)象接收的前一次的個(gè)數(shù)。如果想要判斷等待的同步對(duì)象是否被鎖定,可以使用IsLocked()函數(shù)。該函數(shù)的原型如下:13.7.2 使用信號(hào)量實(shí)現(xiàn)線程同步

59、CSemaphore類對(duì)象代表一個(gè)“信號(hào)量”,可以允許一定數(shù)目的線程訪問(wèn)某個(gè)共享資源。信號(hào)量對(duì)象中保存了當(dāng)前同時(shí)訪問(wèn)某個(gè)共享資源的線程計(jì)數(shù)。如果該計(jì)數(shù)值為0,則所有對(duì)這個(gè)CSemaphore類對(duì)象所控制資源的訪問(wèn)將被放到一個(gè)隊(duì)列中進(jìn)行等待,直到超時(shí)或計(jì)數(shù)值不為0。13.7.2 使用信號(hào)量實(shí)現(xiàn)線程同步CSemaphore類的構(gòu)造函數(shù)原型如下:lInitialCount:表示信號(hào)量對(duì)象初始化計(jì)數(shù)。該參數(shù)的值決定了在信號(hào)量對(duì)象建成后,能同時(shí)訪問(wèn)其中資源的最大線程數(shù)目。該參數(shù)的取值在0IMaxCount之間。lMaxCount:表示信號(hào)量對(duì)象的最大計(jì)數(shù)。該參數(shù)必須大于0。pstrName:表示要?jiǎng)?chuàng)建的

60、信號(hào)量對(duì)象的名稱。lpsaAttributes:表示信號(hào)量對(duì)象的安全屬性的指針。該參數(shù)一般設(shè)置為NULL。13.7.3 使用臨界區(qū)對(duì)象實(shí)現(xiàn)線程同步CCriticalSection類對(duì)象代表一個(gè)“臨界區(qū)”。當(dāng)多個(gè)線程訪問(wèn)一個(gè)獨(dú)占性共享資源時(shí),可以使用臨界區(qū)對(duì)象。在同一時(shí)刻,只允許一個(gè)線程可以擁有臨界區(qū)對(duì)象,進(jìn)而訪問(wèn)資源或是代碼段,而其他線程需要等待。CCriticalSection類的構(gòu)造函數(shù)原型如下:13.7.4 使用互斥量對(duì)象實(shí)現(xiàn)線程同步CMutex類對(duì)象代表一個(gè)“互斥量”。互斥量對(duì)象屬于系統(tǒng)內(nèi)核對(duì)象,它能夠使線程擁有對(duì)某個(gè)資源的絕對(duì)訪問(wèn)權(quán)限。CMutex類的構(gòu)造函數(shù)原型如下:bInitiallyOwn:表示互斥

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論