「學」的部分
如果你認真學習了第6節的內容,那麼,現在你已經成功安裝好了C++的工作環境,也就是Visual C++的某一個版本。你不用把這個集成工作環境想像地那麼難,覺得編程很高大上,然後覺得這個軟體也很高大上。如果這樣想的話,你就很難教好孩子了。編程的高難度時代已經過去,各種各樣的底層技術難題已經被我們的前輩們解決,而且很好地封裝到了各種各樣的函數中,我們只要懂得如何去使用就可以了。這一節課,我們就用這個集成工作環境寫一個Windows程序的框架。
首先,我們看一看Windows程序框架的完整原始碼:
#include <windows.h>#include <windowsx.h>#include <tchar.h>//函數聲明LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);//入口函數int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nShowCmd){//首先定義Windows類WNDCLASSEX w;LPCTSTR wn = _T("我的第一個Windows程序");//賦值w.cbSize = sizeof(WNDCLASSEX);w.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;w.lpfnWndProc = (WNDPROC)WndProc;w.cbClsExtra = 0;w.cbWndExtra = 0;w.hInstance = hInstance;w.hIcon = LoadIcon(hInstance,NULL);w.hCursor = LoadCursor(NULL,IDC_ARROW);w.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);w.lpszClassName = wn;w.hIconSm = LoadIcon(hInstance,NULL);w.lpszMenuName = NULL;//註冊類RegisterClassEx(&w);//創建窗口if (!CreateWindowEx(NULL,wn,L"第一個程序",WS_OVERLAPPEDWINDOW | WS_POPUP | WS_VISIBLE,0,0,800,600,NULL,NULL,hInstance,NULL))return 0;//消息循環bool got;MSG msg;PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );while (WM_QUIT != msg.message){got = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );if(got){if (!TranslateAccelerator(msg.hwnd,NULL,&msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}else{//這裡是以後渲染遊戲的位置/*就是這裡,下面的Sleep語句是單獨的*/Sleep(1);}}return (int)msg.wParam;}LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){HRESULT r = 0L;//開始處理消息switch(msg){case WM_CLOSE:case WM_DESTROY:PostQuitMessage(0);break;}return DefWindowProc(hWnd, msg, wParam, lParam);}
我一上來就拿出大段的代碼,並不是要嚇唬你們,而是因為Windows編程的框架本就比較複雜,像上面這樣的代碼已經簡化了非常多了。而且,只要你認真看完我的解釋,理解這些代碼並不是什麼難事。
為了有一個直觀的印象,我們先用編譯器(也就是那個集成工作環境)來編譯運行一下我們的這個框架。
由於沒有強制性,你下載的Visual Studio版本可能不太一樣,但是操作是差不多的。總得來說分成3步:(如果你是第一次打開Visual Studio,請選擇C++為主要設計語言)
第1步,創建一個新的項目,創建的過程就是在「文件」的「新建」下面選擇「項目」。由於我們要寫的是Windows程序,請選擇「Win32」項目右側的「Win32 項目」,然後自定義一個名稱,再點擊確定就可以了;
然後會有對話框彈出,一般選擇下一步就可以了,在「應用程式設置」中,選中「空項目」然後點完成。
為什麼要創建「空項目」呢?因為遊戲程序是一個相對消耗系統資源的程序。
Visual Studio是為了方便程式設計師編程用的,所以,它能主動生成各種各樣的程序框架,而我們這一節所講的Windows框架也是可以自動生成的。在Visual C++中,這個Windows框架被稱為MFC,是一個非常強大的、微軟提供Windows框架程序。但是,像MFC這樣強大又複雜的Windows框架反而不適合用來寫遊戲程序,因為這些框架功能太強大,而且封裝得太厲害,會嚴重影響最終程序的效率。為了讓遊戲程序能更好地使用計算機的資源,我們要手寫一個最最簡單的Windows框架。
第2步,是要添加一個CPP類型的文件,然後把上面的代碼複製進去。在項目創建完成後,我們就能看到「解決方案資源管理器」,其中就有我們剛創建的項目。只要右擊項目名稱,就能添加CPP文件了。具體的方法,是在右擊菜單中選擇「添加」下面的「新建項」,一般會自動選擇CPP文件,我們只需要輸入文件名稱就能創建了。
創建成功後,這個CPP文件會自動打開,不過暫時裡面什麼都沒有。你想要看效果,就把上面的代碼一字不差地複製進去就可以了。如果你想加深印象,可以試著手動輸入所有的代碼,也就是抄一遍(我個人建議你抄一遍比較好,編程不能一蹴而就,是一個慢慢磨的過程)。
第3步就比較簡單了,直接在「生成」菜單下選擇「生成解決方案」,編譯器就能自動幫你編譯好程序了。只要你沒有輸入錯誤,編譯是一次性通過的。然後,在「調試」下面選擇「開始執行(不調試)」就能直接運行你剛寫的這個程序了。正常來說,桌面上會彈出一個白色的窗口,窗口中一片白,啥都沒有。這個窗口就是Windows的框架,而裡面的白色就是我們後期需要添加素材的地方。
接下來,我們仔細解釋一下這些代碼。
如果你第6節內容學得非常紮實的話,其中的12個概念全部都了如指掌,那麼,上面這一段代碼你是可以看出個大概的。起碼的,你知道變量、注釋、結構、函數和while循環,你不知道的,僅僅是這些代碼為什麼要這樣組織起來罷了。
所以,我在這裡假定,你的第6節內容學得非常紮實,這樣我就能把更多深層次的東西說出來了。如果你認為自己在第6節只是走馬觀花的話,強烈建議你回過頭去好好把第6節的內容學紮實了,否則的話,接下來的內容你可能會看不懂。
一、開頭包含「#include」的3行
在第6節內容中,我們所講解的只是C++語言的一些重要知識點,理解了之後,你就可以看明白大部分的C++代碼,但不代表能看懂。在C++中,這些知識點是以語句的形式存在的,而C++中大致分成兩類語句:帶分號的語句和不帶分號的語句。
所謂帶分號,也就是帶符號「;」的語句(記住,是英文字符),是C++中主要的語句。你可以看上面的例子,你能找到大量的分號,這個符號代表了一個語句的結束。你只要記住,凡是有「;」的語句,只有找到「;」才算一個語句的結束。比方說上面語句中創建窗口的函數CreateWindowsEx並沒有寫在一行,而是分成了很多行來寫,最後在「return 0」後面加上了「;」,也就是說,這麼多行加起來才算是一個語句。
第二類就是這裡說的3行不包含「;」的語句,這類語句的特徵是以「#」開頭,在C++中的術語是「預編譯語句」。我們不需要了解那麼多,隨著你的編程深入,你自然而然就會懂得很多事情。在這裡,我們只需要知道,這裡的三行「#include」代表的是「包含」的意思。我們看「<>」中間的內容,明顯是一個.h類型的文件,這類文件是C++語言中的頭文件。一般的頭文件都是聲明文件,裡面包含了大量的聲明語句。說得再簡單些,這些.h文件中包含了前輩們的編程成果,而我們想要快速編程,就要用到這些編程成果。所以,我們寫這3行語句的目的,是為了告訴編譯器,我們寫的這個程序需要用到這裡指定的一些「編程成果」。
你還可以這樣理解:.h中是一些前輩們製作好的功能,而我們自己的程序中「包含」這些.h文件,就能在我們的程序中使用這些前輩們的功能了。如果我們不包含這些.h文件,下面代碼中的各個函數將會無法使用。
二、函數聲明部分
這裡的函數聲明只有WndProc這麼一個函數。我們在第6節中學習的函數都只有一個前綴,而這裡的函數有兩個前綴——LRESULT和CALLBACK。我們還是初學者,我們只需要知道,這是Windows編程中獨特的回調函數聲明方式。什麼是回調函數?如果你上一節,也就是第8節認真學了的話,就會知道,Windows系統的核心是消息,一切都是為了消息服務的。而這裡聲明的這個WndProc函數,就是專門處理Windows消息用的,這下你應該明白了吧?
三、入口函數
在第8節中我們已經簡要說過了Windows的工作原理,而我們的編程也是在Windows大環境下進行的,所以,所有的Windows程序都是由兩部分組成的:第一,是程序的功能實現部分;第二,是消息的處理部分。