已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
六、多重UnDo/ReDo功能:Edit Box控件提供了UnDo功能,但只能撤销一次操作,要想实现多重UnDo/ReDo功能需要自己设计。UnDo:撤销上一次修改操作,实现时应保存最近几次修改。ReDo:重做上一次撤销的操作,如果你撤销后后悔了,就ReDo吧。1、数据结构利用一个结构数组作为栈保存最近几次修改操作,定义如下:#defineUNDOMAX30/栈深度(最大Undo次数)/可撤销的操作名#defineOP_DELSEL1/删除选择(剪切)#defineOP_REPLACE2/替换选择#defineOP_DELETE3/删除#defineOP_BACK4/Backspace#defineOP_INPUT5/输入/Undo/Redo栈结构typedefstructintop;/操作名intpos;/操作的位置CStringstr1;/旧内容CStringstr2;/新内容STACKNODE;private:STACKNODEm_StackUNDOMAX;/工作栈intutop;/Undo栈顶指针intubottom;/Undo栈底指针intrtop;/Redo栈顶指针intrbottom;/Redo栈底指针BOOLb_DelFlag;/删除标志 UNDOMAX是预定义的栈深度,这里定义为30,表示可撤销最近的30步操作。STACKNODE结构用来定义栈节点,对每一次修改操作,需要纪录修改的位置,修改前的内容和修改后的内容。而且不同的修改操作在撤销时会略有不同,所以还需纪录修改操作名。所有修改可归结为5种:OP_DELSEL:删除选择的文本,此时str1保存被删除的文本,str2为空;OP_REPLACE:替换选择的文本,str1为被换掉的文本,str2为新文本;OP_DELETE:用Del键删除文本,str1保存被删除的文本,str2为空;OP_BACK:用BackSpace键删除文本,str1保存被删除的文本,str2为空;OP_INPUT:键盘输入新文本,str1为空,str2为新输入的文本。其它的操作都可归纳到这5种之内,如剪切就是OP_DELSEL,粘贴就是OP_REPLACE。m_Stack是长度为UNDOMAX的栈,它既是UnDo栈,也是ReDo栈,栈指针utop、ubottom确定UnDo栈位置,rtop、rbottom确定ReDo栈位置。2、栈操作初始化工作栈voidCEditBox:InitStack()for(inti=0;iUNDOMAX;i+)/栈空间m_Stacki.op=-1;m_Stacki.str1=_T();m_Stacki.str2=_T();utop=0;/栈指针ubottom=0;rtop=0;rbottom=0; 入栈voidCEditBox:Push(STACKNODE*pNode)utop=(utop+1)%UNDOMAX;/修改栈顶指针rtop=utop;/清空Redo栈rbottom=utop;if(utop=ubottom)/如果栈满ubottom=(ubottom+1)%UNDOMAX;/修改栈底指针m_Stackutop=*pNode;/入栈 每次修改操作时,把纪录修改的节点推入栈中。栈采用环形结构,当栈满时,新入栈的节点覆盖栈底节点,也就淘汰了最早进入栈内节点。UnDo出栈STACKNODE*CEditBox:UnDoPop()if(utop=ubottom)/栈空returnNULL;STACKNODE*p=&m_Stackutop;rtop=utop;/Redo入栈utop=utop-1;/退栈if(utopop=OP_DELETE&ptop-pos=pos)ptop-str1+=str1;return;STACKNODEnode;node.op=op;node.pos=pos;node.str1=str1;node.str2=str2;Push(&node);/入栈 每做一次修改操作,通过调用SetUndo()函数把修改操作保存到栈中。参数依次为操作名、修改位置、旧内容和新内容。函数中先根据参数填写好STACKNODE节点,再把它推入栈内即可。这里对OP_DELETE操作做了一个特殊处理,当我们用Del键在同一位置连续删除多个字符时,应该记录为一个操作,在撤销时一次性恢复。所以当操作为OP_DELETE时,如果发现上一次操作也是OP_DELETE,且位置相同,则把新删除的字符连接到上次删除的字符串中就行了。处理Del键和BackSpace键用按键消息检测是否进行了Del和BackSpace键操作,并进行相应处理。voidCEditBox:OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)CStringText,SelStr;intpos,SelLen;GetText(pos,Text,SelStr,SelLen);if(nChar=VK_DELETE&!Text.IsEmpty()/Del键if(SelLen)SetUndo(OP_DELSEL,pos,SelStr,_T();/保存删除内容elseif(Textpos=0)/BackSpace键if(SelLen)SetUndo(OP_DELSEL,pos,SelStr,_T();/保存删除的内容elseif(pos0&Textpos-1=0x20)SetUndo(OP_BACK,pos-1,Text.Mid(pos-1,1),_T();elseif(pos1&(Textpos-2pos,p-str2.GetLength();/选择文本ReplaceSel(p-str1);/恢复内容/重做voidCEditBox:EditRedo()STACKNODE*p=RedoPop();/出栈if(p)SetSelText(p-pos,p-str1.GetLength();/选择文本ReplaceSel(p-str2);/恢复内容 EditReplace()和RepAll()EditReplace()函数是用指定文本替换选择的文本。RepAll()是用指定文本重置编辑控件内容。/替换选择voidCEditBox:EditReplace(LPCTSTRstr)CStringText,SelStr;intpos,SelLen;GetText(pos,Text,SelStr,SelLen);SetUndo(OP_REPLACE,pos,SelStr,str);/保存到UndoReplaceSel(str);/替换选择/替换全部voidCEditBox:RepAll(LPCTSTRstr)SetSel(0,-1);/全选EditReplace(str);/替换SetSel(0);/设置插入点为起始位置 EditReplace()函数用来代替CEdit类的ReplaceSel()函数,两者功能一致,但用EditReplace()函数做的操作可以撤销,而ReplaceSel()函数做的操作不能撤销。RepAll()函数用来代替SetWindowText()和前面定义的SetText(),用它做的操作可以撤销。剪切和粘贴CEdit类的Cut()和Paste()函数都需要重新设计,而复制操作Copy()由于不修改文本,可照常使用。/剪切(代替Cut())voidCEditBox:EditCut()CStringText,SelStr;intpos,SelLen;GetText(pos,Text,SelStr,SelLen);SetUndo(OP_DELSEL,pos,SelStr,_T();/保存到UndoCut();/剪切/粘贴(代替Paste())voidCEditBox:EditPaste()OpenClipboard();/打开剪贴板HANDLEStrHandle;StrHandle=:GetClipboardData(CF_TEXT);char*pMem;pMem=(char*):GlobalLock(StrHandle);CStringstr;str=pMem;:GlobalUnlock(StrHandle);CloseClipboard();/关闭剪贴板if(!str.IsEmpty()EditReplace(str);/粘贴/全部剪切voidCEditBox:EditCutAll()SetSel(0,-1);/全选EditCut();/剪切/全部复制voidCEditBox:EditCopyAll()SetSel(0,-1);/全选Copy();/复制/全部删除voidCEditBox:EditClearAll()SetSel(0,-1);/全选EditReplace(_T();/清空 七、CEditBox类的使用:CEditBox类与CEdit类的用法基本相同。你可以在对话框里加入一个Edit Box控件,设置属性Multiline(多行文本)、Vertical scroll(垂直滚动条)、Want return(接收回车),并取消Auto HScroll属性(自动换行);用ClassWizard为控件添加变量,类型设置为CEditBox;再加入头文件#include EditBox.h;之后就可以根据需要编程控制这个编辑控件了。再解决一个小问题,就是Tab键的输入问题。在界面上,Tab键起到选择控件的功能,这导致无法在编辑控件中输入Tab符。解决方法是:先在资源中定义一个Tab快捷键:打开资源的Accelerator下的IDR_MAINFRAME,在快捷键表中添加一个VK_TAB的快捷键,假设ID设置为ID_KEY_TAB;回到视类,用ClassWizard为ID_KEY_TAD添加消息函数OnKeyTab(),在其中加入代码:/处理Tab输入voidCEditTestView:OnKeyTab()m_EditBox.EditReplace(_T(t); 这
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年威海职业学院单招职业适应性测试必刷测试卷附答案解析
- 2026年大理护理职业学院单招职业技能测试题库及答案解析(夺冠系列)
- 2026年宁夏工商职业技术学院单招职业倾向性考试必刷测试卷附答案解析
- 2026年唐山工业职业技术学院单招职业适应性测试题库及答案解析(夺冠系列)
- 房屋拆除更名协议书
- 房屋收回拍卖协议书
- 房屋流转合同协议书
- 房屋线上转让协议书
- 房屋翻新邻居协议书
- 房屋装修托管协议书
- 眼睛和皮肤光辐射最大允许照射量、产品光辐射危害风险专业分类及其可达发射极限
- 广东省高州市全域土地综合整治项目(一期)可行性研究报告
- 根管治疗技术指南
- 医学研究生统计学课件
- 2025国家开放大学《社区工作》形成性考核1234答案
- 院外转运的护理
- 终身教育视野下人工智能赋能特殊职业教育的实践与探索
- 古诗词中蕴含的物理知识
- 温通刮痧技术操作流程图及考核标准
- 三年级上册100道脱式计算加减法习题
- 医患互动与信任关系构建-洞察分析
评论
0/150
提交评论