各位大老,我现在在做一个项目,需要用到richedit做痕迹保留的问题,实在是没有头绪,尤其是如何记录用户每次修改的痕迹一点思路都没有,有谁做过这方面的东东,给个提示或者有这方面的资料给个链接啊。(关于用WORD插件做痕迹保留的不需要)

解决方案 »

  1.   

    参考下VCL里的TRecall类TRecall acts as a temporary repository for the properties of a persistent object. To use TRecall 
     Create an instance of TRecall, assigning an object to use for storing property values (the storage object), and an object whose property values it represents (the reference object). When you create an instance of TRecall, it automatically stores the current properties of the reference object. 
    Call the Store method at any time to take a snapshot of the reference object's properties. TRecall updates the storage object so that it reflects only the property settings from the last time you called the Store method (or, if Store was never called, from the point when the TRecall object was created). 
    Delete the TRecall object to restore the reference object to the set of properties it had when you last called the Store method. 
    If you do not want the TRecall object to restore the properties it is saving, call the Forget method. After you call Forget, the TRecall object can't be used. It does not update the reference object when destroyed and can't save any more properties. You can use TRecall to save the properties of any persistent object, using any explicitly specified storage object. In addition, TRecall has several descendants with their own built-in storage objects that work only with a specific class of reference object. These include TFontRecall, TPenRecall, and TBrushRecall. 
      

  2.   

    我跟踪了TRECALL的源代码,trecall只是实现对处理的控件实现记录最后一次引用对象的属性值而已啊,怎么能够实现痕迹保留呢。我需要的痕迹保留即:对同一篇文档而言,不同的用户操作,能够记录用户每次修改的痕迹并保留。也就是所谓公文流转中的“痕迹保留”功能,不是对文档的REDO/UNDO操作哦。或者说我没有发现TRECALL的更深的用法?请明示啊。
      

  3.   

    补充一下:需要用RICHEDIT来实现,不需要调用WORD来实现。
      

  4.   

    WORD里面好象是通过建立隐藏的临时文件来出来的吧。
      

  5.   

    richedit做痕迹保留?只知道Word
      

  6.   

    谁能给一个完整的思路啊,我现在是想: 在一个用户添加新的文本后或者删除文本,将这段文本的相关参数保存下来,另外一个用户在使用这个文本的时候,将上一个用户处理的文本加色重新回放,但是我现在不知道要保存什么参数好,才能准确定位到指定的文本里去。就象用word的修订功能,每个用户操作都会记录下来那样。
      

  7.   

    那里打开的就在那里描述。
    如 病人自感恶心,并有呕吐腹泻,这样描述也是可理解的。楼主是在做HIS吗。建议用Rx控件包中的RichEdit那个封装的比较好些,并且是免费的。
      

  8.   

       呵呵,谢谢,我现在用的就是RICHEDITOR控件,用楼上的例子来说明:就是我想对“呕吐”这个被删除的信息记录下来是哪个用户什么时间操作的,不知道要记录什么东西才能回放;
       现在我可以处理诸如按"DELETE“键删除做标记;按”backspace“键删除做标记,插入等做标记,但是我的问题是我需要记录哪些信息才合适,目的是我把文件保存重新打开后要重新将这些标记的信息重新标识出来。
       我现在的思路是用一个列表来记录一个包含有用户号、操作时间,操作开始位置和操作长度,操作者的REVINDEX号等信息,在保存的时候将这些记录下来,然后再回放,但是这种思路存在几个问题:
       1、当有信息输入的时候,不会去遍历一遍列表修改相应的记录的操作开始位置吧;
       2、当打开文件时,我要对列表进行便利;
       以上两个问题会造成性能上的问题;   另外,我跟踪过,当richedit保存的时候,只是标记了“<reserved>”,但是不能记录以上我所说的痕迹信息。按照rtf规范直接写串都不行。
      

  9.   

    多重Undo和Redo要RichEdit v2.0才提供,要用到EM_SETUNDOLIMITEM_GETUNDONAMEEM_GETREDONAMEEM_UNDOEM_CANUNDOEM_REDOEM_CANREDO :beta, 时间:2001-5-20 11:02:30, ID:536939自己实现,不过很麻烦 :-p每次改变都把改变的 开始位置、长度、字符串和类型 添加到一个 TList 里面(用一个record)Undo也就是提出某次操作的这些信息然后实现就可以了,你想,有了这些信息,完全可以重现原来的操作了不过好像Redo还要用一个 TList,和Undo的不是同一个。我曾经想做过,不过无法截获文字拖拽的消息,于是放弃 :-( mantousoft, 时间:2001-5-29 19:33:11, ID:546071去下载MiniHex的源代码看看,下面是我从里面抄的:){**********************************************************}{ }{ 功能:管理 Undo 和 Redo. }{ 说明:采用循环队列记录Undo动作和Redo动作, }{ Undo和Redo是两个不同的队列。 }{ }{**********************************************************}unit ActsMgr;interfaceusesWindows, Messages, SysUtils, Classes,Controls, Forms, Dialogs;typeTActType = ( //动作类型atNone,atModify,atInsert,atDelete);PAct = ^TAct;TAct = record //动作记录Enabled: Boolean; //该动作是否能用ActType: TActType; //动作类型Buf: string; //缓冲区Offset: Integer; //偏移Count: Integer; //字节数CurPos: Integer; //光标位置Prev: PAct; //Prev指针Next: PAct; //Next指针end;TActs = array of TAct;TActsMgr = classprivateFUndoActs: TActs; //Undo队列FUndoHead: PAct; //队列头指针FUndoTail: PAct; //队列尾指针FRedoActs: TActs; //Redo队列FRedoHead: PAct; //队列头指针FRedoTail: PAct; //队列尾指针FMaxUndo: Integer; //最大Undo次数procedure SetMaxUndo(Value: Integer);procedure InitAct(var Act: TAct);publicconstructor Create(AMaxUndo: Integer);destructor Destroy; override;property MaxUndo: Integer read FMaxUndo write SetMaxUndo;function AddUndoItem: PAct;function AddRedoItem: PAct;function Undo: PAct;function Redo: PAct;function CanUndo: Boolean;function CanRedo: Boolean;end;implementationconstructor TActsMgr.Create(AMaxUndo: Integer);beginSetMaxUndo(AMaxUndo);end;destructor TActsMgr.Destroy;beginSetLength(FUndoActs, 0);SetLength(FRedoActs, 0);end;procedure TActsMgr.SetMaxUndo(Value: Integer);vari: Integer;beginFMaxUndo := Value;SetLength(FUndoActs, FMaxUndo + 1);for i := 0 to FMaxUndo dobeginif i = FMaxUndo thenFUndoActs[i].Next := @FUndoActs[0]elseFUndoActs[i].Next := @FUndoActs[i+1];if i = 0 thenFUndoActs[i].Prev := @FUndoActs[FMaxUndo]elseFUndoActs[i].Prev := @FUndoActs[i-1];FUndoActs[i].Enabled := False;end;FUndoHead := @FUndoActs[0];FUndoTail := @FUndoActs[0];SetLength(FRedoActs, FMaxUndo + 1);for i := 0 to FMaxUndo dobeginif i = FMaxUndo thenFRedoActs[i].Next := @FRedoActs[0]elseFRedoActs[i].Next := @FRedoActs[i+1];if i = 0 thenFRedoActs[i].Prev := @FRedoActs[FMaxUndo]elseFRedoActs[i].Prev := @FRedoActs[i-1];FRedoActs[i].Enabled := False;end;FRedoHead := @FRedoActs[0];FRedoTail := @FRedoActs[0];end;procedure TActsMgr.InitAct(var Act: TAct);beginwith Act dobeginEnabled := True;Buf := '';Offset := 0;Count := 0;CurPos := 0;end;end;function TActsMgr.AddUndoItem: PAct;beginInitAct(FUndoHead^);Result := FUndoHead;if FUndoHead^.Next = FUndoTail thenFUndoTail := FUndoTail^.Next;FUndoHead := FUndoHead^.Next;FUndoHead^.Enabled := False;end;function TActsMgr.AddRedoItem: PAct;beginInitAct(FRedoHead^);Result := FRedoHead;if FRedoHead^.Next = FRedoTail thenFRedoTail := FRedoTail^.Next;FRedoHead := FRedoHead^.Next;FRedoHead^.Enabled := False;end;function TActsMgr.Undo: PAct;beginif not CanUndo thenbeginResult := nil;Exit;end;FUndoHead := FUndoHead^.Prev;FRedoHead := FRedoHead^.Prev;Result := FUndoHead;end;function TActsMgr.Redo: PAct;beginif not CanRedo thenbeginResult := nil;Exit;end;Result := FRedoHead;FRedoHead := FRedoHead^.Next;FUndoHead := FUndoHead^.Next;end;function TActsMgr.CanUndo: Boolean;beginResult := (FUndoHead <> FUndoTail);end;function TActsMgr.CanRedo: Boolean;beginResult := FRedoHead^.Enabled;end;end.
      

  10.   

    顺便还说一句,RichEdit3.0功能更强,BUG更少.
      

  11.   

    嗯,我现在用的rxrichedit控件是可以支持3.0,看来这个问题是有点复杂啦,再等等看看有没有其他的思路进来,晚上再结贴吧