




已阅读5页,还剩219页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5章菜单 工具栏和状态栏 5 1 1文档应用程序的MFC类结构 用MFCAppWizard exe 创建一个默认的单文档应用程序Ex SDI 将项目工作区窗口切换到 ClassView 类视图 页面 可以看到构成Ex SDI应用程序框架的MFC类结构 如图所示 再创建一个默认的多文档应用程序Ex MDI 可以看到如图所示的MFC类结构 5 1 2项目的文件组织 VisualC 6 0中 项目中所有的源文件都采用文件夹的方式进行管理的 每一个类的源代码均保存同名的h和cpp文件 opt关于开发环境的参数文件 如工具格位置等信息 aps AppStudioFile 资源辅助文件 二进制格式 clwClassWizard信息文件 dsp DeveloperStudioProject 项目文件 plg编译信息文件 mdp MicrosoftDevStudioProject 旧版本的项目文件 bsc用于浏览项目信息 map执行文件的映像信息纪录文件 pch Pre CompiledFile 预编译文件 可以加快编译速度 但是文件非常大 pdb ProgramDatabase 记录程序有关的一些数据和调试信息 ncb无编译浏览文件 nocompilebrowser 5 1 2项目的文件组织 还有相应的Debug 调试 Res 资源 等子文件夹 程序项目Win32Release版本 它与Release的区别在于 Debug版本的运行程序有相应的调试信息码 而Release版本的运行程序没有 但Release版本的运行程序经过代码的优化 其程序的运行效率被最大提升 通过选择 编译 放置可远行配置 菜单命令 在图所示的对话框中 选择 Ex SDI Win32Release 然后单击 确定 按钮 编译后即可 5 2菜单 Windows程序都有各自的菜单 为了使Windows程序更容易操作 许多程序员对于菜单的设计都遵循下列一些规则 若选择某菜单项会弹出一对话框 那么在该菜单项文本后有 2 若某项菜单有子菜单 那么在该菜单项文本后有 3 若菜单项需要助记符 则用括号将带下划线的字母括起来 助记符与Alt构成一个组合键 当按住 Alt 键不放 再敲击 4 该字母时 对应的菜单项就会被选中 4 若某项菜单需要快捷键的支持 则一般将其列在相应菜单项文本之后 所谓 快捷键 是一个组合键 如Ctrl N 使用时是先按下 Ctrl 健不放 然后再按 N 键 任何时候按下快捷键 相应的菜单命令都会被执行 5 1 1更改应用程序菜单 通过菜单编辑器直接修改菜单资源IDR MAINFRAME可以实现添加和修改应用程序菜单 如下示例过程 例Ex MenuSDI 更改应用程序菜单 1 创建一个默认的单文档应用程序Ex MenuSDI 2 在项目工作区窗口中选择ResourceView页面 双击资 Menu 项中的IDR MAINFRAME 则菜单编辑器窗口出现在主界面的右边 项目Ex MenuSDI相应的菜单资源在菜单编辑器窗口中显示出来 3 按快捷键Ctrl R 弹出 插入资源 对话框 在资源类型中选定 Menu 如图 5 1 1更改应用程序菜单 单击 新建 按钮 系统就会为应用程序添加一个新的菜单资源 并自动赋给它一个默认的标识符名称 第一次为DR MENU1 以后依次为IDR MENU2 IDR MENU3 同时自动打开这个新的菜单资源 5 1 1更改应用程序菜单 在Menu资源的ID MENU1上右击鼠标 从弹出的快捷菜单中选择 Properties 命令 在这里可以重新指定菜单资源ID 设置菜单资源的语言和条件 这个条件用来决定菜单资源包含到哪个环境中 例如当指定条件为 DEBUG 则菜单资源只存在于Debug编译环境中 5 1 1更改应用程序菜单 在菜单的空位置上双击鼠标左键 则出现它的属性对话框 通过其属性对话框为菜单ID MENU1添加一个顶层弹出菜单项 测试 T 并在该菜单下添加一个子菜单项 返回 R ID设为ID TEST RETURN 需要再次强调的是 符号 用来指定后面的字符是一个助记符 7 打开Ex MenuSDI程序菜单资源IDR MAINFRAME 在 查看 菜单的最后添加一个子菜单项 显示测试菜单 M ID设为ID VIEW TEST 8 为CMainFrame类添加一个CMenu类型的成员变量m NewMenu CMenu类是用来处理菜单的一个MFC类 5 1 1更改应用程序菜单 按快捷键Ctrl W打开MFCClassWizard对话框 切换到MessageMaps页面 从 Classname 列表中选择CMainFrame 分别为菜单项ID VIEW TEST和ID TEST RETURN添加COMMAND消息映射 使用默认的消息映射函数名 并添中下列代码 voidCMainFrame OnViewTest m NewMenu Detach 使菜单对象和菜单句柄分离m NewMenu LoadMenu IDR MENU1 SetMenu NULL 清除应用程序菜单SetMenu 5 2 2使用键盘快捷键 加速键也往往被称为键盘快捷键 加速键也是一种资源 它的显示 编辑过程和菜单相似 例如下面的示例过程是为前面两个菜单ID VIEW TEST和ID TEST RETURN定义键盘快捷键 先打开上例的项目工作区窗口中Accelerator的资源项 双击IDR MAINFRAME 出现如图的加速键资源列表 5 2 2使用键盘快捷键 2 建立一新的加速键 双击加速键列表的最下端的空行 弹出如图所示的 AccelProperities 对话框 可设置的属性如表所示 5 2 2使用键盘快捷键 3 在上述对话框中 选择Ex MenuSDI添加的 显示测试菜单 菜单项ID VIEW TEST作为要联用的加速键的ID号 单击 下一键 按钮 并按下Ctrl 1作为此加速键的键值 4 按同样的方法 为菜单项ID TEST RETURN添加加速键Ctrl 2 需要说明的是 为了使其他用户能查看并使用该加速键 还需在相应的菜单项文本后面添加加速键内容 例如 可将ID VIEW TEST菜单项的标题改成 显示测试菜 M tCtrl 1 其 t 是将后面的 Ctrl 1 定位到一个表位 5 编译运行并测试 当程序运行后 按 Ctrl 1 和 Ctrl 2将执行相应的菜单命令 5 2 3菜单的编程控制 创建菜单CMenu类的CreateMenu和CreatePopupMenu分别用来创建一个菜单或子菜单框架 它们的原型如下 BOOLCreateMenu 产生一个空菜单BOOLCreatePopupMenu 产生一个空的弹出式子菜单2 装入菜单资源将菜单资源装入应用程序中 需调用CMenu成员函数LoadMenu 然后用SetMenu对应用程序菜单进行重新设置 BOOLLoadMenu LPCTSTRlpszResourceName BOOLLoadMenu UINTnIDResource 其中 lpszResourceName为菜单资源名称 nIDResource为菜单资源ID号 5 2 3菜单的编程控制 3 添加菜单项当菜单创建后 用户可以调用AppendMenu或InsertMenu函数来添加一些菜单项 AppendMenu是将菜单项添加在菜单的末尾处 而InsertMenu在菜单的指定位置处插入菜单项 并将后面的菜单项依次下移 BOOLAppendMenu UINTnFlags UINTnIDNewItem 0 LPCTSTRlpszNewItem NULL BOOLAppendMenu UINTnFlags UINTnIDNewItem constCBitmap pBmp BOOLInsertMenu UINTnPosition UINTnFlags UINTnIDNewItem 0 LPCTSTRlpszNewItem NULL BOOLInsertMenu UINTnPosition UINTnFlags UINTnIDNewItem constCBitmap pBmp 4 删除菜单项调用DeleteMenu函数可将指定的菜单项删除 需要注意的是 调用该函数后 不管菜单依附的窗口是否改变 都应调用CWnd DrawMenuBar使菜单更新 5 2 3菜单的编程控制 函数DeleteMenu的原型如下 BOOLDeleteMenu UINTnPosition UINTnFlags 其中 参数nPosition表示要删除的菜单项位置 它由nFlags进行说明 若当nFlags为MF BYCOMMAND时 nPosition表示菜单项的ID号 而当nFlags为MF BYPOSITION时 nPosition表示菜单项的位置 第一个菜单项位置为0 5 获取菜单项下面的四个CMenu成员函数分别获得菜单的项数 菜单项的ID号 菜单项的文本内容以及弹出式子菜单的句柄 UINTGetMenuItemCount const 该函数用来获得菜单的菜单项数 调用失败后返回 1 UINTGetMenuItemID intnPos const 该函数用来获得由nPos指定菜单项位置 以0为基数 的菜单项的标识号 若nPos是SEPARATOR 则返回 1 5 2 3菜单的编程控制 intGetMenuString UINTnIDItem CString该函数用来获得指定菜单的弹出式菜单的菜单句柄 该弹出式菜单位置由参数nPos指定 开始的位置为0 若菜单不存在 则创建一个临时的菜单指针 下面的示例过程是利用CMenu成员函数向应用程序菜单中添加并处理一个菜单项 例Ex Menu 菜单项的编程控制 1 创建一个默认的单文档应用程序Ex Menu 5 2 3菜单的编程控制 选择 查看 菜单 ResourceSymbols 命令 资源符号 对话框 它能对应用程序中的资源标识符进行管理 程序中添加的菜单项需要一个标识值 最好用一个标识符来代替这个值 因此这里通过 资源符号 对话框来创建一个新的标识符 5 2 3菜单的编程控制 3 单击 新建 按钮 在名字 Name 框中输入一个新的标识符ID NEW MENUITEM 在值 Value 框中 输入该ID的值 系统要求用户定义的ID值应大于15 0X000F 而小于61440 0XF000 保留默认的ID值101 单击 确定 按钮 NewSymbol 对话框 5 2 3菜单的编程控制 4 关闭 资源符号 对话框 在CMainFrame OnCreate函数中添加下列代码 该函数在框架窗口创建时自动调用 intCMainFrame OnCreate LPCREATESTRUCTlpCreateStruct CMenu pSysMenu GetMenu 获得程序菜单指针CMenu pSubMenu pSysMenu GetSubMenu 1 获得第二个子菜单的指针CStringStrMenuItem 新的菜单项 pSubMenu AppendMenu MF SEPARATOR 增加一水平分隔线pSubMenu AppendMenu MF STRING ID NEW MENUITEM StrMenuItem 在子菜单中增加一菜单项 允许使用ON UPDATE COMMAND UI或ON COMMAND的菜单项m bAutoMenuEnable FALSE 关闭系统自动更新菜单状态SysMenu EnableMenuItem ID NEW MENUITEM MF BYCOMMAND MF ENABL 激活菜单项DrawMenuBar 更新菜单return0 5 2 3菜单的编程控制 5 用MFCClassWizard处理OnCommand消息并检测用户菜单的nID参数 BOOLCMainFrame OnCommand WPARAMwParam LPARAMlParam wParam的低字节表示菜单 控件 加速键的命令IDif LOWORD wParam ID NEW MENUITEM MessageBox 你选中了新的菜单项 returnCFrameWnd OnCommand wParam lParam 6 编译运行并测试 这样当选择菜单 编辑 新的菜单项 命令后 就会弹一个对话框 显示 你选中了新的菜单项 消息 5 2 4使用快捷菜单 1 快捷菜单实现函数用资源编辑器和MFC库的CMenu TrackPopupMenu函数可以很容易地创建这样的菜单 CMenu TrackPopupMenu函数原型如下 BOOLTrackPopupMenu UINTnFlags intx inty CWnd pWnd LPCRECTlpRect NULL 该函数用来显示一个浮动的弹出式菜单 其位置由各参数决定 nFlags表示菜单在屏幕显示的位置以及鼠标按钮标志 nFlags的值及其对其他参数的影响 5 2 4使用快捷菜单 2 示例本示例是在前面Ex SDI基础上进行的 当显示主菜单IDR MAINFRAME时 右击鼠标弹出 查看 菜单的子菜单 当显示菜单IDR MENU1时 右击鼠标弹出 测试 菜单的子菜单 续例Ex MenuSDI 使用快捷菜单 1 打开前面的单文档应用程序Ex MenuSDI 2 用MFCClassWizard在CMainFrame类添加WM CONTEXTMENU消息映射 3 编译运行并测试 5 3 1使用工具栏编辑器 选择菜单 文件 打开工作区 将前面的单文档应用程序Ex MenuSDI调入 在项目工作区窗口中选择ResourceView页面 双击 Toolbar 项中的IDR MAINFRAME则工具栏编辑器出现在主界面的右边 5 3 1使用工具栏编辑器 1 创建一个新的工具栏按钮在新建的工具栏中 最右端总有一个空按钮 双击该按钮弹出其属性对话框 在ID框中输入其标识符名称 其右端又出现一个新的空按钮 2 移动一个按钮在工具栏中移动一个按钮 用鼠标左键点中它并拖动至相应位置即可 如果用户拖动它离开工具栏位置 则此按钮从工具栏中消失 3 删除一个按钮将选取中的按钮拖离工具栏 则该按钮就消失了 但若选中按钮后 单击Delete键并不能删除一个按钮 只是将按钮中的图形全部以背景色填充 5 3 1使用工具栏编辑器 4 在工具栏中插入空格在工具栏中插入空格有以下几种情况 如果按扭前没有任何空格 拖动该按钮向右移动并当覆盖相邻按钮的一半以上时 释放鼠标键 则此按钮前出现空格 如果按钮前有空格而按钮后没有空格 拖动该按钮向左移动并当按钮的左边界接触到前面按钮时 释放鼠标键 则此按钮后将出现空格 如果按钮前后均有空格 拖动该按钮向右移动并当接触到相邻按钮时 则此按钮前的空格保留 按钮后的空格消失 相反 拖动该按钮向左移动并当接触到前一个相邻按钮时 则此按钮前面的空格消失 后面的空格保留 5 工具栏按钮属性的设置双击某按钮弹出其属性对话框 如图所示 5 3 1使用工具栏编辑器 工具栏按钮属性对话框 属性对话框中的各项说明见表 5 3 2工具按钮和菜单项相结合 工具按钮和菜单项相结合是指当选择工具按钮或菜单命令时 操作结果是一样的 Ex MenuSDI基础上进行的 通过两个工具按钮分别显示主菜单IDR MAINFRAME和菜单IDR MENU1 1 打开前面的单文档应用程序Ex MenuSDI 2 利用工具栏编辑器设计两个工具按钮 位置内容如图所示 3 双击刚才设计的第一个工具按钮 弹出该工具按钮的属性对话框 将该工具按钮的ID号设为ID TEST RETURN 在提示框内键入 返回应用程序主菜单 n返回主菜单 4 双击刚才设计的第二个工具按钮 弹出该工具按钮的属性对话框 将该工具按钮的ID号设为ID VEW TEST 在提示框内键入 显示测试菜单 n显示测试菜单 5 3 2工具按钮和菜单项相结合 设计的两个工具栏按钮 5 编译运行并测试 程序运行后 将鼠标移至刚才设计的第一个工具按钮处 这时在状态栏上显示出 返回应用程序主菜单 信息 若稍等片刻会弹出提示小窗口 显示出 返回主菜单 字样 单击新添加的这两个按钮 会执行相应的菜单命令 5 3 3多个工具栏的使用 在用MFCAppWizard创建的文档应用程序中往往只有一个工具栏 但在实际应用中 常常需要多个工具栏 1 将项目工作区切换到ResourceView页面 展开Toolbar 工具栏 资源 用鼠标单击IDR MAINFRAME不松开 按下Ctrl键 移动鼠标将IDR MAINFRAME拖到Toolbar资源名称上 复制了工具栏默认资源IDR MAINFRAME 复制后的资源标识系统自动设为IDR MAINFRAME1 2 右击工具栏资源IDR MAINFRAME1 从弹出的快捷菜单中选择Properties命令 如图所示 将ID设为IDR TOOLBAR1 5 3 3多个工具栏的使用 3 双击IDR TOOLBAR1 打开工具栏资源 按图删除不要的工具按钮 4 在CMainFrame类中添加一个成员变量m wndTestBar 变量类型为CToolBar CToolBar类封装了工具栏的操作 5 在CMainFrame OnCreate函数中添加工具栏创建代码 intCMainFrame OnCreate LPCREATESTRUCTlpCreateStruct if CFrameWnd OnCreate lpCreateStruct 1 return 1 5 3 3多个工具栏的使用 intnRes m wndTestBar CreateEx this TBSTYLE FLAT WS CHILD WS VISIBLE CBRS TOP CBRS GRIPPER CBRS TOOLTIPS CBRS FLYBY CBRS SIZE DYNAMIC CRect 0 0 0 0 AFX IDW TOOLBAR 10 if nRes m wndTestBar LoadToolBar IDR TOOLBAR1 TRACE0 Failedtocreatetoolbar n return 1 failtocreate 在CMainFrame OnCreate函数中添加下面的工具栏创建代码 m wndToolBar EnableDocking CBRS ALIGN ANY m wndTestBar EnableDocking CBRS ALIGN ANY EnableDocking CBRS ALIGN ANY DockControlBar 5 3 3多个工具栏的使用 AFX IDW TOOLBAR是系统内部的工具栏子窗口标识 并将AFX IDW TOOLBAR 1的值表示默认的状态栏子窗口标识 当打开 查看 菜单时 单击 工具栏 菜单时 显示或隐藏的工具栏不是原来的工具栏而是新添加的工具栏 我们需要重新指定工具栏子窗口的标识 并使其值等于AFX IDW TOOLBAR 10 6 编译运行 结果如图所示 5 3 3多个工具栏的使用 7 本例希望IDR TOOLBAR1工具栏和IDR MENU1菜单栏在一起 不是一开始就出现 还需要调用CFrameWnd类的成员函数ShowControlBar来使程序一开始运行时隐藏工具栏IDR TOOLBAR1 在CMainFrame OnCreate函数中添加下列代码 intCMainFrame OnCreate LPCREATESTRUCTlpCreateStruct ShowControlBar 代码中 ShowControlBa函数有三个参数 第一个用来指定要操作的工具栏或状态栏指针 第二个是一个布尔型 为TRUE时表示显示 否则表示隐藏 第三个用来表示是否延迟显示或隐藏 为FALSE时表示立即显示或隐藏 5 3 3多个工具栏的使用 8 在CMainFrame OnViewTest和CMainFrame OnTestReturn函数中添加下列代码 voidCMainFrame OnViewTest ShowControlBar 关闭主工具栏 voidCMainFrame OnTestReturn ShowControlBar 显示主工具栏 5 3 3多个工具栏的使用 编译运行并测试 结果如图所示 左边是一开始运行的结果 右边是单击工具按钮运行的结果 5 4 1状态栏的定义 数组中的元素是一些标识常量或是字符串资源的ID号 默认的indicator数组包含了四个元素 ID SEPARATORID INDICATOR CAPSID INDICATOR NUMID INDICATOR SCRL分别显示出CapsLock NumLock和ScrollLock这三个键的状态 5 4 2状态栏的常用操作 MFC的CStatusBar类封装了状态栏的大部分操作 1 增加和减少窗格状态栏中的窗格分为信息行窗格和指示器窗格两类 在状态栏中增加一个信息行窗格 则只需在indicators数组中的适当位置中增加一个ID SEPARATOR标识即可 若在状态栏中增加一个用户指示器窗格 则在indicators数组中的适当位置增加一个在字符串表中定义过的资源ID 其字符串的长度表示用户指示器窗格的大小 若状态栏减少一个窗格 操作与增加相类似 需减少indicators数组元素即可 2 在状态栏上显示文本调用CStatusBar SetPaneText函数可以更新任何窗格 包括信息行窗格 中的文本 此函数原型描述如下 5 4 2状态栏的常用操作 BOOLSetPaneText intnIndex LPCTSTRlpszNewText BOOLbUpdate TRUE lpszNewText表示要显示的字符串 nIndex是表示设置的窗格索引 第一个窗格的索引为0 若bUpdate为TRUE 则系统自动更新显示的结果 下面来看一个示例 例Ex SDIMouse 将鼠标在窗口客户区的位置显示在状态栏上 1 创建一个默认的单文档应用程序Ex SDIMouse 2 将项目工作区切换到ClassView页面 展开CMainFrame所有项 双击构造函数CMainFrame 在文档窗口中出现该函数的定义 在它的前面就是状态栏数组的定义 3 将状态栏indicators数组的定义改为下列代码 staticUINTindicators ID SEPARATOR ID SEPARATOR 5 4 2状态栏的常用操作 4 由于鼠标移动消息WM MOUSEMOVE在CMainFrame类映射后不起作用 只能映射到CEx SDIMouseView类中 CMainFrame类定义的成员变量 需要在CEx SDIMouseView类中添加访问CMainFrame类的代码 Ex SDIMouseView OnMouseMove函数代码如下 voidCEx SDIMouseView OnMouseMove UINTnFlags CPointpoint CStringstr CMainFrame pFrame CMainFrame AfxGetApp m pMainWnd 获得主窗口指针CStatusBar pStatus 5 4 2状态栏的常用操作 5 将MainFrm h文件中的受保护变量m wndStatusBar变成公共变量 6 在Ex SDIMouseView cpp文件的开始处增加下列语句 include Ex SDIMouseView h include MainFrm h 7 编译并运行 结果如图所示 5 4 3改变状态栏的风格 在MFC的CStatusBar类中 有两个成员函数可以改变状态栏风格 它们是 voidSetPaneInfo intnIndex UINTnID UINTnStyle intcxWidth voidSetPaneStyle intnIndex UINTnStyle 其中 参数nIndex表示要设置的状态栏窗格的索引 nID用来为状态栏窗格指定新的ID cxWidth表示窗格的像素宽度 nStyle表示窗格的风格类型 用来指定窗格的外观 例如 将OnMouseMove函数修改为下列代码 则结果如图所示 voidCEx SDIMouseView OnMouseMove UINTnFlags CPointpoint CStringstr CMainFrame pFrame CMainFrame AfxGetApp m pMainWnd 获得主窗口指针CStatusBar pStatus 获得主窗口中的状态栏指针 5 4 3改变状态栏的风格 if pStatus pStatus SetPaneStyle 1 SBPS POPOUT str Format X d Y d point x point y 格式化文本pStatus SetPaneText 1 str 更新第二个窗格的文本 CView OnMouseMove nFlags point 状态栏窗格的风格类型 习题 1 MFC单文档和多文档应用程序一般是由哪些类构成 2 什么是助记符 它是如何在菜单中定义的 3 若对同一个菜单用ClassWizard分别在视图类和主框架窗口类CMainFrame都处理其COMMAND消息 并在它们的函数中添加相同的代码 则当用户选择该菜单后 会有什么样的结果 为什么 4 什么是键盘快捷键 它是如何定义的 5 什么是快捷菜单 用程序实现一般需要哪些步骤 6 状态栏的作用是什么 状态栏的窗格分为几类 如何添加和减少相应的窗格 7 若状态栏只有一个用户定义的指示器窗格 其ID号为ID TEXT PANE 应如何定义 若当用户在客户区双击鼠标 在该窗格中显示 双击鼠标 字样 则应如何编程 8 上机练习本章的示例 6 1框架窗口 1 主框架窗口和文档窗口 主框架窗口是应用程序直接放置在桌面 DeskTop 上的那个窗口 每个应用程序只能有一个主框架窗口 主框架窗口的标题栏上往往显示应用程序的名称 文档窗口对于单文档应用程序来说 它和主框架窗口是一致的 即主框架窗口就是文档窗口 而对于多文档应用程序 文档窗口是主框架窗口的子窗口 多文档应用程序的框架窗口 6 1框架窗口 2 窗口状态的改变 MFCAppWizard为每一个文档应用程序的框架窗口设置了相应的大小和位置 但默认的窗口状态有时并不那么令人满意 这时就需要对窗口状态进行适当的改变 ShowWindow函数的参数值 6 1框架窗口 3 窗口风格的设置 6 1框架窗口 2 在MFCAppWizard中进行修改 选择 文件 新建 菜单 在弹出的 新建 对话框中选择 工程 标签 选择MFCAppWizard exe 的项目类型 指定项目工作文件夹位置 输入项目名Ex SDI2 单击 确定 按钮 2 在向导的第一步中 将应用程序类型选为 单个文档 新建 对话框 6 1框架窗口 3 单击 下一个 按钮 出现向导的第二步对话框 在这里用户可以选择程序中是否加入数据库的支持 Step2 对话框 6 1框架窗口 4 单击 下一个 按钮 出现向导的第三步对话框 允许用户在程序中加入复合文档 自动化 ActiveX控件的支持 6 1框架窗口 5 单击 下一个 按钮 出现向导的第四步对话框 对话框的前几项依次确定对浮动工具条 打印与预览以及通信网络等特性的支持 6 1框架窗口 6 单击 高级 按钮 出现下图所示的对话框 分别用于文档模板字串资源内容和窗口风格的修改 6 1框架窗口 7 单击 关闭 按钮回到向导对话框 单击 下一个 按钮 出现如下图所示的对话框 6 1框架窗口 8 单击 下一个 按钮 出现对话框 在这里 用户可以对MFCAppWizard提供的默认类名 基类名 各个源文件名进行修改 6 1框架窗口 3 修改CREATESTRUCT结构 当窗口创建之前 系统自动调用PreCreateWindow虚函数 在用MFCAppWizard创建文档应用程序结构时 MFC已为主窗口或文档窗口类自动重载了该虚函数 BOOLCMainFrame PreCreateWindow CREATESTRUCT 6 1框架窗口 4 使用ModifyStyle和ModifyStyleEx CWnd类中的成员函数ModifyStyle和ModifyStyleEx也可用来更改窗口的风格 其中ModifyStyleEx还可更改窗口的扩展风格 6 1框架窗口 5 改变窗口的大小和位置 用CWnd类的成员函数SetWindowPos或MoveWindow可以改变窗口的大小和位置 SetWindowPos是一个非常有用的函数 它不仅可以改变窗口的大小 位置 而且还可以改变所有窗口在堆栈排列的次序 Z次序 这个次序是根据它们在屏幕出现的先后来确定的 6 2文档模板 1 文档模板类 文档应用程序框架结构是在程序运行一开始构造的 在单文档应用程序 设项目名为Ex SDI 的应用程序类InitInstance函数中 可以看到这样的代码 BOOLCEx SDI2App InitInstance CSingleDocTemplate pDocTemplate pDocTemplate newCSingleDocTemplate IDR MAINFRAME 资源ID RUNTIME CLASS CEx SDIDoc 文档类 RUNTIME CLASS CMainFrame 主框架窗口类 RUNTIME CLASS CEx SDIView 视图类 AddDocTemplate pDocTemplate returnTRUE 6 2文档模板 2 文档模板字符串资源 在MFCAppWizard创建的应用程序资源中 许多资源标识符都是IDR MAINFRAME 这就意味着这些具有同名标识的资源将被框架自动加载到应用程序中 6 2文档模板 3 使用多个文档类型 用MFCAppWizard exe 创建一个默认的多文档应用程序项目Ex MDIDemo 2 打开项目工作区窗口中StringTable的资源项 双击该项下的StringTable 打开字符串表资源 6 2文档模板 3 双击IDR MAINFRAME列表项 弹出字符串属性对话框 将其标题修改为 多个文档类型实例 4 双击IDR EX MDITYPE列表项 在字符串属性对话中 将其内容修改 5 拖动字符串表编辑器右边的滚动块 直到出现最后一个字符串项 双击最后的空行 在字符串属性对话框中将ID设为 修改IDR MAINFRAME字符串标题 添加新的字符串项 6 2文档模板 6 按快捷键Ctrl W 打开MFCClassWizard 单击 AddClass 按钮 从弹出的菜单中选择New 出现 NewClass 对话框 在Name框中输入类名COtherDoc 在Baseclass组合框中选择基类CDocument 7 单击 OK 按钮 新的文档类COtherDoc就添加到Ex MDIDemo项目中 8 修改CEx MDIDemoApp InitInstance函数代码 9 在类CEx MDIDemoApp源代码文件Ex MDIDemo cpp的开始处 添加包含前面创建的两个派生类的头文件 添加新的文档类COtherDoc 6 2文档模板 编译运行并测试 多类型文档窗口显示 文档类型新建对话框 文件打开对话框中的文件类型 6 3 1MFC文档读写机制 1 创建空文档 文档应用程序运行到应用程序类的InitInstance函数时 它会在调用了AddDocTemplate函数之后 通过CWinApp ProcessShellCommand间接调用CWinApp的另一个非常有用的成员函数OnFileNew 并依次完成工作 2 打开文档 当MFCAppWizard创建文档应用程序时 它会自动将 文件 File 菜单中的 打开 Open 命令 ID号为ID FILE OPEN 映射到CWinApp的OnFileOpen成员函数 3 保存文档 当MFCAppWizard创建应用程序时 它会自动将 文件 File 菜单中的 保存 Save 命令与文档类CDocument的OnFileSave函数在内部关联起来 但用户在程序框架中看不到相应的代码 6 3 1MFC文档读写机制 4 关闭文档 1 若文档内容已被修改 则弹出一个消息对话框 询问用户是否需要将文档保存 2 调用CDocument OnCloseDocument虚函数 关闭所有与该文档相关联的文档窗口及相应的视图 调用文档类CDocument的DeleteContents清除文档数据 5 文档读写操作 打开和保存文档时 系统都会自动调用Serialize函数 事实上 MFCAppWizard在创建文档应用程序框架时已在文档类中重载了Serialize函数 通过在该函数中添加代码可达到实现数据序列化的目的 ar中可以使用 运算符的数据类型 1 简单数组集合类的构造及元素的添加 对简单数组集合类构造的方法都是一样的 均是使用各自的构造函数 它们的原型如下 CByteArrayCByteArray CDWordArrayCDWordArray CObArrayCObArray CPtrArrayCPtrArray CStringArrayCStringArray CUIntArrayCUIntArray CWordArrayCWordArray 6 3 2 使用简单数组集合类 6 3 2 使用简单数组集合类 2 访问简单数组集合类的元素 在MFC中 既可以使用GetAt函数 也可使用 操作符 CObArray operator 示例CObArrayarray CAge pa CAge是一个用户类array Add newCAge 21 添加一个元素array Add newCAge 40 再添加一个元素pa CAge array 0 获取元素0ASSERT pa CAge 21 array 0 newCAge 30 替换元素0 ASSERT CAge array 0 CAge 30 CObArray GetAt示例CObArrayarray array Add newCAge 21 元素0array Add newCAge 40 元素1ASSERT CAge array GetAt 0 CAge 21 6 3 2 使用简单数组集合类 3 删除简单数组集合类的元素 1 使用函数GetSize和整数下标值访问简单数组集合类中的元素 2 若对象元素是在堆内存中创建的 则使用delete操作符删除每一个对象元素 3 调用函数RemoveAll删除简单数组集合类中的所有元素 CObArrayarray CAge pa1 CAge pa2 array Add pa1 newCAge 21 array Add pa2 newCAge 40 ASSERT array GetSize 2 for inti 0 i array GetSize i deletearray GetAt i array RemoveAll 下面代码过程是一个CObArray的删除示例 6 3 3 建立可序列化的类 使一个类可序列化的目的是使其具有CArchive的序列化功能 即可以在文档类中的Serialize函数中直接通过CArchive引用变量进行该类数据的读写操作 在MFC中 一个可序列化的类必须是CObject的一个派生类 且在类声明中 需要包含DECLARE SERIAL宏调用 而在类的实现文件中包含IMPLEMENT SERIAL宏调用 这个宏有三个参数 前两个参数分别表示类名和基类名 第三个参数表示应用程序的版本号 最后还需要重载Serialize函数 使该类的数据成员进行相关序列化操作 6 3 4 文档序列化示例 添加用于学生基本信息记录输入的对话框 对话框资源的复制 学生基本信息输入对话框 6 3 4 文档序列化示例 2 添加并处理菜单项 在Ex StudentDoc cpp文件的开始处 添加包含CStuInfoDlg类的头文件包含 2 在菜单资源的主菜单中添加顶层菜单项 学生基本信息 S 在该顶层菜单项中添加子菜单 添加 A ID STUINFO ADD 3 用MFCClassWizard为CEx StudentDoc类添加处理菜单项ID STUINFO ADD的COMMAND消息 并添加代码 voidCEx StudentDoc OnStuinfoAdd CStuInfoDlgdlg if dlg DoModal IDOK return 添加记录CStudentInfo pStudent newCStudentInfo dlg m strName dlg m strNo dlg m bMale dlg m tBirth dlg m strSpecial m stuObArray Add pStudent SetModifiedFlag 设置文档更改标志UpdateAllViews NULL 更新视图 6 3 4 文档序列化示例 3 修改CEx StudentDoc类代码 在Ex StudentDoc h文件的classCEx StudentDoc前面 添加包含CStudentInfo类的头文件 2 为CEx StudentDoc类添加下列成员变量 public CObArraym stuObArray 对象集合类对象 3 为CEx StudentDoc类添加成员函数CStudentInfo GetStudentInfoAt intnIndex 用来获取m stuObArray中指定索引号的CStudentInfo类指针 为CEx StudentDoc类添加成员函数intGetAllRecNum void 用于获取集合类中对象的个数其代码如下 intCEx StudentDoc GetAllRecNum returnm stuObArray GetSize 6 3 4 文档序列化示例 5 在CEx StudentDoc类析构函数 CEx StudentDoc添加下列代码 CEx StudentDoc CEx StudentDoc intnIndex GetAllRecNum while nIndex deletem stuObArray GetAt nIndex 删除并释放对象的内存空间m stuObArray RemoveAll 6 在CEx StudentDoc Serialize函数中添加下列代码 voidCEx StudentDoc Serialize CArchive 6 3 4 文档序列化示例 4 修改CEx StudentView类代码 voidCEx StudentView OnDraw CDC pDC CEx StudentDoc pDoc GetDocument ASSERT VALID pDoc inty 0 for intnIndex 0 nIndexGetAllRecNum nIndex pDoc GetStudentInfoAt nIndex Display y pDC y 16 将CEx StudentView OnDraw代码修改 用来将所有的学生基本信息记录显示在视图中 6 3 4 文档序列化示例 5 修改文档的字串资源打开文档的字串资源IDR MAINFRAME 将其内容修改为 6 编译运行并测试 Ex Student运行结果 Ex Student nStudentRec nEx Stu n记录文件 rec n rec nExStudent Document nEx StuDocument 6 3 5 使用CFile类 文件的打开和关闭 1 构造一个不带指定任何参数的CFile对象 2 调用成员函数Open并指定文件路径以及文件标志 CFile类的文件访问方式 6 3 5 使用CFile类 2 文件的读写和定位 CFile还支持获取文件状态 包括文件是否存在 创建与修改的日期和时间 逻辑大小和路径等 rStatus用来存放文件状态信息 它是一个CFileStatus结构类型 该结构具有下列成员 CTimem ctime文件创建日期和时间CTimem mtime文件最后一次修改日期和时间CTimem atime文件最后一次访问日期和时间LONGm size文件的逻辑大小字节数 就像DOS命令中DIR所显示的大小BYTEm attribute文件属性charm szFullName MAX PATH 文件名 3 CFile和CArchive类之间的关联 可以将一个外部磁盘文件和一个CArchive对象关联起来 6 4 1 一般视图类的使用 MFC中的CView类及其它的派生类封装了视图的各种不同的功能 它们为用户实现最新的Windows特性提供了很大的便利 CView的派生类及其功能描述 6 4 1 一般视图类的使用 1 CEditView类 CEditView类对象是一种视图 像CEdit类一样 它也提供窗口编辑控制功能 可以用来执行简单文本操作 如打印 查找 替换 剪贴板的剪切 复制和粘贴等 更改CEx EditView的基类 Ex Edit运行结果 6 4 1 一般视图类的使用 2 CRichEditView类 CRichEditView类使用了复文本编辑控件 因此它支持混合字体格式和更大数据量的文本 CRichEditView类被设计成与CRichEditDoc和CRichEditCntrItem类一起使用 它们可实现一个完整的ActiveX包容器应用程序 3 CFormView类 1 添加并设计表单 NewForm 对话框 添加表单后的开发环境 6 4 1 一般视图类的使用 2 完善代码并测试 Ex Form运行结果 Ex Form最终运行结果 3 CHtmlView类 CHtmlView类是在文档视图结构中提供WebBrowser控件的功能 4 CScrollView类 5 列表视图 CScrollView类不仅能直接支持视图的滚动操作 而且还能管理视口的大小和映射模式 并能响应滚动条消息 键盘消息以及鼠标滚轮消息 列表视图类CListView按照MFC文档视图结构封装了列表控件CListCtrl的功能 6 树视图 6 4 2 文档与视图的相互作用 CView GetDocument函数 视图对象只有一个与之相联系的文档对象 它所包含的GetDocument函数允许应用程序由视图得到与之相关联的文档 2 CDocument UpdateAllViews函数 如果文档中的数据发生了改变 那么所有的视图都必须被通知到 以便它们能够对所显示的数据进行相应的更新 3 CView OnUpdate函数 这是一个虚函数 4 CView OnInitialUpdate函数 当应用程序被启动时 或当用户从 文件 菜单中选择了 新建 或 打开 时 该CView虚函数都会被自动调用 5 CDocument OnNewDocument函数 在文档应用程序中 当用户从 文件 菜单中选择 新建 命令时 框架将首先构造一个文档对象 然后调用该虚函数 6 4 3 应用程序对象指针的互调 从文档类中获取视图对象指针 在文档类中有一个与其关联的各视图对象的列表 并可通过CDocument类的成员函数GetFirstViewPo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【正版授权】 ISO 11452-1:2025 EN Road vehicles - Component test methods for electrical disturbances from narrowband radiated electromagnetic energy - Part 1: General principles and termi
- 2020-2025年安全员之B证(项目负责人)全真模拟考试试卷A卷含答案
- 企业审计实务教学课件
- 第四节产品的包装与储运PackingStoringandT
- 叙事作文教学课件
- Brand KPIs for milk:Milky Mist in India-英文培训课件2025
- 口腔种植学介绍课件教案
- 小学生科普课程课件
- 2025年初中科学教师课程标准考试测试卷及答案
- 2025年新初二英语人教新版学困生专题复习《连词成句》
- 2025年北京市中考数学真题试卷及答案
- 软件项目需求调研报告样例
- 硬笔书法全册教案共20课时
- 模切品质培训
- 深圳市公安局招聘警务辅助人员笔试真题2024
- 会展销售培训
- 2025年安徽省中考数学试卷真题(含标准答案及解析)
- 政府采购法律法规及操作实务
- CJ/T 409-2012玻璃钢化粪池技术要求
- 中国慢性髓性白血病诊疗指南更新
- 消防跑点培训材料
评论
0/150
提交评论