送給初學者的禮物:遊戲程式設計起源連載三(轉)

post0發表於2007-08-12
送給初學者的禮物:遊戲程式設計起源連載三(轉)[@more@]

  第二章 使用Win32程式資源

  一、簡介

  歡迎繼續收看!透過本章題目可能你已經猜出了本章論題,我將教會你在Windows程式中使用資源。簡單的講,資源即資料,它們通常是和程式的EXE檔案相關聯的,但是它們又是獨一無二的。首先,資源在執行過程中不能被修改。它們實際上都是隻讀檔案,而且程式程式碼不能夠直接訪問它們。另外,資源並不在程式的資料區內。在裝入時,程式資源通常在某個磁碟檔案中,直到程式需要它們時才被裝入。使用資源是一件很容易的事情,並且它的妙處無窮。Windows為我們提供了大量的資源型別,但我們這裡只學一些最常用,最容易的:圖示(icon)、游標(cursor)、點陣圖(bitmap)、選單(menu)和字串(string)。此後,我還將教你建立自己風格型別的資源,使你為所欲為。

  

  重複一下,要想看懂本章,你得有點C語言的基礎。C++有時用一用,但不影響你學習本章內容。並且我假定你已經讀過了上一章內容“Windows程式設計基礎”。還是用Microsoft Visual C++的編譯器。

  

  資源指令碼

  在進行細節之前,我們要先搞懂怎樣要編譯器知道它所要編譯的資源型別。方法是使用稱之為資源指令碼的特殊檔案,它是一個簡單的文字檔案,可以手工編輯,也可以讓Visual C++自動編輯,或者你用其它的自動編輯器編輯。無論如何,資源指令碼檔案要有一個.rc的副檔名。大多數的指令碼檔案都從定義資源行開始,最簡單的資源行通常要用到資源型別,就像這樣:

  

  [identifier]  [resource type]  [filename]

  【識別符號】    【資源型別】   【檔名稱】

  

  識別符號可以用兩種方式表示:一種是能表示資源意思的字串,另一種是在資源相對應的標頭檔案中用#define定義過的數字常量。如果你選擇數字常量,這通常是一個好主意,別忘了把相應的標頭檔案加入到你的資源指令碼。資源指令碼使用C語言風格的檔案格式好像比較容易理解。以下是一個比較簡單的資源指令碼例項:

  

  #include "resource.h"

  // icons

  ICON_MAIN ICON myicon.ico

  // bitmaps

  IMG_TILESET1 BITMAP tileset.bmp

  IMG_TILESET2 BITMAP tileset2.bmp

  

  

  例子中的ICON_MAIN和IMG_TILESET是字串呢,還是數字常量?這無傷大雅,編譯器編譯的時候會自己判斷。如果發現在標頭檔案中有#define的定義,那就認為是字元常量,否則,就是字串。如果有些迷茫,不要緊。我將解釋我們要用到的每一個資源型別。如果您覺得麻煩那讓我們用全自動的資源插入系統吧!(在Visual C++中,在“插入”下拉選單中,選擇“資源”)現在你知道了建立資源指令碼的基礎知識,讓我們開始進一步的行程吧!

  

  圖示和游標

  你每天在使用的大多數的Windows程式,都有自己的圖示,簡單的說,就是EXE檔案同這個圖示資源相關聯了,獨特風格的游標也是如此。你已經知道圖示的指令碼行樣子了,游標的和它很相似,看看吧:

  

  [identifier] CURSOR [filename]

  [identifier] ICON [filename]

  

  增加了一行指令碼行後,也就是意味著你的EXE檔案又多了一個關聯。也就是說你的EXE檔案要根據識別符號去相應的位置尋找相應的檔案[filename]。你可以使用任何你喜歡用的圖示/游標編輯器去編輯相應的檔案。我通常利用Visual C++中的編輯器。

  

  把資源指令碼做出來後,並沒有完事兒,因為你還不知道怎麼呼叫相應的資源,要想知道圖示和游標是怎樣在你的程式中被呼叫的,讓我們回過頭來,看一看上一章中的視窗類(windows class)檔案:

  

  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;

  // message handler function

  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

  

  還記得它吧?這個hIcon用來表示整個程式;hIconSm用來出現在開始選單和視窗的標題欄裡;hCursor用來表示在你所建立的視窗中的游標的樣子。我向你保證,我們要實現自己的風格一點都不復雜。下面是它們的原形:

  

  HICON LoadIcon(

  HINSTANCE hInstance,

  // handle to application instance

  LPCTSTR lpIconName

  // icon-name string or icon resource identifier

  );

  HCURSOR LoadCursor(

  HINSTANCE hInstance,

  // handle to application instance

  LPCTSTR lpCursorName

  // name string or cursor resource identifier

  );

  

  返回的型別是它們自己相對應的型別。其內部的引數都很直觀:

  

  ※ HINSTANCE hInstane:但程式執行時,把圖示或游標相對應的控制程式碼傳遞給WinMain()函式。若要使用Windows的標註圖示或游標,就把它設定為NULL。

  

  ※ LPCTSTR lpIconName,lpCursorName:是你要呼叫的資源的識別符號字串。如果你在指令碼檔案中用字串直接作為識別符號,就直接傳送它好了;如果你是用數字常量,就要使用一個Windows標頭檔案裡的宏MAKEINTRESOURCE()來把它們協調一致。

  

  讓我們看一看下面的資源指令碼,是關於圖示和游標的:

  

  #include "resource.h"

  ICON_MAIN ICON myicon.ico

  CURSOR_ARROW CURSOR arrow.cur

  

  如果識別符號ICON_MAIN合CURSOR_ARROW在標頭檔案resource.h中沒有被#define定義過,那麼我們將直接傳遞它給資源呼叫函式,象這樣:

  

  sampleClass.hIcon = LoadIcon(hinstance, "ICON_MAIN");

  

  如果它們在標頭檔案resource.h中這樣定義過:

  

  #define ICON_MAIN 1000

  #define CURSOR_ARROW 2000

  

  你就必須用宏MAKEINTRESOURCE()把它們轉變為LPCTSTR型別。下面給出你幾種意義相同的呼叫方法,都是正確的喔!

  

  sampleClass.hIcon = LoadIcon(hinstance,

  MAKEINTRESOURCE(ICON_MAIN));

  or...

  sampleClass.hIcon = LoadIcon(hinstance,

  MAKEINTRESOURCE(1000));

  or...

  int ident = 1000;

  sampleClass.hIcon = LoadIcon(hinstance,

  MAKEINTRESOURCE(ident));

  

  關於圖示和游標的呼叫,你學的差不多了。就這個話題,我還想告訴你一件事兒。如果你除了在程式的開始設定游標外,在程式中還要設定游標,有一個簡單的Windows函式可以完成它:

  

  HCURSOR SetCursor(HCURSOR hCursor);

  

  僅僅一個引數,它是一個控制程式碼,是在呼叫LoadCursor()時得到的,函式返回撥用的上一個游標的控制程式碼,如果沒有設定過上一個游標,返回值是NULL。

  

  點陣圖

  想要往程式裡新增圖象,透過點陣圖資源可能是最簡單的辦法了。點陣圖是Windows之本,當然提供了一些函式來處理點陣圖,請記住,如果你使用了太多的點陣圖,你的EXE檔案將要非常巨大。在資源指令碼中設定點陣圖同圖示和游標沒什麼區別:

  

  [identifier] BITMAP [filename]

  

  有一個函式LoadBitmap(),同LoadCursor()和LoadIcon()的用法很相似,它將得到一個控制程式碼,由於我還沒有講過圖形(graphics),就不具體說函式的功能了,你可以猜一猜它是怎樣工作的,一旦你得到了圖形控制程式碼,你將怎樣使用它呢?更多的留待以後再講。不要擔心,現在只是要你有點兒準備。下面看看我們還應該學點兒什麼。

  

  字串表格

  字串表

  

  字串表是我最喜歡的資源型別。正象你所想的:一個充滿字串的龐大表格。字串表有很多用處。你可以用它儲存你的檔名稱,遊戲中的人物對話,訊息框中的文字,選單中的文字等等。在資源指令碼里建立一個字串表很容易,就像這樣:

  

  STRINGTABLE

  {

  // entries go here

  }

  

  一個字串表由幾部分組成:一個標識字串的數字;緊跟著一個逗號;然後是加了雙引號的字串本身。字串表裡的字串被允許使用溢位符號,如

  

  或 。注意,字串表本身並沒有識別符號,所以每個程式只能有一個字串表。一個簡單的字串表可能象下面這個樣子:

  

  // program information

  STRINGTABLE

  {

  1, "3D Space Game v1.0"

  2, "Written by The Masked Coder"

  3, "(C) 2000 WienerDog Software"

  }

  

  從程式的字串表裡呼叫字串,將使用――你可能猜到了――LoadString()函式。這是它的原形:

  

  int LoadString(

  HINSTANCE hInstance, // handle to module containing string resource

  UINT uID,      // resource identifie

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-951675/,如需轉載,請註明出處,否則將追究法律責任。

相關文章