前面已經(jīng)說(shuō)了資源的基本概念,不過(guò)只是做了和很簡(jiǎn)單的介紹,這次我們來(lái)點(diǎn)狠的,深入的。前面我雖然也用了資源,不過(guò)只是鼠標(biāo)光標(biāo)的,回憶下我們的程序,是那么的簡(jiǎn)陋。我們?cè)缇拖氚阉o裝點(diǎn)下了吧,不用著急,學(xué)完了這節(jié)后,你就可以成為一個(gè)雕刻師了,想讓你的窗口咋樣基本都可以了(需要練習(xí)了,呵呵)。
以當(dāng)前我這個(gè)Word編輯窗口為例,可以看到一個(gè)窗口有很多項(xiàng)的,而我們之前的串口跟這個(gè)相比,真可謂小巫見(jiàn)大巫。前面的程序連最起碼的菜單欄都沒(méi)有,真是慚愧呀。在Vb做界面,簡(jiǎn)直就跟畫(huà)圖是一樣一樣的,Java中可以在編程時(shí),一個(gè)一個(gè)組件往窗體對(duì)象(JFrame)上畫(huà)(也許有IDE可以手畫(huà)的),VC中呢,也可以畫(huà),但是注意的細(xì)節(jié)明顯比VB要多。其實(shí)手畫(huà)的過(guò)程,只是程序幫了我們,幫我們寫(xiě)了資源文件。這和用網(wǎng)頁(yè)設(shè)計(jì)工具是一樣的,我們只顧點(diǎn)鼠標(biāo),代碼則是網(wǎng)頁(yè)設(shè)計(jì)工具生成的了。同樣,其他編程也是這樣,這樣的好處是:一可以讓初學(xué)者很容易進(jìn)入狀態(tài) ,二是可以加快開(kāi)發(fā),可以少寫(xiě)n拖代碼。壞處是:不懂得底層機(jī)制,很多人寫(xiě)了n久的程序,也只能是比葫蘆畫(huà)瓢,寫(xiě)的程序界面還是自己學(xué)習(xí)時(shí)候的那種樣式,界面單調(diào)死板,開(kāi)發(fā)不出個(gè)性界面的。鑒于工具帶來(lái)的負(fù)面影響,我才給大家從基本說(shuō)起,雖然我們是用VC 6.0的環(huán)境,但是我還是手寫(xiě)資源來(lái)教大家定義資源文件,并不利用VC中IDE工具。如果大家資源文件寫(xiě)的很熟練的話,再用VC中的IDE工具,不用去看多余的書(shū),自然一看就知道是怎么回事,到時(shí)用起來(lái)就是得心應(yīng)手。說(shuō)實(shí)在話,如果不理解Windows的一些處理機(jī)制,上去直接去學(xué)習(xí)VC,我敢肯定學(xué)一段時(shí)間后,大部分人會(huì)頭昏腦脹,事倍功半,雖有收獲,然仍是皮毛,有放棄之想。好了廢話不多說(shuō)了,言歸正傳。
如上圖,是我這節(jié)要實(shí)現(xiàn)的效果,上面有菜單欄,其中點(diǎn)擊“查看”可以菜單子菜單項(xiàng),彈出的有禁用的菜單、分割線和灰化的菜單項(xiàng)。還有一個(gè)我自己做的圖標(biāo)(xhk字樣的,左上角)。單擊標(biāo)題欄上的圖標(biāo)可以彈出系統(tǒng)菜單,在有的程序,在窗口中擊鼠標(biāo)
右鍵,就可以彈出“快捷菜單”,這些菜單都屬于彈出式菜單。菜單中的菜單項(xiàng)有好幾種,從資源定義的角度來(lái)看,分割用的橫線也是一個(gè)菜單項(xiàng)。除橫線外其他菜單項(xiàng)可以供用戶選擇,也可以設(shè)置為“禁止”或“灰化”狀態(tài)暫時(shí)停用,如果上圖的?旖萱I,這個(gè)不用說(shuō)了,大家都知道是做什么用的。菜單項(xiàng)顯示的字符都是在資源文件中定義,至于如何來(lái)響應(yīng)按鍵則要在消息處理函數(shù)中添寫(xiě)代碼了,本節(jié)先不討論怎樣獲取這些消息和處理這些消息,這寫(xiě)留到下節(jié)中完成,本節(jié)先常用資源的定義格式說(shuō)下,先完成界面上的東東。
view source
print?
01 1. 菜單資源的定義
02 在資源腳本文件菜單中的定義格式是這樣的:
03 菜單 ID MENU [DISCARDABLE]
04 BEGIN
05 菜單項(xiàng)的定義
06 END
07 也可以這樣定義:
08 菜單 ID MENU [DISCARDABLE]
09 {
10 菜單項(xiàng)的定義
11 }
“菜單 ID MENU [DISCARDABLE]”可以用來(lái)制定菜單的ID值和內(nèi)存屬性,菜單ID可以是16位(二進(jìn)制位)的整數(shù),也可以
是字符串。但是如果ID位字符串的話,在程序中引用的時(shí)候就要用字符串指針代替菜單ID值,顯然這樣不太方便,所以在我們經(jīng)常
用整數(shù)來(lái)做菜單的ID值。MENU關(guān)鍵詞后面的DISCARDABLE是菜單的內(nèi)存屬性,表示菜單在不再使用的時(shí)候可以暫時(shí)從內(nèi)存中釋
放以節(jié)省內(nèi)存,是個(gè)可選屬性。菜單項(xiàng)的定義必須在BEGIN和END關(guān)鍵詞之內(nèi),這兩個(gè)關(guān)鍵詞也可以用{和}來(lái)代替。
菜單項(xiàng)目的定義方法有三類:
1. 常用的MENUITEM 菜單文字,命令I(lǐng)D [,選項(xiàng)列表]2. 分割線MENUITEM SEPARATOR3. 下級(jí)菜單和菜單定義的方式一樣POPUP 菜單文字 [,選項(xiàng)列表]BEGIN Item-definitionsEND
下面對(duì)這三類加以說(shuō)明
第一類:
菜單文字——顯示在菜單項(xiàng)中的字符串。像上圖中的“被禁用的菜單項(xiàng)”和“被灰化的菜單項(xiàng)”。
命令I(lǐng)D——不同菜單項(xiàng)的標(biāo)識(shí)。當(dāng)菜單被選中的時(shí)候,Windows會(huì)向窗口過(guò)程發(fā)送WM_COMMAND消息,消息的參數(shù)就是這
個(gè)命令I(lǐng)D。這個(gè)可以分辨用戶選中了哪個(gè)菜單項(xiàng),如果想讓兩個(gè)菜單項(xiàng)具有相同的功能,可以設(shè)置為相同的ID。
選項(xiàng)列表——用來(lái)形容菜單項(xiàng)的各種屬性,它可以是下列選項(xiàng):
CHECHKED——表示打上選定標(biāo)識(shí)。
GRAYED——表示菜單項(xiàng)是灰化的。
INACTIVE——表示菜單項(xiàng)是禁用的。
MENUBRREAK或MENUBARBREAK——表示將這個(gè)菜單項(xiàng)和以后的那個(gè)列到新的列中。
第二類:
菜單項(xiàng)之間的分割線,沒(méi)什么好說(shuō)的了。
第三類:
彈出式菜單,前文有解釋,這里說(shuō)下它的選項(xiàng):
GREAYED——灰化。
INACTIV——禁用。
HELP——表示本項(xiàng)和以后的菜單項(xiàng)是右對(duì)齊的,像上圖中的“幫助”菜單。
2.快捷鍵的定義
快捷鍵定義是很簡(jiǎn)單的,格式如下:
快捷鍵 ID ACCELERATORS
BEGIN
鍵名,命令I(lǐng)D[,類型][,選項(xiàng)]
END
BEGIN和END仍然可以用{和}替換。
鍵名——表示加速鍵對(duì)應(yīng)的按鍵,可以有3中定義方式:
“^字母”:表示Ctrl鍵加上字母鍵。
“字母”:表示字母,這時(shí)類型必須指明VIRTKEY。
數(shù)值:表示ASCII碼,這時(shí)類型必須為ASCII
命令I(lǐng)D——按下快捷鍵后,Windows就向程序發(fā)送此命令I(lǐng)D。
類型——用來(lái)指定鍵的定義方式,可以是VIRTKEY和ASCII,分別用來(lái)表示“鍵名”字段定義的是虛擬鍵還是ASCII碼。
選項(xiàng)——可以使Alt,Control或Shift中的單個(gè)或多個(gè),如果指定多個(gè),則中間用逗號(hào)隔開(kāi),表示快捷鍵是按鍵加上這些控制鍵的
組合鍵。
說(shuō)了這么多,考驗(yàn)我們的時(shí)候終于到了,下面我們就來(lái)寫(xiě)程序了。
兵馬未動(dòng),糧草先行,我們先來(lái)把界面定義好,定義一個(gè)MyMenu.rc的資源文件,內(nèi)容如下:
/**************MyMenu.rc Written By XHK 2009.3.3*************/
#include <resource.h>
#define ICO_MAIN 0X1000 //圖標(biāo)
#define IDM_MAIN 0X2000 //菜單
#define IDA_MAIN 0X2000 //快捷鍵
#define IDM_OPEN 0X4101 //“打開(kāi)”菜單項(xiàng)
#define IDM_INACTIVE 0X4201 //“被禁用的菜單項(xiàng)”
#define IDM_GRAYED 0X4202 //“灰化的菜單項(xiàng)”
#define IDM_HELP 0X4301 //“幫助”菜單項(xiàng)
/********The ico file of the window***********/
ICO_MAIN ICON "xhk.ico"
/*********************************************/
/**Next is the definition of the Menus**********/
IDM_MAIN menu discardable
{
popup "文件(&F)"
{
menuitem "打開(kāi)(&O)\tCtrl+Alt+O",IDM_OPEN
}
popup "查看(&V)"
{
menuitem "被禁用的菜單項(xiàng)",IDM_INACTIVE,INACTIVE
menuitem separator
menuitem "被灰化的菜單項(xiàng)",IDM_GRAYED,GRAYED
}
popup "幫助(&H)",HELP
{
menuitem "幫助主題(&H)\tF1",IDM_HELP
}
}
//下面定義快捷建
IDA_MAIN accelerators
{
VK_F1,IDM_HELP,VIRTKEY //F1
"O",IDM_OPEN,VIRTKEY,CONTROL,ALT //Ctrl+Alt+O
}
把我們用到的資源ico文件xhk.ico也和此文件放到同一目錄下,然后用資源編譯器rc.exe把MyMenu.rc編譯成MyMenu.res
下面該出兵了, 程序代碼,采用最精簡(jiǎn)的:
/***********MyMenu.c Written By XHK 2009.3.3************/
#include <windows.h>
#define ICO_MAIN 0X1000 //圖標(biāo)
#define IDM_MAIN 0X2000 //菜單
#define IDA_MIAN 0X2000 //快捷鍵
//回調(diào)函數(shù)
LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
switch(Msg)//處理消息過(guò)程,什么是消息,下節(jié)再講
{
case WM_DESTROY://響應(yīng)鼠標(biāo)單擊關(guān)閉按鈕事件
PostQuitMessage(0);//退出消息隊(duì)列,至于什么是消息隊(duì)列,下節(jié)說(shuō)
return 0;//退出函數(shù)
}
return DefWindowProc(hWnd,Msg,wParam,lParam);
}
//主函數(shù)
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int
nShowCmd)
{
char *cName = "myWindow";
char *cCaption = "帶目錄的窗口 - Made By XHK";
WNDCLASSEX wc;
HWND hWnd;
MSG Msg;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = NULL;
wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(ICO_MAIN));//載入圖標(biāo)
wc.hIconSm = NULL;
wc.hInstance = hInstance;
wc.lpfnWndProc = WinProc;
wc.lpszClassName =(LPSTR)cName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wc);
hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,cName,cCaption,WS_OVERLAPPEDWINDOW,
200,100,300,200,NULL,LoadMenu(hInstance,MAKEINTRESOURCE
(IDM_MAIN)),hInstance,NULL);
if(hWnd == NULL)
{//容錯(cuò)處理
MessageBox(NULL,"There's an Error","Error
Title",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
ShowWindow(hWnd,nShowCmd);//顯示窗口
UpdateWindow(hWnd);
while(GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);//翻譯消息
DispatchMessage(&Msg);//分派消息
}
return Msg.message;
}
把此編譯為MyMenu.obj,再和MyMenu.res進(jìn)行連接成MyMenu.exe,運(yùn)行看看和我截的圖一樣不。當(dāng)然你也可以定義自己想
要的界面,不過(guò)如果是初學(xué)者,可能沒(méi)有那么高的悟性吧,不急,慢慢來(lái),你會(huì)成為高手的。
本節(jié)又是長(zhǎng)篇大論,可能勞您心煩,然資源這方面的知識(shí),在網(wǎng)上也不太好找,想介紹簡(jiǎn)單點(diǎn),怕大家日后碰到?jīng)]見(jiàn)過(guò)而又
不好找,所以我盡量壓縮篇幅,依然是冗余漫長(zhǎng)。如果大家能夠看到這里,說(shuō)明您的耐力是很強(qiáng)的,是做大事者,相信您有如此
精神,一定會(huì)光宗耀祖,出人頭地,成就一番輝煌的事業(yè)的。