




已閱讀5頁,還剩86頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第一章 VC+基礎(chǔ)知識Visual C+(以下簡稱VC)是一個(gè)強(qiáng)大的編程工具,它以C+為語言基礎(chǔ)。C+是由C語言發(fā)展而來,是面向?qū)ο蟪绦蛟O(shè)計(jì)語言之一,要用VC開發(fā)程序,要有堅(jiān)實(shí)的C+語言基礎(chǔ)。我們在學(xué)習(xí)VC+語言之前首先必須了解兩個(gè)基本概念1 了解C+語言的編程思想:即面向?qū)ο蟮乃枷耄嫦驅(qū)ο笕筇匦詳?shù)據(jù)封裝、繼承性、多態(tài)性。2 了解windows編程基礎(chǔ)。這是我們在學(xué)習(xí)VC+語言之前必須闖過的兩道基礎(chǔ)關(guān)。在這一章中,我們要了解面向?qū)ο缶幊痰幕舅枷?,Windows編程的基礎(chǔ)以及MFC的基礎(chǔ)知識。由于時(shí)間有限,我們只能將以后學(xué)習(xí)VC+時(shí)遇到的概念做一簡要介紹。第一節(jié) 面向?qū)ο蟪绦蛟O(shè)計(jì)的基本概念一、什么是面向?qū)ο竺嫦驅(qū)ο螅╫bject oriented,簡稱OO)是一種新的軟件設(shè)計(jì)思想。這種思想力求使在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,有經(jīng)常接觸類、對象等專業(yè)名詞;到底什么是類、什么是對象呢?在程序又是怎樣運(yùn)用呢?類是面向?qū)ο蟪绦蛟O(shè)計(jì)的核心,它實(shí)際是一種新的數(shù)據(jù)類型,也是實(shí)現(xiàn)抽象類型的工具,因?yàn)轭愂峭ㄟ^抽象數(shù)據(jù)類型的方法來實(shí)現(xiàn)的一種數(shù)據(jù)類型。類是對某一類對象的抽象;而對象是某一種類的實(shí)例,因此,類和對象是密切相關(guān)的。沒有脫離對象的類,也沒有不依賴于類的對象。二、封裝性封裝性是面向?qū)ο蟮幕A(chǔ)。面向?qū)ο笙到y(tǒng)的封裝性其實(shí)是一種信息隱藏技術(shù),它使系統(tǒng)設(shè)計(jì)人員能清楚地標(biāo)注出他們所提供的服務(wù)截面,用戶只看見對象提供的操作功能,看不到其中的數(shù)據(jù)和操作代碼細(xì)節(jié)。面向?qū)ο笙到y(tǒng)的封裝單位是對象,對對象的封裝是通過類的描述來實(shí)現(xiàn)的。1、什么是類 類是一種復(fù)雜的數(shù)據(jù)類型,它是將不同類型的數(shù)據(jù)和與這些數(shù)據(jù)相關(guān)的操作(函數(shù))封裝在一起的集合體。這有點(diǎn)像C語言中的結(jié)構(gòu),唯一不同的就是結(jié)構(gòu)沒有定義所說的“數(shù)據(jù)相關(guān)的操作”,“數(shù)據(jù)相關(guān)的操作”就是我們平常經(jīng)??吹降摹胺椒ā?,因此,類具有更高的抽象性,類中的數(shù)據(jù)具有隱藏性,類還具有封裝性。 類的結(jié)構(gòu)(也即類的組成)是用來確定一類對象的行為的,這些行為是通過一種操作接口來描述的(也即平時(shí)我們所看到的類的成員函數(shù)),使用者只關(guān)心的是接口的功能(也就是我們只關(guān)心類的各個(gè)成員函數(shù)的功能),對它是如何實(shí)現(xiàn)的并不感興趣。而操作接口又被稱為這類對象向其他對象所提供的服務(wù)。2、類的定義格式 類的定義格式一般地分為說明部分和實(shí)現(xiàn)部分。說明部分是用來說明該類中的成員,包含數(shù)據(jù)成員的說明和成員函數(shù)的說明。成員函數(shù)是用來對數(shù)據(jù)成員進(jìn)行操作的,又稱為“方法”。實(shí)現(xiàn)部分是用來對成員函數(shù)的定義。概括說來,說明部分將告訴使用者“干什么”,而實(shí)現(xiàn)部分是告訴使用者“怎么干”。類的一般定義格式如下:class public: private: ; 下面簡單地對上面的格式進(jìn)行說明:class是定義類的關(guān)鍵字,是種標(biāo)識符。一對花括號內(nèi)是類的說明部分(包括前面的類頭)說明該類的成員。類的成員包含數(shù)據(jù)成員和成員函數(shù)兩部分。訪問權(quán)限上來分,類的成員又分為:公有的(public)、私有的(private)和保護(hù)的(protected)三類。公有的成員用public來說明,公有部分往往是一些操作(即成員函數(shù)),它是提供給用戶的接口功能。這部分成員可以在程序中引用。私有的成員用private來說明,私有部分通常是一些數(shù)據(jù)成員,這些成員是用來描述該類中的對象的屬性的,用戶是無法訪問它們的,只有成員函數(shù)或經(jīng)特殊說明的函數(shù)才可以引用它們,它們是被用來隱藏的部分。保護(hù)類(protected)將在以后介紹。 關(guān)鍵字public,private和protected被稱為訪問權(quán)限修飾符或訪問控制修飾符。它們在類體內(nèi)(即一對花括號內(nèi))出現(xiàn)的先后順序無關(guān),并且允許多次出現(xiàn),用它們來說明類成員的訪問權(quán)限。 其中,是類定義中的實(shí)現(xiàn)部分,這部分包含所有在類體內(nèi)說明的函數(shù)的定義。如果一個(gè)成員函數(shù)的類體內(nèi)定義了,實(shí)現(xiàn)部分將不出現(xiàn)。如果所有的成員函數(shù)都在類體內(nèi)定義,則實(shí)現(xiàn)部分可以省略。下面給出一個(gè)日期類定義的例子:class CDatepublic:/公共部分以下兩個(gè)函數(shù)是該類提供給外界的接口void SetDate(int y, int m, int d);/ 該函數(shù)的功能為日期賦值int IsLeapYear();/判斷是否是閏年void Print();/打印日期private:/該類的成員變量是私有的只能在該類內(nèi)部調(diào)用int year, month, day;/類的實(shí)現(xiàn)部分,即函數(shù)體void CDate:SetDate(int y, int m, int d)year = y;month = m;day = d;int CDate:IsLeapYear()return(year%4=0 & year%100!=0) | (year%400=0);void CDate:Print();coutyear.month.dayendl;這里出現(xiàn)的作用域運(yùn)算符:是用來標(biāo)識某個(gè)成員函數(shù)是屬于哪個(gè)類的。3、對象和對象的定義我們已經(jīng)知道,對象是類的實(shí)例。對象是屬于某個(gè)已知的類。因此,定義對象之前,一定要先定義好該對象的類。下面簡單的介紹對象的定義。 (1)、對象的定義格式 對象在確定了它的類以后,其定義格式如下: 其中,是待定的對象所屬的類的名字,即所定義的對象是該類類型的對象。中可以有一個(gè)或多個(gè)對象名,多個(gè)對象名時(shí)用逗號分隔。中,可以是一般的對象名,還可以是指向?qū)ο蟮闹羔樏蛞妹?,也可以是對象?shù)組名。如: CDate date1, date2, *Pdate, date31;(2)、對象成員的表示方法 一個(gè)對象的成員就是該對象的類所定義的成員。對象成員有數(shù)據(jù)成員和成員函數(shù),其表示方式如下: . 或者 .() 前者用來表示數(shù)據(jù)成員的,后者用來表示成員函數(shù)的。如: date1.year, date1.month, date1.day; date1.SetDate( y, m, d); 這里,是一個(gè)運(yùn)算符,該運(yùn)算符的功能是表示對象的成員。指向?qū)ο蟮闹羔樀某蓡T表示如下: -如: Pdate-year, Pdate-month, Pdate-day; Pdate-SetDate( y, m, d); 由同一個(gè)類所創(chuàng)建的對象的數(shù)據(jù)結(jié)構(gòu)是相同的,類中的成員函數(shù)是共享的。兩個(gè)不同的對象的名字是不同的,它們的數(shù)據(jù)結(jié)構(gòu)的內(nèi)容(即數(shù)據(jù)成員的值)是不同的。因此,系統(tǒng)對已定義的對象僅給它們分配數(shù)據(jù)成員變量,而一般數(shù)據(jù)成員又都為私有成員,不同對象的數(shù)據(jù)成員的值可以是不相同的。(3)對象的初始化構(gòu)造函數(shù)和析構(gòu)函數(shù) 構(gòu)造函數(shù)和析構(gòu)函數(shù)是在類體中說明的兩種特殊的成員函數(shù)。構(gòu)造函數(shù)的功能是在創(chuàng)建對象時(shí),使用給定的值來將對象初化。析構(gòu)函數(shù)的功能是用來釋放一個(gè)對象的,在對象刪除前,用它來做一些清理工作,它與構(gòu)造函數(shù)的功能正好相反。下面舉一例子來說明構(gòu)造函數(shù)和析構(gòu)函數(shù)的特點(diǎn):class CDatepublic: CDate(int y, int m, int d);CDate(); CDate(); int IsLeapYear(); void Print();private: int year, month, day;/類的實(shí)現(xiàn)部分CDate:CDate(int y, int m, int d) year = y; month = m; day = d; cout構(gòu)造函數(shù)已被調(diào)用。n;CDate:CDate() cout析構(gòu)函數(shù)被調(diào)用。n;int CDate:IsLeapYear() return(year%4=0 & year%100!=0) | (year%400=0);void CDate:Print()coutyear.month.dayendl;1、構(gòu)造函數(shù)可以重載,即可以定義多個(gè)參數(shù)個(gè)數(shù)不同的函數(shù)。 2、程序中不能直接調(diào)用構(gòu)造函數(shù),在創(chuàng)建對象時(shí)系統(tǒng)自動(dòng)調(diào)用構(gòu)造函數(shù)。 析構(gòu)函數(shù)的特點(diǎn)如下: 1、析構(gòu)函數(shù)也是一個(gè)特殊的函數(shù),它的名字同類名,并在前面加“”字符,用來與構(gòu)造函數(shù)加以區(qū)別。析構(gòu)函數(shù)不指定數(shù)據(jù)類型,并且也沒有參數(shù)。 2、一個(gè)類中只可能定義一個(gè)析構(gòu)函數(shù)。 3、析構(gòu)函數(shù)可以被調(diào)用,也可以系統(tǒng)調(diào)用。在下面兩種情況下,析構(gòu)函數(shù)會被自動(dòng)調(diào)用。 如果一個(gè)對象被定義在一個(gè)函數(shù)體內(nèi),則當(dāng)這個(gè)函數(shù)結(jié)束時(shí),該對象的析構(gòu)函數(shù)被自動(dòng)調(diào)用。 當(dāng)一個(gè)對象是使用new運(yùn)算符被動(dòng)態(tài)創(chuàng)建的,在使用delete運(yùn)算符釋放它時(shí),delete將會自動(dòng)調(diào)用析構(gòu)函數(shù)。三、繼承性1為什么要使用繼承類支持層次機(jī)制,因此我們可以借用可重用性部件來很容易的從一個(gè)或多個(gè)已有類出發(fā),來生產(chǎn)各種更符合我們要求的新類。假設(shè)我們從類A出發(fā)來派生新的類B,那么我們稱類A為類B的基類(base class),類B為類A的派生類(derived class),類B繼承了類A中的各種行為和狀態(tài),并可添加自己的成員變量和成員函數(shù)。我們先來看一個(gè)例子,上圖給出了自然世界中的生物的一種繼承層次圖,最高層次的生物類代表了層次結(jié)構(gòu)中最一般的概念,較低層次的類表示由上一層的類(即其基類)所派生的特殊的概念。如上面的繼承關(guān)系,動(dòng)物類從其基類生物類中繼承生物類的所有屬性和行為,并且定義了動(dòng)物類所特有的屬性和行為,類似的,脊椎動(dòng)物類從動(dòng)物類那兒繼承了所有的屬性和行為,并且定義了自身特有的屬性和行為;,人類從靈長動(dòng)物類那兒繼承了所有的屬性和行為,并且定義了人類所特有的屬性和行為。之所以舉上面的例子是為了將程序空間和現(xiàn)實(shí)生活空間來進(jìn)行對比,結(jié)果說明一點(diǎn),類的繼承使得我們可以以一種自然的方式來模擬生活空間中的對象的層次結(jié)構(gòu),也就是說,我們可以以一種符合正常思維邏輯的自然的方式來思考和組織應(yīng)用程序的結(jié)構(gòu),然后,可以將這個(gè)結(jié)構(gòu)幾乎不作修改或者只需作少量的修改地用面向?qū)ο蟮木幊虂肀磉_(dá),從而大大的縮短了軟件系統(tǒng)的開發(fā)周期。下面我們舉一個(gè)現(xiàn)實(shí)編程中的例子,考慮MFC (Microsoft Foundation Class Library,Microsoft基礎(chǔ)類庫)中的CEdit類,它封裝了Windows中的編輯框控件,圖2.2顯示了CEdit類的繼承結(jié)構(gòu)。圖2.2 類CEdit在MFC中的繼承層次2怎樣繼承通過繼承機(jī)制,可以利用已有的數(shù)據(jù)類型來定義新的數(shù)據(jù)類型。所定義的新的數(shù)據(jù)類型不僅擁有新定義的成員,而且還同時(shí)擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。 在C+語言中,一個(gè)派生類可以從一個(gè)基類派生,也可以從多個(gè)基類派生。從一個(gè)基類派生的繼承稱為單繼承;從多個(gè)基類派生的繼承稱為多繼承。派生類的定義格式 單繼承的定義格式如下:class : ;class CEdit:CWnd 其中,是新定義的一個(gè)類的名字,它是從中派生的,并且按指定的派生的。常使用如下三種關(guān)鍵字給予表示: public 表示公有基類; private 表示私有基類; protected 表示保護(hù)基類;四、多態(tài)性多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計(jì)的重要特性之一。它與前面講過的封裝性和繼承性構(gòu)成了面向?qū)ο蟪绦蛟O(shè)計(jì)的三大特性。這三大特性是相互關(guān)聯(lián)的。封裝性是基礎(chǔ),繼承性是關(guān)鍵,多態(tài)性是補(bǔ)充,而多態(tài)性又必須存在于繼承的環(huán)境之中。 所謂多態(tài)性是指發(fā)出同樣的消息被不同類型的對象接收時(shí)導(dǎo)致完全不同的行為。這里所說的消息主要是指對類的成員函數(shù)的調(diào)用,而不同的行為是指不同的實(shí)現(xiàn)。利用多態(tài)性,用戶只需發(fā)送一般形式的消息,而將所有的實(shí)現(xiàn)留給接收消息的對象。對象根據(jù)所接收到的消息而做出相應(yīng)的動(dòng)作(即操作)。 函數(shù)重載和運(yùn)算符重載是簡單一類多態(tài)性。重要的多態(tài)性是建立在虛函數(shù)的概念和方法基礎(chǔ)上的。假定我們已經(jīng)定義了一個(gè)指向哺乳動(dòng)物類的實(shí)例對象的指針,如下所示:CMammal *pMammal然后我們定義了一個(gè)人類的實(shí)例對象和一個(gè)狒狒類的實(shí)例對象,如下所示:CHuman Human;CBaboon Baboon;然后,我們可以將指針pMammal指向Human對象,在C+語言中是可以這樣做的:pMammal=&Human;也可以將指針指向Human對象:pMammal=&Baboon;考查上面的兩種情況,我們假定在哺乳動(dòng)物類、人類和狒狒類中都定義了一個(gè)Eat (吃)方法,很顯然,當(dāng)我們使用下面的代碼來調(diào)用人類對象和狒狒類對象的Eat方法時(shí)不會遇到什么問題:Human.Eat();Baboon.Eat();但是,現(xiàn)在來考慮下面的代碼:pMammal-Eat();當(dāng)pMammal指向不同的對象時(shí),上面的代碼將發(fā)生什么樣的結(jié)果。很顯然,當(dāng)pMammal指向一個(gè)哺乳動(dòng)物類的實(shí)例對象時(shí),上面的代碼將調(diào)用哺乳動(dòng)物類的Eat方法。但是,當(dāng)pMammal指向一個(gè)人類的實(shí)例對象時(shí),上面的代碼是調(diào)用人類的Eat方法呢,還是仍然調(diào)用哺乳動(dòng)物類的Eat方法?我們期望的是前面一種情況,這就是類和對象的多態(tài)性。我們期望,當(dāng)pMammal指向不同的實(shí)例對象時(shí),編譯器將根據(jù)實(shí)例對象的類型調(diào)用正確的Eat方法。在C+中,類的多態(tài)性是通過虛函數(shù)來實(shí)現(xiàn)的。就上面的例子來說,我們將Eat方法定義為一個(gè)公有的虛函數(shù),這樣,當(dāng)pMammal指針指向一個(gè)人類的實(shí)例對象時(shí),編譯器調(diào)用的就是人類的Eat方法,當(dāng)pMammal指針指向一個(gè)狒狒類的實(shí)例對象時(shí),編譯器調(diào)用的就是狒狒類的實(shí)例對象,從而實(shí)現(xiàn)了運(yùn)行時(shí)的多態(tài)。在C+中,多態(tài)定義為不同函數(shù)的同一接口。封裝性、繼承性和多態(tài)性是面向?qū)ο缶幊痰娜筇卣鳎瑒t開始的時(shí)候,你也許對它們還沒有非常清晰的概念,但這沒有什么關(guān)系,當(dāng)你使用了一段時(shí)間的C+語言,然后再回過頭來看這些概念時(shí),你就會發(fā)現(xiàn)對它們有了更深入的認(rèn)識和了解。事實(shí)上,許多的C+程序正是在使用C+語言進(jìn)行編程已有相當(dāng)一段時(shí)間時(shí)才對這三個(gè)概念有了正確而清晰的認(rèn)識的。第二章 Visual c+概述第一節(jié) Win32應(yīng)用程序設(shè)計(jì)在過去,進(jìn)行Windows程序設(shè)計(jì)是一件痛苦異常的事情,原因是那時(shí)候還沒有現(xiàn)在的這些設(shè)計(jì)精美的應(yīng)用程序開發(fā)工具。在Microsoft的另一種易學(xué)易用的編程工具Visual Basic中,從某種角度說,Windows程序不是編出來的,而是由程序員畫出來的。但是要知道,一個(gè)出色的Windows的應(yīng)用程序并不僅在于在屏幕上繪出程序的各個(gè)窗口和在窗口中恰當(dāng)?shù)陌才琶恳粋€(gè)控件。對于具有一定基礎(chǔ)的程序員而言,更重要的內(nèi)容在于知道Windows和Windows應(yīng)用程序的運(yùn)行機(jī)制,以及它們之間以何種方式來進(jìn)行通信,然而,明確自己在編寫Windows時(shí)所需做的工作是哪一些。換句話說,我們需要透過Windows漂亮的圖形用戶界面,認(rèn)清在底層所發(fā)生的每一件事情。然而,這并非是一件容易的事。雖然,使用MFC和AppWizard,我們?nèi)钥赡苤恍枰卮饚讉€(gè)簡單的問題和添加少數(shù)的幾條代碼就能夠生成功能完整的Windows應(yīng)用程序。沒有一個(gè)成功的商業(yè)軟件是使用這樣的方式生成的。同時(shí),也只有深入的理解了MFC應(yīng)用程序框架的運(yùn)行機(jī)制,才可能用好和用活這一工具,才能達(dá)到熟悉掌握Visual C+的境界。盡管說MFC應(yīng)用程序框架提供的是面向?qū)ο蟮腤indows編程接口,這和傳統(tǒng)的使用C語言和SDK來進(jìn)行的Windows應(yīng)用程序設(shè)計(jì)有著很大的不同,但是從底層來說,其中的大部分功能仍是通過調(diào)用最基本的Win32 API來實(shí)現(xiàn)的。其中最重要的一點(diǎn)是,Windows應(yīng)用程序的運(yùn)行機(jī)制仍然沒有改變,它們?nèi)匀皇峭ㄟ^消息來和操作系統(tǒng),進(jìn)而和用戶進(jìn)行交互的事件驅(qū)動(dòng)的應(yīng)用程序。MFC對這一切進(jìn)行了比較徹底的封裝,它們隱藏在你所看不見的背面。即使你對這一切一無所知,你仍可以在Visual C+中使用MFC來進(jìn)行程序設(shè)計(jì)。但是,經(jīng)驗(yàn)表明,理解這一切的最好的方式是回過頭去,看一看這些內(nèi)容在SDK編寫的應(yīng)用程序是如何實(shí)現(xiàn)的,然后,再看一看在MFC中是如何把它們一層一層的與程序員隔離開的。我們在本節(jié)主要學(xué)習(xí)Windows應(yīng)用程序的消息處理機(jī)制。一、事件驅(qū)動(dòng)的應(yīng)用程序Windows應(yīng)用程序是事件驅(qū)動(dòng)(或稱作消息驅(qū)動(dòng))的應(yīng)用程序。Windows是一個(gè)多任務(wù)的操作系統(tǒng),也就是說,在同一時(shí)刻,在Windows中有著多個(gè)應(yīng)用程序的實(shí)例正在運(yùn)行,比如說這時(shí)我正在打開字處理軟件Word來編寫這本書的書稿,同時(shí),還打開了Visual C+的集成開發(fā)環(huán)境Microsoft Developer Studio來調(diào)試書中的示例程序,而且,后臺還在放著歌曲。在這樣的一個(gè)操作系統(tǒng)中,不可能像過去的DOS那樣,由一個(gè)應(yīng)用程序來享用所有的系統(tǒng)資源,這些資源是由Windows統(tǒng)一管理的。那么,特定的應(yīng)用程序如何獲得用戶輸入的信息呢?事實(shí)上,Windows時(shí)刻監(jiān)視著用戶的一舉一動(dòng),并分析用戶的動(dòng)作與哪一個(gè)應(yīng)用程序相關(guān),然后,將用戶的動(dòng)作以消息的形式發(fā)送給該應(yīng)用程序,應(yīng)用程序時(shí)刻等待著消息的到來,一但發(fā)現(xiàn)它的消息隊(duì)列中有未處理的消息,就獲取并分析該消息,最后,應(yīng)用程序根據(jù)消息所包含的內(nèi)容采取適當(dāng)?shù)膭?dòng)作來響應(yīng)用戶所作的操作。舉一個(gè)例子來說明上面的問題,假設(shè)我們編了一個(gè)程序,該程序有一個(gè)File菜單,那么,在運(yùn)行該應(yīng)用程序的時(shí)候,如果用戶單擊了File菜單,這個(gè)動(dòng)作將被Windows (而不是應(yīng)用程序本身!)所捕獲,Windows經(jīng)過分析得知這個(gè)動(dòng)作應(yīng)該由上面所說的那個(gè)應(yīng)用程序去處理,既然是這樣,Windows就發(fā)送了個(gè)叫做WM_COMMAND的消息給應(yīng)用程序,該消息所包含的信息告訴應(yīng)用程序:“用戶單擊了File菜單”,應(yīng)用程序得知這一消息之后,采取相應(yīng)的動(dòng)作來響應(yīng)它,這個(gè)過程稱為消息處理。Windows為每一個(gè)應(yīng)用程序(確切地說是每一個(gè)線程)維護(hù)了相應(yīng)的消息隊(duì)列,應(yīng)用程序的任務(wù)就是不停的從它的消息隊(duì)列中獲取消息,分析消息和處理消息,直到一條接到叫做WM_QUIT消息為止,這個(gè)過程通常是由一種叫做消息循環(huán)的程序結(jié)構(gòu)來實(shí)現(xiàn)的。Windows所能向應(yīng)用程序發(fā)送的消息多達(dá)數(shù)百種,但是,對于一般的應(yīng)用程序來說,只是其中的一部分有意義,舉一個(gè)例子,如果你的應(yīng)用程序只使用鼠標(biāo),那么如WM_KEYUP、WM_KEYDOWN和WM_CHAR等消息就沒有任何意義,也就是說,應(yīng)用程序中事實(shí)上不需要處理這些事件,對于這些事件,只需要交給Windows作默認(rèn)的處理即可。因此,在應(yīng)用程序中,我們需要處理的事件只是所有事件中的一小部分。因此,從某種角度上來看,Windows應(yīng)用程序是由一系列的消息處理代碼來實(shí)現(xiàn)的。這和傳統(tǒng)的過程式編程方法很不一樣,編程者只能夠預(yù)測用戶所利用應(yīng)用程序用戶界面對象所進(jìn)行的操作以及為這些操作編寫處理代碼,卻不可以這些操作在什么時(shí)候發(fā)生或者是以什么順序來發(fā)生,也就是說,我們不可能知道什么消息會在什么時(shí)候以什么順序來臨。圖3. 1 Windows應(yīng)用程序的基本流程什么是消息1、消息的組成:一個(gè)消息由一個(gè)消息名稱(UINT),和兩個(gè)參數(shù)(WPARAM,LPARAM)。當(dāng)用戶進(jìn)行了輸入或是窗口的狀態(tài)發(fā)生改變時(shí)系統(tǒng)都會發(fā)送消息到某一個(gè)窗口。例如當(dāng)菜單轉(zhuǎn)中之后會有WM_COMMAND消息發(fā)送,WPARAM的高字中(HIWORD(wParam))是命令的ID號,對菜單來講就是菜單ID。當(dāng)然用戶也可以定義自己的消息名稱,也可以利用自定義消息來發(fā)送通知和傳送數(shù)據(jù)。 2、誰將收到消息:一個(gè)消息必須由一個(gè)窗口接收。在窗口的過程(WNDPROC)中可以對消息進(jìn)行分析,對自己感興趣的消息進(jìn)行處理。例如你希望對菜單選擇進(jìn)行處理那么你可以定義對WM_COMMAND進(jìn)行處理的代碼,如果希望在窗口中進(jìn)行圖形輸出就必須對WM_PAINT進(jìn)行處理。 3、未處理的消息到那里去了:M$為窗口編寫了默認(rèn)的窗口過程,這個(gè)窗口過程將負(fù)責(zé)處理那些你不處理消息。正因?yàn)橛辛诉@個(gè)默認(rèn)窗口過程我們才可以利用Windows的窗口進(jìn)行開發(fā)而不必過多關(guān)注窗口各種消息的處理。例如窗口在被拖動(dòng)時(shí)會有很多消息發(fā)送,而我們都可以不予理睬讓系統(tǒng)自己去處理。 4、窗口句柄:說到消息就不能不說窗口句柄,系統(tǒng)通過窗口句柄來在整個(gè)系統(tǒng)中唯一標(biāo)識一個(gè)窗口,發(fā)送一個(gè)消息時(shí)必須指定一個(gè)窗口句柄表明該消息由那個(gè)窗口接收。而每個(gè)窗口都會有自己的窗口過程,所以用戶的輸入就會被正確的處理。例如有兩個(gè)窗口共用一個(gè)窗口過程代碼,你在窗口一上按下鼠標(biāo)時(shí)消息就會通過窗口一的句柄被發(fā)送到窗口一而不是窗口二。第二節(jié) Visual C+和MFC Visual C+的核心是Microsoft基礎(chǔ)類庫,即通常所說的MFC。盡管使用Visual C+進(jìn)行編程并不一定要使用MFC,使用MFC也不一定就要使用Visual C+,Borland C+的新版本也提供了對MFC的支持,然而事實(shí)上,在很多情況下,我們提到Visual C+時(shí)指的就是MFC,而提到MFC時(shí)指的也就是Visual C+。MFC相當(dāng)徹底的封裝了Win32軟件開發(fā)工具包(Software Development Kit,即通常所說的SDK)中的結(jié)構(gòu)、功能,它為編程者提供了一個(gè)應(yīng)用程序框架,這個(gè)應(yīng)用程序框架為編程者完成了很多Windows編程中的例行性工作,如管理窗口、菜單和對話框,執(zhí)行基本的輸入和輸出、使用集合類來保存數(shù)據(jù)對象等等,并且,MFC使得在程序中使用很多過去很專業(yè)、很復(fù)雜的編程課題,如ActiveX、OLE、本地?cái)?shù)據(jù)庫和開放式數(shù)據(jù)庫互聯(lián)ODBC和Internet應(yīng)用程序設(shè)計(jì)等,以及其它的應(yīng)用程序界面特性,如屬性頁(也叫標(biāo)簽對話框)、打印和打印預(yù)覽、浮動(dòng)的和可定制的工具條變得更加的容易。附表1 MFC類庫層次表第二節(jié) 框架、文檔和視21 文檔類一、 單文檔和多文檔結(jié)構(gòu)在一個(gè)程序中處理多個(gè)文檔,稱為多文檔結(jié)構(gòu)(MDI),例如word和excel,在一個(gè)程序中處理一個(gè)文檔,成為單文檔結(jié)構(gòu)(SDI)。如果你的程序適合文檔/視模式,你會發(fā)現(xiàn)使用文檔/視體系的SDI或MDI來創(chuàng)建應(yīng)用程序會大大簡化工作量。在文檔/視結(jié)構(gòu)中,文檔用于管理數(shù)據(jù)而視圖用于顯示數(shù)據(jù)并處理用戶的操作。所以數(shù)據(jù)的管理和顯示是分開的。二、 文檔類(CDocument)在文檔/視結(jié)構(gòu)中,文檔的任務(wù)通常是對數(shù)據(jù)進(jìn)行管理和維護(hù)。我們通常將數(shù)據(jù)保存在文檔類的成員變量中。視可以直接或間接的訪問文檔類中的這些成員變量,并通過這種方式來顯示和更新數(shù)據(jù)。文檔還負(fù)責(zé)將數(shù)據(jù)保存到永久存儲介質(zhì)中。常見的情況是將數(shù)據(jù)保存到磁盤文件或數(shù)據(jù)庫中。在Visual C+的與文檔/視結(jié)構(gòu)相關(guān)的文檔中,我們稱這個(gè)過程叫串行化(serialize)。MFC類庫為數(shù)據(jù)的串行化提供了默認(rèn)的支持,我們只需要在此基礎(chǔ)中稍加修改就可以為自定義的文檔類提供串行化支持。文檔類還可以處理命令消息,這里所謂的命令消息是指來自如菜單、工具欄按鈕和加速鍵的WM_COMMAND通知消息。與Windows消息和控件通知消息不同,命令消息可以被多種對象處理,這些對象除了窗口和視外,還可以是文檔、文檔模板或應(yīng)用程序本身。除了WM_COMMAND外,文檔不能處理其它的Windows消息。所有的文檔類都以CDocument類為其基類。CDocument類提供了文檔類所需要的最基本的功能實(shí)現(xiàn)。更重要的是,CDocument類為文檔對象以及文檔和其它對象(如視對象、應(yīng)用程序?qū)ο笠约翱蚣艽翱诘?交互的實(shí)現(xiàn)提供了一個(gè)框架。我們所做的工作基本上是在這個(gè)已有框架的基礎(chǔ)上,添加與特定應(yīng)用程序相關(guān)的實(shí)現(xiàn)。從CDocument類派生自己的文檔類所需的典型步驟為:1. 為每一個(gè)文檔類型從CDocument類(當(dāng)然也可以是其它CDocument類的派生類)派生一個(gè)相應(yīng)的文檔類。2. 為文檔類添加成員變量。這些成員變量用來保存文檔的數(shù)據(jù),其它對象(如與文檔相關(guān)聯(lián)的視)直接或間接的訪問這些成員變量來讀取或更新文檔的數(shù)據(jù)。3. 重載Serialize成員函數(shù),實(shí)現(xiàn)文檔數(shù)據(jù)的串行化。如果您的應(yīng)用程序只使用一種文檔類型,那么,在創(chuàng)建應(yīng)用程序工程時(shí),AppWizard已為我們完成了一部分工作。典型地,AppWizard為應(yīng)用程序框架生成一個(gè)CDocument類的派生類,在默認(rèn)情況下該類的命名依賴于工程的名稱。然后,AppWizard在該文檔類中重載了基類的幾個(gè)成員函數(shù),包括OnNewDocument和Serialize等。但是,AppWizard在這些重載函數(shù)中只是簡單地調(diào)用基類的相應(yīng)函數(shù),我們可以根據(jù)自己的需要來修改它們。下面我們來看一個(gè)簡單的例子。1. 首先創(chuàng)建一個(gè)MFC AppWizard (exe)工程,并取名為Example。如果需要了解如何使用AppWizard創(chuàng)建一個(gè)基于文檔/視結(jié)構(gòu)的多文檔界面應(yīng)用程序框架。2. 在Workspace窗口的ClassView選項(xiàng)卡中展開Example classes,可以看到AppWizard為Example程序生成的所有類。右擊CExampleDoc類,單擊Add Member Variable.,在Variable Type框中輸入成員變量的類型CString,在Variable Declaration框中輸入成員變量名m_str。由于我們希望其它類的對象可以訪問該成員變量,因此在Access框中選擇其訪問類型為Public。單擊 “OK”,Visual C+將該成員變量的定義添加類的定義中。再按照與上面的過程相同的方法,在類CExampleDoc中添加類型為LOGFONT的公有成員變量m_lf。在類CExampleDoc的定義中包括多個(gè)public塊。我們可以把這些定義都放到同一個(gè)public塊中,在定義中包括多個(gè)public塊只是為了區(qū)別開不同用途的公有成員。3. 為了測試該程序中,我們在CExampleDoc的OnNewDocument成員變量中為公有成員m_str賦以初值 “您好, 歡迎使用本程序!”,并彈出一個(gè)字體對話框讓用戶為該字符串選定字體。方法是使用下面的代碼替換OnNewDocument的實(shí)現(xiàn)代碼中的/ TODO注釋:m_str=您好, 歡迎使用本程序!;CFontDialog dlg;dlg.GetCurrentFont(&m_lf);/ 將用戶選定的字體信息填充到LOGFONT類型的結(jié)構(gòu)m_lf中,以供視類使用if(dlg.DoModal()=IDOK)dlg.GetCurrentFont(&m_lf);4.在MFC應(yīng)用程序中,文檔類是和視類一起協(xié)作以完成應(yīng)用程序功能的。下面我們將為Example程序的視類CExampleView類的OnDraw成員函數(shù)添加一些代碼,以將文檔類中的m_str成員變量的內(nèi)容顯示到視的框架窗口中。我們用下面的代碼來替換類CExampleView的OnDraw成員函數(shù)。/ 獲取當(dāng)前客戶區(qū)的大小CRect rectClient;GetClientRect(rectClient);CSize sizeClient=rectClient.Size();/ 從文件中讀取數(shù)據(jù)CExampleDoc* pDoc=(CExampleDoc*) GetDocument();CString str=pDoc-m_str;LOGFONT lf=pDoc-m_lf;/ 使字體充滿整個(gè)客戶區(qū)lf.lfHeight=sizeClient.cy;lf.lfWidth=long(sizeClient.cx/str.GetLength();/ 用當(dāng)前字體信息生成CFont對象CFont *pFont=new CFont;pFont-CreateFontIndirect(&lf);/ 改變當(dāng)前所用字體,并保存舊字體CFont *pOldFont=pDC-SelectObject(pFont);/ 用新選定的字體繪制字符串 您好, 歡迎使用本程序!CSize sizeTextExtent=pDC-GetTextExtent(str);pDC-TextOut(sizeClient.cx-sizeTextExtent.cx)/2,(sizeClient.cy-sizeTextExtent.cy)/2,str);/ 恢復(fù)系統(tǒng)默認(rèn)字體pDC-SelectObject(pOldFont);在上面的示例程序中,我們在文檔類中定義了兩個(gè)公有的成員變量m_str和m_lf,然后在視類的OnDraw成員函數(shù)中訪問了這兩個(gè)成員變量,通過這些變量從文檔中獲取所要顯示的字符串和所使用的字體。三、串行化數(shù)據(jù)在Visual C+術(shù)語中,我們把對象的保存到磁盤中或從磁盤中讀取對象稱作串行化。串行化的基本觀點(diǎn)是每一個(gè)對象都應(yīng)該能夠?qū)⒆陨淼漠?dāng)前數(shù)據(jù)保存到磁盤中,這些數(shù)據(jù)一般由其成員變量所提供;在需要的時(shí)候,對象還應(yīng)該能夠從磁盤中讀出所保存的數(shù)據(jù),并用這些數(shù)據(jù)來重建該對象。無論是保存文檔或是打開文檔,應(yīng)用程序都是通過調(diào)用文檔類的Serialize成員函數(shù)來完成串行化操作的。因此,在大多數(shù)情況下,我們都通過重載Serialize成員函數(shù)來實(shí)現(xiàn)文檔的串行化。 圖8.7 保存文件時(shí)的串行化過 圖8.8 打開文檔時(shí)的串行化過程Serialize成員函數(shù)帶有一個(gè)CArchive類型的參數(shù),這是一個(gè)與所打開的文件相關(guān)聯(lián)的對象。一般情況下,我們總是使CArchive對象來保存和打開文檔。例如我們把字體保存入文件中:void CExampleDoc:Serialize(CArchive& ar)if (ar.IsStoring()arm_str;arm_lf.lfHeightm_lf.lfWidthm_lf.lfEscapementm_lf.lfOrientationm_lf.lfWeightm_lf.lfItalicm_lf.lfUnderlinem_lf.lfStrikeOutm_lf.lfCharSetm_lf.lfOutPrecisionm_lf.lfClipPrecisionm_lf.lfQualitym_lf.lfPitchAndFamilym_str;CString lfFaceName;arm_lf.lfHeightm_lf.lfWidthm_lf.lfEscapementm_lf.lfOrientationm_lf.lfWeightm_lf.lfItalicm_lf.lfUnderlinem_lf.lfStrikeOutm_lf.lfCharSetm_lf.lfOutPrecisionm_lf.lfClipPrecisionm_lf.lfQualitym_lf.lfPitchAndFamilylfFaceName;strcpy(m_lf.lfFaceName,lfFaceName);42 視圖類在MFC中視類用于向用戶顯示文檔中的數(shù)據(jù)、以及接受用戶的輸入。MFC提供了很多視圖類,這些類都是基于Cview,這個(gè)類提供了使用視極其相關(guān)文檔時(shí)所必需的功能。一、CViewCView類在整個(gè)系統(tǒng)類體系中的位置。圖8.17 類CView的繼承示意圖類CWnd為類CView的直接基類。從這里,我們至少可以得到的一個(gè)最基本的概念就是,視類的對象具有窗口的一些基本特性。視類CView是一個(gè)用戶定義視類的常用基類。一個(gè)視類與一個(gè)文檔相連接,在文檔與用戶之間起了一個(gè)橋梁的作用。一個(gè)視類可以直接地接受文檔的數(shù)據(jù),也可以通過成員函數(shù)的調(diào)用來實(shí)現(xiàn)。在視中調(diào)用文檔可以通過GetDocument()函數(shù)實(shí)現(xiàn)。當(dāng)一個(gè)類的數(shù)據(jù)發(fā)生變化時(shí),該文檔所關(guān)聯(lián)的視類通常通過調(diào)用函數(shù)CDocument:UpdateAllViews來作出響應(yīng)。這個(gè)函數(shù)是維護(hù)數(shù)據(jù)正確顯示的常用手段。視類CView具有為數(shù)不多的成員函數(shù)。但這些成員函數(shù)中的很多個(gè)是有著重要的意義的。函數(shù)OnBeginPrinting初始化打印,OnEndPrinting結(jié)束一個(gè)打印任務(wù),而OnEndPrintPreview則更是關(guān)于打印預(yù)覽操作的一個(gè)重要函數(shù),而函數(shù)OnPreparePrinting則負(fù)責(zé)了對打印以及打印預(yù)覽的全面支持。另外,視類中的兩個(gè)成員函數(shù)OnDraw(該函數(shù)在屏幕發(fā)生變化或因?yàn)榻裹c(diǎn)的變易需要重繪時(shí)調(diào)用,沒有該函數(shù),就不可能在程序的切換后保證屏幕的正確顯示),OnUpdate則對維護(hù)程序的正確顯示負(fù)有重要的責(zé)任。(當(dāng)一個(gè)文檔發(fā)生變化時(shí),絕大多數(shù)情況下總是希望其各個(gè)視圖中的數(shù)據(jù)能得到同步的正確顯示的。)函數(shù)UpdateAllViews則是實(shí)現(xiàn)單文檔多視圖程序不可缺少的手段。(在一個(gè)文檔的任一視發(fā)生變化時(shí),通過該類實(shí)現(xiàn)各視圖的正確顯示。)二、CScrollView:該類為視增加了滾動(dòng)條。盡管我們?nèi)孕枰谝曋挟嬜约旱膱D形,該類仍可以做許多工作,如:管理窗口和原點(diǎn)、管理映射模式,以及收到滾動(dòng)條的消息時(shí)自動(dòng)滾動(dòng)。類CScrollView的繼承層次如圖圖8.22 類CScrollView的繼承圖解三、 CEditView類CEditView主要被設(shè)計(jì)來支持類似編輯控件所要實(shí)現(xiàn)的功能,通過打印,查找/替換的支持。它們擁有自己的內(nèi)存,可以在程序中被任意正確地使用。四、 CRichEditView五、 CtreeView圖8.20 類CTreeView的繼承圖解該類主要提供一些樹型控件所實(shí)現(xiàn)的功能的支持。六、 ClistView提供基于列表控件視。七、CFormView和CRecordView類:CFormView提供類似填空形式的視,CRecordView提供支持ODBC的視。例:為上例加上鍵盤處理,由鍵盤輸入的字符加入到屏幕上。因而對類CkeyView進(jìn)行自定義使它能處理擊鍵。鍵擊消息只有五個(gè)(發(fā)往具有當(dāng)前焦點(diǎn)的窗口),如下所示:WM_KEYDOWN 鍵已按下WM_SYSKEYDOWN 系統(tǒng)鍵被按下WM_KEYUP 鍵已釋放WM_SYSKEYUP 系統(tǒng)鍵已釋放WM_CHAR 轉(zhuǎn)換鍵MFC庫中的視窗函數(shù)OnKeyDown和OnKeyUp按下列方式處理WM_KEYDOWN和WM_KEYUP消息:void OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags);void OnKeyUp(UINT nChar,UINT nRepCnt,UINT nFlags);當(dāng)程序員表明要處理WM_KEYDOWN和M_KEYUP消息時(shí),Visual C+ 將生成這些函數(shù)的框架。處理鍵盤消息的一個(gè)更有效的途徑是處理消息WM_CHAR,即在類View中建立OnChar。void CKeyView:OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) / TODO: Add your message handler code here and/or call defaultCKeyDoc *pDoc=GetDocument();pDoc-data_string+=nChar;/ .CView:OnChar(nChar, nRepCnt, nFlags);CClientDC dc(this);dc.TextOut(0,0,pDoc-data_string,Pdoc-data_string.GetLength());/ .23 在視圖中繪圖一、CView的OnDraw函數(shù)如果在視圖中自己想繪圖,那么通常兩個(gè)地方中的一個(gè)需要編寫代碼。一個(gè)是視圖中ondraw函數(shù)是一個(gè)虛函數(shù),這個(gè)函數(shù)被主框架調(diào)用顯示文檔。第二個(gè)是截獲WM_PAINT消息,處理視圖的OnPaint函數(shù)。OnDraw(CDC* pDC)二、CDC類繪圖工作是基于設(shè)備環(huán)境(DC)中進(jìn)行的。DC包含將要被繪制的設(shè)備的信息,以及不同的對象,如畫筆、字體等,并提供了進(jìn)行繪圖的函數(shù)。DC(Device Context設(shè)備環(huán)境)對象是一個(gè)抽象的作圖環(huán)境,可能是對應(yīng)屏幕,也可能是對應(yīng)打印機(jī)或其它。這個(gè)環(huán)境是設(shè)備無關(guān)的,所以你在對不同的設(shè)備輸出時(shí)只需要使用不同的設(shè)備環(huán)境就行了,而作圖方式可以完全不變。這也就是Windows耀眼的一點(diǎn)設(shè)備無關(guān)性。如同你將對一幅畫使用照相機(jī)或復(fù)印機(jī)將會產(chǎn)生不同的輸出,而不需要對畫進(jìn)行任何調(diào)整。在MFC中,設(shè)備環(huán)境(DC)被封裝在CDC類中,CDC類中包含絕大多數(shù)GDI調(diào)用。實(shí)際上,CDC類有兩個(gè)設(shè)備環(huán)境,m_hDC(用于輸出)和m_hAttribDC(用于屬性查詢)。三、和GDI有關(guān)的各種對象在Windows中有各種GDI對象(不要和C+對象混淆),通過使用這幾中對象來影響繪圖效果,當(dāng)你在進(jìn)行繪圖就需要利用這些對象。而各種對象都擁有各種屬性,下面分別講述各種GUI對象和擁有的屬性。1 字體對象Cfont用于輸出文字時(shí)選用不同風(fēng)格和大小的字體??蛇x擇的風(fēng)格包括:是否為斜體,是否為粗體,字體名稱,是否有下劃線等。顏色和背景色不屬于字體的屬性。關(guān)于如何創(chuàng)建和使用字體使用字體時(shí)必須首先創(chuàng)建字體。設(shè)置字體的顏色和背景是通過調(diào)用CDC的函數(shù)來實(shí)現(xiàn)的。SetTextColor()SetBkColor()該類封裝一個(gè)Window的圖形設(shè)備接口(GDI)字體并且提供了操縱字體的成員函數(shù),要想使用CFont對象,首先要構(gòu)造一個(gè)CFont對象,然后使用成員函數(shù)CreateFont、CreateFontIndirect、CreatePointFont或CreatePointFontIndirect進(jìn)行初始化,把該對象與Windows字體相連,這樣用戶使可以使用該對象的成員函數(shù)來操縱字體。2 刷子CBrush對象決定填充區(qū)域時(shí)所采用的顏色或模板。對于一個(gè)固定色的刷子來講它的屬性為顏色,是否采用網(wǎng)格和網(wǎng)格的類型如水平的,垂直的,交叉的等。你也可以利用8*8的位圖來創(chuàng)建一個(gè)自定義模板的刷子,在使用這種刷子填充時(shí)系統(tǒng)會利用位圖逐步填充區(qū)域。第一個(gè)構(gòu)造函數(shù)構(gòu)造了一支未被初始化的畫刷,如果用戶使用了該構(gòu)造函數(shù),則必須對所得到的Brush對象進(jìn)行初始化。本小節(jié)后面將介紹幾種初始化的方法。其他重裁的構(gòu)造函數(shù)分別使用指定的顏色、陰影線模式和顏色或位圖指針來構(gòu)造一支以被初始化的畫刷。如果在調(diào)用過程中遇到錯(cuò)誤,則會產(chǎn)生一個(gè)異常。 下面是對這些構(gòu)造函數(shù)所用到的參數(shù)的詳細(xì)說明: 參數(shù)crColor:以RGB顏色指定畫刷的前景色。如果是表示陰影線的畫刷,定的是陰影線的顏色。 參數(shù)nIndex:指定了畫刷的陰影線的風(fēng)格,詳細(xì)介紹如表18所示。創(chuàng)建畫刷的函數(shù)BOOL CreateSolidBrush(COLORREF crColor);創(chuàng)建以指定顏色填充的實(shí)體畫刷BOOL CreateHatchBrush(int index,COLORREF crColor);創(chuàng)建一個(gè)陰影填充畫刷,index對應(yīng)上表的取值BOOL CreatePatternBrush(CBitmap* pBitmap);創(chuàng)建一個(gè)用指定位圖填充的畫刷BOOL CreateBrushIndirect(const LPBRUSH lpBrush);創(chuàng)建一個(gè)用指定結(jié)構(gòu)定義參數(shù)的畫刷3畫筆CPen對象在畫點(diǎn)和畫線時(shí)有用。它的屬性包括顏色,寬度,線的風(fēng)格,如虛線,實(shí)線,點(diǎn)劃線等。 第一個(gè)構(gòu)造函數(shù)不帶任何參數(shù),由于它所構(gòu)造的只是一個(gè)未初始化的CPen對象,對該對象進(jìn)行初始化的方法將在本節(jié)后面詳細(xì)介紹,另外,該構(gòu)造函數(shù)總是可以被成功調(diào)用的。不創(chuàng)建筆。需要用其他函數(shù)創(chuàng)建筆。 第二個(gè)構(gòu)造函數(shù)帶有3個(gè)參數(shù),分別對畫筆的線形、線寬和顏色進(jìn)行了初始化。下面分別對其常用的參數(shù)進(jìn)行介紹: 參數(shù)nPenSty1e:指定畫筆的風(fēng)格(樣式),也就是畫筆的線形。該參數(shù)該構(gòu)造函數(shù)中可以為如表15所列值。 參數(shù)nWidth:該參數(shù)指定畫筆的寬度。對于該構(gòu)造函數(shù),無論什么映射模式,設(shè)備單位的寬度總是1個(gè)像素。 參數(shù)rColor:包含了一個(gè)畫筆所具有的RGB顏色。第三個(gè)構(gòu)造函數(shù)帶有5個(gè)參數(shù),下面分別加以介紹: 前3個(gè)參數(shù)功能同上,nPenstyle除了具有上一個(gè)構(gòu)造函數(shù)中所介紹的參數(shù)值外,表16所列的參數(shù)值。參數(shù)nWidth;含義基本與上一構(gòu)造函數(shù)的同一參數(shù)含義相同,區(qū)別在于如果參數(shù)nPenStyle的值為PS_GEOMETRIC,那么該參數(shù)值是針對邏輯單位而言的,并且該參
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030城市配送產(chǎn)業(yè)規(guī)劃專項(xiàng)研究報(bào)告
- 2025-2030商品肉雞行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報(bào)告
- 2025屆四川省樹德中學(xué)高考考前模擬英語試題含解析
- 福建省莆田市仙游第一中學(xué)2025屆高考英語四模試卷含解析
- 2025-2030養(yǎng)老院行業(yè)市場深度發(fā)展趨勢與前景展望戰(zhàn)略研究報(bào)告
- 2025-2030全球及中國疏浚服務(wù)行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報(bào)告
- 2025-2030中央廚房行業(yè)市場深度調(diào)研及趨勢前景與投融資研究報(bào)告
- 2025-2030中國高爾夫裝備和消耗品行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報(bào)告
- 江蘇省連云港市錦屏高級中學(xué)2025屆高考臨考沖刺英語試卷含解析
- 云南省宣威市二中2025年高考英語三模試卷含答案
- (二模)濟(jì)寧市2025年4月高考模擬考試地理試卷
- 首都醫(yī)科大學(xué)附屬北京安貞醫(yī)院招聘考試真題2024
- 抽化糞池合同協(xié)議
- 中醫(yī)養(yǎng)生館運(yùn)營方案中醫(yī)養(yǎng)生館策劃書
- (二模)寧波市2024-2025學(xué)年第二學(xué)期高考模擬考試 英語試卷(含答案)+聽力音頻+聽力原文
- 食品安全自查、從業(yè)人員健康管理、進(jìn)貨查驗(yàn)記錄、食品安全事故處置等保證食品安全的規(guī)章制度
- 物理實(shí)驗(yàn)通知單記錄單初二上
- 關(guān)于完善和落實(shí)罪犯互監(jiān)制度的思考
- GB∕T 40501-2021 輕型汽車操縱穩(wěn)定性試驗(yàn)通用條件
- 認(rèn)識浮力+阿基米德原理
- 防止電力生產(chǎn)重大事故地二十五項(xiàng)反措
評論
0/150
提交評論