第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 #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 #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;
第11单元资源 pFrame->Create(0, T("Beautiful Cats")) pFrame->ShowWindow(m nCmdShow) this->m pMainWnd peral return TRUe //全局应用程序对象 CMinMFCApp Thisapp Bewtiful Cats 输出:在框架窗口中显示一幅 图片,如图11-1所示。 分析:在框架窗口类的构造函 数中载入位图资源并取得其宽度和高度 数据。在 OnPaint()函数中,首先建立 内存设备环境并选入已装载的位图资 源,然后使用 Bitblt()函数将位图显 示在框架窗口的客户区 CDC类的成员函数 StreTchBlt() 也可用来显示位图资源。其原型为 图11-1显示图片程序 BOOL StretchBlt( int x, int y, int nwidth, int nHeight, CDC* pSrcDC int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop ) 与BBt()对比,可发现 StretchBlt()多了两个参数 nSrcwidth和 nSrcheight.这两个参 数与xSre和ysre配合可确定位图中的一个矩形区域。通过改变由参数 n width和 nheight 确定的目标区矩形,可实现图象的缩放输出(参看例11-3 114菜单(Menu) 菜单在 Windows应用程 序中具有非常重要的地位。菜 新建 单也是一种资源,因此也要通打开@c 过 Developer Studio的资源编_男存为a 辑器编辑。“弹出式菜单”打印四 popup)、“选项 打印设置0B 出a) tem)和“分隔线”( separator) 是构成“树状菜单的三大要 素”,如图11-2所示。 通过“弹出式菜单”可以 ○ 调出一个子菜单,也可以说弹 出式菜单就是一个子菜单。分 隔线用来区分一组选项。 图112典型的菜单
第 11 单元 资源 - 220 - pFrame->Create(0,_T("Beautiful Cats”)); pFrame->ShowWindow(m_nCmdShow); this->m_pMainWnd = pFrame; return TRUE; } // 全局应用程序对象 CMinMFCApp ThisApp; 输 出:在框架窗口中显示一幅 图片,如图 11-1 所示。 分 析:在框架窗口类的构造函 数中载入位图资源并取得其宽度和高度 数据。在 OnPaint()函数中,首先建立 一内存设备环境并选入已装载的位图资 源,然后使用 BitBlt()函数将位图显 示在框架窗口的客户区。 CDC 类的成员函数 StreTchBlt() 也可用来显示位图资源。其原型为: BOOL StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop ); 与 BitBlt()对比,可发现 StretchBlt()多了两个参数 nSrcWidth 和 nSrcHeight。这两个参 数与 xSrc 和 ySrc 配合可确定位图中的一个矩形区域。通过改变由参数 nWidth 和 nHeight 确定的目标区矩形,可实现图象的缩放输出(参看例 11-3)。 11.4 菜单(Menu) 菜单在 Windows 应用程 序中具有非常重要的地位。菜 单也是一种资源,因此也要通 过 Developer Studio 的资源编 辑器编辑。“弹出式菜单” (popup)、“选项”(menu item)和“分隔线”(separator) 是构成“树状菜单的三大要 素”,如图 11-2 所示。 通过“弹出式菜单”可以 调出一个子菜单,也可以说弹 出式菜单就是一个子菜单。分 隔线用来区分一组选项。 图 11-2 典型的菜单 图 11-1 显示图片程序
第11单元资源 通过菜单中的“选项”可以调用应用程序的某项功能。每个选项均有一个标识符,而且 只有选项才有标识符,弹出式菜单和分隔线都没有标识符,在应用程序中只对选项编程 当用户选择了一个菜单选项后,就会向应用程序发送一个命令消息 WM COMMAND 该消息的格式为 ON COMMAND( id, memberFxn 其中参数id可以是菜单选项的标识符,而参数 member Fxr为接收该消息的窗口中用于处理 该消息的成员函数名。 在MFC程序中,通过 CMenu类对象对菜单进行操作。 在应用程序中加入菜单的要通过三个步骤 编辑菜单资源,设置菜单属性(见118:“向项目中添加资源”和11.9.3:“菜单编 辑器”); 2.在Wnd类的 PreCreate Window()成员函数中载入菜单 3.为每个菜单选项添加 WM COMMAND消息映射和对应的消息处理函数。 载入菜单的工作可在CWnd类的 PreCreate Window()函数中进行,其原型为 virtual BOOL Pre Create Window( CREATESTRUCT& cs 其中参数cs的类型为 CREATESTRUCT。该类型用于存放建立窗口的初始化参数: typedef struct tag CREATESTRUCT i LPVOID ∥创建窗口的参数指针 HANDLE ∥实例句柄 HMENU hMenu ∥菜单 HWND hwnd Parent ∥/父窗口 ∥窗口高 ∥窗口宽 ∥窗口左上角y坐标 ∥窗口左上角x坐标 LONG ∥窗口类型 LPCSTR lpszName, ∥窗口名称 LPCSTR IpszClass ∥/窗口类名 dwExStyle ∥附加类型 I CREATESTRUCT PreCreate Window()函数在窗口创建前被调用,通过重载该函数,程序员可以设置各种窗 口参数,也可以使用 Load Menu()载入菜单资源。其方法为: cS hMenu= LoadMenu(NULL, MAKEINTRESOURCE(IDR MAINMENUD)) 载入菜单后,还需为每个菜单选项添加消息映射和消息处理成员函数 例11-3修改1-2,使之可以不同比例放大或缩小图象 说明:使用 StretchBlt()函数代替 BitBlt()函数就可实现图象的缩放显示。在项
第 11 单元 资源 - 221 - 通过菜单中的“选项”可以调用应用程序的某项功能。每个选项均有一个标识符,而且 只有选项才有标识符,弹出式菜单和分隔线都没有标识符,在应用程序中只对选项编程。 当用户选择了一个菜单选项后,就会向应用程序发送一个命令消息 WM_COMMAND。 该消息的格式为: ON_COMMAND ( id, memberFxn ) 其中参数 id 可以是菜单选项的标识符,而参数 memberFxn 为接收该消息的窗口中用于处理 该消息的成员函数名。 在 MFC 程序中,通过 CMenu 类对象对菜单进行操作。 在应用程序中加入菜单的要通过三个步骤: 1. 编辑菜单资源,设置菜单属性(见 11.8:“向项目中添加资源”和 11.9.3:“菜单编 辑器”); 2. 在 Wnd 类的 PreCreateWindow()成员函数中载入菜单; 3. 为每个菜单选项添加 WM_COMMAND 消息映射和对应的消息处理函数。 载入菜单的工作可在 CWnd 类的 PreCreateWindow()函数中进行,其原型为: virtual BOOL PreCreateWindow( CREATESTRUCT& cs ); 其中参数 cs 的类型为 CREATESTRUCT。该类型用于存放建立窗口的初始化参数: typedef struct tagCREATESTRUCT { LPVOID lpCreateParams; // 创建窗口的参数指针 HANDLE hInstance; // 实例句柄 HMENU hMenu; // 菜单 HWND hwndParent; // 父窗口 int cy; // 窗口高 int cx; // 窗口宽 int y; // 窗口左上角 y 坐标 int x; // 窗口左上角 x 坐标 LONG style; // 窗口类型 LPCSTR lpszName; // 窗口名称 LPCSTR lpszClass; // 窗口类名 DWORD dwExStyle; // 附加类型 } CREATESTRUCT; PreCreateWindow()函数在窗口创建前被调用,通过重载该函数,程序员可以设置各种窗 口参数,也可以使用 LoadMenu()载入菜单资源。其方法为: cs.hMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MAINMENU)); 载入菜单后,还需为每个菜单选项添加消息映射和消息处理成员函数。 [例 11-3] 修改 11-2,使之可以不同比例放大或缩小图象。 说 明:使用 StretchBlt()函数代替 BitBlt()函数就可实现图象的缩放显示。在项
第11单元资源 目中加入一个弹出式菜单(将标识符改为 IDR MAINMENU),内含3个菜单选项:缩小1 倍显示,按原尺寸显示和放大1倍显示,其标识符分别改为 ID SHRINK, ID BESTFIT和 ID ZOOMOUT。 程序 ∥/ Example11-3:以不同尺寸显示BMP图片 #include #include resource. h //框架窗口类 class CMy Wnd: public CFrameWnd CBitmap m Bitmap float m tImes int m nHeight nWidth public CMy Wne BOOL PreCreateWindow (createstruct &cs) protected afx msg void OnPaint o afx msg void OnShrink O afx msg void OnBestFito afx msg void OnZoomOuto DECLARE MESSAGE MAP O /消息映射 BEGIN MESSAGE MAP(CMyWnd, CFrameWnd ON WM PAINTO ON COMMAND (ID SHRINK, On Shrink) oN COMMAND(ID BESTFIT, OnBestFit) ON COMMAND (ID ZOOMOUT, OnZoomOut) END MESSAGE MAP O //主窗口类的成员函数 CMyWnd: CMyWndO BITMAP BM m Bitmap. LoadBitmap(IDB BITMAP1) m Bitmap. Get Bitmap( &BM) m nWidth BM. bmWidth
第 11 单元 资源 - 222 - 目中加入一个弹出式菜单(将标识符改为 IDR_MAINMENU),内含 3 个菜单选项:缩小 1 倍显示,按原尺寸显示和放大 1 倍显示,其标识符分别改为 ID_SHRINK,ID_BESTFIT 和 ID_ZOOMOUT。 程 序: // Example 11-3:以不同尺寸显示 BMP 图片 #include #include "resource.h" // 框架窗口类 class CMyWnd: public CFrameWnd { CBitmap m_Bitmap; float m_fTimes; int m_nHeight; int m_nWidth; public: CMyWnd(); BOOL PreCreateWindow(CREATESTRUCT &cs); protected: afx_msg void OnPaint(); afx_msg void OnShrink(); afx_msg void OnBestFit(); afx_msg void OnZoomOut(); DECLARE_MESSAGE_MAP() }; // 消息映射 BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd) ON_WM_PAINT() ON_COMMAND(ID_SHRINK, OnShrink) ON_COMMAND(ID_BESTFIT, OnBestFit) ON_COMMAND(ID_ZOOMOUT, OnZoomOut) END_MESSAGE_MAP() // 主窗口类的成员函数 CMyWnd::CMyWnd() { BITMAP BM; m_Bitmap.LoadBitmap(IDB_BITMAP1); m_Bitmap.GetBitmap(&BM); m_nWidth = BM.bmWidth;
第11单元资源 m nHeight BM. bmHeight m fTi lmes 1.0: //装入菜单 BOOL CMyWnd: Pre CreateWindow(CREATESTRUCT &cs) cs hMenu LoadMenu (NULL, MAKEINTRESOURCE (IDR MAINMENU)) return CFrameWnd: Pre CreateWindow(cs) //缩小图象 void CMy Wnd:: On O m tImes =0.5: Invalidate o /放大图象 void CMy Wnd:: OnZoomOutO m tImes = 2.0 Invalidate o //原样显示 void CMyWnd: OnBestFitO 1.0 Invalidate O //响应绘制窗口客户区消息 void CMyWnd: OnPaint CPaintdc dc(this) MemDC. CreateCompatibleDC(NULL) MemDC. SelectObject(&m Bitmap dc StretchBlt(0, 0,(int)(m nWidth=m fTimes) (int)(m nHeight*m fTimes) &MemDC, 0, 0, m nWidth, m nHeight, SRCCOPY)
第 11 单元 资源 - 223 - m_nHeight = BM.bmHeight; m_fTimes = 1.0; } // 装入菜单 BOOL CMyWnd::PreCreateWindow(CREATESTRUCT &cs) { cs.hMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MAINMENU)); return CFrameWnd::PreCreateWindow(cs); } // 缩小图象 void CMyWnd::OnShrink() { m_fTimes = 0.5; Invalidate(); } // 放大图象 void CMyWnd::OnZoomOut() { m_fTimes = 2.0; Invalidate(); } // 原样显示 void CMyWnd::OnBestFit() { m_fTimes = 1.0; Invalidate(); } // 响应绘制窗口客户区消息 void CMyWnd::OnPaint() { CPaintDC dc(this); CDC MemDC; MemDC.CreateCompatibleDC(NULL); MemDC.SelectObject(&m_Bitmap); dc.StretchBlt(0, 0, (int)(m_nWidth*m_fTimes), (int)(m_nHeight*m_fTimes), &MemDC, 0, 0, m_nWidth, m_nHeight, SRCCOPY); }
第11单元资源 /应用程序类 lass Cmy App public cWinAl ublic BOOL InitInstance o //应用窗口类的成员函数 //初始化应用程序实例 BOOL CMyApp: InitInstanceO CMy Wnd *pFrame new CMyWnd pFrame->Create(o, T("Show Bitmap 1.0)) Frame->ShowWindow (SW SHOWMAXIMIZED Frame->Update O this->m pMainWnd pframe return TRUE //全局应用程序对象 yApp Thisapp 输入输出:通过菜单可选择图片的 显示尺寸,如图11-3所示 自学内容 115快捷键 图11-3可变显示大小的图片程岸 快捷键总是与菜单选项配合使用。如果要为某菜单配上相应的快捷键,首先要插入快捷 键表资源,然后插入对每个菜单项的快捷键(参看118:“向项目中添加资源”和11.94 快捷键编辑器”) 在程序中载入快捷键资源的方法与载入菜单资源的方法类似,均可在Wnd类的成员函 数 PreCreate Window()中进行。载入快捷键使用Wnd类的成员函数 LoadAcceltable(), 其原型为: BOOL LoadAccelTable( LPCTSTR lpszResourceName 其中参数 lpszResource Name为快捷键表名称。如果要使用资源标识符,可使用带参宏定义 MAKEINTRESOURCE()将其转换为资源名称。 由于快捷键是与菜单选项配合使用,所以无需专为快捷键消息添加消息映射和消息处理 函数
第 11 单元 资源 - 224 - // 应用程序类 class CMyApp: public CWinApp { public: BOOL InitInstance(); }; // 应用窗口类的成员函数 // 初始化应用程序实例 BOOL CMyApp::InitInstance() { CMyWnd *pFrame = new CMyWnd; pFrame->Create(0,_T("Show Bitmap 1.0")); pFrame->ShowWindow(SW_SHOWMAXIMIZED); pFrame->UpdateWindow(); this->m_pMainWnd = pFrame; return TRUE; } // 全局应用程序对象 CMyApp ThisApp; 输入输出:通过菜单可选择图片的 显示尺寸,如图 11-3 所示。 自学内容 11.5 快捷键 快捷键总是与菜单选项配合使用。如果要为某菜单配上相应的快捷键,首先要插入快捷 键表资源,然后插入对每个菜单项的快捷键(参看 11.8:“向项目中添加资源”和 11.9.4: “快捷键编辑器”)。 在程序中载入快捷键资源的方法与载入菜单资源的方法类似,均可在 Wnd 类的成员函 数 PreCreateWindow()中进行。载入快捷键使用 Wnd 类的成员函数 LoadAccelTable(), 其原型为: BOOL LoadAccelTable ( LPCTSTR lpszResourceName ); 其中参数 lpszResourceName 为快捷键表名称。如果要使用资源标识符,可使用带参宏定义 MAKEINTRESOURCE()将其转换为资源名称。 由于快捷键是与菜单选项配合使用,所以无需专为快捷键消息添加消息映射和消息处理 函数。 图 11-3 可变显示大小的图片程序