记得好像在从RichEdit 2.0 开始,无限撤消已经成为RichEdit组件的默认设置,可以直接调用的.但是Delphi7中好像不行,只能撤消1步但是我在VB6,VB.NET中试了,就可以无限撤消.应该不是组件的问题.
我开始搜索了一下,方法好像都很复杂.有没有简单的方法?

解决方案 »

  1.   

    转贴:无限 Undo 和 Redo 功能
    RichEdit 控件怎样实现 RxRichEdit 的无限 UnDo 功能? 在 RxRichEdit 里的查找对话框如果遮住了选定的文字时 ,会自动移开 ,请问是怎样实现的? 
    请给出代码可以吗?!最好有说明 ,谢谢~ 
    :Zephyr,  时间 :2000-4-9 23:49:22, ID:216632多重 Undo 和 Redo 要 RichEdit v2.0 才提供 ,要用到   EM_SETUNDOLIMIT  EM_GETUNDONAME  EM_GETREDONAME  EM_UNDO  EM_CANUNDO  EM_REDO  EM_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;
    interface
    uses  Windows, Messages, SysUtils, Classes,  Controls, Forms, Dialogs;
    type  TActType = (              // 动作类型               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 = class  private    FUndoActs: 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);
      public    constructor 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;
    implementation
    constructor TActsMgr.Create(AMaxUndo: Integer);begin  SetMaxUndo(AMaxUndo);end;
    destructor TActsMgr.Destroy;begin  SetLength(FUndoActs, 0);  SetLength(FRedoActs, 0);end;
    procedure TActsMgr.SetMaxUndo(Value: Integer);var  i: Integer;begin  FMaxUndo := Value;  SetLength(FUndoActs, FMaxUndo + 1);  for i := 0 to FMaxUndo do  begin    if i = FMaxUndo then      FUndoActs[i].Next := @FUndoActs[0]    else      FUndoActs[i].Next := @FUndoActs[i+1];    if i = 0 then      FUndoActs[i].Prev := @FUndoActs[FMaxUndo]    else      FUndoActs[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 do  begin    if i = FMaxUndo then      FRedoActs[i].Next := @FRedoActs[0]    else      FRedoActs[i].Next := @FRedoActs[i+1];    if i = 0 then      FRedoActs[i].Prev := @FRedoActs[FMaxUndo]    else      FRedoActs[i].Prev := @FRedoActs[i-1];    FRedoActs[i].Enabled := False;  end;  FRedoHead := @FRedoActs[0];  FRedoTail := @FRedoActs[0];end;
    procedure TActsMgr.InitAct(var Act: TAct);begin  with Act do  begin    Enabled := True;    Buf := '';    Offset := 0;    Count := 0;    CurPos := 0;  end;end;
    function TActsMgr.AddUndoItem: PAct;begin  InitAct(FUndoHead^);  Result := FUndoHead;
      if FUndoHead^.Next = FUndoTail then    FUndoTail := FUndoTail^.Next;  FUndoHead := FUndoHead^.Next;  FUndoHead^.Enabled := False;end;
    function TActsMgr.AddRedoItem: PAct;begin  InitAct(FRedoHead^);  Result := FRedoHead;
      if FRedoHead^.Next = FRedoTail then    FRedoTail := FRedoTail^.Next;  FRedoHead := FRedoHead^.Next;  FRedoHead^.Enabled := False;end;
    function TActsMgr.Undo: PAct;begin  if not CanUndo then  begin    Result := nil;    Exit;  end;  FUndoHead := FUndoHead^.Prev;  FRedoHead := FRedoHead^.Prev;  Result := FUndoHead;end;
    function TActsMgr.Redo: PAct;begin  if not CanRedo then  begin    Result := nil;    Exit;  end;  Result := FRedoHead;  FRedoHead := FRedoHead^.Next;  FUndoHead := FUndoHead^.Next;end;
    function TActsMgr.CanUndo: Boolean;begin  Result := (FUndoHead <> FUndoTail);end;
    function TActsMgr.CanRedo: Boolean;begin  Result := FRedoHead^.Enabled;end;
    end.
      

  2.   

    不行
    编译要出错Build
      [Error] UMain.pas(370): Undeclared identifier: 'TAct'
      [Error] UMain.pas(371): Identifier redeclared: 'TAct'
      [Error] UMain.pas(373): Constant or type identifier expected
      [Error] UMain.pas(380): Constant or type identifier expected
      [Error] UMain.pas(381): Class, interface and object types only allowed in type section
      [Fatal Error] UMain.pas(388): Could not compile used unit 'UnitInsertChar.pas'问下楼上,帖子在哪里转的,麻烦地址给出来。另:有没有一个好点的关于无限Undo Redo的源码例子下载。谢谢大家。
      

  3.   

    与  hqhhh(枫叶) 相同,,,发送一个 EM_UNDO 消息就行了,
      

  4.   

    RichEdit1.perform(EM_SETUNDOLIMIT, 100, 0);100 - undo limit(works just for RichEdit 2, does not work on Memo and Edit)
      

  5.   

    微软的RichEdit2.0的DLL或OCX
    delphi没有支持吧