我先申明一下以免很多網友可能誤會我,在VC方面我也是剛脫貧還未致富,我寫這些文章就是因為我脫貧的時候太艱辛,希望大家能夠共同富裕。
上兩節我們講了一個簡單的MFC的程序,和消息映射宏的用法,我們這一節將講述資源文件,在將資源文件之前,我們看一下VC++的文件簡介,那我們看下面這一張圖。(來自《深入淺出MFC》侯大師)
這張圖清楚的描述了VC++的文件系統,他們是分為兩條線的一個是源文件,一個是資源文件。
先講第一條線—源文件,.c或者.cpp文件,在加入了頭文件.H文件後,就進入編譯器工具。
在講第二條線—資源文件,有最上面的三個工具,對話框工具編輯對話框文件.dlg,圖片編輯器編輯圖片(.bmp)、光標(.cur)、圖標(.ico)文件,字體編輯器編輯字體文件(.FON)(但是字體我沒有看到哪裡可以用,請高人指點)。所有的資源文件合成一個文件.RC文件,即資源文件,我們可以想到,這資源文件和我們的源文件怎麼關聯呢?那麼唯一相關聯的是.H文件,這個頭文件就是我們等一下要用的resource.h這個文件。
.c或者.cpp文件和頭文件編譯成.obj文件,而.rc文件和頭文件編譯成.res文件,.obj和庫文件和.res文件連結成可執行文件。
大家可能都看煩了,下面來上機創建一個資源文件,即菜單,為我們上兩節的程序加一個菜單。先打開我們的上兩節的程序的工程,然後,新建—〉在打開的對話框裡,我們自動會在文件選項卡裡,我們選擇Resource Script選項,在文件文本框中填寫一個文件名,自己起一個名字。那麼,我們就給我們的工程加了一個資源文件。在彈出的窗體,點擊右鍵,在談出的菜單中點擊Insert菜單---〉Menu--新建.,在彈出得菜單編輯器,我們雙擊主菜單,彈出的屬性框中,填寫菜單標題 如:我的菜單.回車後,我們就建立了一個菜單資源文件。我們可以看到,這個資源編輯器是WYSIWYG(What you see is what you get所見及所得)界面,我只簡單介紹一下:
資源編輯器創建的資源會自動的生成resource.h這個頭文件,我們剛才也講了,這個頭文件是資源文件和源代碼文件的一個橋梁,所以我們在源代碼例一定要#include “resource.h”,我們在創建子菜單的時候會發現,有一個資源ID號要你填寫(自己起一個名字,不要重復),那麼這個資源號就是我們在源代碼裡要引用的。
我們已經添加了菜單,我們運行程序,發現菜單並沒有出現,因為我們的菜單並沒有和我們的某一個窗體相關聯。那麼如何關聯?
我們回憶我們在寫SDK程序是我們是如何加菜單的。我們使用CreateWindow這個API函數來創建窗體,同時也關聯菜單(當然,也可以在注冊類裡關聯),我們知道MFC就是對API的封裝後,CreateWindow當然也被封裝了,他被封裝成了很多類的Create方法,其中就有CFrameWnd。我們在Sample 類裡繼承了CFrameWnd,我們右鍵點擊 Sample 構造函數裡的Create方法,在彈出的菜單裡點擊Goto Define of Create,在彈出的菜單點確定。我們來到了Create方法的定義
BOOL Create(LPCTSTR lpszClassName,//注冊類,MFC將注冊類封裝,我們填寫NULL
LPCTSTR lpszWindowName,//窗體名,窗體標題
DWORD dwStyle = WS_OVERLAPPEDWINDOW,//窗體風格
const RECT& rect = rectDefault,//窗體的矩形區域
CWnd* pParentWnd = NULL,
// 父窗體指針
LPCTSTR lpszMenuName = NULL, //窗體的菜單
DWORD dwExStyle = 0,//窗體擴展風格
CCreateContext* pContext = NULL);//框架窗體的視圖和文檔信息,一般填NULL
那我們看到前面兩個參數,沒有等號,說明他們是必選的參數,後面是可選的,在可選的參數裡面有一個窗體的菜單,他的類型是LPCTSTR,我們看這個類型有一個方法,分開看,首先L是long ,P是指針,CT是Const常量 ,STR是字符串,也就是一個指向常量字符串的長指針。我們打開MSDN看這個方法的參數如何填寫,在MSDN的索引中添Create回車,在彈出的主題中選擇CFrameWnd::Create,我們找到菜單這個參數的解釋
lpszMenuName
Identifies the name of the menu resource to be used with the window.
Use MAKEINTRESOURCE if the menu has an integer ID instead
of a string. This parameter can be NULL.
我們看到我們要使用MAKEINTRESOURCE這個宏來包裝我們的菜單ID,其他的參數我們用默認的。
Create(NULL,"MFC Window",WS_OVERLAPPEDWINDOW,rectDefault,NULL,MAKEINTRESOURCE(IDR_MENU1),0,NULL);
不要忘記在前面加上#include "resource.h",在運行程序就會發現菜單。全部程序如下(不包括資源文件)
#include <afxwin.h>
#include "resource.h"
class sample:public CFrameWnd
{
public:
sample()
{
Create(NULL,"MFC Window",WS_OVERLAPPEDWINDOW,rectDefault,NULL,MAKEINTRESOURCE(IDR_MENU1),0,NULL);
MessageBox("My MFC Window","CFrame constructor",MB_OK);
}
void OnLButtonDown(UINT,CPoint)//添加的消息處理函數
{
::MessageBox(NULL,"ddd","dd",MB_OK);
}
DECLARE_MESSAGE_MAP()//消息映射的申明
};
BEGIN_MESSAGE_MAP(sample,CFrameWnd)
//這個宏填寫兩個參數,一個子類,一個父類
ON_WM_LBUTTONDOWN()//左鍵按下的事件
END_MESSAGE_MAP()//結束宏
class App:public CWinApp
{
public:
BOOL InitInstance();
BOOL ExitInstance();
};
BOOL App::InitInstance()
{
MessageBox(0,"My MFC Window","InitInstance",MB_OK|MB_ICONASTERISK);
sample *obj;
obj=new sample;
m_pMainWnd=obj;
obj->ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}
BOOL App::ExitInstance()
{
MessageBox(0,"My Window","ExitInstance",MB_OK|MB_ICONHAND);
return TRUE;
}
App a;
我們這一節用菜單為例子,講解了資源文件,以及填寫參數的方法,下一節再見。