第11单元资源 第11单元资源 本单元教学目标 介绍资源的概念以及图标、位图、菜单、工具栏和状态栏等资源的编程方法。 学习要求 掌握 Developer Studio的各种资源编辑器的用法,能在应用程序中添加图标、位图、菜 单和工具条等资源并进行相应的编程工作。 授课內容 除了文档对象的数据成员和变量外,典型的 Windows应用程序还会用到一些称为资源 的数据,包括确定应用程序的用户界面的一些文本和图形,如菜单、加速键、位图、光标、 图标、对话框、控件、字符串和工具栏等。 当 Windows调用一个应用程序时就从程序的可执行文件中读取程序代码和初始化数 据,并将其复制到分配的内存中。然而,除了一些特殊情况,资源数据仍保留在硬盘上的可 执行文件中。实际上,当应用程序创建窗口、显示对话框或装载位图时,才从EXE文件或 DLL文件中读取相应的资源数据 令 Developer Studio提供了几种资源编辑器,可以通过它们创建或编辑应用项目的资源数 本单元介绍在应用程序中首先会遇到的几种界面元素,包括图标、位图、菜单、工具栏、 加速键和状态栏。对话框和控件分别放在第14单元和第15单元讨论。 111资源脚本文件和资源头文件 项目在一个扩展名为rc的文件中定义资源,资源文件常与项目同名。资源文件是文本 文件,可用文本编辑器编辑阅读,然而更方便的方法是通过 Developer Studio的各种资源编 辑器进行编辑。在资源文件中定义了菜单脚本和字符串等内容,但不包含位图和图标的图形 数据。图形资源保存在单独的文件中,在资源文件中只保存了它们的名字和位置 在项目中,资源通过资源标识符加以区别。通常在使用资源编辑器建立资源或将一外部 资源插入项目时为资源命名标识符。标识符的命名有一定的规则,如 IDR MAINFRAME代 表主框架窗口的菜单和工具栏, IDD ABOUTBOX代表 About(关于)对话框。通常将一个 项目中所有的资源标识符均放在头文件 Resource. h中定义,因此在源代码文件中要包含此头 文件。下面列出一些MFC使用的资源标识符前缀: 标识符前缀 说明 主菜单、工具栏、加速键表和应用程序图标
第 11 单元 资源 - 215 - 第 11 单元 资源 本单元教学目标 介绍资源的概念以及图标、位图、菜单、工具栏和状态栏等资源的编程方法。 学习要求 掌握 Developer Studio 的各种资源编辑器的用法,能在应用程序中添加图标、位图、菜 单和工具条等资源并进行相应的编程工作。 授课内容 除了文档对象的数据成员和变量外,典型的 Windows 应用程序还会用到一些称为资源 的数据,包括确定应用程序的用户界面的一些文本和图形,如菜单、加速键、位图、光标、 图标、对话框、控件、字符串和工具栏等。 当 Windows 调用一个应用程序时就从程序的可执行文件中读取程序代码和初始化数 据,并将其复制到分配的内存中。然而,除了一些特殊情况,资源数据仍保留在硬盘上的可 执行文件中。实际上,当应用程序创建窗口、显示对话框或装载位图时,才从 EXE 文件或 DLL 文件中读取相应的资源数据。 Developer Studio 提供了几种资源编辑器,可以通过它们创建或编辑应用项目的资源数 据。本单元介绍在应用程序中首先会遇到的几种界面元素,包括图标、位图、菜单、工具栏、 加速键和状态栏。对话框和控件分别放在第 14 单元和第 15 单元讨论。 11.1 资源脚本文件和资源头文件 项目在一个扩展名为.rc 的文件中定义资源,资源文件常与项目同名。资源文件是文本 文件,可用文本编辑器编辑阅读,然而更方便的方法是通过 Developer Studio 的各种资源编 辑器进行编辑。在资源文件中定义了菜单脚本和字符串等内容,但不包含位图和图标的图形 数据。图形资源保存在单独的文件中,在资源文件中只保存了它们的名字和位置。 在项目中,资源通过资源标识符加以区别。通常在使用资源编辑器建立资源或将一外部 资源插入项目时为资源命名标识符。标识符的命名有一定的规则,如 IDR_MAINFRAME 代 表主框架窗口的菜单和工具栏,IDD_ABOUTBOX 代表 About(关于)对话框。通常将一个 项目中所有的资源标识符均放在头文件 Resource.h 中定义,因此在源代码文件中要包含此头 文件。下面列出一些 MFC 使用的资源标识符前缀: 标识符前缀 说明 IDR_ 主菜单、工具栏、加速键表和应用程序图标
第11单元资源 216 对话框 控件和光标 字符串 消息框提示字符串 菜单命令 资源编译器是 Developer Studio的一个独立组成部分,负责将程序的文本和图形资源编 译成目标文件。这些目标文件将和源程序编译生成的目标文件一起连接为可执行文件。 112图标(Ion) 在 Windows中,每个文件均有一个图标,通过双击该图标可打开该文件。作为应用程 序的图标,应该醒目、美观,并能与程序的功能有所关联。但在前几单元中,我们没有对程 序的图标做相应处理,因此所有程序均使用了MFC缺省的程序图标,缺乏特色。下面介绍 在应用程序中添加图标的方法。 向程序中添加资源要经过经过如下步骤:如果项目中还没有资源文件,则首先应为项目 建立一个资源文件。然后将资源加入项目,并在程序中引用资源。向项目中添加资源可使用 Developer Studio的 Insert/Resource….菜单选项,选择相应的资源类型并加入新资源(参看 11.8:“向项目中添加资源”) 在应用程序中引用资源,首先要在程序首部添加文件包含命令 # include“ resource.h” 该头文件中包含了项目中所有资源的标识符定义(由资源编辑器自动插入) 与设定图标有关的代码通常放在应用程序类的成员函数 InitInstance()中。首先使用 CWinApp类的成员函数 HICON CWinApp: Loadlcon(LPCTSTR lpszResourceName)const HICON CWinApp: Loadlcon (UINT nlDResource)const 载入图标。这里HCON为图标句柄类型,参数 lpszResourceName为图标的名称, nIDResource 为图标的ID。该函数的返回值即该图标的句柄。 然后调用CWnd类的成员函数 HICON CWnd: Setlcon(HICON hlcon, BOOL bBiglcon 安装图标。其中参数 bBiglcon确定安装的是何种图标。图标有两种:大图标为32×32点阵 小图标为16×16点阵。使用哪个图标是由操作系统的设置决定的,作为应用程序,应该同 时提供两种图标。该函数的返回值为窗口原来图标的句柄。 1例11-为例9-3的吹泡泡程序添加一标识符为 IDI MAINICON的图标(该图标应已 按11.8:“向项目中添加资源”中的方法建立并加入项目) 说明:建立项目的方法见98:“用 Visual c艹+集成开发环境开发win32应用程序”。 程序:在例9-3程序前面添加一文件包含命令
第 11 单元 资源 - 216 - IDD_ 对话框 IDC_ 控件和光标 IDS_ 字符串 IDP_ 消息框提示字符串 ID_ 菜单命令 资源编译器是 Developer Studio 的一个独立组成部分,负责将程序的文本和图形资源编 译成目标文件。这些目标文件将和源程序编译生成的目标文件一起连接为可执行文件。 11.2 图标(Icon) 在 Windows 中,每个文件均有一个图标,通过双击该图标可打开该文件。作为应用程 序的图标,应该醒目、美观,并能与程序的功能有所关联。但在前几单元中,我们没有对程 序的图标做相应处理,因此所有程序均使用了 MFC 缺省的程序图标,缺乏特色。下面介绍 在应用程序中添加图标的方法。 向程序中添加资源要经过经过如下步骤:如果项目中还没有资源文件,则首先应为项目 建立一个资源文件。然后将资源加入项目,并在程序中引用资源。向项目中添加资源可使用 Developer Studio 的 Insert/Resource…菜单选项,选择相应的资源类型并加入新资源(参看 11.8:“向项目中添加资源”)。 在应用程序中引用资源,首先要在程序首部添加文件包含命令 #include “resource.h” 该头文件中包含了项目中所有资源的标识符定义(由资源编辑器自动插入)。 与设定图标有关的代码通常放在应用程序类的成员函数 InitInstance()中。首先使用 CWinApp 类的成员函数 HICON CWinApp::LoadIcon(LPCTSTR lpszResourceName)const; HICON CWinApp::LoadIcon(UINT nIDResource)const; 载入图标。这里 HICON 为图标句柄类型,参数 lpszResourceName 为图标的名称,nIDResource 为图标的 ID。该函数的返回值即该图标的句柄。 然后调用 CWnd 类的成员函数 HICON CWnd::SetIcon(HICON hIcon, BOOL bBigIcon); 安装图标。其中参数 bBigIcon 确定安装的是何种图标。图标有两种:大图标为 32×32 点阵, 小图标为 16×16 点阵。使用哪个图标是由操作系统的设置决定的,作为应用程序,应该同 时提供两种图标。该函数的返回值为窗口原来图标的句柄。 [例 11-1] 为例 9-3 的吹泡泡程序添加一标识符为 IDI_MAINICON 的图标(该图标应已 按 11.8:“向项目中添加资源”中的方法建立并加入项目)。 说 明:建立项目的方法见 9.8:“用 Visual C++集成开发环境开发 Win32 应用程序”。 程 序:在例 9-3 程序前面添加一文件包含命令:
第11单元资源 # include” resource.h” 并将 CMy App: InitInstance()函数修改为: BOOL CMyApp: InitInstanceO hicon hIcon hIcon= Loadicon( IDI MAINICON);∥/载入图标 CMy Wnd *pFrame new CMyWnd pFrame->Create(0,T("吹泡泡程序")) Frame-> SemIcon( hIcon,TRUE);//设置大图标 Frame- SemIcon( hIcon, FALSE);//设置小图标 frame->ShowWindow(m nCmdShow) this->m pMainWnd pframe return TRUE 分析:同一图标有大、小两种尺寸,均用同一标识符表示,同时载入程序,但要分 别安装 113位图(Bmap) 所谓位图,即点阵式图象。与图标不同的是位图的尺寸非常灵活,可以任意设置。实际 上,应用程序通常使用两种位图:一种可由位图编辑器(参看11.9.2:“位图编辑器”)生 成、编辑,通常尺寸较小,颜色种类数较少(最多256色)。这类位图往往用作应用程序中 的某种标志或小幅图象。另一种位图就是通常的图象文件,可通过专用的图象工具软件生成 也可通过扫描仪等设备直接将照片、图片等输入计算机,可以是真彩图象。 Developer Studio 可将BMP格式的图象文件作为资源加入项目 在MFC中,用 CBitmap类对象存放位图的参数。 CBitmap类有以下几个重要成员函数: 1.载入位图资源: BOOL Load Bitmap( LPCTSTR lpszResourceName ) BOOL Load Bitmap( UINT nlDResource ) 其中参数 lpszResourceName和 nIDResource分别为资源名称和标识符。装载成功时该函数返 回非零值,否则返回零。 2.读位图信息 int Get Bitmap( BITMAP* pBitMap ) 其中参数 bItmAp为一 BITMAP结构体对象的地址。 BITMAP结构体类型用于存放位图有 关信息 typedef struct tag BITMAP
第 11 单元 资源 - 217 - #include ”resource.h” 并将 CMyApp::InitInstance()函数修改为: BOOL CMyApp::InitInstance() { HICON hIcon; hIcon = LoadIcon(IDI_MAINICON); // 载入图标 CMyWnd *pFrame = new CMyWnd; pFrame->Create(0,_T("吹泡泡程序")); pFrame->SetIcon(hIcon, TRUE); // 设置大图标 pFrame->SetIcon(hIcon, FALSE); // 设置小图标 pFrame->ShowWindow(m_nCmdShow); this->m_pMainWnd = pFrame; return TRUE; } 分 析:同一图标有大、小两种尺寸,均用同一标识符表示,同时载入程序,但要分 别安装。 11.3 位图(Bitmap) 所谓位图,即点阵式图象。与图标不同的是位图的尺寸非常灵活,可以任意设置。实际 上,应用程序通常使用两种位图:一种可由位图编辑器(参看 11.9.2:“位图编辑器”)生 成、编辑,通常尺寸较小,颜色种类数较少(最多 256 色)。这类位图往往用作应用程序中 的某种标志或小幅图象。另一种位图就是通常的图象文件,可通过专用的图象工具软件生成, 也可通过扫描仪等设备直接将照片、图片等输入计算机,可以是真彩图象。Developer Studio 可将.BMP 格式的图象文件作为资源加入项目。 在 MFC 中,用 CBitmap 类对象存放位图的参数。CBitmap 类有以下几个重要成员函数: 1.载入位图资源: BOOL LoadBitmap( LPCTSTR lpszResourceName ); BOOL LoadBitmap( UINT nIDResource ); 其中参数 lpszResourceName 和 nIDResource 分别为资源名称和标识符。装载成功时该函数返 回非零值,否则返回零。 2.读位图信息 int GetBitmap( BITMAP* pBitMap ); 其中参数 pBitMap 为一 BITMAP 结构体对象的地址。BITMAP 结构体类型用于存放位图有 关信息: typedef struct tagBITMAP {
第11单元资源 bm Type ∥位图类型(0) bm Wid ∥位图宽 int bmHeight ∥位图高 nt bmWidthBytes,∥位图每行的字节数 bYte bm Planes ∥位平面数 bYte bm BitsPixel,∥每点字节数 LPⅤ oid bm bits; ∥位图数据指针 1 BITMAP 与一般的图形相比,位图的显示过程稍复杂些。首先应建立一合适的内存设备环境 CDC MemDC, MemDC. Create CompatibleDC(NULI 并将位图选入该设备环境: MemDC. SelectObject(&m Bitmap 然后可用CDC类的 Bitblt()成员函数从内存设备环境中将位图复制到指定设备(如窗口 或打印机)。 BitBlt()函数的原型为: BOOL BitBlt( int x, int y, int n Width, int nHeight, CDC* pSrcDC int xSrc, int ySrc, DWORD dwRop); 其中参数x,y为目标区左上角坐标, nwidth和 nHeight分别为目标区的宽度和高度(逻 辑坐标), pSrcDC为内存设备指针,xSrc和ySre为原图中欲显示块左上角坐标, drOp 为复制方式,常用值为 SRCCOPY,即将位图按原样复制。通过恰当设置这些参数,可以输 出位图中的某个矩形区域 例1121显示一张位图文件(BMP) 说明:首先建立Win32 Application空白项目和源代码文件(不要忘记设置项目使 之可以使用MFC类库),然后按11.8:“向项目中添加资源”的方法为项目建立资源文件 并将待显示的位图文件作为资源装入项目 程序: ∥/ Example11-2:显示BMP图片 #include <afxwin. h> #include resource. h ∥/框架窗口类 class CMy Wnd: public CFrameWnd CBitmap m Bitmap int m nHeight int m nWidth public
第 11 单元 资源 - 218 - int bmType; // 位图类型(0) int bmWidth; // 位图宽 int bmHeight; // 位图高 int bmWidthBytes; // 位图每行的字节数 BYTE bmPlanes; // 位平面数 BYTE bmBitsPixel; // 每点字节数 LPVOID bmBits; // 位图数据指针 } BITMAP; 与一般的图形相比,位图的显示过程稍复杂些。首先应建立一合适的内存设备环境: CDC MemDC; MemDC. CreateCompatibleDC(NULL); 并将位图选入该设备环境: MemDC.SelectObject(&m_Bitmap); 然后可用 CDC 类的 BitBlt()成员函数从内存设备环境中将位图复制到指定设备(如窗口 或打印机)。BitBlt()函数的原型为: BOOL BitBlt ( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop ); 其中参数 x,y 为目标区左上角坐标,nWidth 和 nHeight 分别为目标区的宽度和高度(逻 辑坐标),pSrcDC 为内存设备指针,xSrc 和 ySrc 为原图中欲显示块左上角坐标,dwRop 为复制方式,常用值为 SRCCOPY,即将位图按原样复制。通过恰当设置这些参数,可以输 出位图中的某个矩形区域。 [例 11-2] 显示一张位图文件(.BMP)。 说 明:首先建立 Win32 Application 空白项目和源代码文件(不要忘记设置项目使 之可以使用 MFC 类库),然后按 11.8:“向项目中添加资源”的方法为项目建立资源文件, 并将待显示的位图文件作为资源装入项目。 程 序: // Example 11-2:显示 BMP 图片 #include <afxwin.h> #include "resource.h" // 框架窗口类 class CMyWnd: public CFrameWnd { CBitmap m_Bitmap; int m_nHeight; int m_nWidth; public:
第11单元资源 CMyWndo protected fx msg void OnPaint o DECLARE MESSAGE MAP O /消息映射 BEGIN MESSAGE MAP (CMyWnd, CFrameWnd) ON WM PAINTO END MESSAGE MAPO /框架窗口类的成员函数 MyWnd: CMyWnd O m Bitmap. LoadBitmap(IDB BITMaP1) BITMAP BM Bitmap GetBitmap(&BM) m nWidth bM. bmWidth m nHeight BM. bmHeight //响应绘制窗口客户区消息 void CMyWnd:: OnPainto CPaintDC dc(this) CDC MemC lemDC. Create CompatibleDC (NULL) MemDC. SelectObject(&m Bitmap): dc BitBlt(0, 0, m nWidth, m nHeight, & MemDC, 0, 0, SRCCOPY) //应用程序类 class CMinMFCApp public CWinApp public BOOL InitInstance o //应用程序类的成员函数 //初始化应用程序实例 ool CMinMFCA InitInsta CMy Wnd *kpFrame new CMyWnd
第 11 单元 资源 - 219 - CMyWnd(); protected: afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() }; // 消息映射 BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd) ON_WM_PAINT() END_MESSAGE_MAP() // 框架窗口类的成员函数 CMyWnd::CMyWnd() { m_Bitmap.LoadBitmap(IDB_BITMAP1); BITMAP BM; m_Bitmap.GetBitmap(&BM); m_nWidth = BM.bmWidth; m_nHeight = BM.bmHeight; } // 响应绘制窗口客户区消息 void CMyWnd::OnPaint() { CPaintDC dc(this); CDC MemDC; MemDC.CreateCompatibleDC(NULL); MemDC.SelectObject(&m_Bitmap); dc.BitBlt(0,0,m_nWidth,m_nHeight,&MemDC,0,0,SRCCOPY); } // 应用程序类 class CMinMFCApp: public CWinApp { public: BOOL InitInstance(); }; // 应用程序类的成员函数 // 初始化应用程序实例 BOOL CMinMFCApp::InitInstance() { CMyWnd *pFrame = new CMyWnd;