送給初學(xué)者的禮物:C++游戲編程起源連載一

字號(hào):

第一章 Windows編程基礎(chǔ)
    簡介
    本章目的是介紹WINDOWS編程基礎(chǔ)。在本章結(jié)束時(shí),你應(yīng)該能夠很好的工作了,雖燃可能是簡單的WINDOWS程序。你需要有C語言的基礎(chǔ)知識(shí),我很少將C++的代碼擴(kuò)充到程序中。當(dāng)然,由于WINDOWS本身就是面向?qū)ο蟮?,一點(diǎn)類的知識(shí)是不會(huì)對(duì)你有什么損害的。如果你不熟悉C++,沒有關(guān)系,我想你還是能從我這里學(xué)到大部分的東西。所有的程序代碼都通過了MICROSOFT VISUAL C++6.0的編譯,如果你還沒有合適的編譯器,那就用它好了,還是很棒的。開動(dòng)吧!
    多數(shù)的Windows程序都需要Windows.h和Windowsx.h這兩個(gè)頭文件,要確保使用它們。當(dāng)然,你還需要其它的標(biāo)準(zhǔn)的C的頭文件,象stdio.h,conio.h等。除了這些,你還會(huì)經(jīng)??吹皆诔绦虻拈_始有這樣一行代碼:
    #define WIN32_LEANAND_MEAN
    它表示W(wǎng)indows的頭文件中將拒絕接受MFC的東西,這將加速你的build時(shí)間。如果你從沒有打算應(yīng)用MFC在你的游戲編程中,那就使用它吧。如果你以前從沒有看過這種聲明類型——在#define后,直接加上一個(gè)“單詞”,那么它的作用就是有條件編譯??纯聪旅娴睦樱?BR>    #ifdef DEBUG_MODE
     printf("Debug mode is active!");
    #endif
    意思是:如果程序的開始包含#define DEBUG_MODE,那么就printf(),否則退出。這個(gè)對(duì)于你跟蹤程序的邏輯錯(cuò)誤是很有幫助的。
    WinMain()函數(shù)
    DOS下的C語言從main()開始,Windows下的C語言從WinMain()開始,一個(gè)空的WinMain()函數(shù)是這樣的:
    int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
     return(0);
    }
    一個(gè)函數(shù)即使什么也沒做,也應(yīng)該返回一個(gè)值。是的,有好多東西我們不熟悉。首先的首先,WINAPI是個(gè)什么聲明?WINAPI是在windows.h頭文件中定義的一個(gè)宏,它把函數(shù)調(diào)用翻譯成正確的調(diào)用約定。當(dāng)我們?cè)诔绦蛑行枰玫絽R編語言的時(shí)候,我們?cè)趤砩罹克昧耍涀?,如果要用WinMain(),就必須要有WINAPI。
    下一步讓我們來看看括號(hào)里的四個(gè)參數(shù):
    ◎ HINSTANCE hinstance:HINSTANCE是一個(gè)句柄類型的標(biāo)識(shí)符。變量hinstance是一個(gè)整數(shù),用于標(biāo)識(shí)程序?qū)嵗?。Windows設(shè)置這個(gè)參數(shù)的值,并把它傳遞給你的程序代碼。很多Windows函數(shù)都要用到它。
    ◎ HINSTANCE hPreInstance:你不用擔(dān)心這個(gè)參數(shù),它已經(jīng)被廢掉了。它只是為古老的Windows版本服務(wù)的。你將還會(huì)看到類似的情況。
    ◎ LPSTR lpCmdLine:是一個(gè)指向字符串的指針,它僅在程序名是從DOS命令行輸入或是從Run對(duì)話框中輸入時(shí)才起作用。因此,很少被程序代碼所用。
    ◎ int nCmdShow:決定了窗口在初始顯示時(shí)的狀態(tài)。Windows通常給這個(gè)參數(shù)分配一個(gè)值。通常是SW_打頭的一個(gè)常量。例如SW_SHOWNORMAL表示默認(rèn)狀態(tài),SW_MAXINIZE或SW_MINIMIZE分別表示和最小模式等等。
    以上大體上是WinMain()的參數(shù)的介紹。下面對(duì)變量、參數(shù)、常量、類等的命名方法介紹一下。
    一、消息
    當(dāng)你在DOS下編程的時(shí)候,你不必?fù)?dān)心其它程序的運(yùn)行,因?yàn)镈OS是獨(dú)占模式。但你在Windows平臺(tái)上編程時(shí),你不得不考慮其它正在運(yùn)行的程序。鑒于此,Windows通過“消息”來連接操作申請(qǐng)和具體操作。簡單的說,就是我們指示程序或程序本身向Windows發(fā)出諸如移動(dòng)窗口、放大窗口、關(guān)閉窗口等申請(qǐng),Windows再根據(jù)申請(qǐng),考察實(shí)地情況,拒絕或發(fā)出指令,讓程序(計(jì)算機(jī))作出相應(yīng)的動(dòng)作。再例如,鼠標(biāo)隨時(shí)向Windows發(fā)出消息,匯報(bào)光標(biāo)位置,左鍵或右鍵是否按下等,Windows再根據(jù)消息作出相應(yīng)的反應(yīng)??傊?,無論何時(shí),Windows都要隨時(shí)掌控所有的消息,而且,Windows是一直不斷地接收到各種消息。
    這種功能是通過一種被命名為CALLBACK函數(shù)類型實(shí)現(xiàn)的。不用害怕,消息傳遞來傳遞去都是由Windows自己完成的,你只要聲明一個(gè)CALLBACK函數(shù)就可以了,就像WINAPI用在WinMain()前一樣。如果還沒有明白,不要緊,往下看你就明白了?,F(xiàn)在,我要離開這個(gè)話題一會(huì)兒,因?yàn)槟阒挥邢冉⒋翱冢╓indows),傳遞消息才有可能實(shí)現(xiàn)。 二、窗口類
    現(xiàn)在談?wù)撘稽c(diǎn)C++的知識(shí),因?yàn)橐虢⒁粋€(gè)窗口,你就得先建立一個(gè)窗口類。窗口類包含所有的有關(guān)窗口的信息,如用什么樣的鼠標(biāo)符號(hào),菜單樣式等等。開發(fā)任何一個(gè)窗口程序,都離不開窗口類的建立。為了達(dá)到此目的,你必須填寫WNDCLASSEX結(jié)構(gòu)。EX的意思是“擴(kuò)充”的意思,因?yàn)橛幸粋€(gè)老的結(jié)構(gòu)叫作WNDCLASS,這里,我們將使用WNDCLASSEX結(jié)構(gòu),它的樣子如下:
    typedef struct _WNDCLASSEX {
     UINT cbSize;
     UINT style;
     WNDPROC lpfnWndProc;
     int cbClsExtra;
     int cbWndExtra;
     HANDLE hInstance;
     HICON hIcon;
     HCURSOR hCursor;
     HBRUSH hbrBackground;
     LPCTSTR lpszMenuName;
     LPCTSTR lpszClassName;
     HICON hIconSm;
    } WNDCLASSEX;
    這個(gè)結(jié)構(gòu)有不少成員,討厭的是,你必須為窗口類設(shè)置每一個(gè)成員。莫發(fā)愁,紙老虎一個(gè)。讓我們來個(gè)速成。
    ※ UINT cbSize:指定了以字節(jié)為單位的結(jié)構(gòu)的大小。這個(gè)成員是通過sizeof(WNDCLASSEX)實(shí)現(xiàn)的。你將會(huì)經(jīng)??吹剿?,尤其是你使用了DirectX。