cancle()高手不会

jackiecheng001 2006-03-09 11:18:28
如何做类似office撤消操作的功能,就是返回功能
...全文
252 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
jackiecheng001 2006-03-16
  • 打赏
  • 举报
回复
大家到我另外一个帖子接分啊
呵呵
jackiecheng001 2006-03-16
  • 打赏
  • 举报
回复
谢谢
TianChong(VC.NET++) , li_d_s(我是小鬼-日货?送我都不要,哪怕是丰田和日产的轿车)
为答谢TianChong(VC.NET++),我会特地送分 100 的
li_d_s 2006-03-15
  • 打赏
  • 举报
回复
他说的那个方法有点小问题的,如果是用rowscopy过来,状态变成了newmodified!,保存时候就是插入而不是更新了,而且如果真的要实现改了三处,想cancel两处,这个非常之麻烦
jackiecheng001 2006-03-15
  • 打赏
  • 举报
回复
TianChong(VC.NET++)
谢谢啊,你说的第二种方法我还有点具体的不很明白,望指点啊!
就是在一个dw上面我怎样 知道用户上次修改了什么,在哪个位置,修改后的标识位(方便返回撤消时判断撤消的步数)
呵呵,我想你肯定是从pb转向vc++ 的,看过你的其他回复,觉得你window下面的功底不错
佩服,向你学习,努力中
hangzhou6274(猎人)
本家,还没有回来啊?呵呵,得先注明美国时间啊,呵呵
TianChong 2006-03-15
  • 打赏
  • 举报
回复
上面打错了字,“新增列和删除了列”修正为:“新增行和删除了行”

为了能恢复被删除的行,你最好在undoit的数组里也保存对应行的行号及列号,行号就是被删除时的行号,列号为-1,表示被删除,0表示是新增的,这样就可以使用insert或delete来对删除或新增的行进行恢复。相当麻烦的,我不明白你为什么要这样处理,方法都在上面了,消化消化吧。
TianChong 2006-03-15
  • 打赏
  • 举报
回复
我明白了,你非要像OFFICE的EXCEL一样,例如我先修改了第一行,然后又修改了第五行,然后又修改了第三行,那么,现在要取消操作就是:第一次将第三行恢复,如果再按一次取消就恢复第五行,再按一次就恢复第一行,对吧?这个也简单啊,只是你的分这么少,要我们答这么多次,实在...咳咳...我还是帮人帮到底吧,不过请适当加些分(100分可以吧):

假设你要撤消一百次(够用了吧?)

新建一个数组:undoit[100][2] //100行,2列
新建一个全局的(或者是窗口级的)数字变量long ltimes,用于记录修改的次数,初始值为0
对这个窗口或数据窗口建立eventid为pbm_keydown的事件,并监控ALT+Z键是否同否被按下,不能使用CTRL+Z,因为这个WINDOWS有默认的操作,最好不要改它.

窗口有二个dw,一个叫dw_1,一个叫dw_2,打开窗口时同时提取数据,只是dw_1显示,dw_2隐藏
dw_1里要对itemchanged等事件进行监控,发现任何一列数据被改动就进行以下的记录操作:
读取这个被修改的列和行,将之保存到这个数组里:
ltimes++
if ltimes>100 then
if Messagebox("提示","不支持超过100的UNDO操作,您是否要丢弃100次之前的UNDO记录? ",question!,yesno!)=1 then
//使用FOR从undoit[1][1]=undoit[2][1]....一直将所有2-100行往前移一行.也就是原来第二行变第一行,第三行变第二行,...第一百行变第九十九行了,这样第一百行的位置又可以用了,但第一行已被丢弃.
end if
end if

undoit[ltimes][1]=行号
undoit[ltimes][2]=列号
只要一直有修改就一直这么操作

当发现用户要UNDO时,也简单:
因为永远是从最后一步往前撤消,所以,我们只要分别读取:
行号=undoit[ltimes][1]
列号=undoit[ltimes][2]

就知道,是这一个单元格要撤消,我们从dw_2里读取这个数据出来,注意你要分辨这个单元格是什么类型的,是string,还是datatime还是其它,这个自己去完成吧,也不难,先取这个类型值,然后使用choose case来作处理,是string就用dw_2.getitemstring(行,列),是日期就用dw_2.getitemdatetime(行,列),等等,取到后就使用dw_1.setitem()设置回dw_1,如果设置回去成功,那么这一步就算被撤消了,ltimes要减1,如果ltimes被撤消了所有步骤,你还要提示一下已没有可撤消的步骤。

另外还要注意比较难的操作有:
新增列和删除了列,这个也可以实现,但要更复杂,如你另建一个数组来保存删除的行号,并且在撤消操作时要检查一下这个数组,如果被删除行数组(就叫rowdel[]吧)里存在X个行号比你要撤消的行号小的记录,假设有Y条,那你从dw_2读取后,要在setitem时,将行号减y,否则就错了。总之方法要好好整理整理,一定可以的,不过这样真的很烦。我可没这么多空写出代码来,我想有方法已经足够清楚了。自已领会吧。收笔。
hangzhou6274 2006-03-15
  • 打赏
  • 举报
回复
还没解决这个问题啊,有点难度的哦
TianChong 2006-03-14
  • 打赏
  • 举报
回复
简单的cancel功能是很容易实现的,例如,你让用户在操作的最后要进行[保存]确认,如果后悔了想不改,可以点击[取消]按钮(不是关闭),其实和关闭不保存是差不多的意思,只是这是不关闭窗口也不保存,而且恢复到未修改的状态,有三个方法:
1.点击取消按钮,就调用dw_1.retreve().这样程序就得新检索了数据,而没有将你修改的东西保存.
2.窗口有二个dw,一个叫dw_1,一个叫dw_2,打开窗口时同时提取数据,只是一个显示,一个隐藏,然后用户要取消数据时,就将dw_2的数据一行一行的读取恢复到dw_1中,这个很简单的,直接使用rowcopy()就可以了,不要真的一行一行的去复制,这样很慢的.
3.如果是保存之后才想取消,就麻烦一些,你要每次都将更新前的数据保存到一个临时表中,例如只保存5次,大于5次的自动删除,这样你就可以根据情况有5次的恢复机会,但是这样会很浪费空间啊,也可以根据更新语句来撤消操作,这可就相当复杂了,这里不多说了.像MSSQL SERVER的数据库日志就是这样记录的.总之,一般不要使用第3种方法.
jackiecheng001 2006-03-14
  • 打赏
  • 举报
回复
顶下 马上给分阿 楼上大哥,多谢阿
li_d_s 2006-03-10
  • 打赏
  • 举报
回复
比如你再dw里面改了两个地方,通过buffer也能判断到哪个地方改过了,但是这个是没有先后顺序的,如果要cancel就只能两个都cancel了,而不能说你想要cancel掉后面一个操作,这样很麻烦的
jackiecheng001 2006-03-10
  • 打赏
  • 举报
回复
li_d_s(我是小鬼-日货?送我都不要,哪怕是丰田和日产的轿车)
很高兴楼上能给我建议,现在我把问题补充一下

返回主要是在dw中,主要是对数值的上一步的撤消,我想通过查看primary buffer中的状态位进行返回,各位老大给点意见,能具体最好啊,分数可以再加啊,只要大家发言啊
li_d_s 2006-03-09
  • 打赏
  • 举报
回复
如果只是简单的文本输入控件的cancel,本身已经自带了
如果是操作的cancel,就需要记录每一步干了啥,然后给反过来,这个很麻烦的说,比如dw改了哪些数据都要记录下来

609

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder DataWindow
社区管理员
  • DataWindow社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧