




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、ppt簡介共14章、442頁,涵蓋了vc的基礎介紹,以及mfc程序的創建,控件的使用、多線程、多媒體編程、網絡編程、動態鏈接庫的使用等等,是那些喜歡MFC但是不知道從何學起的MFC愛好者的最佳的基礎教材!第1章 Visual C+集成開發環境第2章 MFC與應用程序框架第3章 C+語言基礎第4章 C+的面向對象 65第5章 菜單欄、工具欄和狀態欄第六章 對話框 108頁始 第七章 控件 134頁始第八章 MFC常用類 171頁始第九章 多媒體類第10章 DLL的開發與調用 237第11章 文檔和視圖 271第12章 數據庫編程 296第13章 多線程編程 340第14章 WinSock網絡通信
2、開發 395第1章 Visual C+集成開發環境Visual C+是一個功能強大的可視化應用程序開發工具。其憑借強大功能,受大了廣大程序員的歡迎。當今流行的Visual C+的開發工具是6.0版本。下面來介紹Visual C+ 6.0的一些基本情況。1.1 Visual C+ 6.0概述Visual C+是一種C/C+語言的集成開發環境(IDE)。當最初還處于DOS時代的Borland公司推出了Turbo Pascal和Turbo C,讓程序員感受到了把編譯器和編輯器集成在一起使用時的方便。Microsoft公司也看到了這一點,于是,兩個公司開始合作,推出了Quick C和Microsoft
3、 C/C+等多個DOS版本的C/C+集成開發環境。隨著Windows的不斷成熟,于是Microsoft開始開發Windows下的Visual C+。經過多次版本的修訂與更新,現在大多數程序員使用的是Visual C+ 6.0版本。Visual C+是一個可視化的C+的集成開發環境。在使用Visual C+時,開發人員可以通過鼠標拖動方便地設計程序的界面,相應的代碼系統會自動生成。MFC(Microsoft Fundermental Classes)是微軟提供的Visual C+可以調用的類庫,其中封裝了開發人員常用的類。使用MFC可以大大提高編程人員的工作效率。1.2 Visual C+6.0
4、界面介紹安裝好Visual C+開發環境后,桌面上并沒有其快捷圖標,需讀者自己修改。選擇“開始”菜單,從所有程序中,找到Microsoft Visual Studio 6.0級聯菜單下的Microsoft Visual C+菜單項。選擇該菜單項,并將其拖動到桌面上,則在桌面上創建了Microsoft Visual Studio的快捷圖標。雙擊快捷圖標,即可啟動Visual C+6.0集成開發環境。每次運行Visual C+6.0時,會彈出一個【Tip of the day】對話框,如下圖所示。1.2 Visual C+6.0界面介紹技巧:【Tip of the day】對話框中介紹了很多關于開
5、發環境的使用方法以及編程方面的小技巧。如果想在下次啟動Visual C+ 6.0時不再顯示該提示對話框,可以選擇下一次啟動時不再顯示它。1.2 Visual C+6.0界面介紹為了便于說明,首先創建一個IDE的MFC項目(具體創建步驟,后面會詳細介紹),如下圖所示。1.2 Visual C+6.0界面介紹從上圖中可以看出,Visual C+的界面被分成了7部分。上面依次標題欄、菜單欄和工具欄。中間左側部分是工作區窗口,右側部分是編輯區。最下方是輸出窗口和狀態欄。1.2.1 工作區窗口和輸出窗口工作區窗口和輸出窗口是在一個程序編譯時使用最多的停靠式窗口。工作區窗口中顯示了當前程序中的所有類、資源
6、和文件信息。工作區窗口分為3個部分:Class View(類視圖)、Resource View(資源視圖)和File View(文件視圖)。Class View:顯示當前工作區中所有工程定義的C+類。雙擊某個類名,Visual C+會自動打開這個類的文件,并將編輯區定位到該類的定義處。雙擊類中的成員函數和變量,編輯區則定位到該成員函數或變量的定義處。1.2.1 工作區窗口和輸出窗口Resource View:顯示當前工作區中所有的資源。這些資源包括快捷鍵、對話框、圖標、菜單、字符條編輯器、工具欄和版本信息。雙擊其中的ID號,會顯示相應的資源信息。File View:顯示屬于當前工程的所有文件,
7、包括C/C+源文件、頭文件、資源文件等。輸出窗口與工作區一樣,分為多個選擇卡。其中最常用的選項卡被放在了最外面,分別為Build、Debug、Find in Files 1和Find in Files 2。1.2.1 工作區窗口和輸出窗口Build:Build顯示工程在創建中,經過的每一個步驟及相應信息。如果出現編譯鏈接錯誤,那么出現錯誤的文件、原因、行號等內容會顯示在Build中。雙擊該錯誤信息行,編輯區則定位在該錯誤出現的行。Debug:工程通過編譯后,運行調試版本時,Debug選項卡中會顯示具體的調試信息。1.2.1 工作區窗口和輸出窗口Find in Files 1和Find in F
8、iles 2:兩個選項卡的作用相同,用于顯示從多個文件中查找字符串的結果。當用戶想要查看某個函數或變量出現在哪些文件中,單擊【Edit】|【Find in Files】命令,彈出【Find in Files】對話框,如下圖所示。在【Find in Files】對話框中的【Find what】后的編輯框中,輸入想要查找的內容,單擊【Find】按鈕即可。查找到的內容會輸出到Find in Files選項卡中。1.2.2 菜單欄和工具欄菜單欄位于集成開發環境的頂部。菜單欄由9個菜單項組成:File(文件)、Edit(編輯)、View(視圖)、Insert(插入)、Project(工程)、Build(
9、編譯)、Tools(工具)、Windows(窗口)、Help(幫助)。每一個菜單項都有一個下拉式菜單,其中的菜單項用于完成特定的功能。工具欄位于菜單欄的下面。工具欄可以稱作是美化的菜單欄,其由許多按鈕構成。其中的按鈕用于完成特定的功能。工具欄可以任意拖動,也可以成為一個浮動窗口。1.2.3 編輯區在Visual C+中,編寫應用程序代碼的位置就是編輯區。該編輯區的功能十分強大,智能化程度也非常高。在編輯區內,除了能編寫C/C+語言外,還能編寫SQL、HTML和VBScript等其他編程語言。如下圖所示。1.2.4 聯機幫助Visual C+6.0不像其他集成開發環境一樣把幫助系統集成在開發環境
10、內部,而是提供了一個專門為Visual C+設計的MSDN類庫。MSDN雖然是一個獨立的幫助系統,但卻能很好地和Visual C+6.0集成在一起。MSDN的使用方式有以下幾種:單擊【Help】|【Contents】命令;單擊【Help】|【Search】命令;單擊【Help】|【Index】命令;按下【F2】鍵。通過上述幾種命令方式,即可運行MSDN。1.2.4 Visual C+中的文件擴展名打開程序Hello World所在的文件夾,看到該文件夾自動生成了許多擴展名不同的文件,如下圖所示。1.2.6 Visual C+中的文件擴展名了解這些不同的擴展名文件,對于理解Visual C+6.
11、0如何組織和管理項目文件是很有必要的。有關這些文件擴展名及其說明,如下表所示。第2章 MFC與應用程序框架在Visual C+集成開發環境下,使用微軟基礎類庫MFC,可以開發出功能強大的Windows應用程序。另外,通過MFC AppWizard自動生成的MFC應用程序框架,還可以很方便地開發自己想要實現的功能。本章將先介紹有關MFC的基礎知識,然后對MFC應用程序框架作具體介紹。2.1 微軟基礎類庫MFCMFC是一種重要的編程方法,它是微軟公司的特定的應用程序包裝接口。本節將講解MFC概述及其類庫結構。2.1.1 MFC概述MFC的英文全稱是Microsoft Foundation Clas
12、ses,即微軟的基礎類庫。MFC的本質就是一個包含了許多微軟公司已經定義好的對象的類庫。雖然開發人員要編寫的程序在功能上各有不同,但是從結構上講,都可以化分為對用戶界面的設計、對文件的操作、對數據庫的訪問及對多媒體的使用等一些最主要的方面。這一點正是微軟提出MFC類庫最重要的原因。在MFC類庫中,大約有200個類。在進行程序設計時,只需簡單地調用已有的類及類中的方法即可。另外,還可以利用“繼承”方法從已有類中派生出自己想要的類。這時,派生出來的類不但擁有父類中的方法和屬性,還可以根據自己的需求,自定義一些特殊的屬性和方法,使得派生類功能更加強大。MFC有較好的移植性,可應用于眾多平臺。2.1.
13、2 MFC類庫結構MFC中類可劃分為基類、應用程序結構類、窗口類、OLE類、數據庫類等10大類,而且在其中的一些大類的基礎上又派生出許多子類。MFC的類庫結構的層次圖如下圖所示。2.1.2 MFC類庫結構從上圖中可以看出,CObject是一個原始基類。絕大多數MFC類的最終基類都是CObject。原始基類下面,主要包括以下幾種類:MFC應用程序結構類,窗口、對話框和控件類,輸出(設備文本)和繪圖類,簡單數據類型類,數組、列表和映射類,文件和數據庫類,Internet和網絡類,OLE類以及高度和異常類。MFC的應用程序結構類分為CWinApp和CWinThread。使用MFC創建的每一個應用程序
14、都包含一個由類CWinApp派生而來的應用程序對象。該對象是一個全局對象。應用程序對象主要用于處理應用程序的初始化,同時也處理應用程序事件的消息循環。CCmdTarget和CCmdUI為MFC中常用的有關發送命令的類。CDocument為MFC中常用的應用程序文檔的基類。CDocTemplate為文檔模版類,通常是應用程序的單文檔或多文檔的基類。CView類是常用的視圖類。2.2 MFC應用程序框架分析在前面介紹過如何創建一個基于單文檔的應用程序。對于如何選擇性地創建基于多文檔或是基于對話框的應用程序,將會在后續章節詳細介紹。本節主要對MFC應用程序框進行簡單的概括,使讀者了解MFC應用程序框
15、架的結構與工作機制。2.2.1 入口函數入口函數就是指一個程序的入口點。WinMain函數是Windows程序的入口函數。為了便于講解,首先要創建一個MFC應用程序,程序名命名為sample0201。具體創建步驟不再詳細介紹。從創建好的sample0201程序中,并不能找到WinMain函數。這是因為典型Windows程序的大部分初始化工作都是標準化的,因此把WinMain函數隱藏在應用程序的框架中。當一個程序編譯時,會自動將該函數鏈接到程序中。在計算機中找到Visual C+的安裝目錄,筆者安裝在F盤,則按照下面這個路徑依次打開文件夾,“F:Program FilesMicrosoft Vi
16、sual StudioVC98MFCSRC”。打開后,會發現一個源文件“WinMain.cpp”。該文件中則定義了MFC應用程序的入口函數AfxWinMain。文件的源代碼如下:2.2.1 入口函數2.2.1 入口函數當一個應用程序啟動時,會自動調用應用程序框架內部的AfxWinMain函數。根據其前綴Afx就知道WinMain是一個全局的MFC函數。從上述代碼中可以看出,WinMain函數會查找該應用程序的一個全局構造對象。該對象是由CWinApp的派生類創建,因此有程序啟動時,它就被創建好了。然后WinMain對該應用程序進行初始化,在此過程調用的是該程序全局構造對象的InitApplic
17、ation()和InitInstance()函數。完成初始化后,WinMain調用Run()函數,運行應用程序的消息循環。最后結束應用程序時,WinMain調用AfxWinTerm()函數,做一些清理工作。2.2.2 InitInstance()函數InitInstance()函數的作用是初始化程序。每次啟動一個應用程序時,Winmain函數會自動調用InitInstance()函數。打開創建的程序sample0201,在該程序的CSample0201App類中,可以看到該程序對InitInstance()函數進行了重載。該重載代碼如下:2.2.2 InitInstance()函數從上述代碼中
18、可以看出,在ShowWindow和UpdateWindos之前,程序要做兩個動作,一個是注冊窗口類,另一個是構建窗口類。InitInstance()函數規定了生成的應用程序是基于單文檔的、基于多文檔的或是基于對話框的。因此在CWinApp中必須重載InitInstance()函數。2.2.3 應用類Run()函數與查找WinMain函數類似,在Visual C+的安裝目錄下,按照下面這個路徑依次打開文件夾,“F:Program FilesMicrosoft Visual StudioVC98MFCSRC”。打開后,會發現一個源文件“THRDCORE.CPP”。該文件中定義了應用類Run()函數
19、,源代碼如下:2.2.3 應用類Run()函數從上述代碼中可以看出,如果消息隊列沒有消息,則調用OnIdle( )函數,并遞增iIdleCount計數標志,該計數標志表示在兩次消息處理過程只共調用了多少次OnIdle()函數。bIdle是消息隊列空閑的標志,當消息隊列有消息時,則調用PumpMessage()函數,進行消息翻譯和消息派發。其中PreTranslateMessage(&m_msgCur)對消息進行翻譯,DispatchMessage(&m_msgCur)把消息m_madCur發送到應用程序主框架窗口。注意:在應用程序sample0201的CSample0201Ap
20、p的Run函數繼承了CWinApp的虛函數Run()。而CWinApp的Run()函數調用了CWinThread的Run()函數。2.2.4 消息映射表當MFC應用程序類中的Run()函數把消息交給主窗口的窗口函數后,窗口函數將如何處理這些消息。在Win32程序中,處理窗口消息的窗口函數WinProc()函數通過switchcase結構對消息進行判斷并分別進行處理。但在MFC應用程序的主窗口類對消息的處理并沒有沿襲Win32程序的做法。MFC應用程序中進行消息處理,是為每一個要處理的消息添加一個消息處理函數。這種定義消息和消息處理函數的對照表,稱為消息映射表。MFC的消息映射表采用映射宏的方式
21、,將消息和消息處理函數一一對應起來。以應用程序的主框架為例,在類的聲明文件MainFrame.h中添加聲明消息映射的宏。2.2.4 消息映射表在類的實現文件MainFrame.cpp中,添加消息映射宏的定義語句。其中,ID_MY_MESSAGE為自定義的菜單項命令ID號,OnMymessage()為響應菜單命令的成員函數。2.2.5 MFC消息分類MFC應用程序對消息的描述一般分為3類:窗口消息、命令消息和控件消息。1窗口消息窗口消息一般與創建窗口、繪制窗口、移動窗口和銷毀窗口等操作有關。另外,當使用鼠標、鍵盤等與操作窗口有關的動作時,也會產生窗口消息。窗口消息的一般的表示形式是以“WM_”開
22、頭的消息。常見的窗口消息如下所述。WM_CHAR:使用鍵盤時產生的消息。其對應的消息處理函數為OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)。WM_CREATE:創建窗口時產生的消息,用于窗口的初始化。其對應的消息處理函數為OnCreate(LPCREATESTRUCT lpCreateStruct)。WM_PAINT:通知窗口對自身進行繪制。一般在移動窗口、改變窗口大小、繪制圖形時使用。其對應的消息處理函數為OnPaint()。1窗口消息WM_LBUTTONDOWM:使用鼠標左鍵時產生的消息。通知窗口單擊了左鍵。其對應的消息處理函數為OnLButt
23、onDown(UINT nFlags, CPoint point)。WM_MOUSEMOVE:移動鼠標時產生的消息。其對應的消息處理函數為OnMouseMove(UINT nFlags, CPoint point)。WM_CLOSE:關閉窗口時產生的消息。其對應的消息處理函數為OnClose()。WM_DESTROY:銷毀窗口時產生的消息。其對應的消息處理函數為OnDestroy()。2命令消息命令消息一般與處理用戶的某個請求或執行用戶的某個命令有關。一般通過選擇菜單項、單擊工具欄按鈕和按加速鍵產生命令消息。在MFC應用程序中,凡是從基類CCmdTarget派生出來的子類,都能處理命令消息。另
24、外,文檔類、視圖類和應用程序類都能處理命令消息。創建命令消息時,可以使用MFC Class Wizard建立消息映射和消息處理函數之間的關系。例如,應用程序類發出文件打開命令,假設打開文件對應的菜單資源ID為ID_FILE_IPEN,則其命令消息如下:3控件消息普通的控件都是子窗口,因為其都繼承自CWnd。它們通過向其父窗口(一般為對話框)發關消息,響應用戶的動作(如移動鼠標,單擊等)。控件消息一般是由按鈕(BN_)、編輯框(EN_)、下拉列表框(LBN_)和組合框(CBN_)等控件產生的。其消息映射宏是在消息名前加上ON_,例如:第3章 C+語言基礎要使用Visual C+進行Windows
25、應用程序的開發,就要掌握面向對象的思想和C+語言。本章先講述一個簡單的C+程序,然后根據這個程序,向讀者介紹C+中語言基礎。3.2 C+的基本數據類型及數據數據類型是對數據的一種抽象描述。在計算機程序中能操作的數據有很多種,不同的數據所需要的存儲空間有所不同。將數據按照類型進行分類,有助于程序員對于存儲空間的分配。本節將具體介紹有關C+中的數據及其所屬的數據類型。3.2.2 變量變量是一種特殊的標識符,在變量中可以存儲數據。變量中存儲的數據可以根據程序的需要而改變,因此稱為變量。1定義變量在C+中,使用一個變量必須先定義該變量。C+中定義變量的語法代碼如下:定義一個變量需要說明兩點,一是變量的
26、類型,二是變量的名稱。其中,變量的類型是C+中的數據類型。變量名是用戶為變量起的名稱。3.2.2 變量C+的變量名由字符及數字等組成。變量名必須滿足以下幾個條件。變量名只能由字母、數字和下劃線(_)組成。變量名必須以字母或下劃線開頭。變量名不能包含空白字符(換行符、空格和制表符稱為空白字符)。變量名不能與保留字名相同。變量名區分大小寫。3.2.2 變量2變量賦值如果想要使用一個變量,就要為其進行賦值。如果沒有對定義的變量賦值,Visual C+會為該變量默認一個值。例如,如果是一個int類型的變量且沒有賦值,Visual C+將默認其值為0。C+中為變量賦值的方法有兩種:一種是在定義變量的同時
27、賦值,另一種是在定義變量后賦值。在定義變量的同時賦值,代碼如下:在定義變量后賦值,代碼如下:3.2.3常量常量與變量相反,是一個不隨時間和程序變化而變化的值。C+中,常量的命名規則和變量的大體相同。不同的是,常量名稱中的字母都為大寫。C+中定義符號常量的語法代碼如下:例如,在計算圓形面積的時候,經常用到PI。為了避免重復地輸入PI的實際取值,而用下面的形式聲明PI的取值。這樣,在程序中編譯時,會將程序中出現的所有字符串PI全部置換成3.14。如果想要修改程序中PI的值,只需在頭文件處修改,全部PI的取值都會發生變化。3.2.3常量C+中定義靜態常量的語法代碼如下:在C+中,同聲符號常量一樣,在
28、聲明靜態常量時,也要對其進行初始化,代碼如下:注意:在符號常量中,PI沒有類型,不占有存儲單元,且容易出錯。而在Const常量中,PI有數據類型,并且占有存儲單元,有地址,因此可以使用指針指向它。3.3 C+的運算符及表達式運算符和表達式是一種程序語言的基礎。運算符的作用是操作變量或表達式。C+中的運算符包括賦值運算符、算術運算符、邏輯運算符、關系運算符、位運算符、逗號運算符、條件運算符等。本節將介紹這些運算符及其所組成的表達式。3.3.1 表達式表達式是C+程序中不可缺少的一部分。表達式是由運算符、操作數(變量、常量或函數等)和標點符號,按照一定規則組成的一個有意義的語句。例如:3.3.2
29、運算符C+中的運算符就是一種符號,該符號可以用于處理數據。平時有數學計算中所使用的“+”、“-”、“”、“”都屬于運算符。只是這些運算符在C+中的表現形式可能與日常生活中有所不同。下面將對C+中的運算符作具體介紹。1賦值運算符賦值運算符是用于為變量或常量指定數值的運算體符。其操作符號為“”,示例代碼如下:上述表達式的意義是,把b的值賦值給a。其中,b可以是一個單純的變量,也可以是一個表達式。3.3.2 運算符2算術運算符算術運算符是用于進行數學運算的運算符。例如,加、減、乘、除等就是算術運算符。操作完成后,返回一個數字型的值。算術運算符包括加法運算符(+)、減法運算符(-)、乘法運算符(*)、
30、除法運算符(/)、模運算符()。上述算術運算符都是二元運算符,該運算符兩端的數據必須是數字。3.3.2 運算符3邏輯運算符邏輯運算符,即用于處理邏輯值的運算符。邏輯運算符通常用在條件判斷語句或循環語句中,如if、while語句等。C+中的邏輯運算符包括邏輯與運算符(&)、邏輯或運算符(|)、邏輯非運算符(!)。由邏輯運算符構成的表達式,稱為邏輯表達式。邏輯表達式的返回值為邏輯值(true或false),一般情況下,1代表true,0代表false。邏輯與運算符可以進行與操作,其操作方法為:如果邏輯與運算符前的數為false(或是可以得出false的邏輯表達式),則返回false,否則返
31、回true;當邏輯與運算符前后兩個數都為true時,才返回true。邏輯或運算符可以進行或操作,其操作方法為:只要邏輯或運算符前后的數據中有一個為true(或是可以得出true的邏輯表達式),則返回true;當邏輯或運算符前后兩個數都為false時,才返回false。邏輯非運算符要求要操作的數據必須是邏輯值,或是能夠轉換成邏輯值的邏輯表達式。邏輯非運算符可以進行非操作,其操作方法為:如果要操作的數據為true,則返回false;如果要操作的數據為false,則返回true。3.3.2 運算符4關系運算符關系運算符,即用于比較兩個數據關系大小的運算符,并根據比較的結果返回一個邏輯值。關系運算符包
32、括大于運算符()、大于等于運算符(=)、小于運算符()、小于等于運算符(”一起使用。使用cin的語法代碼如下:例如,想要從鍵盤輸入一些數據,將使用下述代碼:如果想要一次性輸入多個數據,不是使用逗號作為分隔符,而應該用“”分隔,應該寫成:3.4.1 C+的輸入輸出2輸出語句C+的輸出語句用cout表示。其中,cout必須和“”一起使用,使用cout的語法代碼如下:例如,想要從鍵盤輸出一些數據,將使用下述代碼:如果想要一次性的輸出多個數據,同樣不是使用逗號作為分隔符,而是每項數據之間用“Close();/關閉記錄集m_pConnection-Close();/關閉連接第13章 多線程編程Windo
33、ws是一個多任務的操作系統。多線程運行可以提高系統的運行效率,因此使用比較廣泛。本章將對進程與線程進行簡單介紹。內容包括:進程與線程、線程的使用、線程的終止與通信等。通過本章的學習,讀者可以在程序中調用其他應用程序,可以實現進程間的通信,可以實現線程的同步。下面對多線程技術進行詳細介紹。 13.1 進程與線程進程(Process)是應用程序的執行實例。每個進行都可以訪問進程中的所有資源。一個進程是由一個或多個進行、代碼、數據和應用程序在內存中的其他資源組成。當一個應用程序啟動,相應的一個進程進行也會啟動,這個進行稱為父進程。一個應用程序還可以啟動其他進程,被啟動的其他進程稱為子進程。想要查看進
34、程,可以打開Windows的任務管理器。單擊【進程】標簽,在【進程】選擇卡中可以查看當前系統中的各個進程,如右圖所示。進程是資源的分配單位,每個進程都擁有自己的地址空間和上下文環境。13.1 進程與線程進程是線程的容器,線程是進程內部的一個執行單元。一個進程可以有一個或是多個線程,但這些線程僅生存于該進程中。也就是說,線程是在它所屬的進程地址空間里執行代碼,并在進程的地址空間對數據進行操作。線程用于描述進程中的運行路徑。當一個進程被啟動時,系統就要創建一個主線程。該主線程是應用程序需要的唯一線程,但進程也可以創建其他線程來完善進程的其他操作。13.2 線程的分類在MFC中,線程分為兩類:用戶界
35、面線程(User-Interface Thread)和工作者線程(Worker Thread)。用戶界面線程:該線程通常用來處理用戶的輸入并響應用戶生成的事件和消息。用戶界面線程是從CWinThread類派生而來的。在MFC中,CWinApp對象就是一個用戶界面線程。通常情況下,用戶界面線程都是主線程。當應用程序啟動時,用戶界面線程隨之啟動。當應用程序退出時,用戶界面線程也會隨之終止。工作者線程:該線程通常不需要用戶進行輸入,由后臺進行處理。因此,工作者線程又被稱為后臺線程。工作者線程和用戶界面線程的區別在于,工作者線程不用從CWinThread類派生。13.3 線程類(CWinThread)
36、在MFC上,CWinThread類封裝了對線程的操作。下面對CWinThtead類中的成員函數和成員變量作具體介紹。其中,CWinThread類中常用的函數如下:(1)調用CreateThread()函數可以創建一個新的線程,該函數的原型如下:dwCreateFlags:表示線程創建的標志。nStackSize:表示線程堆棧的大小。lpSecurityAttrs:表示線程的安全屬性。13.3 線程類(CWinThread)(2)調用SetThreadPriority()函數可以設置線程的優先級,該函數的原型如下:其中,nPriority參數定義了線程的優先級。其取值如下表所示。13.3 線程類
37、(CWinThread)(3)調用GetThreadPriority()函數可以獲取線程的優先級,該函數原型如下:(4)調用PostThreadMessage()函數可以向另一個CWinThread對象發送消息,該函數的原型如下:message:表示用戶定義消息的標識。wParam:表示消息的第一個參數。lParam:表示消息的第二個參數。13.3 線程類(CWinThread)(5)調用SuspendThread()函數可以將線程的掛起計數加1,當線程的掛起計數大于0時,該線程將暫停執行,稱之為掛起狀態。該函數的原型如下:(6)調用ResumeThread()函數可以將線程的掛起計數減1。當
38、線程的掛起計數減少到0時,恢復線程的執行。該函數的原型如下:13.3 線程類(CWinThread)在CWinThread類中,還需要重載一些函數來完成對線程的操作。(1)重載InitInstance()函數用于控制用戶界面線程實例的初始化工作,該函數的原型如下:(2)重載ExitInstance()函數用于控制清理操作,該函數的原型如下:(3)重載OnIdle()函數用于控制線程空閑處理操作,該函數的原型如下:lCount:表示計數器。此外,CWinThread類中有以下幾個重要的成員變量。m_hThread:表示當前線程的句柄。m_nThreadID:表示當前線程的ID。m_pMainWn
39、d:表示指向應用程序主窗口的指針。13.4 線程的使用在MFC中,創建一個新的線程時,可以使用全局函數AfxBeginThread()。AfxBeginThread()有兩種原型,分別用于創建用戶界面線程和工作者線程。13.4.1 啟用用戶界面線程當啟用用戶界面線程時,調用AfxBeginThread()的原型如下:pThreadClass:表示用戶界面線程對象運程時類結構指針。pParam:表示傳遞給控制函數的參數。nPriority:表示線程的優先級。nStackSize:表示線程堆棧的大小。dwCreateFlags:表示線程創建的標志。lpSecurityAttrs:表示安全屬性(SE
40、CURITY_ATTRIBUTES)結構指針。13.4.1 啟用用戶界面線程另外,啟用用戶界面線程還可以先創建一個CWinThread類的對象,然后調用CreateThread()函數。代碼如下:13.4.2 啟用工作者線程當啟用工作者線程時,調用AfxBeginThread()的原型如下:pfnThreadProc:表示工作者線程的控制函數指針。pParam:表示傳遞給控制函數的參數。nPriority:表示線程的優先級。nStackSize:表示線程堆棧的大小。dwCreateFlags:表示線程創建的標志。lpSecurityAttrs:表示安全屬性(SECURITY_ATTRIBUTE
41、S)結構指針。注意:函數的返回值是一個線程指針。一般情況下,需要保存該指針,以便于以后根據該指針來終止該線程。13.4.3 用戶界面線程在實際應用過程中,有時需要在線程中創建對話框。此時,可以使用用戶界面線程來實現。在MFC中,創建用戶界面線程的具體步驟如下:(1)從CWinThread類派生一個子類。(2)在子類的InitInstance()函數中設置線程的主窗口。(3)調用AfxBeginThread()函數創建用戶界面線程。13.4.3 用戶界面線程【示例13-1】創建用戶界面線程。在一個基于對話框的MFC應用程序中,創建一個用戶界面線程用來啟動另外一個對話框。(1)創建一個基于對話框的
42、MFC應用程序sample1301。(2)設計對話框資源,如下圖所示。13.4.3 用戶界面線程(3)單擊【Insert】|【Resource】命令,彈出【Insert Resource】(插入資源)對話框。選擇Dialog結點,如左圖所示。(4)設計新插入的對話框資源,如右圖所示。13.4.3 用戶界面線程(5)雙擊新添加的對話框資源,為其添加相應的類CSubDlg,如左圖所示。(6)單擊【Insert】|【New Class】命令,彈出【New Class】對話框。添加一個CWinThread類的子類CSubThread,如右圖所示。13.4.3 用戶界面線程(7)添加并修改CSubThr
43、ead類中的數據成員和成員函數。其中,SubThread.h文件中的代碼如下:SubThread.cpp文件中的代碼如下:13.4.3 用戶界面線程(8)在對話框類CSample1301Dlg的【創建用戶界面線程】按鈕中添加如下代碼:在【取消】按鈕中添加如下代碼:13.4.3 用戶界面線程(9)運行程序sample1301,彈出主對話框。單擊【創建用戶界面線程】按鈕,彈出【用戶界面線程】對話框。當運行程序sample1301的同時,可以打開系統的任務管理器進行查看。當主對話框彈出時,進程中多了一個sample1301.exe進程。當彈出【用戶界面線程】對話框時,沒有相應的進程出現。從上述內容中
44、可以看出,本例成功地創建了一個用戶界面線程。13.4.4 工作者線程創建工作者線程不需要使用CWinThread類的派生類,而是需要實現控制函數。在工作者線程的控制函數中,定義了線程的生命周期。當進入控制函數時,線程將被啟動。而當退出函數時,線程將被終止。【示例13-2】創建工作者線程。在一個基于對話框的MFC應用程序中,創建工作者線程,并在對話框進行初始化時啟用。(1)創建一個基于對話框的MFC應用程序sample1302。(2)設計對話框資源,如下圖所示。13.4.4 工作者線程(3)添加成員變量。為兩個ListBox控件添加成員變量,分別為m_list1和m_list2。其中,類別為Co
45、ntrol,類型為CListBox。(4)為CSample1302Dlg類添加兩個自定義函數,分別如下:(5)為控制函數添加代碼。其中,FirstThread()函數中添加的代碼如下:SecondThread()函數中添加的代碼如下:13.4.4 工作者線程(6)在對話框類CSample1302Dlg的OnInitDialog()函數中添加如下代碼:(7)修改Sample1302Dlg.h文件中的函數聲明,將線程函數聲明為static函數。 13.4.4 工作者線程(8)運行程序sample1302,結果如圖13.8所示。注意:如果不按照第(7)步驟對Sample1302Dlg.h文件進行修改
46、,會出現如下錯誤提示:AfxBeginThread : none of the 2 overloads can convert parameter 1 from type unsigned int (void *)。13.5 線程的終止當一個線程終止時,關閉該線程所屬的所有對象句柄,將該線程對象狀態變為有信息號狀態,并將該線程對象終止狀態STILL_ACTIVE改為退出碼。通常情況下,線程終止分為兩種:正常終止和異常終止。13.5.1 正常終止線程對于用戶界面線程而言,使其正常終止只需在用戶界面線程中調用PostQuitMessage()即可。該函數的原型如下:nExitCode:表示線程的退
47、出碼。對于工作者線程而言,當控制函數正常執行到函數的結束點(return語句)后,該線程也就正常終止了。另外,用戶也可以選擇使用AfxEndThread()函數來終止該線程。AfxEndThread()函數的原型如下:13.5.2 異常終止線程異常終止是指線程內部出現自身無法終止的情況,在其他線程中強行終止該線程。異常終止用于在緊急情況下安全退出控制。如果想要終止線程,可以使用TerminateThread()函數。該函數的原型如下:hThread:表示將要終止的線程句柄。該參數可以使用創建線程返回時返回的CWinThread從m_hThread成員變量中得到。dwExitCode:表示線程的
48、退出碼。13.5.3 線程的退出碼根據線程的退出碼,可以判斷線程的執行情況。使用GetExitCode()函數可以獲取工作者線程或用戶界面線程退出碼。該函數的原型如下:hThread:表示線程句柄。該參數可以使用創建線程返回時返回的CWinThread從m_hThread成員變量中得到。lpExitCode:表示接收返回的終止狀態的地址。13.5.3 線程的退出碼如果線程沒有被終止,則終止狀態返回STILL_ACTIVE。如果線程已經被終止,則返回的終止狀態可以是以下取值中的一個:在ExitThread()或TerminateThread()函數中指定的退出值。在線程函數的return語句中的
49、返回值。線程所屬進程中的退出值。13.5.3 線程的退出碼想要獲取線程的退出碼,還要做一些其他工作。一般線程終止后,線程對象將被刪除,用戶不能獲取m_hThread句柄。想要解決這個問題,可以采用以下兩個辦法。(1)在創建線程后,設置線程對象的m_bAutoDelete成員變量為FALSE。這樣,CWinThread對象在線程終止后仍將存在。在退出應用程序之前,還需要手動添加刪除CWinThread線程對象的代碼。(2)單獨選擇保存線程句柄。在創建線程后,使用Win32函數DuplicateHandle()將m_hThread復制到另一個句柄。這樣,盡管對象被自動刪除了,但使用復制的句仍然可以
50、獲取線程的退出碼。注意:采用第二種方法時,在復制句柄之前,線程不能終止。最安全的方法是在創建線程進使用CREATE_SUSPENDED掛起,復制好后,調用ResumeThread()函數恢復線程的執行。13.6 線程的通信通常情況下,在次線程是為主線程服務的,這就預示著主線程和次線程之間會進行及時的通信。下面對線程間的通信作簡單介紹。13.6.1 通信原理在線程間進行通信的過程中,需要用到以下幾個函數。其中,調用PostMessage()函數可以進行線程間的通信。該函數的原型如下:hWnd:表示消息發送的目的窗口句柄。Msg:表示將要發送的消息。wParam:表示消息的第1個參數。lParam
51、:表示消息的第2個參數。13.6.1 通信原理調用PostThreadMessage()函數可以向某個線程發送消息,該函數的原型如下:idThread:表示線程標識。Msg:表示將要發送的消息。wParam:表示消息的第1個參數。lParam:表示消息的第2個參數。13.6.1 通信原理如果想要對消息進行外理,用戶界面線程和工作者線程的處理方式不同。在用戶界面線程中,有兩種方式對消息進行處理。(1)使用消息映射宏ON_THREAD_MESSAGE。該宏的定義格式如下:message:表示消息標識ID。memberFxn:表示CWinThread消息處理函數的名稱。(2)使用PreTransla
52、teMessage()函數,直接對消息進行處理。該函數的原型如下:pMeg:表示包含消息的MSG結構指針。13.6.1 通信原理在工作者線程中,可以使用GetMessage()函數對消息進行處理。該函數的原型如下:lpMsg:表示消息MSG結構指針。hWnd:表示窗口句柄。wMsgFilterMin:表示第1個消息。wMsgFilterMax:表示最后一個消息。13.6.2 用戶界面線程通信下面通過一個實例來介紹用戶界面線程間的通信。【示例13-3】實現用戶界面線程間的通信。(1)創建一個基于對話框的MFC應用程序sample1303。(2)設計對話框資源,如下圖所示。(3)添加成員變量。其中
53、,從上到下,各文本框對應的成員變量分別為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】對話框。添加一個CWinThread類的子類CWinThread,如圖13.10所示。13.6.2 用戶界面線程通信(5)在CompareThread.h文件中添加如下代碼:在CompareThread.cpp文件中添加如下代碼:(6)在
54、CSample1303Dlg類中添加一條自定義消息,代碼如下:13.6.2 用戶界面線程通信(7)重載CCompareThread類的PreTranslateMessage()函數。右擊CCompareThread類,在彈出的彈出式菜單中選擇【Add Virtual Function】菜單項,彈出【New Virtual Override for Class CCompareThread】對話框。從左邊的列表框中雙擊【PreTranslateMessage】選項,將其移動到右邊的列表框中,如下圖所示。13.6.2 用戶界面線程通信(8)單擊【Add and Edit】按鈕,進入編輯區。在Pre
55、TranslateMessage()函數中添加代碼如下:13.6.2 用戶界面線程通信(9)為對話框類CSample1303Dlg添加一個成員變量,如下圖所示。該變量用于保存線程的標識。(10)在對話框類CSample1303Dlg的初始化函數中創建并啟動用戶界面線程,代碼如下:13.6.2 用戶界面線程通信(11)在【比較】按鈕的消息響應函數中添加如下代碼:(12)運行程序sample1303,結果如下圖所示。在運行程序時,單擊【比較】按鈕,并沒有直接對a、b的值進行比較,而是發送一條WM_CPMPARE的消息,交由CCompareThread類的PreTranslateMessage()函
56、數進行處理。13.7 線程的同步在編寫多線程應用程序時,經常會出現線程間同步訪問共享資源的情況。多個線程同時訪問同一個共享資源將可能發生無法預知的錯誤。例如,一個線程正在更新數據集,而同時另外一個線程正在讀取數據。那么,第二個線程只會讀取一部分正確的數據。為了解決這個問題,Visual C+6.0提供了同步類。同步類包括同步對象和同步訪問對象。其中,同步對象分為4種,分別是CSemaphore(信號量)、CCriticalSection(臨界區)、CMutex(互斥量)和CEvent(事件)。下面對這些同步類分別進行介紹。13.7.1 同步訪問對象同步訪問對象提供了對同步對象的封裝。同步訪問對
57、象分為兩種,分別是CSingleLock和CMultiLock。1CSingleLock如果一次只需要等待一個同步對象,可以使用CSingleLock類的對象。CSingleLock類的構造函數如下:pObject:表示同步對象指針。該參數不能為NULL。bInitialLock:表示是否在初始化時對同步對象進行訪問。如果想要獲取同步對象,可以使用Lock()函數。該函數的原型如下:dwTimeOut:表示同步對象等待的時間。13.7.1 同步訪問對象如果想要釋放同步對象,可以使用Unlock()函數。該函數的原型如下:lCount:表示要釋放的對象數。lPrevCount:表示同步對象接收的
58、前一次的個數。如果想要判斷等待的同步對象是否被鎖定,可以使用IsLocked()函數。該函數的原型如下:13.7.1 同步訪問對象2CMultiLock如果在某個特定的時刻要使用多個同步對象,可以使用CMultiLock類的對象。CMultiLock類的構造函數原型如下:ppObjects:表示同步對象數組指針。dwCount:表示同步對象數組元素的個數。bInitialLock:表示是否在初始化時對同步對象進行訪問。13.7.1 同步訪問對象如果想要獲取同步對象,可以使用Lock()函數。該函數的原型如下:dwTimeOut:表示同步對象等待的時間。bWaitForAll:表示是否等待所有的
59、同步對象。dwWakeMask:指定其他放棄等待的條件。13.7.1 同步訪問對象如果想要釋放同步對象,可以使用Unlock()函數。該函數的原型如下:lCount:表示要師范的對象數,該參數必須大于0。lPrevCount:表示同步對象接收的前一次的個數。如果想要判斷等待的同步對象是否被鎖定,可以使用IsLocked()函數。該函數的原型如下:13.7.2 使用信號量實現線程同步CSemaphore類對象代表一個“信號量”,可以允許一定數目的線程訪問某個共享資源。信號量對象中保存了當前同時訪問某個共享資源的線程計數。如果該計數值為0,則所有對這個CSemaphore類對象所控制資源的訪問將被
60、放到一個隊列中進行等待,直到超時或計數值不為0。13.7.2 使用信號量實現線程同步CSemaphore類的構造函數原型如下:lInitialCount:表示信號量對象初始化計數。該參數的值決定了在信號量對象建成后,能同時訪問其中資源的最大線程數目。該參數的取值在0IMaxCount之間。lMaxCount:表示信號量對象的最大計數。該參數必須大于0。pstrName:表示要創建的信號量對象的名稱。lpsaAttributes:表示信號量對象的安全屬性的指針。該參數一般設置為NULL。13.7.3 使用臨界區對象實現線程同步CCriticalSection類對象代表一個“臨界區”。當多個線程訪問一個獨占性共享資源時
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 45450-2025再生高溫合金原料術語和分類
- 投標擔保合同
- 2025鋁合金門窗制作合同
- 2025自動化控制系統配件采購合同
- 2025年關于學校食堂餐飲服務外包合同標準版樣本
- 2025年煙花爆竹門面租賃合同模板
- 2025年福建省農產品買賣合同范本
- 2025市場經理聘請合同范本
- 2025年智能設備購銷合同范本
- 2025年北京市存量房屋租賃合同自行成交版
- 人民醫院病房樓裝修改造工程施工組織設計方案
- 創傷性休克患者的護理
- 初中學業水平考試的“一核二融三層四維”命題理論探析
- 數字經濟學試題答案
- 專題13 統計與概率-【好題匯編】五年(2020-2024)高考數學真題分類匯編(含答案解析)
- 國家開放大學本科(非英語專業)學士學位英語統一考試樣題
- GB/T 44273-2024水力發電工程運行管理規范
- 城軌行車課程設計
- 2024年南京市中考歷史試題及答案
- 2024羽毛球教案36課時
- A類供應商績效評價表
評論
0/150
提交評論