本書(shū)介紹了在Microsoft Windows 98、Microsoft Windows NT 4.0和Windows NT 5.0下程序?qū)懽鞯姆椒?。這些程序用C語(yǔ)言編寫(xiě)并使用原始的Windows Application Programming Interface(API)。如在本章稍后所討論的,這不是寫(xiě)作Windows程序的唯一方法。然而,無(wú)論最終您使用什么方式寫(xiě)作程序,了解Windows API都是非常重要的。
正如您可能知道的,Windows 98已成為使用Intel 32位微處理器(例如486和Pentium)的IBM兼容型個(gè)人計(jì)算機(jī)環(huán)境上最新的圖形操作系統(tǒng)之代表。Windows NT是IBM PC兼容機(jī)種以及一些RISC(精簡(jiǎn)指令集計(jì)算機(jī))工作站上使用的Windows工業(yè)增強(qiáng)型版本。
使用本書(shū)有三個(gè)先決條件。首先,您應(yīng)該從使用者的角度熟悉Windows 98。不要期望可以在不了解Windows使用者接口的情形下開(kāi)發(fā)其應(yīng)用程序。因此,我建議您在開(kāi)發(fā)程序(或在進(jìn)行其它工作)時(shí)使用執(zhí)行Windows的機(jī)器來(lái)跑Windows應(yīng)用程序。
第二,您應(yīng)了解C語(yǔ)言。如果要寫(xiě)Windows程序,一開(kāi)始卻不想了解C語(yǔ)言,那不是一個(gè)好主意。我建議您在文字控制臺(tái)環(huán)境中,例如在Windows 98 MS-DOS命令提示窗口下提供的環(huán)境中學(xué)習(xí)C語(yǔ)言。Windows程序設(shè)計(jì)有時(shí)包括一些非文字模式程序設(shè)計(jì)的C語(yǔ)言部分;在這些情況下,我將針對(duì)這些問(wèn)題提供討論。但大多數(shù)情況下,您應(yīng)非常熟悉該語(yǔ)言,特別是C語(yǔ)言的結(jié)構(gòu)和指針。了解標(biāo)準(zhǔn)C語(yǔ)言執(zhí)行期鏈接庫(kù)的一些相關(guān)知識(shí)是有幫助的,但不是必要的。
第三,您應(yīng)該在機(jī)器上安裝一個(gè)適于進(jìn)行Windows程序設(shè)計(jì)的32位C語(yǔ)言編譯器和開(kāi)發(fā)環(huán)境。在本書(shū)中,假定您正在使用Microsoft Visual C++ 6.0,該軟件包可獨(dú)立購(gòu)買,也可作為Visual Studio 6.0軟件包的一部分購(gòu)買。
到此為止,我將不再假設(shè)您具有任何圖形使用者接口(如Windows)的程序?qū)懽鹘?jīng)驗(yàn)。
Windows幾乎不需要介紹。然而人們很容易忘記Windows給辦公室和家庭桌上型計(jì)算機(jī)所帶來(lái)的重大改變。Windows在其早期曾經(jīng)走過(guò)一段坎坷的道路,征服桌上型計(jì)算機(jī)市場(chǎng)的前途一度相當(dāng)渺茫。
Windows簡(jiǎn)史
在1981年秋天IBM PC推出之后不久,MS-DOS就已經(jīng)很明顯成為PC上的主流操作系統(tǒng)。MS-DOS代表Microsoft Disk Operating System(磁盤(pán)操作系統(tǒng))。MS-DOS是一個(gè)小型的操作系統(tǒng)。MS-DOS提供給用戶一種命令列接口,提供如DIR和TYPE的命令,也可以將應(yīng)用程序加載內(nèi)存執(zhí)行。對(duì)于應(yīng)用程序?qū)懽髡?,它提供了一組函數(shù)呼叫,進(jìn)行文件的輸入輸出(I/O )。對(duì)于其它的外圍處理-尤其是將文字或圖形寫(xiě)到顯示器上-應(yīng)用程序可以直接存取PC的硬件。
由于內(nèi)存和硬件的限制,成熟的圖形環(huán)境緩慢地才到來(lái)。當(dāng)蘋(píng)果計(jì)算機(jī)公司不幸的Lisa計(jì)算機(jī)在1983年1月發(fā)表時(shí),它提供了不同于文字模式環(huán)境的另一種選擇,并在1984年1月成為Macintosh上圖形環(huán)境的一種標(biāo)準(zhǔn)。盡管Macintosh的市場(chǎng)占有率在下降,但是它仍然被認(rèn)為是衡量所有其它圖形環(huán)境的標(biāo)準(zhǔn)。包括Macintosh和Windows的所有圖形環(huán)境,其實(shí)都要?dú)w功于Xerox Palo Alto Research Center(PARC)在70年代中期所作的開(kāi)拓性研究工作。
Windows是由微軟在1983年11月(在Lisa之后,Macintosh之前)宣布,并在兩年后(1985年11月)發(fā)行。在此后的兩年中,緊隨著Microsoft Windows早期版本1.0之后,又推出了幾種改進(jìn)版本,以支持國(guó)際商業(yè)市場(chǎng),并提供新型視訊顯示器和打印機(jī)的驅(qū)動(dòng)程序。
Windows版本2.0是在1987年11月正式在市場(chǎng)上推出的。該版本對(duì)使用者接口做了一些改進(jìn)。這些改進(jìn)中最有效的是使用了可重迭式窗口,而Windows 1.0中使用的是并排式窗口。Windows 2.0還增強(qiáng)了鍵盤(pán)和鼠標(biāo)接口,特別是加入了菜單和對(duì)話框。
至此,Windows還只要求Intel 8086或者8088等級(jí)的微處理器,以「實(shí)際模式」執(zhí)行,只能存取地址在1MB以下的內(nèi)存。Windows/386(在Windows 2.0之后不久發(fā)行的)使用Intel 386微處理器的「虛擬8086」模式,實(shí)現(xiàn)將直接存取硬件的多個(gè)MS-DOS程序窗口化和多任務(wù)化。為了統(tǒng)一起見(jiàn),Windows版本2.1被更名為Windows/286。
Windows 3.0是在1990年5月22日發(fā)表的。它將Windows/286和Windows/386結(jié)合到同一種產(chǎn)品中。Windows 3.0有了一個(gè)很大的改變,這就是對(duì)Intel的286、386和486微處理器保護(hù)模式的支持。這能使Windows和Windows應(yīng)用程序能存取高達(dá)16MB的內(nèi)存。Windows用于執(zhí)行程序和維護(hù)文件的「外殼」程序得到了全面的改進(jìn)。Windows 3.0是第一個(gè)在家用和辦公室市場(chǎng)上取得立足點(diǎn)的版本。
任何Windows的歷史介紹都必須包括一些OS/2的說(shuō)明,OS/2是對(duì)DOS和Windows的另一種選擇,最初是由Microsoft和IBM合作開(kāi)發(fā)的。OS/2版本1.0(只有文字模式)在Intel 286(或者后來(lái)的)微處理器上運(yùn)行,在1987年末發(fā)布。在1988年10月的OS/2版本1.1中出現(xiàn)了管理圖形使用者接口的PM(Presentation Manager)。PM最初的設(shè)計(jì)構(gòu)想是成為Windows的一種保護(hù)模式版本,但是圖形API改變程度太大,致使軟件生產(chǎn)廠商很難提供對(duì)這兩種平臺(tái)的支持。
到1990年9月,IBM和Microsoft之間的沖突達(dá)到了高峰,導(dǎo)致這兩個(gè)公司最后分道揚(yáng)鑣。IBM接管了OS/2,而Microsoft明確表示W(wǎng)indows將是他們操作系統(tǒng)策略的中心。雖然OS/2仍然擁有一些狂熱的崇拜者,但是它遠(yuǎn)不及Windows這樣的普及程度。
Microsoft Windows版本3.1是1992年4月發(fā)布的,其中包括的幾個(gè)重要特性是TrueType字體技術(shù)(給Windows帶來(lái)可縮放的輪廓字體)、多媒體(聲音和音樂(lè))、對(duì)象連結(jié)和嵌入(OLE:Object Linking and Embedding)和通用對(duì)話框。跟OS/2一樣,Windows 3.1只能在保護(hù)模式下運(yùn)作,并且要求至少配置了1MB內(nèi)存的286或386處理器。
在1993年7月發(fā)表的Windows NT是第一個(gè)支持Intel 386、486和Pentium微處理器32位保護(hù)模式的Windows版本。Windows NT提供32位平坦尋址,并使用32位的指令集。(本章后面我會(huì)談到一些尋址空間的問(wèn)題)。Windows NT還可以移植到非Intel處理器上,并在幾種使用RISC芯片的工作站上執(zhí)行。
Windows 95是在1995年8月發(fā)布的。和Windows NT一樣,Windows 95也支持Intel 386或更高等級(jí)處理器的32位保護(hù)模式。雖然它缺少Windows NT中的某些功能,諸如高安全性和對(duì)RISC機(jī)器的可移植性等,但是Windows 95具有需要較少硬件資源的優(yōu)點(diǎn)。
Windows 98在1998年6月發(fā)布,具有許多加強(qiáng)功能,包括執(zhí)行效能的提高、更好的硬件支持以及與因特網(wǎng)和全球信息網(wǎng)(WWW)更緊密的結(jié)合。
Windows方面
Windows 98和Windows NT都是支持32位優(yōu)先權(quán)式多任務(wù)(preemptive multitasking)及多線程的圖形操作系統(tǒng)。Windows擁有圖形使用者接口(GUI ),這種使用者界面也稱作「可視化接口」或「圖形窗口環(huán)境」。有關(guān)GUI的概念可追溯至70年代中期,在Alto和Star等機(jī)器上以及SmallTalk等環(huán)境中由Xerox PARC所作的研究工作。該項(xiàng)研究的成果后來(lái)被Apple Computer和Microsoft引入主流并流行起來(lái)。雖然有一些爭(zhēng)議,但現(xiàn)在已非常清楚,GUI是(Microsoft的Charles Simonyi的說(shuō)法)一個(gè)在個(gè)人計(jì)算機(jī)工業(yè)史上集各方面技術(shù)大成于一體的最重要產(chǎn)物。
所有GUI都在點(diǎn)矩陣對(duì)應(yīng)的視訊顯示器上處理圖形。圖形提供了使用屏幕的最佳方式、傳遞信息的可視化豐富多彩環(huán)境,以及能夠WYSIWYG(what you see is what you get:所見(jiàn)即所得)的圖形視訊顯示和為書(shū)面文件準(zhǔn)備好格式化文字輸出內(nèi)容。
在早期,視訊顯示器僅用于響應(yīng)使用者通過(guò)鍵盤(pán)輸入的文字。在圖形使用者接口中,視訊顯示器自身成為使用者輸入的一個(gè)來(lái)源。視訊顯示器以圖標(biāo)和輸入設(shè)備(例如按鈕和滾動(dòng)條)的形式顯示多種圖形對(duì)象。使用者可以使用鍵盤(pán)(或者更直接地使用鼠標(biāo)等指向設(shè)備)直接在屏幕上操縱這些對(duì)象,拖動(dòng)圖形對(duì)象、按下鼠標(biāo)按鈕以及滾動(dòng)滾動(dòng)條。
因此,使用者與程序的交流變得更為親密。這不再是一種從鍵盤(pán)到程序,再到視訊顯示器的單向信息流動(dòng),使用者已經(jīng)能夠與顯示器上的對(duì)象直接交互作用了。
使用者不再需要花費(fèi)長(zhǎng)時(shí)間學(xué)習(xí)如何使用計(jì)算機(jī)或掌握新程序了。Windows讓這一切成真,因?yàn)樗袘?yīng)用程序都有相同的基本外觀和感覺(jué)。程序占據(jù)一個(gè)窗口-屏幕上的一塊矩形區(qū)域。每個(gè)窗口由一個(gè)標(biāo)題列標(biāo)識(shí)。大多數(shù)程序功能由程序的菜單開(kāi)始。用戶可使用滾動(dòng)條觀察那些無(wú)法在一個(gè)屏幕中裝下的信息。某些菜單項(xiàng)目觸發(fā)對(duì)話框,用戶可在其中輸入額外的信息。幾乎在每個(gè)大的Windows程序中都有一個(gè)用于開(kāi)啟文件的特殊對(duì)話框。該對(duì)話框在所有這些Windows程序中看起來(lái)都一樣(或接近相同),而且?guī)缀蹩偸菑耐徊藛芜x項(xiàng)中啟動(dòng)。
一旦您了解使用一個(gè)Windows程序的方法,您就非常容易學(xué)習(xí)其它的Windows程序。菜單和對(duì)話框允許用戶試驗(yàn)一個(gè)新程序并探究它的功能。大多數(shù)Windows程序同時(shí)具有鍵盤(pán)接口和鼠標(biāo)接口。雖然Windows程序的大多數(shù)功能可通過(guò)鍵盤(pán)控制,但使用鼠標(biāo)要容易得多。
從程序?qū)懽髡叩慕嵌瓤?,一致的使用者接口?lái)自于Windows建構(gòu)菜單和對(duì)話框的內(nèi)置程序。所有菜單都有同樣的鍵盤(pán)和鼠標(biāo)接口,因?yàn)檫@項(xiàng)工作是由Windows處理,而不是由應(yīng)用程序處理。
為便于多個(gè)程序的使用,以及這些程序間信息的交換,Windows支持多任務(wù)。在同一時(shí)刻能有多個(gè)Windows程序顯示并運(yùn)行。每個(gè)程序在屏幕上占據(jù)一個(gè)窗口。用戶可在屏幕上移動(dòng)窗口,改變它們的大小,在不同程序間切換,并從一個(gè)程序向另一個(gè)程序傳送數(shù)據(jù)。因?yàn)檫@些窗口看起來(lái)有些像桌面上的紙(當(dāng)然,這是計(jì)算機(jī)還未占據(jù)辦公桌之前的年代),Windows有時(shí)被稱作:一個(gè)顯示多個(gè)程序的「具象化桌面」。
Windows的早期版本使用一種「非優(yōu)先權(quán)式(non-preemptive)」的多任務(wù)系統(tǒng)。這意味著Windows不使用系統(tǒng)定時(shí)器將處理時(shí)間分配給系統(tǒng)中運(yùn)行的多個(gè)應(yīng)用程序,程序必須自愿放棄控制以便其它程序運(yùn)行。在Windows NT和Windows 98中,多任務(wù)是優(yōu)先權(quán)式的,而且程序自身可分割成近乎同時(shí)執(zhí)行的多個(gè)執(zhí)行緒。
操作系統(tǒng)不對(duì)內(nèi)存進(jìn)行管理便無(wú)法實(shí)現(xiàn)多任務(wù)。當(dāng)新程序啟動(dòng)、舊程序終止時(shí),內(nèi)存會(huì)出現(xiàn)碎裂空間。系統(tǒng)必須能夠?qū)㈤e置的內(nèi)存空間組織在一起,因此系統(tǒng)必須能夠移動(dòng)內(nèi)存中的程序代碼和數(shù)據(jù)塊。
即使是在8088微處理器上跑的Windows 1.0也能進(jìn)行這類內(nèi)存管理。在實(shí)際模式限制下,這種能力被認(rèn)為是軟件工程一個(gè)令人驚訝的成就。在Windows 1.0中,PC硬件結(jié)構(gòu)的640KB內(nèi)存限制,在不要求任何額外內(nèi)存的情況下被有效地?cái)U(kuò)展了。但Microsoft并未就此停步:Windows 2.0允許Windows應(yīng)用程序存取擴(kuò)充內(nèi)存(EMS);Windows 3.0在保護(hù)模式下,允許Windows應(yīng)用程序存取高達(dá)16MB的擴(kuò)展內(nèi)存。Windows NT和Windows 98通過(guò)成熟的32位操作系統(tǒng)及平坦尋址空間,擺脫了這些舊的限制。
Windows上執(zhí)行的程序可共享在稱為「動(dòng)態(tài)鏈接庫(kù)」的文件中的例程。Windows包括一個(gè)機(jī)制,能夠在執(zhí)行時(shí)連結(jié)使用動(dòng)態(tài)鏈接庫(kù)中例程的程序。Windows自身基本上就是一個(gè)動(dòng)態(tài)鏈接庫(kù)的集合。
Windows是一個(gè)圖形接口,Windows程序能夠在視訊顯示器和打印機(jī)上充分利用圖形和格式化文字。圖形接口不僅在外觀上更有吸引力,而且還能夠讓使用者傳遞高層次的信息。
Windows應(yīng)用程序不能直接存取屏幕和打印機(jī)等圖形顯示設(shè)備硬件。相反,Windows提供一種圖形程序語(yǔ)言(稱作圖形設(shè)備接口,或者GDI),使顯示圖形和格式化文字更容易。Windows虛擬化了顯示硬件,使為Windows編寫(xiě)的程序可使用任何具有Windows設(shè)備驅(qū)動(dòng)程序的視頻卡或打印機(jī),而程序無(wú)需確定系統(tǒng)相連的設(shè)備類型。
對(duì)Windows開(kāi)發(fā)者來(lái)說(shuō),將與設(shè)備無(wú)關(guān)的圖形接口輸出到IBM PC上不是件輕松的事。PC的設(shè)計(jì)是基于開(kāi)放式架構(gòu)的原則,鼓勵(lì)第三方硬件制造商為PC開(kāi)發(fā)接口設(shè)備,而且開(kāi)發(fā)了大量這樣的設(shè)備。雖然出現(xiàn)了多種標(biāo)準(zhǔn),PC上的傳統(tǒng)MS-DOS程序仍不得不各自支持許多不同的硬設(shè)備。這對(duì)MS-DOS字處理軟件來(lái)說(shuō)非常普遍,它們連同1到2張有許多小文件的磁盤(pán)一同銷售,每個(gè)文件支持一種特定的打印機(jī)。Windows程序不要求每個(gè)應(yīng)用程序都自行開(kāi)發(fā)這些驅(qū)動(dòng)程序,因?yàn)檫@種支持是Windows的一部分。
動(dòng)態(tài)鏈接
Windows運(yùn)作機(jī)制的核心是一個(gè)稱作「動(dòng)態(tài)鏈接」的概念。Windows提供了應(yīng)用程序豐富的可呼叫函數(shù),大多數(shù)用于實(shí)作其使用者接口和在視訊顯示器上顯示文字和圖形。這些函數(shù)采用動(dòng)態(tài)鏈接庫(kù)(Dynamic Linking Library,DLL)的方式撰寫(xiě)。這些動(dòng)態(tài)鏈接庫(kù)是些具有.DLL或者有時(shí)是.EXE擴(kuò)展名的文件,在Windows 98中通常位于\WINDOWS\SYSTEM子目錄中,在Windows NT中通常位于\WINNT\SYSTEM和\WINNT\SYSTEM32子目錄中。
在早期,Windows的主要部分僅通過(guò)三個(gè)動(dòng)態(tài)鏈接庫(kù)實(shí)作。這代表了Windows的三個(gè)主要子系統(tǒng),它們被稱作Kernel、User和GDI。當(dāng)子系統(tǒng)的數(shù)目在Windows最近版本中增多時(shí),大多數(shù)典型的Windows程序產(chǎn)生的函數(shù)呼叫仍對(duì)應(yīng)到這三個(gè)模塊之一。Kernel(日前由16位的KRNL386.EXE和32位的KERNEL32.DLL實(shí)現(xiàn))處理所有在傳統(tǒng)上由操作系統(tǒng)核心處理的事務(wù)-內(nèi)存管理、文件I/O和多任務(wù)管理。User(由16位的USER.EXE和32位的USER32.DLL實(shí)作)指使用者接口,實(shí)作所有窗口運(yùn)作機(jī)制。GDI(由16位的GDI.EXE和32位的GDI32.DLL實(shí)作)是一個(gè)圖形設(shè)備接口,允許程序在屏幕和打印機(jī)上顯示文字和圖形。
Windows 98支持應(yīng)用程序可使用的上千種函數(shù)呼叫。每個(gè)函數(shù)都有一個(gè)描述名稱,例如CreateWindow。該函數(shù)(如您所猜想的)為程序建立新窗口。所有應(yīng)用程序可以使用的Windows函數(shù)都在表頭文件里預(yù)先聲明過(guò)。
在Windows程序中,使用Windows函數(shù)的方式通常與使用如strlen等C語(yǔ)言鏈接庫(kù)函數(shù)的方式相同。主要的區(qū)別在于C語(yǔ)言鏈接庫(kù)函數(shù)的機(jī)械碼連結(jié)到您的程序代碼中,而Windows函數(shù)的程序代碼在您程序執(zhí)行文件外的DLL中。
當(dāng)您執(zhí)行Windows程序時(shí),它通過(guò)一個(gè)稱作「動(dòng)態(tài)鏈接」的過(guò)程與Windows相接。一個(gè)Windows的.EXE文件中有使用到的不同動(dòng)態(tài)鏈接庫(kù)的參考數(shù)據(jù),所使用的函數(shù)即在那些動(dòng)態(tài)鏈接庫(kù)中。當(dāng)Windows程序被加載到內(nèi)存中時(shí),程序中的呼叫被指向DLL函數(shù)的入口。如果該DLL不在內(nèi)存中,就把它加載到內(nèi)存中。
當(dāng)您連結(jié)Windows程序以產(chǎn)生一個(gè)可執(zhí)行文件時(shí),您必須連結(jié)程序開(kāi)發(fā)環(huán)境提供的特定「引用鏈接庫(kù)(import library)」。這些引用鏈接庫(kù)包含了動(dòng)態(tài)鏈接庫(kù)名稱和所有Windows函數(shù)呼叫的引用信息。連結(jié)程序使用該信息在.EXE文件中建立一個(gè)表格,在加載程序時(shí),Windows使用它將呼叫轉(zhuǎn)換為Windows函數(shù)。
為說(shuō)明Windows程序設(shè)計(jì)的多種技術(shù),本書(shū)提供了許多范例程序。這些程序使用C語(yǔ)言撰寫(xiě)并原原本本的使用Windows API來(lái)開(kāi)發(fā)程序。我將這種方法稱作「古典」Windows程序設(shè)計(jì)。這是我們?cè)?985年為Windows 1.0寫(xiě)程序的方法,它今天仍是寫(xiě)作Windows程序的有效方法。
API和內(nèi)存模式
對(duì)于程序?qū)懽髡邅?lái)說(shuō),操作系統(tǒng)是由本身的API定義的。API包含了所有應(yīng)用程序能夠使用的操作系統(tǒng)函數(shù)呼叫,同時(shí)包含了相關(guān)的數(shù)據(jù)型態(tài)和結(jié)構(gòu)。在Windows中,API還意味著一個(gè)特殊的程序架構(gòu),我們將在每章的開(kāi)頭進(jìn)行研究。
一般而言,Windows API自Windows 1.0以來(lái)一直保持一致,沒(méi)什么重大改變。具有Windows 98程序?qū)懽鹘?jīng)驗(yàn)的Windows程序?qū)懽髡邥?huì)對(duì)Windows 1.0程序的原始碼感覺(jué)非常熟悉。API改變的一種方式是進(jìn)行增強(qiáng)。Windows 1.0支持不到450個(gè)函數(shù)呼叫,現(xiàn)在已有了上千種函數(shù)呼叫。
Windows API和它的語(yǔ)法的最大變化來(lái)自于從16位架構(gòu)向32位架構(gòu)轉(zhuǎn)化的過(guò)程中。Windows從版本1.0到版本3.1使用16位Intel 8086、8088、和286微處理器上所謂的分段內(nèi)存模式,由于兼容性的原因,從386開(kāi)始的32位Intel微處理器也支持該模式。在這種模式下,微處理器緩存器的大小為16位,因此C的int數(shù)據(jù)型態(tài)也是16位寬。在分段內(nèi)存模式下,內(nèi)存地址由兩個(gè)部分組成-一個(gè)16位段(segment)指針和一個(gè)16位偏移量(offset)指標(biāo)。從程序?qū)懽髡叩慕嵌瓤矗@非常凌亂并帶來(lái)了long或far指針(包括段地址和偏移量地址)和short或near指標(biāo)(包括帶有假定段地址的偏移量地址)的區(qū)別。
從Windows NT和Windows 95開(kāi)始,Windows支持使用Intel 386、486和Pentium處理器32位模式下的32位平坦尋址內(nèi)存模式。C語(yǔ)言的int數(shù)據(jù)型態(tài)也擴(kuò)展為32位的值。為32位版本W(wǎng)indows編寫(xiě)的程序使用簡(jiǎn)單的平坦線性空間尋址的32位指針值。
用于16位版本W(wǎng)indows的API(Windows 1.0到Windows 3.1)現(xiàn)在稱作Win16。用于32位版本W(wǎng)indows的API(Windows 95、Windows 98和所有版本的Windows NT)現(xiàn)在稱作Win32。許多函數(shù)呼叫在從Win16到Win32的轉(zhuǎn)變中保持相同,但有些需要增強(qiáng)。例如,圖像坐標(biāo)點(diǎn)由Win16中的16位值變?yōu)閃in32中的32位值。此外,某些Win16函數(shù)呼叫返回一個(gè)包含在32位整數(shù)值中的二維坐標(biāo)點(diǎn)。這在Win32中不可能,因此增加的新函數(shù)呼叫以不同方式運(yùn)作。
所有32位版本的Windows都支持Win16 API(以確保和舊有應(yīng)用程序兼容)和Win32 API(以運(yùn)行新應(yīng)用程序)。非常有趣的是,Windows NT與Windows 95及Windows 98的工作方式不同。在Windows NT中,Win16函數(shù)呼叫通過(guò)一個(gè)轉(zhuǎn)換層被轉(zhuǎn)化為Win32函數(shù)呼叫,然后被操作系統(tǒng)處理。在Windows 95和Windows 98中,該操作正相反:Win32函數(shù)呼叫通過(guò)轉(zhuǎn)換層轉(zhuǎn)換為Win16函數(shù)呼叫,再由操作系統(tǒng)處理。
在同一時(shí)刻有兩個(gè)不同的Windows API集(至少名稱不同)。Win32s (「s」代表「subset(子集)」)是一個(gè)API,允許程序?qū)懽髡呔帉?xiě)在Windows 3.1上執(zhí)行的32位應(yīng)用程序。該API僅支持已被Win16支持的32位函數(shù)版本。此外,Windows 95 API一度被稱作Win32c(「c」代表「compatibility(兼容性)」),但該術(shù)語(yǔ)已被拋棄了。
現(xiàn)在,Windows NT和Windows 98都被認(rèn)為能夠支持Win32 API。然而,每個(gè)操作系統(tǒng)依然都支持某些不被別的操作系統(tǒng)支持的某些功能特性。因?yàn)樗鼈兊南嗤幨窍喈?dāng)可觀的,所以有可能編寫(xiě)在兩個(gè)操作系統(tǒng)下都可執(zhí)行的程序。而且,人們普遍認(rèn)為這兩個(gè)產(chǎn)品最終會(huì)合而為一。
語(yǔ)言選項(xiàng)
使用C語(yǔ)言和原始的API不是編寫(xiě)Windows 98程序的唯一方法。然而,這種方法卻提供給您最佳的性能、最強(qiáng)大的功能和在發(fā)掘Windows特性方面最大的靈活性。可執(zhí)行文件相對(duì)較小且運(yùn)行時(shí)不要求外部鏈接庫(kù)(自然,Windows DLL自身除外)。最重要的是,不管您最終以什么方式開(kāi)發(fā)Windows應(yīng)用程序,熟悉API會(huì)使您對(duì)Windows內(nèi)部有更深入的了解。
雖然我認(rèn)為學(xué)習(xí)古典的Windows程序設(shè)計(jì)對(duì)任何Windows程序?qū)懽髡叨际侵匾?,我沒(méi)有必要建議使用C和API編寫(xiě)每個(gè)Windows應(yīng)用程序。許多程序?qū)懽髡撸貏e是那些為公司內(nèi)部開(kāi)發(fā)程序或在家編寫(xiě)娛樂(lè)程序的程序?qū)懽髡呦矚g輕松的開(kāi)發(fā)環(huán)境,例如Microsoft Visual Basic或者Borland Delphi(它結(jié)合了對(duì)象導(dǎo)向的Pascal版本)。這些環(huán)境使程序?qū)懽髡邔⒕杏趹?yīng)用程序的使用者接口和相關(guān)使用者接口對(duì)象的程序代碼上。要學(xué)習(xí)Visual Basic,您也許需要參考Microsoft Press的一些其它圖書(shū),例如Michael Halvorson1996年著的《Learn Visual Basic Now》。
在專業(yè)程序?qū)懽髡咧校貏e是那些開(kāi)發(fā)商業(yè)應(yīng)用程序的程序?qū)懽髡撸璏icrosoft Visual C++和Microsoft Foundation Class Library(MFC)是近年來(lái)流行的選擇。MFC在一組C++對(duì)象類別中封裝了許多Windows程序設(shè)計(jì)中的瑣碎細(xì)節(jié)。Jeff Prosise的《Programming Windows with MFC,第二版》(Microsoft Press,1999年)提供了MFC程序的寫(xiě)作指南。
最近,Internet和World Wide Web的流行大力推廣著Sun Microsystems的Java,這是一個(gè)受C++啟發(fā)卻與微處理器無(wú)關(guān)的程序設(shè)計(jì)語(yǔ)言,而且結(jié)合了可在幾個(gè)操作系統(tǒng)平臺(tái)上執(zhí)行的圖形應(yīng)用程序開(kāi)發(fā)工具組。Microsoft Press有一本關(guān)于Microsoft J++(Microsoft的Java)開(kāi)發(fā)工具的好書(shū),《Programming Visual J++ 6.0》(1998年),由Stephen R. Davis著。
顯然,很難說(shuō)哪種方法更有利于開(kāi)發(fā)Windows應(yīng)用程序。更主要的是,也許是應(yīng)用程序自身的特性決定了所使用的工具。不管您最后實(shí)際上使用什么工具寫(xiě)作程序,學(xué)習(xí)Windows API將使您更深入地了解Windows工作的方式。Windows是一個(gè)復(fù)雜的系統(tǒng),在API上增加一個(gè)程序?qū)懽鲗硬⑽礈p少它的復(fù)雜性,僅僅是掩蓋了它,早晚您會(huì)碰到它。了解API會(huì)給您更好的補(bǔ)救機(jī)會(huì)。
在原始的Windows API之上的任何軟件層都必定將您限制在全部功能的一個(gè)子集內(nèi)。您也許發(fā)現(xiàn),例如,使用Visual Basic編寫(xiě)應(yīng)用程序非常理想,然而它不允許您做一個(gè)或兩個(gè)很簡(jiǎn)單的基本工作。在這種情況下,您將不得不使用原始的API呼叫。API定義了作為Windows程序?qū)懽髡咚璧囊磺小](méi)有什么方法比直接使用API更萬(wàn)能的了。
MFC尤其問(wèn)題百出。雖然它大幅簡(jiǎn)化了某些工作(例如OLE),我卻經(jīng)常發(fā)現(xiàn)要讓它們按我所想的去工作時(shí),會(huì)在其它特性(例如Document/View架構(gòu))上碰壁。MFC還不是Windows程序設(shè)計(jì)者所追求的靈丹妙藥,很少有人認(rèn)為它是一個(gè)好的對(duì)象導(dǎo)向設(shè)計(jì)的模型。MFC程序?qū)懽髡邚乃麄兪褂玫膶?duì)象類別定義如何工作中受益頗深,并會(huì)發(fā)現(xiàn)他們經(jīng)常參考MFC原始碼,搞懂這些原始碼是學(xué)習(xí)Windows API的好處之一。
程序開(kāi)發(fā)環(huán)境
在本書(shū)中,假定您正使用Microsoft Visual C++ 6.0,標(biāo)準(zhǔn)版、專業(yè)版和企業(yè)版都可以。經(jīng)濟(jì)的標(biāo)準(zhǔn)版足以應(yīng)付本書(shū)中的程序設(shè)計(jì)需求。Visual C++ 還是Visual Studio 6.0中的一部分。
Microsoft Visual C++ 軟件包中包括C編譯器和其它編譯及連結(jié)Windows程序所需的文件和工具等。它還包括Visual C++ Developer Studio,一個(gè)可編輯原始碼、以交談方式建立資源(如圖標(biāo)和對(duì)話框)以及編輯、編譯、執(zhí)行和測(cè)試程序的環(huán)境。
如果您正使用Visual C++ 5.0,則需要為Windows 98和Windows NT 5.0更新表頭文件和引用鏈接庫(kù),這些東西可從Microsoft的網(wǎng)站上得到。在 http://www.microsoft.com/msdn/,選擇「Downloads」,然后選擇「 Platform SDK」(軟件開(kāi)發(fā)套件),您就能在選擇的目錄中下載和安裝更新文件。要讓Microsoft Developer Studio瀏覽這些目錄,可以從「Tool」菜單項(xiàng)選擇「 Options」然后按下「Directories」標(biāo)簽。
Microsoft網(wǎng)站上的msdn部分代表「Microsoft Developer Network(Microsoft軟件開(kāi)發(fā)者網(wǎng)絡(luò))」。這是一個(gè)向程序?qū)懽髡咛峁┝私?jīng)常更新的CD-ROM的計(jì)劃,這些CD-ROM中包含了程序?qū)懽髡咴赪indows開(kāi)發(fā)中所需的最新東西。您也可以訂閱MSDN,這樣就避免經(jīng)常得從Microsoft的網(wǎng)站下載文件。
API文件
本書(shū)不是Windows API權(quán)威的正式文件的替代品。那組文件不再以印刷形式出版,它僅能從CD-ROM或Internet上取得。
當(dāng)您安裝Visual C++ 6.0時(shí),您將得到一個(gè)包括API文件的在線求助系統(tǒng)。您可通過(guò)訂閱MSDN或使用Microsoft網(wǎng)站上的在線求助系統(tǒng)更新該文件。連接到 http://www.microsoft.com/msdn/,并選擇「MSDN Library Online」。
在Visual C++ 6.0中,從「Help」菜單項(xiàng)選擇「Contents」項(xiàng)目開(kāi)啟MSDN窗口。API文件按樹(shù)形結(jié)構(gòu)組織,尋找標(biāo)有「 Platform SDK」的部分,所有在本書(shū)中引用的文件都來(lái)自于該部分。我將向您介紹如何從「 Platform SDK」開(kāi)始尋找以斜線分層分門(mén)別類的文件的位置。(我知道「Platform SDK」是整個(gè)MSDN知識(shí)庫(kù)中較為晦澀的部分,但我敢保證那是Windows程序設(shè)計(jì)的基本核心。)例如,對(duì)于如何在Windows程序中使用鼠標(biāo)的文件,您可參考/ Platform SDK / User Interface Services / User Input / Mouse Input。
我在前面提到Windows大致分為Kernel、User和GDI子系統(tǒng)。kernel接口在/ Platform SDK / Windows Base Services中,User界面函數(shù)在 / Platform SDK / User Interface Services中,GDI位于 / Platform SDK / Graphics and Multimedia Services / GDI中。
現(xiàn)在是開(kāi)始寫(xiě)些程序的時(shí)候了。為了便于對(duì)比,讓我們以一個(gè)非常短的Windows程序和一個(gè)簡(jiǎn)短的文字模式程序開(kāi)始。這會(huì)幫助我們找到使用開(kāi)發(fā)環(huán)境并感受建立和編譯程序機(jī)制的正確方向。
文字模式(Character-Mode)模型
程序?qū)懽髡邆兿矏?ài)的一本書(shū)是《The C Programming Language》(Prentice Hall,1978年和1988年),由Brian W. Kernighan和Dennis M. Ritchie(親切地稱為K&R)編著。該書(shū)的第一章以一個(gè)顯示「hello, world」的C語(yǔ)言程序開(kāi)始。
這里是在《The C Programming Language》第一版第6頁(yè)中出現(xiàn)的程序:
main (){ printf ("hello, world\n") ;}
以前C程序?qū)懽髡咴谑褂胮rintf等C執(zhí)行期鏈接庫(kù)函數(shù)時(shí),無(wú)需先聲明它們。但這是90年代,我們?cè)敢饨o編譯器一個(gè)在我們的程序中標(biāo)出錯(cuò)誤的機(jī)會(huì)。這里是在K&R第二版中修正的程序:
#includemain (){ printf ("hello, world\n") ;}
該程序仍然是那么短。但它可通過(guò)編譯并執(zhí)行得很好,但當(dāng)今許多程序?qū)懽髡吒敢馇宄卣f(shuō)明main函數(shù)的返回值,在這種情況下ANSI C規(guī)定該函數(shù)必須返回一個(gè)值:
#includeint main (){ printf ("hello, world\n") ; return 0 ;}
我們還可以包括main的參數(shù),把程序弄得更長(zhǎng)一些,但讓我們暫且這樣就好了-包括一個(gè)include聲明、程序的進(jìn)入點(diǎn)、一個(gè)對(duì)執(zhí)行期鏈接庫(kù)函數(shù)的呼叫和一個(gè)return語(yǔ)句。
同樣效果的Windows程序
Windows關(guān)于「hello, world」程序的等價(jià)程序有和文字模式版本完全相同的組件。它有一個(gè)include聲明、一個(gè)程序進(jìn)入點(diǎn)、一個(gè)函數(shù)呼叫和一個(gè)return語(yǔ)句。下面便是該程序:
/*------------------------------------------------------------------HelloMsg.c -- Displays "Hello, Windows 98!" in a message box (c) Charles Petzold, 1998--------------------------------------------------------------------*/#includeint WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){MessageBox (NULL, TEXT ("Hello, Windows 98!"), TEXT ("HelloMsg"), 0);return 0 ;}
在剖析該程序之前,讓我們看一下在Visual C++ Developer Studio中建立新程序的方式。
首先,從File菜單中選New。在 New對(duì)話框中,單擊Projects頁(yè)面標(biāo)簽,選擇 Win32 Application。在Location欄中,選擇一個(gè)子目錄,在 Project Name欄中,輸入該項(xiàng)目的名稱,此時(shí)該名稱是HelloMsg,這便是在 Location欄中顯示的目錄的子目錄。Create New Workspace復(fù)選框應(yīng)該勾起來(lái),Platforms部分應(yīng)該顯示 Win32,選擇OK。
將會(huì)出現(xiàn)一個(gè)標(biāo)題為Win32 Application - Step 1 Of 1的對(duì)話框,指出要建立一個(gè)Empty Project,并按下Finish按鈕。
從File菜單中再次選擇New。在 New對(duì)話框中,選擇Files頁(yè)面標(biāo)簽,選擇 C++ Source File。Add To Project復(fù)選框應(yīng)被選中,并應(yīng)顯示HelloMsg。在 File Name欄中輸入HelloMsg.c,選中OK。
現(xiàn)在您可輸入上面所示的HELLOMSG.C文件,您也可以選擇Insert菜單和 File As Text選項(xiàng)從本書(shū)附帶的CD-ROM上復(fù)制HELLOMSG.C的內(nèi)容。
從結(jié)構(gòu)上說(shuō),HELLOMSG.C與K&R的「hello,world」程序是相同的。表頭文件STDIO.H已被WINDOWS.H所代替,進(jìn)入點(diǎn)main被WinMain所代替,而且C語(yǔ)言執(zhí)行時(shí)期鏈接庫(kù)函數(shù)printf被Windows API函數(shù)MessageBox所代替。然而,在程序中有許多新東西,包括幾個(gè)陌生的大寫(xiě)標(biāo)識(shí)符。
讓我們從頭開(kāi)始。
表頭文件
HELLOMSG.C以一個(gè)前置處理器指示命令開(kāi)始,實(shí)際上在每個(gè)用C編寫(xiě)的Windows程序的開(kāi)頭都可看到:
#include
WINDOWS.H是主要的含入文件,它包含了其它Windows表頭文件,這些表頭文件的某些也包含了其它表頭文件。這些表頭文件中最重要的和最基本的是:
這些表頭文件定義了Windows的所有數(shù)據(jù)型態(tài)、函數(shù)呼叫、數(shù)據(jù)結(jié)構(gòu)和常數(shù)標(biāo)識(shí)符,它們是Windows文件中的一個(gè)重要部分。使用Visual C++ Developer Studio的Edit菜單中的Find in Files搜索這些表頭文件非常方便。您還可以在Developer Studio中打開(kāi)這些表頭文件并直接閱讀它們。
程序進(jìn)入點(diǎn)
正如在C程序中的進(jìn)入點(diǎn)是函數(shù)main一樣,Windows程序的進(jìn)入點(diǎn)是WinMain,總是像這樣出現(xiàn):
int WINAPI WinMain ( HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine,int iCmdShow)
該進(jìn)入點(diǎn)在/ Platform SDK / User Interface Services / Windowing / Windows / Window Reference / Window Functions中有說(shuō)明。它在WINBASE.H中聲明如下:
intWINAPIWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd );
您會(huì)注意到我在HELLOMSG.C中做了許多小改動(dòng)。第三個(gè)參數(shù)在WINBASE.H中定義為L(zhǎng)PSTR,我將它改為PSTR。這兩種數(shù)據(jù)型態(tài)都定義在WINNT.H中,作為指向字符串的指針。LP前綴代表「長(zhǎng)指針」,這是16位Windows下的產(chǎn)物。
我還在WinMain聲明中改變了兩個(gè)參數(shù)的名稱。許多Windows程序中的變量名使用一種稱作「匈牙利表示法」的命名系統(tǒng),該系統(tǒng)在變量名稱前面增加了表示變量數(shù)據(jù)型態(tài)的短前綴,我將在第三章更詳細(xì)地討論這個(gè)概念?,F(xiàn)在僅需記住前綴i表示int、sz表示「以零結(jié)束的字符串」。
WinMain函數(shù)聲明為返回一個(gè)int值。WINAPI標(biāo)識(shí)符在WINDEF.H定義,語(yǔ)句如下:
#define WINAPI __stdcall
該語(yǔ)句指定了一個(gè)呼叫約定,包括如何生產(chǎn)機(jī)械碼以在堆棧中放置函數(shù)呼叫的參數(shù)。許多Windows函數(shù)呼叫聲明為WINAPI。
WinMain的第一個(gè)參數(shù)被稱作「執(zhí)行實(shí)體句柄」。在Windows程序設(shè)計(jì)中,句柄僅是一個(gè)應(yīng)用程序用來(lái)識(shí)別某些東西的數(shù)字。在這種情況下,該句柄唯一地標(biāo)識(shí)該程序,還需要它在其它Windows函數(shù)呼叫中作為參數(shù)。在Windows的早期版本中,當(dāng)同時(shí)運(yùn)行同一程序多次時(shí),您便創(chuàng)建了該程序的「多個(gè)執(zhí)行實(shí)體(multiple instances)」。同一應(yīng)用程序的所有執(zhí)行實(shí)體共享程序和只讀的內(nèi)存(通常是例如菜單和對(duì)話框模板的資源)。程序通過(guò)檢查hPrevInstance參數(shù)就能夠確定自身的其它執(zhí)行實(shí)體是否正在運(yùn)行。然后它可以略過(guò)一些繁雜的工作并從前面的執(zhí)行實(shí)體將某些數(shù)據(jù)移到自己的數(shù)據(jù)區(qū)域。
在32位Windows版本中,該概念已被拋棄。傳給WinMain的第二個(gè)參數(shù)總是NULL(定義為0)。
WinMain的第三個(gè)參數(shù)是用于執(zhí)行程序的命令列。某些Windows應(yīng)用程序利用它在程序啟動(dòng)時(shí)將文件加載內(nèi)存。WinMain的第四個(gè)參數(shù)指出程序最初顯示的方式,可以是正常的或者是最大化地充滿整個(gè)畫(huà)面,或者是最小化顯示在工作列中。我們將在 第三章中介紹使用該參數(shù)的方法。
MessageBox函數(shù)
MessageBox函數(shù)用于顯示短信息。雖然,MessageBox顯示的小窗口不具有什么功能,實(shí)際上它被認(rèn)為是一個(gè)對(duì)話框。
MessageBox的第一個(gè)參數(shù)通常是窗口句柄,我們將在第三章介紹其含義。第二個(gè)參數(shù)是在消息框主體中顯示的字符串,第三個(gè)參數(shù)是出現(xiàn)在消息框標(biāo)題列上的字符串。在HELLMSG.C中,這些文字字符串的每一個(gè)都被封裝在一個(gè)TEXT宏中。通常您不必將所有字符串都封裝在TEXT宏中,但如果想將您的程序轉(zhuǎn)換為Unicode字符集,這確是一個(gè)好主意。我將在第二章詳細(xì)討論該問(wèn)題。
MessageBox的第四個(gè)參數(shù)可以是在WINUSER.H中定義的一組以前綴MB_開(kāi)始的常數(shù)的組合。您可從第一組中選擇一個(gè)常數(shù)指出希望在對(duì)話框中顯示的按鈕:
#define MB_OK 0x00000000L#define MB_OKCANCEL 0x00000001L#define MB_ABORTRETRYIGNORE 0x00000002L#define MB_YESNOCANCEL 0x00000003L#define MB_YESNO 0x00000004L#define MB_RETRYCANCEL 0x00000005L
如果在HELLOMSG中將第四個(gè)參數(shù)設(shè)置為0,則僅顯示「OK」按鈕??梢允褂肅語(yǔ)言的OR(|)操作符號(hào)將上面顯示的一個(gè)常數(shù)與代表內(nèi)定按鈕的常數(shù)組合:
#define MB_DEFBUTTON1 0x00000000L#define MB_DEFBUTTON2 0x00000100L#define MB_DEFBUTTON3 0x00000200L#define MB_DEFBUTTON4 0x00000300L
還可以使用一個(gè)常數(shù)指出消息框中圖示的外觀:
#define MB_ICONHAND 0x00000010L#define MB_ICONQUESTION 0x00000020L#define MB_ICONEXCLAMATION 0x00000030L#define MB_ICONASTERISK 0x00000040L
這些圖示中的某些有替代名稱:
#define MB_ICONWARNING MB_ICONEXCLAMATION#define MB_ICONERROR MB_ICONHAND#define MB_ICONINFORMATION MB_ICONASTERISK#define MB_ICONSTOP MB_ICONHAND
雖然只有少數(shù)其它MB_常數(shù),但您可以自己參考表頭文件或 / Platform SDK / User Interface Services / Windowing / Dialog Boxes / Dialog Box Reference / Dialog Box Functions里的文件。
在本程序中,MessageBox返回?cái)?shù)值1,但更嚴(yán)格地說(shuō)它返回IDOK,IDOK在WINUSER.H中定義,等于1。根據(jù)在消息框中顯示的其它按鈕,MessageBox函數(shù)還可返回IDYES、IDNO、IDCANCEL、IDABORT、 IDRETRY或IDIGNORE。
這個(gè)小的Windows程序真的與K&R的「hello, world」程序有著同等效果嗎?您也許認(rèn)為不是,因?yàn)镸essageBox函數(shù)并沒(méi)有「hello, world」中printf函數(shù)所具有的潛在格式化文字能力。但我們將在下一章中看到編寫(xiě)類似printf的MessageBox版本的方法。
編譯、連結(jié)和執(zhí)行
當(dāng)您準(zhǔn)備編譯HELLOMSG時(shí),您可從「Build」菜單中選擇「 Build Hellomsg.exe」,或者按F7,或者在「 Build」工具列中選擇「Build」圖示。(該圖示的外觀顯示在「 Build」菜單中。如果當(dāng)前沒(méi)有顯示「Build」工具列,您可從「 Tools」菜單中選擇「Customize」并選擇「 Toolbars」頁(yè)面標(biāo)簽,選中「Build」或者「 Build MiniBar」。)
另一種方法,您可從「Build」菜單中選擇「Execute Hellomsg.exe」,或者按「Ctrl+F5」,或者在「 Build」工具列單擊「Execute Program」圖標(biāo)(該圖標(biāo)看上去像一個(gè)紅的感嘆號(hào)),就會(huì)彈出一個(gè)消息框詢問(wèn)是否編譯該程序。
正常情況下,在編譯階段,編譯器從C原始碼文件產(chǎn)生一個(gè).OBJ(目標(biāo))文件。在連結(jié)階段,連結(jié)程序結(jié)合.OBJ文件和.LIB(庫(kù))文件以建立.EXE(可執(zhí)行)文件。通過(guò)在「 Project」頁(yè)面標(biāo)簽上選擇「Settings」并單擊「 Link」頁(yè)面標(biāo)簽可以查看這些庫(kù)文件的列表。特別地,您會(huì)注意到KERNEL32.LIB、USER32.LIB和GDI32.LIB。這些是三個(gè)主要Windows子系統(tǒng)的「引用鏈接庫(kù)」。它們包含了動(dòng)態(tài)鏈接庫(kù)的名稱以及放進(jìn).EXE文件的引用信息。Windows使用該信息處理程序?qū)ERNEL32.DLL、USER32.DLL、GDI32.DLL動(dòng)態(tài)鏈接庫(kù)中函數(shù)的呼叫。
在Visual C++ Developer Studio中,您可用不同的設(shè)定編譯和連結(jié)程序。內(nèi)定情況下,它們是「Debug」和「Release」??蓤?zhí)行文件被存放在以這些名稱命名的子目錄下。在Debug設(shè)定下,信息被附加到 .EXE文件中,這些信息有助于測(cè)試程序和追蹤原始碼。
如果您喜歡在命令列下工作,附上的CD-ROM包含所有范例程序的.MAK(make)文件。(可通過(guò)「 Tools」菜單選擇「Options」,再選擇「 Build」頁(yè)面標(biāo)簽,來(lái)告訴Developer Studio生成make文件。這里有一個(gè)復(fù)選框需要勾選)。您需要執(zhí)行在Developer Studio的BIN子目錄下的VCVARS32.BAT來(lái)設(shè)置環(huán)境變量。要從命令列執(zhí)行make文件,可以轉(zhuǎn)到HELLOMSG目錄并執(zhí)行:
NMAKE /f HelloMsg.mak CFG="HelloMsg - Win32 Debug"
或者
NMAKE /f HelloMsg.mak CFG="HelloMsg - Win32 Release"
然后您可通過(guò)輸入:
DEBUG\HELLOMSG
或者
RELEASE\HELLOMSG
從命令列執(zhí)行.EXE文件。
我已經(jīng)在本書(shū)附上的CD-ROM中對(duì)項(xiàng)目文件中的內(nèi)定Debug設(shè)定做了一個(gè)改動(dòng)。在「 Project Settings」對(duì)話框中,選擇「C/C++」頁(yè)面標(biāo)簽后,在「 Preprocessor Definitions」欄中,我已定義了標(biāo)識(shí)符UNICODE。我將在下一章中對(duì)此有更多的解釋。
聯(lián)系客服