高级程序设计语言-MFC(资源的应用).ppt_第1页
高级程序设计语言-MFC(资源的应用).ppt_第2页
高级程序设计语言-MFC(资源的应用).ppt_第3页
高级程序设计语言-MFC(资源的应用).ppt_第4页
高级程序设计语言-MFC(资源的应用).ppt_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

高级程序设计语言,mfc(资源的应用),mfc(资源应用),菜单、工具栏和状态栏,5.1.1 文档应用程序的mfc类结构,用mfc appwizard(exe)创建一个默认的单文档应用程序ex_sdi,将项目工作区窗口切换到“classview(类视图)”页面,可以看到构成ex_sdi 应用程序框架的mfc类结构,如图所示。再创建一个默认的多文档应用程序ex_mdi,可以看到如图所示的mfc类结构。,5.1.2 项目的文件组织,visual c+ 6.0中,项目中所有的源文件都采用文件夹的方 式进行管理的,每一个类的源代码均保存同名的h和cpp文件。,.dsp:vc开发环境生成的工程文件。 .dsw:vc开发环境生成的workspace文件,用来把多个工程 组织到一个workspace中。工作区文件。 .rc:资源定义文件 .clw:classwizard生成的用来存放类信息的文件。 .opt:vc开发环境自动生成的用来存放workspace中各种选项的文件。工程关于开发环境的参数文件。如工具条位置信息等。 .pch(pre-compiled file) 预编译文件,可以加快编译速度。,5.1.2 项目的文件组织,还有相应的debug(调试)、res(资源)等子文件夹。 程序项目win32 release版本,它与debug的区别在于:debug版本的运行程序有相应的调试信息码,而release版本的运行程序没有,但release版本的运行程序经过代码的优化,其程序的运行效率被最大提升。 通过选择”build”“set active configuration”菜单命令,在图所示的对话框中,选择“ex_sdi-win32 release”,然后单击确定按钮,编译后即可。,5.2 菜单,windows程序都有各自的菜单。为了使windows程序更容易 操作,许多程序员对于菜单的设计都遵循下列一些规则:,若选择某菜单项会弹出一对话框,那么在该菜单项文本后 有“”。 (2) 若某项菜单有子菜单,那么在该菜单项文本后有“”。 (3) 若菜单项需要助记符,则用括号将带下划线的字母括起来。助记符与alt构成一个组合键,当按住“alt”键不放,再敲击(4) 该字母时,对应的菜单项就会被选中。,(4)若某项菜单需要快捷键的支持,则一般将其列在相应菜单项文本之后。所谓“快捷键”是一个组合键,如ctrl+n,使用时是先按下“ctrl”健不放,然后再按“n”键。任何时候按下快捷键,相应的菜单命令都会被执行,菜单的执行顺序,当一个菜单项的时候,最先接受到菜单项消息的是 cmainframe框架类。 cmainframe框架类将会把菜单项消息交给它的子窗口view 类,由view类首先进行处理; 如果view类检测到没对该菜单项消息做响应,则view类把 菜单项消息交由文档类doc类进行处理; 如果doc类检测到doc类中也没对该菜单项消息做响应,则 doc类又把该菜单项消息交还给view类,由view类再交还给 cmainframe类处理。 如果cmainframe类查看到cmainframe类中也没对该消 息做响应,则最终交给app类进行处理,5.1.1 更改应用程序菜单,通过菜单编辑器直接修改菜单资源idr_mainframe可以实现添加和修改应用程序菜单,如下示例过程。 例ex_menusdi 更改应用程序菜单 (1) 创建一个默认的单文档应用程序ex_menusdi。 (2) 在项目工作区窗口中选择resourceview页面,双击 资“menu”项中的idr_mainframe,则菜单编辑器窗口 出现在主界面的右边,项目ex_menusdi相应的菜单资 源在菜单编辑器窗口中显示出来。,(3) 按快捷键ctrl+r,弹出“插入资源”对话框,在资源类型中选定“menu”,如图,5.1.1 更改应用程序菜单,单击新建按钮,系统就会为应用程序添加一个新的菜单资源,并自动赋给它一个默认的标识符名称(第一次为idr_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,需要再次强调的是,符号&用来指定后面的字符是一个助记符。,打开ex_menusdi程序菜单资源idr_mainframe,在“查看”菜单的最后添加一个子菜单项“显示测试菜单(&m)”,id设为id_view_test。 为cmainframe类添加一个cmenu类型的成员变量m_newmenu,cmenu类是用来处理菜单的一个mfc类。,5.1.1 更改应用程序菜单,按快捷键ctrl+w打开mfc classwizard对话框,切换到message maps页面,从“class name”列表中选择cmainframe,分别为菜单项id_view_test和id_test_return添加command消息映射,使用默认的消息映射函数名,并添中下列代码:,void cmainframe: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 使用键盘快捷键,建立一新的加速键,双击加速键列表的最下端的空行,弹出如图所示的“accel properities”对话框,可设置的属性如表所示 。,5.2.2 使用键盘快捷键,在上述对话框中,选择ex_menusdi添加的“显示测试 菜单”菜单项id_view_test作为要联用的加速键的id号,单 击下一键按钮,并按下ctrl+1作为此加速键的键值。 按同样的方法,为菜单项id_test_return添加速键ctrl+2。需要说明的是,为了使其他用户能查看并使用该加速键,还需在相应的菜单项文本后面添加加速键内容。例如,可将id_view_test菜单项的标题改成“显示测试菜(&m)tctrl+1”,其“t”是将后面的“ctrl+1”定位到一个表位。 编译运行并测试。当程序运行后,按“ctrl+1”和“ctrl+2 将执行相应的菜单命令。,菜单的编号,一个菜单栏可以有若干个子菜单,一个子菜单又 可以有若干个菜单项等。对菜单栏的子菜单由左至右 建立从0开始的索引。对特定子菜单的菜单项由上至下 建立了从0开始的索引。访问子菜单和菜单项均可以通 过其索引或标识(如果有标识的话)进行 。,5.2.3 菜单的编程控制,创建菜单 cmenu类的createmenu和createpopupmenu分别用来创建一个菜单或子菜单框架,它们的原型如下: bool createmenu( ); / 产生一个空菜单 bool createpopupmenu( ); / 产生一个空的弹出式子菜单 2. 装入菜单资源 将菜单资源装入应用程序中,需调用cmenu成员函数loadmenu,然后用setmenu对应用程序菜单进行重新设置。 bool loadmenu( lpctstr lpszresourcename ); bool loadmenu( uint nidresource ); 其中,lpszresourcename为菜单资源名称,nidresource为菜单资 源id号。,5.2.3 菜单的编程控制,3. 添加菜单项 当菜单创建后,用户可以调用appendmenu或insertmenu 函数来添加一些菜单项。appendmenu是将菜单项添加在菜单的末尾处,而insertmenu在菜单的指定位置处插入菜单项,并将后面的菜单项依次下移。,bool appendmenu( uint nflags, uint nidnewitem = 0,lpctstr psznewitem = null ); bool appendmenu( uint nflags, uint nidnewitem, const cbitmap* pbmp ); bool insertmenu( uint nposition, uint nflags, uint nidnewitem = 0, lpctstr lpsznewitem = null ); bool insertmenu( uint nposition, uint nflags, uint nidnewitem, const cbitmap* pbmp );,4.删除菜单项 调用deletemenu函数可将指定的菜单项删除,需要注意的是:调用该函数后,不管菜单依附的窗口是否改变,都应调用cwnd:drawmenubar使菜单更新。,5.2.3 菜单的编程控制,函数deletemenu的原型如下:,bool deletemenu( uint nposition, uint nflags ); 其中,参数nposition表示要删除的菜单项位置,它由nflags进行说明。若当nflags为mf_bycommand时,nposition表示菜单项的id号,而当nflags为mf_byposition时,nposition表示菜单项的位置(第一个菜单项位置为0)。,5. 获取菜单项 下面的四个cmenu成员函数分别获得菜单的项数、菜单项的id号、菜单项的文本内容以及弹出式子菜单的句柄。 uint getmenuitemcount( ) const; 该函数用来获得菜单的菜单项数,调用失败后返回-1。,uint getmenuitemid( int npos ) const; 该函数用来获得由npos指定菜单项位置(以0为基数)的菜单项的标识号,若npos是separator,则返回-1。,5.2.3 菜单的编程控制,int getmenustring( uint niditem, cstring 该函数用来获得指定菜单的弹出式菜单的菜单句柄。该弹出式菜单位置由参数npos指定,开始的位置为0。若菜单不存在,则创建一个临时的菜单指针。,例ex_menu 菜单项的编程控制 (1) 创建一个默认的单文档应用程序ex_menu。,5.2.3 菜单的编程控制,选择“查看”菜单“resource symbols”命令, “资源符号”对话框,它能对应用程序中的资源标识符进行管理。程序中添加的菜单项需要一个标识值,最好用一个标识符来代替这个值,因此这里通过“资源符号”对话框来创建一个新的标识符。,5.2.3 菜单的编程控制,(3) 单击新建按钮,在名字(name)框中输入一个新的标识符id_new_menuitem。在值(value)框中,输入该id的值,系统要求用户定义的id值应大于15(0x000f)而小于61440(0xf000)。保留默认的id值101,单击确定按钮。,5.2.3 菜单的编程控制,(4) 关闭“资源符号”对话框,在cmainframe:oncreate函数中添加下列代码,该函数在框架窗口创建时自动调用。,int cmainframe:oncreate(lpcreatestruct lpcreatestruct) . cmenu* psysmenu = getmenu(); / 获得程序菜单指针 / 获得第二个子菜单的指针 cmenu* psubmenu = psysmenu-getsubmenu(1); cstring strmenuitem(“新的菜单项“); psubmenu-appendmenu(mf_separator); / 增加一水平分隔线 / 在子菜单中增加一菜单项 psubmenu-appendmenu(mf_string,id_new_menuitem,strmenuitem); / psubmenu-insertmenu(1,mf_byposition, id_new_menuitem, strmenuitem); / 允许没有使用on_update_command_ui或on_command的菜单项 m_bautomenuenable = false; / 关闭系统自动更新菜单状态 / 激活菜单项 psysmenu-enablemenuitem(id_new_menuitem,mf_bycommand|mf_enabled); drawmenubar(); / 更新菜单 return 0; ,5.2.3 菜单的编程控制,(5) 用mfc classwizard处理oncommand消息并检测用户菜单的nid参数。,bool cmainframe:oncommand(wparam wparam, lparam lparam) / wparam的低字表示菜单、控件、加速键的命令id if (loword(wparam) = id_new_menuitem) messagebox(“你选中了新的菜单项“); return cframewnd:oncommand(wparam, lparam) ,(6) 编译运行并测试。 这样当选择菜单“编辑”“新的菜单项”命令后,就会弹一个对话框,显示“你选中了新的菜单项”消息。,5.2.4 使用快捷菜单,1. 快捷菜单实现函数 用资源编辑器和mfc库的cmenu:trackpopupmenu函数可以很容易地创建这样的菜单,cmenu:trackpopupmenu 函数原型如下:,bool trackpopupmenu( uint nflags, int x, int y, cwnd* pwnd, lpcrect lprect = null ); 该函数用来显示一个浮动的弹出式菜单,其位置由各参数决定。nflags表示菜单在屏幕显示的位置以及鼠标按钮标志,nflags的值及其对其他参数的影响,5.2.4 使用快捷菜单,2. 示例 本示例是在前面ex_sdi基础上进行的,当显示主 菜单idr_mainframe时,右击鼠标弹出“查看”菜 单的子菜单,当显示菜单idr_menu1时,右击鼠 标弹出“测试”菜单的子菜单。,续例ex_menusdi 使用快捷菜单 (1) 打开前面的单文档应用程序ex_menusdi。,(2) 用mfc classwizard在cmainframe类添加 wm_contextmenu消息映射。,(3) 编译运行并测试。,void cmainframe:oncontextmenu(cwnd* pwnd, cpoint point) cmenu* psysmenu=getmenu(); /获得程序菜单指针 int ncount=psysmenu-getmenuitemcount();/获得顶层菜单个数 int nsubmenupos=-1; for(int i=0;igetmenustring(i,str,mf_byposition); /若是菜单标题是“查看”或“测试”,记录下所在位置 if(str.left(4)=“查看“)|(str.left(4)=“测试“) nsubmenupos=i; break ; psysmenu-getsubmenu(nsubmenupos)-trackpopupmenu( tpm_centeralign|tpm_rightbutton,point.x,point.y,this); ,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_view_test,在提示框内键入“显示测试菜单n显示测试菜单”。,5.3.2 工具按钮和菜单项相结合,设计的两个工具栏按钮,(5) 编译运行并测试。程序运行后,将鼠标移至刚才设计的第一个工具按钮处,这时在状态栏上显示出“返回应用程序主菜单”信息,若稍等片刻会弹出提示小窗口,显示出“返回主菜单”字样,单击新添加的这两个按钮,会执行相应的菜单命令。,5.3.3 多个工具栏的使用,在用mfc appwizard创建的文档应用程序中往往只有一个工具栏,但在实际应用中,常常需要多个工具栏。,(1) 将项目工作区切换到resourceview页面,展开toolbar(工具栏)资源,用鼠标单击idr_mainframe不松开,按下ctrl键,移动鼠标将idr_mainframe拖到toolbar资源名称上,复制了工具栏默认资源idr_mainframe,复制后的资源标识系统自动设为idr_mainframe1。,(2) 右击工具栏资源idr_mainframe1,从弹出的快捷菜单中选择properties命令,如图所示,将id设为idr_toolbar1。,工具栏的创建步骤,1)创建工具栏资源 2)构造ctoolbar对象 3)调用create或createex创建工具栏并将它与该ctoolbar对象 连接。 4)用loadtoolbar为工具栏对象加载工具栏资源 5)设置工具栏和框架窗口的停靠或被停靠属性 6)让工具栏停靠在框架窗口,5.3.3 多个工具栏的使用,(3) 双击idr_toolbar1,打开工具栏资源,按图删除不要 的工具按钮。,(4) 在cmainframe类中添加一个成员变量m_wndtestbar,变 量类型为ctoolbar。ctoolbar类封装了工具栏的操作。,(5) 在cmainframe:oncreate函数中添加工具栏创建代码: int cmainframe:oncreate(lpcreatestruct lpcreatestruct) if (cframewnd:oncreate(lpcreatestruct) = -1) return -1;,5.3.3 多个工具栏的使用,int nres = 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(“failed to create toolbarn“); return -1; / fail to create ,在cmainframe:oncreate函数中添加下面的工具栏创建代码,/让工具栏可以停靠任何一边 m_wndtoolbar.enabledocking(cbrs_align_any); m_wndtestbar.enabledocking(cbrs_align_any); enabledocking(cbrs_align_any); /让框架窗口可以被停靠 dockcontrolbar( ,5.3.3 多个工具栏的使用,bool createex(cwnd* pparentwnd, dword dwctrlstyle = tbstyle_flat, dword dwstyle = ws_child | ws_visible | cbrs_align_top, crect rcborders = crect(0, 0, 0, 0), uint nid = afx_idw_toolbar); pparentwnd:父窗口指针 dwctrlstyle:工具栏按钮的风格 dwstyle:工具栏的风格 rcborders:工具栏四周边框大小,一般为0 nid:工具栏子窗口id,the desired styles for the control bar. can be one or more of the following: cbrs_align_top allows the control bar to be docked to the top of the client area of a frame window. cbrs_align_bottom allows the control bar to be docked to the bottom of the client area of a frame window. cbrs_align_left allows the control bar to be docked to the left side of the client area of a frame window. cbrs_align_right allows the control bar to be docked to the right side of the client area of a frame window. cbrs_align_any allows the control bar to be docked to any side of the client area of a frame window. cbrs_border_top causes a border to be drawn on the top edge of the control bar when it would be visible. cbrs_border_bottom causes a border to be drawn on the bottom edge of the control bar when it would be visible. cbrs_border_left causes a border to be drawn on the left edge of the control bar when it would be visible. cbrs_border_right causes a border to be drawn on the right edge of the control bar when it would be visible. cbrs_float_multi allows multiple control bars to be floated in a single mini-frame window. cbrs_tooltips causes tool tips to be displayed for the control bar. cbrs_flyby causes message text to be updated at the same time as tool tips. cbrs_gripper causes a gripper, similar to that used on bands in a crebar object, to be drawn for any ccontrolbar-derived class,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函数中添加下列代码:,int cmainframe:oncreate(lpcreatestruct lpcreatestruct) / 关闭测试工具栏 showcontrolbar( ,代码中,showcontrolba函数有三个参数,第一个用来指定要操作的工具栏或状态栏指针,第二个是一个布尔型,为true时表示显示,否则表示隐藏,第三个用来表示是否延迟显示或隐藏,为false时表示立即显示或隐藏。,5.3.3 多个工具栏的使用,(8) 在cmainframe:onviewtest和cmainframe:ontestreturn 函数中增加下列代码(红色显示,m_newmenu为cmenu类型):,void cmainframe:onviewtest() m_newmenu.detach(); /使菜单对象和菜单句柄分离 m_newmenu.loadmenu( idr_menu1 ); setmenu(null); / 清除应用程序菜单 setmenu( ,void cmainframe:ontestreturn() m_newmenu.detach(); /使菜单对象和菜单句柄分离 m_newmenu.loadmenu( idr_mainframe ); setmenu(null); setmenu( ,5.3.3 多个工具栏的使用,编译运行并测试,结果如图所示,左边是一开始 运行的结果,右边是单击工具按钮运行的结果。,5.4.1 状态栏的定义,数组中的元素是一些标识常量或是字符串资源的id号。 默认的indicator数组包含了四个元素:id_separator id_indicator_caps id_indicator_num id_indicator_scrl 分别显示出capslock、numlock和scrolllock这三个键的状态。,5.4.2 状态栏的常用操作,mfc的cstatusbar类封装了状态栏的大部分操作。,1. 增加和减少窗格 状态栏中的窗格分为信息行窗格和指示器窗格两类。在状 态 栏中增加一个信息行窗格,则只需在indicators数组中的 适当位置中增加一个id_separator标识即可;若在状态 栏中增加一个用户指示器窗格,则在indicators数组中的适 当位置增加一个在字符串表中定义过的资源id,其字符串 的长度表示用户指示器窗格的大小。若状态栏减少一个 窗格,操作与增加相类似,需减少indicators数组元素即可。,2. 在状态栏上显示文本 调用cstatusbar:setpanetext函数可以更新任何窗格(包 括信息行窗格)中的文本。此函数原型描述如下:,5.4.2 状态栏的常用操作,bool setpanetext( int nindex, lpctstr lpsznewtext, bool bupdate = true ); nindex是表示设置的窗格索引(第一个窗格的索引为0)。 lpsznewtext表示要显示的字符串。 若bupdate为true,则系统自动更新显示的结果。,例ex_sdimouse 将鼠标在窗口客户区的位置显示在状态栏上 (1) 创建一个默认的单文档应用程序ex_sdimouse。 (2) 将项目工作区切换到classview页面,展开cmainframe 所有项,双击构造函数cmainframe,在文档窗口中出现该 函数的定义,在它的前面就是状态栏数组的定义。,(3) 将状态栏indicators数组的定义改为下列代码: static uint indicators = id_separator, id_separator, ;,5.4.2 状态栏的常用操作,(4) 由于鼠标移动消息wm_mousemove在cmainframe类映射后不起作用,只能映射到cex_sdimouseview类中。cmainframe类定义的成员变量,需要在cex_sdimouseview类中添加访问cmainframe类的代码。,void cex_sdimouseview:onmousemove(uint nflags, cpoint point) cstring str; / 获得主窗口指针 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类中,有两个成员函数可以改变状态栏风格,它们是: void setpaneinfo( int nindex, uint nid, uint nstyle, int cxwidth ); void setpanestyle( int nindex, uint nstyle ); 其中,参数nindex表示要设置的状态栏窗格的索引,nid用来为状态栏窗格指定新的id,cxwidth表示窗格的像素宽度,nstyle表示窗格的风格类型,用来指定窗格的外观。,状态栏窗格的风格类型,void cex_statusview:onmousemove(uint nflags, cpoint point) cstring str; cclientdc dc(this);/得到客户区的设备dc cstatusbar* pstatus= ,5.4.3 改变状态栏的风格,mfc(资源应用)文档的读写,文档模板类,文档应用程序框架结构是在程序运行一开始被构造的。 csingledoctemplate* pdoctemplate; pdoctemplate = new csingledoctemplate( idr_mainframe, /资源id runtime_class(cex_studentdoc), /文档类 runtime_class(cmainframe), /主窗口类 runtime_class(cex_studentview); /视图类 adddoctemplate(pdoctemplate); adddoctemplate是类cwinapp的成员函数,其作用是建立 应用程序类、文档类、视图类以及主框架类之间的相互联系。,文档模板字符串资源,在mfc appwizard创建的应用程序资源中,许多资源标识符都是idr_mainframe这就意味着这些具有同名标识的资源将被框架自动加载到应用程序中。,标识文档类型、标题,序列化的概念,将文档中的数据成员变量的值保存在磁盘文件 中,或者将存储的文档文件中的数据读取到相应的 成员变量中。这个过程称为序列化( serialize )。,6.3.1 mfc文档读写机制,1. 创建空文档,文档应用程序运行到应用程序类的initinstance函数时,它会在调用了adddoctemplate函数之后,通过cwinapp: processshellcommand间接调用cwinapp的另一个非常有用的成员函数onfilenew,并依次完成工作: 1、构造文档对象,但不从磁盘中读数据; 2、构造cmainframe的对象,并创建该主框架窗口,但不显示; 3、构造视图对象,并创建视图窗口,也不显示; 4、通过内部机制,使文档、主框架和视图“对象”之间“真正”建立联 系。 5、调用cdocument:onnewdocment,并调用cdocument: deletecontents虚函数来清除文档对象的内容; 6、调用视图对象的cview:oninitialupdate虚函数对视图进行初始化 操作; 7、调用框架对象的cframewnd:activeframe虚函数,以便显示出 带有菜单、工具栏、状态栏以及视图窗口的主框架窗口。,对于单文档应用程序,文档、主框架以及视图对象仅被创建一次,adddoctemplate建立类之间联系,6.3.1 mfc文档读写机制,2. 打开文档,当mfc appwizard创建文档应用程序时,它会自动将“文件(file)”菜单中的“打开(open)”命令(id号为id_file_open)映射到cwinapp的onfileopen成员函数。 onfileopen函数进一步完成下列工作: 1、弹出通用文件“打开”对话框; 2、文档指定后,调用文档对象的cdocument:onopendocment虚 函数。 该函数将打开文档,并调用deletecontents清除文档对象 的内容,然 后创建 一个carchive对象用于数据的读取,接着又自 动调用serialize函数; 3、调用视图对象的cview:oninitialupdate虚函数;,6.3.1 mfc文档读写机制,3. 保存文档,当mfc appwizard创建应用程序时,它会自动将“文件(file)”菜单中的“保存(save)”命令与文档类cdocument的onfilesave函数在内部关联起来。 onfilesave函数进一步完成下列工作: 1、弹出通用文件“保存”对话框,让用户提供一个用户名; 2、调用文档对象的cdocment:onsavedocument虚函数,接着又 自动调用serialize函数,将carchive对象的内容保存在文档中。 注意: onfilesave函数和onfilesaveas函数的区别。不管文档 有没有存过, onfilesaveas都会执行上述两个步骤。 3、上述将文档存盘的必要操作都是由系统自动完成。,6.3.1 mfc文档读写机制,4. 关闭文档,(1) 若文档内容已被修改,则弹出一个消息对话框,询问用户是否需要将文档保存。用户选择“是”,则执行onfilesave过程。 (2) 调用cdocument:onclosedocument虚函数,关闭所有与该文档相关联的文档窗口及相应的视图,调用文档类cdocument的deletecontents清除文档数据。 注意:cdocument的protected类型变量m_bmodified的逻辑值来判断用户是否对文档进行修改。通常,可以用setmodifiedflag函数将该标志置为true,这样当用户关闭文档时,应用程序才会显示是否保存文档的询问消息对话框。,6.3.1 mfc文档读写机制,5. 文档读写操作,打开和保存文档时,系统都会自动调用serialize函数。在该函数中添加代码实现数据序列化目的 void cex_sdidoc:serialize(carchive& ar) if (ar.isstoring() /当文档数据需要存盘时 / todo: add storing code here else /当文档数据需要读取时 / todo: add loading code here ,isstoring确定归档文件是否被存储,6.3.1 mfc文档读写机制,carchive对象中可以使用运算符进行简单的数据读写功能,carchive(归档)类使用了缓冲区,即一段内存空间作为临时数据存储地,对carchive的读写都先依次排列到此缓冲区,当缓冲区满或用户要求时,将此段整理后的数据读写到制定的存储媒质。,5. 文档读写操作,它内部有一内部标记,表示文档是存入(写盘)还是载入(读盘)。,每次只能有一个活动的存档与一个carchive对象相连。,6.3.1 mfc文档读写机制,例6.3 一个简单的文档序列化实例 1)创建单文档应用程序ex_sdi 2)在string table资源,将idr_mainframe内容改为: 文档序列化操作n文档nex_sdin自定义文档(*.my)n.mynexsdi.documentnex_sdi document 3)在cex_sdidoc类中添加 public: char m_charchive100; cstring m_strarchive; bool m_bismydoc;,6.3.1 mfc文档读写机制,4),bool cex_sdidoc:onnewdocument() if (!cdocument:onnewdocument() return false; strcpy(m_charchive,“ ,6.3.1 mfc文档读写机制,5)向文档存入数据 void cex_sdidoc:serialize(carchive ,6.3.1 mfc文档读写机制,6)从文档载入(读出)数据,void cex_sdidoc:serialize(carchive ,1. 简单数组集合类的构造及元素的添加,对简单数组集合类构造的方法都是一样的,均是使用各自的构造函数,它们的原型如下:,cbytearray cbytearray( ); cdwordarray cdwordarray( ); cobarray cobarray( ); cptrarray cptrarray( ); cstringarray cstringarray( ); cuintarray cuintarray( ); cwordarray cwordarray( );,6.3.2. 使用简单数组集合类,例:cobarray array; /使用默认的内存块大小 cobarray * parray=new array; /使用堆内存中的默认的内存大小,类似于c中数组,但不同的是它们大小可以动态地增减 。其优点是:优化数据结构,简化数据的序列化操作,保证数据类型的安全性,6.3.2. 使用简单数组集合类,2、简单数组大小的设置:有效利用内存 void setsize(int nnewsize,int ngrowby=-1) nnewsize:新元素的数目(大于等于0) ngrowby:表示当数组需要扩展时允许可添加的最少元素数目,默认时为自动扩展 int getsize() const; 得到数组元素数目,6.3.2. 使用简单数组集合类,3、向简单数组元素添加元素 int add(cobject * newelement); 向数组末尾添加一个新元素,函数返回被添加元素的 数组下标; int append(const cobarray 向数组的末尾添加由src指定的另一个数组内容。函 数返回加入的第一个元素的序号。,6.3.2. 使用简单数组集合类,4、访问简单数组集合类的元素,在mfc中,既可以使用getat函数,也可使用“”操作符:,/ cobarray:operator 示例 cobarray array; array.add( new cage( 21 ) ); array0 = new cage( 30 ); / 替换元素0;,cobject* getat( int nindex ) const; 返回值:索引处当前元素的cobje

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论