第二章 使用Win32程序資源
一、簡介
歡迎繼續(xù)收看!通過本章題目可能你已經(jīng)猜出了本章論題,我將教會你在Windows程序中使用資源。簡單的講,資源即數(shù)據(jù),它們通常是和程序的EXE文件相關(guān)聯(lián)的,但是它們又是獨一無二的。首先,資源在運行過程中不能被修改。它們實際上都是只讀文件,而且程序代碼不能夠直接訪問它們。另外,資源并不在程序的數(shù)據(jù)區(qū)內(nèi)。在裝入時,程序資源通常在某個磁盤文件中,直到程序需要它們時才被裝入。使用資源是一件很容易的事情,并且它的妙處無窮。Windows為我們提供了大量的資源類型,但我們這里只學一些最常用,最容易的:圖標(icon)、光標(cursor)、位圖(bitmap)、菜單(menu)和字符串(string)。此后,我還將教你建立自己風格類型的資源,使你為所欲為。
重復一下,要想看懂本章,你得有點C語言的基礎(chǔ)。C++有時用一用,但不影響你學習本章內(nèi)容。并且我假定你已經(jīng)讀過了上一章內(nèi)容“Windows編程基礎(chǔ)”。還是用Microsoft Visual C++的編譯器。
資源腳本
在進行細節(jié)之前,我們要先搞懂怎樣要編譯器知道它所要編譯的資源類型。方法是使用稱之為資源腳本的特殊文件,它是一個簡單的文本文件,可以手工編輯,也可以讓Visual C++自動編輯,或者你用其它的自動編輯器編輯。無論如何,資源腳本文件要有一個.rc的擴展名。大多數(shù)的腳本文件都從定義資源行開始,最簡單的資源行通常要用到資源類型,就像這樣:
[identifier] [resource type] [filename]
【標識符】 【資源類型】 【文件名稱】
標識符可以用兩種方式表示:一種是能表示資源意思的字符串,另一種是在資源相對應的頭文件中用#define定義過的數(shù)字常量。如果你選擇數(shù)字常量,這通常是一個好主意,別忘了把相應的頭文件加入到你的資源腳本。資源腳本使用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是字符串呢,還是數(shù)字常量?這無傷大雅,編譯器編譯的時候會自己判斷。如果發(fā)現(xiàn)在頭文件中有#define的定義,那就認為是字符常量,否則,就是字符串。如果有些迷茫,不要緊。我將解釋我們要用到的每一個資源類型。如果您覺得麻煩那讓我們用全自動的資源插入系統(tǒng)吧?。ㄔ赩isual C++中,在“插入”下拉菜單中,選擇“資源”)現(xiàn)在你知道了建立資源腳本的基礎(chǔ)知識,讓我們開始進一步的行程吧!
圖標和光標
你每天在使用的大多數(shù)的Windows程序,都有自己的圖標,簡單的說,就是EXE文件同這個圖標資源相關(guān)聯(lián)了,獨特風格的光標也是如此。你已經(jīng)知道圖標的腳本行樣子了,光標的和它很相似,看看吧:
[identifier] CURSOR [filename]
[identifier] ICON [filename]
增加了一行腳本行后,也就是意味著你的EXE文件又多了一個關(guān)聯(lián)。也就是說你的EXE文件要根據(jù)標識符去相應的位置尋找相應的文件[filename]。你可以使用任何你喜歡用的圖標/光標編輯器去編輯相應的文件。我通常利用Visual C++中的編輯器。
把資源腳本做出來后,并沒有完事兒,因為你還不知道怎么調(diào)用相應的資源,要想知道圖標和光標是怎樣在你的程序中被調(diào)用的,讓我們回過頭來,看一看上一章中的窗口類(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用來出現(xiàn)在開始菜單和窗口的標題欄里;hCursor用來表示在你所創(chuàng)建的窗口中的光標的樣子。我向你保證,我們要實現(xiàn)自己的風格一點都不復雜。下面是它們的原形:
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
);
一、簡介
歡迎繼續(xù)收看!通過本章題目可能你已經(jīng)猜出了本章論題,我將教會你在Windows程序中使用資源。簡單的講,資源即數(shù)據(jù),它們通常是和程序的EXE文件相關(guān)聯(lián)的,但是它們又是獨一無二的。首先,資源在運行過程中不能被修改。它們實際上都是只讀文件,而且程序代碼不能夠直接訪問它們。另外,資源并不在程序的數(shù)據(jù)區(qū)內(nèi)。在裝入時,程序資源通常在某個磁盤文件中,直到程序需要它們時才被裝入。使用資源是一件很容易的事情,并且它的妙處無窮。Windows為我們提供了大量的資源類型,但我們這里只學一些最常用,最容易的:圖標(icon)、光標(cursor)、位圖(bitmap)、菜單(menu)和字符串(string)。此后,我還將教你建立自己風格類型的資源,使你為所欲為。
重復一下,要想看懂本章,你得有點C語言的基礎(chǔ)。C++有時用一用,但不影響你學習本章內(nèi)容。并且我假定你已經(jīng)讀過了上一章內(nèi)容“Windows編程基礎(chǔ)”。還是用Microsoft Visual C++的編譯器。
資源腳本
在進行細節(jié)之前,我們要先搞懂怎樣要編譯器知道它所要編譯的資源類型。方法是使用稱之為資源腳本的特殊文件,它是一個簡單的文本文件,可以手工編輯,也可以讓Visual C++自動編輯,或者你用其它的自動編輯器編輯。無論如何,資源腳本文件要有一個.rc的擴展名。大多數(shù)的腳本文件都從定義資源行開始,最簡單的資源行通常要用到資源類型,就像這樣:
[identifier] [resource type] [filename]
【標識符】 【資源類型】 【文件名稱】
標識符可以用兩種方式表示:一種是能表示資源意思的字符串,另一種是在資源相對應的頭文件中用#define定義過的數(shù)字常量。如果你選擇數(shù)字常量,這通常是一個好主意,別忘了把相應的頭文件加入到你的資源腳本。資源腳本使用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是字符串呢,還是數(shù)字常量?這無傷大雅,編譯器編譯的時候會自己判斷。如果發(fā)現(xiàn)在頭文件中有#define的定義,那就認為是字符常量,否則,就是字符串。如果有些迷茫,不要緊。我將解釋我們要用到的每一個資源類型。如果您覺得麻煩那讓我們用全自動的資源插入系統(tǒng)吧?。ㄔ赩isual C++中,在“插入”下拉菜單中,選擇“資源”)現(xiàn)在你知道了建立資源腳本的基礎(chǔ)知識,讓我們開始進一步的行程吧!
圖標和光標
你每天在使用的大多數(shù)的Windows程序,都有自己的圖標,簡單的說,就是EXE文件同這個圖標資源相關(guān)聯(lián)了,獨特風格的光標也是如此。你已經(jīng)知道圖標的腳本行樣子了,光標的和它很相似,看看吧:
[identifier] CURSOR [filename]
[identifier] ICON [filename]
增加了一行腳本行后,也就是意味著你的EXE文件又多了一個關(guān)聯(lián)。也就是說你的EXE文件要根據(jù)標識符去相應的位置尋找相應的文件[filename]。你可以使用任何你喜歡用的圖標/光標編輯器去編輯相應的文件。我通常利用Visual C++中的編輯器。
把資源腳本做出來后,并沒有完事兒,因為你還不知道怎么調(diào)用相應的資源,要想知道圖標和光標是怎樣在你的程序中被調(diào)用的,讓我們回過頭來,看一看上一章中的窗口類(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用來出現(xiàn)在開始菜單和窗口的標題欄里;hCursor用來表示在你所創(chuàng)建的窗口中的光標的樣子。我向你保證,我們要實現(xiàn)自己的風格一點都不復雜。下面是它們的原形:
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
);

