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