06资源.docx
- 文档编号:25202087
- 上传时间:2023-06-06
- 格式:DOCX
- 页数:32
- 大小:531.86KB
06资源.docx
《06资源.docx》由会员分享,可在线阅读,更多相关《06资源.docx(32页珍藏版)》请在冰豆网上搜索。
06资源
第6章资源2
6.1资源概述2
6.1.1资源的含义2
6.1.2资源头文件2
6.1.3资源描述文件4
6.2菜单资源4
6.2.1菜单资源的定义4
6.2.2编辑菜单6
6.2.3自定义菜单9
6.2.4菜单编辑器13
6.3快捷键表15
6.3.1快捷键资源定义15
6.3.2快捷键编辑器16
6.4图标17
6.4.1图标编辑器17
6.4.2图标资源定义18
6.5位图19
6.5.1位图资源定义20
6.5.2使用位图20
习题624
实验6资源25
第6章资源
在Windows应用程序中,除了文档中的数据之外,还需要一些用户界面所需要的特殊数据,例如菜单、图标、位图等等。
这些特殊数据一般驻留在计算机磁盘上,只有当应用程序需要时才会载入计算机内存,这种特殊数据就称为资源。
本章主要介绍如下内容:
●资源的含义;
●资源标识、资源头文件和资源描述文件;
●菜单资源的定义和使用;
●快捷键表的定义和使用;
●图标和位图的定义和使用
6.1资源概述
6.1.1资源的含义
几乎所有的Windows应用程序的用户界面(UserInterface,UI)都需要在窗口中出现菜单、图标、对话框、光标、快捷键、工具条等特殊数据。
但是,同一个应用程序在不同的应用环境中对这些特殊数据的要求是各不相同的。
例如,一款在全球范围内发布的软件,其UI数据在不同国家就应该有不同的版本,适应不同国家人民对语言和风格的需要。
把这些UI数据统统编写在应用程序中是不合适的,因为应用程序运行时可能只用到多套数据中的某一套,甚至是部分数据。
也就是说,应用程序只把需要的数据载入程序,而那些暂时不用的就让它们仍然驻留在计算机磁盘中备用。
所以,对于这些特殊数据应该用不同的方式制作和保存,使得它们具有上述特点。
Windows把这种类型的数据称为资源。
资源就是一种可供Windows应用程序利用,可单独编辑,并可动态加载的数据。
为了产生资源数据,要求程序员提供两种文本文件:
资源头文件和资源描述文件。
6.1.2资源头文件
在Windows应用程序的用户界面中,有各种各样不同类型的资源。
这些不同类型的资源必须有一个标识符,这些标识符就是用一些符号表示的编号,标识符定义在资源头文件Resource.h中。
定义标识符的格式如下:
#define资源标识符编号
为了对不同类型的资源加以区别,所以必须为资源命名标识符。
通常,这些标识符要放在头文件Resource.h中。
为提高可读性,资源标识符遵循一定的命名规则。
例如:
IDR_MAINFRAME表示主框架窗口里面所使用的资源,IDD_ABOUTBOX表示选择窗口菜单栏【帮助】|【关于】后弹出的“关于对话框”。
表6-1显示了一些常用的资源标识符前缀。
表6-1常用的资源标识符前缀
标识符前缀
说明
标识符前缀
说明
IDD_
对话框资源前缀
IDS_
字符串前缀
IDR_
主菜单、工具栏、图标前缀
IDP_
消息框提示字符串前缀
IDC_
控件、光标前缀
ID_
菜单命令项前缀
那么如何找到资源头文件Resource.h呢?
建立Windows应用程序框架以后,在文件视图(FileView)选项卡中,选择HeaderFiles前面的加号按钮,双击Resource.h文件夹,在代码窗口中显示的就是资源头文件Resource.h的代码,见图6-1所示。
VC++提供的应用程序向导MFCAppWizard自动在Resource.h提供了下列资源的定义。
#defineIDD_ABOUTBOX100
#defineIDR_MAINFRAME128
#defineIDR_EXP6_1TYPE129
第一行定义了“关于对话框资”资源标识符为IDD_ABOUTBOX,编号为100;第二行定义了主框架窗口里面所使用的资源标识符IDR_MAINFRAME,编号为128;第三行定义了文档图标资源标识符IDR_EXP6_1TYPE,编号是129。
除了这三行预先定义好的资源标识符之外,程序员可以根据应用的需要,定义程序要使用的资源标识符及编号。
由于要区别不同资源,所有资源标识符的编号必须区别开来,即不能有相同编号。
例如,程序员可以为应用程序添加一个对话框,自定义这个对话框资源标识符为IDD_MY_DIALOG,其编号为130。
在Resource.h文件中添加下列代码:
#defineIDD_MY_DIALOG130
图6-1资源头文件Resource.h
6.1.3资源描述文件
为了方便在MFC应用程序中使用资源,MFC允许在资源描述文件中,以一个统一的标识符来标识主框架窗口所需的各种资源,例如:
菜单栏、工具栏、图标、光标、位图等。
这样,使用一个标识符就可以把主框架窗口所需要的资源一起装载到应用程序中。
资源描述文件描述了各种资源的属性,文件名为工程名.rc,rc作为资源描述文件的后缀名。
例如,建立的工程名为exp6_1.rc,存放的位置在工程名文件夹的里面。
打开该文件的方式是,右键点击exp6_1.rc,在弹出的下拉选项中选【打开方式】|【记事本】。
对于一般的资源数据来说,例如:
菜单栏、对话框等,只用资源描述文件来描述其资源具有的属性就可以了。
对于特殊的资源数据来说,例如:
图标、光标、位图等这类图形,则需要用另外的工具进行制作成单独的文件并保存在工程名文件夹下的res文件夹中,在资源描述文件中只需要指明这些资源的标识符和存贮位置(路径),见图6-2。
在res文件夹中预先放置了4个资源文件,分别是MFC应用程序的图标文件、附加资源的脚本文件、文档图标文件和工具条位图文件。
图6-2res文件夹包含的资源文件
6.2菜单资源
菜单是Windows应用程序界面的重要组成部分。
菜单可以让用户直观地掌握和使用应用程序所提供的各种功能。
因此,一个菜单栏的设计质量的高低,会直接影响到一个应用程序设计的质量。
6.2.1菜单资源的定义
一个菜单是由三个层次组成的,分别是菜单栏、菜单项、菜单命令选项。
其中菜单栏包括多个菜单项,一个菜单项包含多个菜单命令选项,菜单命令选项能产生命令消息并激活程序某些功能。
1.菜单栏的定义
在资源描述文件中,关于菜单栏的定义语句格式为:
主框架窗口资源标识符MENU[,载入特性选项]
其中,MENU是定义菜单的关键字。
为了满足应用程序不同的需要,在定义菜单时,尅在关键字MENU后面使用不同的载入特性选项,用来声明菜单被载入时特性。
菜单栏的加载特性选项见表6-2。
表6-2菜单栏可选的加载特性选项
特性选项
说明
DISCARDABLE
当应用程序不再需要时,应用程序可丢弃该菜单栏
FIXED
菜单栏保存在内存中固定的位置
LOADONCALL
需要时才加载菜单栏
MOVEABLE
菜单栏在内存中可以移动位置
PRELOAD
立即加载菜单
菜单定义语句后面是一系列用BEGIN开头,END结束的语句块。
每个语句块代表一个菜单项。
最外层的BEGIN-END语句块描述的是菜单栏。
2.菜单项的定义
菜单栏的每个项就是一个菜单项。
菜单项为弹出式菜单,定义菜单项时要在菜单项标题之前,使用关键字POPUP表示弹出式,用&定义菜单项的热键。
其定义的格式是:
POPUP“子菜单标题”[,选项]
在定义菜单项时,也可以设置一些选项。
常用的菜单项的选项见表6-3。
表6-3菜单项的常用选项
选项
说明
MENUBARBREAK
菜单项的纵向分隔标志
CHECKED
使菜单项带有选中标志
INACTIVE
使菜单项无效
GRAYED
使菜单项无效,并且菜单项文字变为灰色
3.菜单命令选项
菜单中可以向应用程序发出消息的选项叫做菜单命令选项,每个菜单命令选项必须定义一个唯一的标识。
使用关键字MENUITEM来定义一个菜单命令选项,其格式为:
MEMUITEM“菜单命令选项名称”,菜单命令选项标识符(ID)[,选项]
菜单命令选项标识符是以IDD_作为前缀,选项与表6-3中的菜单项的常用选项相同。
在应用程序运行中,当程序用户选中任何一个菜单命令选项时,都会发出一个命令消息WM_COMMAND。
这个消息对于所有菜单命令选项来说都是相同的,所以应用程序在收到这个消息后,必须根据菜单命令选项标识符(ID)来找到该消息来自于哪个菜单项。
因此,在定义菜单命令选项消息映射时,其参数中要包含菜单命令选项的ID和消息响应函数这两项内容。
所以,菜单命令选项的消息映射宏的格式是:
ON_COMMAND(菜单命令选项的ID,消息响应函数名)
在菜单命令选项的中,还可以用一个特殊菜单项SEPARATOR。
这个菜单命令选项不产生任何消息,其作用只是在菜单上形成一条横向的分割线,以便于对菜单项进行分类,见图6-3。
图6-3资源描述文件中的菜单脚本与窗口运行后菜单的对照
6.2.2编辑菜单
在使用MFCAppWizard生成应用程序框架时,自动提供了一个菜单。
用户不需要编写菜单资源描述文件,而是在现有的菜单资源描述文件基础上进行修改,形成满足自己要求的菜单。
因此,程序员并不是从头到尾来编写资源描述文件中的菜单定义部分,而是在现有菜单定义的基础上对资源描述文件进行修改,形成满足应用要求的菜单。
下面通过一个例子来分析如何编辑菜单。
例6-1用MFCAppWizard创建一个应用程序,在编辑菜单的下拉子菜单中添加一个选项“显示”,当用户选中这项后,窗口中显示“显示”的字符串。
(1)用MFCAppWizard生成工程名为exp6_1的单文档应用程序框架。
(2)直接打开工程项目名的文件夹,以记事本的方式打开exp6_1.rc,找到菜单定义部分,在编辑菜单POPUP“编辑(&E)”中的“粘贴”下面一行添加下列代码,然后保存exp6_1.rc文件。
MENUITEM"显示(&S)\tCtrl+S",ID_EDIT_SHOW
这行代码意味着给“编辑”菜单项添加一个菜单命令选项“显示”,其ID是ID_EDIT_SHOW,热键是‘S’。
这个自定义的资源标识符需要在头文件中定义。
(3)在工程管理窗口中选FileView,双击HeaderFiles下的资源头文件Resource.h,在其中定义新添加的菜单命令选项的标识ID。
#defineID_EDIT_SHOW130
(4)在文档类的声明中声明一个字符指针,记录在视图类窗口中出现的字符串。
右键文档类选“添加成员变量”,填写类型为char*,变量名为m_str。
char*m_str;
(5)在文档类的构造函数中初始化m_str为空串。
在CExp6_1Doc中的CExp6_1Doc函数中添加m_str="";
(6)消息映射中添加宏指定“显示”菜单命令子项ID与消息响应函数的对应关系。
在工程管理窗口中选FileView,双击SourceFiles下的视图类的源文件exp6_1View.cpp,在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间添加下列ON_COMMAND。
OnShow函数是ID_EDIT_SHOW对应的消息响应函数,这个函数应该在视图类的声明文件中声明函数原型。
BEGIN_MESSAGE_MAP(CExp6_1View,CView)
ON_COMMAND(ID_EDIT_SHOW,OnShow)
END_MESSAGE_MAP()
(7)在工程管理窗口中选FileView,双击HeaderFiles下的视图类的声明文件exp6_1View.h,在DECLARE_MESSAGE_MAP()的下一行声明消息函数OnShow的原型。
afx_msg表示消息响应函数。
classCExp6_1View:
publicCView
{…
protected:
DECLARE_MESSAGE_MAP()
afx_msgvoidOnShow();//添加的函数原型声明
};
如果双击视图类的OnShow函数,弹出一个不能找到定义的警告框,因此需要定义该函数。
(8)双击SourceFiles下的视图类的源文件exp6_1View.cpp,在文件尾部添加下列代码来定义OnShow函数。
本例使用CClientDC类的对象,调用TextOut函数来输出字符串。
voidCExp6_1View:
:
OnShow()
{
CExp6_1Doc*pDoc=GetDocument();
CClientDCdc(this);
pDoc->m_str="显示";
dc.TextOut(50,50,pDoc->m_str);
}
例6-1程序运行结果见图6-4。
程序运行以后用鼠标点击编辑菜单,下拉菜单栏中出现“显示”这个菜单命令选项,见图6-4(a)。
鼠标点击这个菜单命令选项后,出现图6-4(b),在窗口中出现显示的字符串“显示”。
(a)(b)
图6-4例6-1程序运行结果
与鼠标消息、键盘消息不同的是,点击菜单命令选项产生的消息WM_COMMAND并没有在类向导的消息列表中出现。
因此,无法通过类向导添加菜单命令选项的消息响应函数。
点击任何一个菜单命令选项产生的消息WM_COMMAND是一样的,只能通过在视图类的源文件中添加ON_COMMAND宏来指定菜单命令选项ID和消息响应函数一一对应的关系。
在视图类头文件中声明消息响应函数原型,在视图类源文件定义函数。
鼠标、键盘等消息通过类向导添加的消息响应函数,在视图类的源文件和头文件中自动添加宏和消息响应函数原型,自动指定了消息与响应函数一一对应的关系。
凡是通过类向导添加的消息响应函数,宏和消息函数原型的声明都是以灰色代码出现在相应的文件中,并且在视图类的源文件中自动出现消息响应函数的定义。
而菜单命令消息通过手写添加的宏和消息函数原型的声明,都是以黑色代码出现在相应文件中,见图6-5。
(a)在视图类的源文件中(b)在视图类的声明文件中
图6-5类向导添加的灰色代码和手写的黑色代码
6.2.3自定义菜单
程序员也可以根据用户需要,完全定义自己的菜单,例子6-2说明了它的创建和使用方法。
例6-2编写一个Windows应用程序,在窗口用户区出现一个矩形,使用菜单“图形|变圆形”命令选项可以把原来的矩形变成圆形,使用菜单“图形|变矩形”命令选项可以把圆形变成矩形。
(1)用MFCAppWizard生成工程名为exp6_2的单文档应用程序框架。
(2)双击FileView中HeaderFiles文件夹下的资源头文件Resource.h,定义如下标识。
系统预先提供的菜单是放在IDR_MAINFRAME中,而自定义菜单假设放在IDR_MAINFRAME1中,需要对该标识和两个菜单命令选项标识进行定义
#defineIDR_MAINFRAME1130
#defineID_CHANGE_ELLIPSE131
#defineID_CHANGE_RECTANGLE132
(3)在资源描述文件中用新的菜单定义脚本代替原有菜单脚本。
在工程名文件夹下以记事本方式打开exp6_2.rc文件,删除原来菜单定义脚本,用输入下列菜单定义代码,最后保存文件。
#include"resource.h"
IDR_MAINFRAME1MENUPRELOADDISCARDABLE
BEGIN
POPUP"图形(&F)"
BEGIN
MENUITEM"变圆形($E)\tCrl+E",ID_CHANGE_ELLIPSE
MENUITEM"变矩形(&R)...\tCtrl+R",ID_CHANGE_RECTANGLE
END
END
(4)修改应用程序类CExp6_2App类的InitInstance函数,加载上面的资源。
只需要将CSingleDocTemplate构造函数中第一个参数由原来的IDR_MAINFRAME改为IDR_MAINFRAME1即可。
BOOLCExp6_2App:
:
InitInstance()
{….
pDocTemplate=newCSingleDocTemplate(
IDR_MAINFRAME1,//加载资源
RUNTIME_CLASS(CExp6_2Doc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CExp6_2View));
}
修改后运行程序,发现程序窗口使用的是新设计的菜单,见图6-6。
由于还没有编写消息响应函数,所以两个菜单命令选项为灰色以表示无法使用。
图6-6自定义的新菜单
(5)在文档类中添加矩形类对象m_Rect。
右键文档类选“添加成员变量”,填写类型为CRect,变量名为m_Rect。
在文档类的构造函数中对矩形类对象m_Rect进行初始化。
CExp6_2Doc:
:
CExp6_2Doc()
{
m_Rect.left=50;
m_Rect.top=50;
m_Rect.right=100;
m_Rect.bottom=100;
}
(6)在视图类的实现文件中声明宏。
双击FileViews中SouceFiles文件夹下的exp6_2View.cpp文件,在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间输入两个On_COMMAND宏的定义,指定两个菜单命令选项的资源ID与消息响应函数一一对应的关系。
BEGIN_MESSAGE_MAP(CExp6_2View,CView)
ON_COMMAND(ID_CHANGE_ELLIPSE,OnEllipse)
ON_COMMAND(ID_CHANGE_RECTANGLE,OnRectangle)
END_MESSAGE_MAP()
(7)在视图类的声明文件中对两个菜单命令选项的消息响应函数进行声明。
双击FileViews中HeaderFiles文件夹下的exp6_2View.h文件,在DECLARE_MESSAGE_MAP()下面一行输入两个消息响应函数的声明。
classCExp6_2View:
publicCView
{…
protected:
DECLARE_MESSAGE_MAP()
afx_msgvoidOnEllipse();//添加的消息响应函数
afx_msgvoidOnRectangle();
};
(8)再次打开视图类的源文件exp6_2View.cpp,添加一个int变量type,表示绘图类型。
在视图类的构造函数中初始化该变量值为2。
添加两个消息响应函数的函数体。
CExp6_2View:
:
CExp6_2View()
{type=2;}//类型为2代表矩形
voidCExp6_2View:
:
OnEllipse()
{
CExp6_2Doc*pDoc=GetDocument();
type=1;//类型为1代表圆形
InvalidateRect(NULL,TRUE);//刷新,参数TRUE表示不保留以前图形
}
voidCExp6_2View:
:
OnRectangle()
{
CExp6_2Doc*pDoc=GetDocument();
type=2;
InvalidateRect(NULL,TRUE);
}
(9)在OnDraw()函数体中添加下列代码,根据类型type来绘制图形。
if(type==1)
pDC->Ellipse(pDoc->m_Rect);
elseif(type==2)
pDC->Rectangle(pDoc->m_Rect);
运行程序以后的结果如图6-7(a),编写了消息响应函数以后,两个菜单命令选项才变为黑色。
用鼠标点击“图形|变圆形”命令选项后出现图6-7(b)。
本例不能像例6-1那样把绘制图形的代码放在消息响应函数中,否则图形会重叠出现在窗口中,这是因为没有使用刷新方法InvalidateRect()。
图6-7(a)例6-2程序运行结果图6-7(b)点击“变圆形”后的结果
6.2.4菜单编辑器
从前两个例题可以看出,无论是编辑菜单还是自定义菜单,都需要手动编写宏声明、函数原型声明、消息响应函数定义。
有没有一种更直观的编辑工具来帮助我们制作菜单呢?
答案是有的,这就是VisualC++提供的可视化菜单编辑器。
在开发环境的工程窗口中点击第二个选项卡ResourceView,双击Menu文件夹图标下面的IDR_MAINFRAME,即可打开图6-8所示的菜单编辑器,接下来直接在菜单编辑器上对菜单进行编辑和修改。
图6-8菜单编辑器
在菜单编辑器中,双击某个菜单项,打开该菜单项的属性编辑窗口,可以设置菜单项的标题,见图6-9。
双击菜单项最下面的空行,打开一个菜单命令选项的属性对话框窗口,在其中可以设置菜单命令选项的标题、资源标识符(ID)等内容,见图6-10。
可以通过这种方式为菜单项添加一个新的菜单命令选项,以代替在资源描述文件中输入脚本代码。
图6-9使用菜单编辑器编辑菜单项
图6-10使用菜单编辑器编辑菜单命令选项
例6-3使用菜单编辑器来重新完成例6-1所要求的菜单。
(1)用MFCAppWizard生成工程名为exp6_3的单文档应用程序框架。
(2)选ResourceView,双击Menu文件夹图标下面的IDR_MAINFRAME,在菜单编辑器的“编辑”菜单最后一行双击,在弹出的菜单命令选项属性对话框中填写Caption为显示,ID中填写ID_EDIT_SHOW,如图6-10。
单击“文件|保存”,保存后在头文件Resource.h自动添加菜单命令选项资源ID的定义。
后面的步骤类似于例6-1中的步骤(4)~步骤(8)。
运行程序以后的结果如图6-11。
图6-11(a)程序运行结果图6-11(b)点击“显示”后的结果
图6-11例6-3程序运行结果
6.3快捷键表
6.3.1快捷键资源定义
在菜单命令选项中除了菜单选项标题外还有快捷键,快捷键总是和菜单选项配合使用的。
在资源描述文件中,用快捷键表来定义菜单的快捷键。
在资源描述文件中定义快捷键表的语句格式为:
资源标识符ACCELERATORS[载入选项]
其中,ACCELERATORS是定义快捷键的关键字。
这个定义语句的后面是一对BEGIN-END语句块,这个语句块汇总定义了各个菜单命令选项的快捷键。
定义语句块的格式为:
键的字符或虚拟码,对应菜单命令选项的资源标识符,VIRTKEY,其他键
其中,键的字符是指菜单命令选项的快捷键字符,虚拟码是指快捷键字符的虚拟码,VIRTKEY是虚拟键的关键字,其他键与快捷键的字符同时按下去。
例如,例6-2程序的菜单命令选项的快捷键字符已经在菜单定义脚本中指定,但并没有体现快捷键作用。
因此,需要在资源描述文件中找到快捷键定义部分,添加下列代码。
IDR_MAINFRAME1ACCELERATORSPRELOADMOVEABLEPURE
BEGIN
"E",ID_CHANGE_ELLIPSE,VIRTKEY,CONTROL
"R",ID_CHANGE_RECTANGLE,VIRTKEY,CONTROL
EN
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 06 资源