C++ 新建一個窗口


首先要談論一點C++的知識,因為要想建立一個窗口,你就得先建立一個窗口類。窗口類包含所有的有關窗口的信息,如用什么樣的鼠標符號,菜單樣式等等。開發任何一個窗口程序,都離不開窗口類的建立。為了達到此目的,你必須填寫WNDCLASSEX結構。EX的意思是“擴充”的意思,因為有一個老的結構叫作WNDCLASS,這里,我們將使用WNDCLASSEX結構,它的樣子如下: 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; 這個結構有不少成員,討厭的是,你必須為窗口類設置每一個成員。莫發愁,紙老虎一個。讓我們來個速成。 ※ UINT cbSize:指定了以字節為單位的結構的大小。這個成員是通過sizeof(WNDCLASSEX)實現的。你將會經常看到它,尤其是你使用了DirectX。 ※ UINT style:指定了窗口的風格。它經常被以CS_打頭的符號常量定義。兩種或兩種以上的風格可以通過C語言中的“或”(|)運算符加以組合。大多數情況我們只應用四種風格,出於對文章長度的考慮,我們只列出這四種。若你還需要其它的,到MSDN里找一下好了。當然前提是你使用的是Visual C++。 ◎ CS_HREDRAW:一旦移動或尺寸調整使客戶區的寬度發生變化,就重新繪制窗口。 ◎ CS_VREDRAW:一旦移動或尺寸調整使客戶區的高度發生變化,就重新繪制窗口。 ◎ CS_OWNDC:為該類中的每一個窗口分配一個唯一的設備上下文。 ◎ CS_DBLCLKS:當用戶雙擊鼠標時向窗口過程發送雙擊消息。 ※ WNDPROC lpfnWndProc:是指向窗口過程的指針。一般都指向CALLBACK函數。如果你沒有用過函數指針,簡單理解為函數的地址就是函數的名字,名字后面別帶括號。 ※ int cbClsExtra:它是為類保留的額外信息 。大多數程序員不用它,你在在寫游戲程序時也不太可能用它,所以,設為0好了。 ※ int cbWndExtra:同上一個差不多,設為0好了。 ※ HANDLE hInstance:是指向窗口過程實例的句柄。同時也是WinMain()函數的參數之一。應該設置為hinstance。 ※ HICON hIcon:指向窗口圖標的句柄,它通常被LoadIcon()函數設置。在你學會如何在你的程序中使用資源前,你先設置成如下樣子:LoadIcon(NULL,IDI_WINLOGO)。當然,還有一些其它的IDI_打頭的符號常量,可以自己去幫助文件里尋找。 ※ HCURSOR hCursor:指向窗口光標的句柄,它通常被LoadCursor()函數設置,在你學會如何在你的程序中使用資源前,你先用Windows默認的吧,LoadCursor(NULL,IDC_ARROW)。 ※ HBRUSH hbrBackground:當你的窗口過程得到消息,要求刷新(或重畫)窗口時,至少要用一種純色或“brush”(畫刷)重畫窗口區域,畫刷是由參數確定的。你可以使用GetStockObject()函數調用幾種常備的畫刷,如BLACK_BRUSH, WHITE_BRUSH, GRAY_BRUSH等。現在,你就用GetStockObject(BLACK_BRUSH)吧。也許你覺得我說的太簡單了,是因為不想把開始弄得太復雜。在以后的篇幅里會詳細講述的。 ※ LPCTSTR lpszMenuName:如果你想建立一個有下拉菜單的窗口,你得給這個參數賦一個菜單名稱(這涉及到資源),由於你還不知道怎么創建菜單,你就先用NULL設置成一個沒有菜單的窗口吧。 ※ LPCSTR lpszClassName:很顯然,你需要給類起個名字,隨你便,如“**”。要用雙引號引上。 ※ HICON hIconSm:指向小圖標的句柄。小圖標用來顯示在窗口的標題欄里。要用到LoadIcon()函數,現在,先用Windows默認的吧,LoadIcon(NULL,IDI_WINLOGO)。 好了,現在你關於WNDCLASSEX結構知道的已經差不多了,你可以自己設置它了。下面是一個例子: WNDCLASSEX sampleClass; // declare structure variable sampleClass.cbSize = sizeof(WNDCLASSEX); // always use this! sampleClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; // standard settings sampleClass.lpfnWndProc = MsgHandler; // we need to write this! sampleClass.cbClsExtra = 0; // extra class info, not used sampleClass.cbWndExtra = 0; // extra window info, not used sampleClass.hInstance = hinstance; // parameter passed to WinMain() sampleClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Windows logo sampleClass.hCursor = LoadCursor(NULL, IDC_ARROW); // standard cursor sampleClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // a simple black brush sampleClass.lpszMenuName = NULL; // no menu sampleClass.lpszClassName = "Sample Class" // class name sampleClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // Windows logo again 我想,現在你已經有點兒不太崇拜Windows程序員了吧。言歸正傳,有一點我得提醒你,注意函數GetStockObject()前的(HBRUSH)類型配置,這是因為GetStockObject()可以調用其它的對象,不僅僅是“brush”,所以你需要一個HBRUSH類型配置。在Visual C++舊版本里不用配置,但新的6.0版本需要它,否則會編譯出錯。 下一件事是注冊這個窗口類,只有這樣,你才能創建新的窗口。十分簡單,你只需要調用一個RegisterClassEX()函數,它只有一個參數,就是你的窗口類的地址(名字),根據我上面給的例子,這里應該這樣: RegisterClassEx(&sampleClass); 我們的窗口類創建完了,我們可以用它創建一個窗口了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM