请问RichEdit控件怎样实现RxRichEdit的无限UnDo功能?(225分)

  • 主题发起人 主题发起人 Bao
  • 开始时间 开始时间
B

Bao

Unregistered / Unconfirmed
GUEST, unregistred user!
RichEdit控件怎样实现RxRichEdit的无限UnDo功能?
在RxRichEdit里的查找对话框如果遮住了选定的文字时,会自动移开,请问是怎样实现的?

请给出代码可以吗?!最好有说明,谢谢~
答案希望可以E-mail到iveny@263.net(不E也行),只要可行,马上给分,请勿灌水!
 
看它的源码吧.
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=216618
 
无限undo功能,可以自己开一个动态数组或者巨大数组,每做一次操作,执行S
aveThisStep过程,undo时, 执行 loadlastStep函数, redo时执行loadNextStep操作
函数的写法,应该不难。多想想,就做个通用的出来!。
 
自己实现,不过很麻烦 :-p
每次改变都把改变的 开始位置、长度、字符串和类型 添加到一个 TList 里面
(用一个record)
Undo也就是提出某次操作的这些信息然后实现就可以了,你想,有了这些信息,
完全可以重现原来的操作了
不过好像Redo还要用一个 TList,和Undo的不是同一个。

我曾经想做过,不过无法截获文字拖拽的消息,于是放弃 :-(
 
去下载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.Next := @FUndoActs[0]
else
FUndoActs.Next := @FUndoActs[i+1];
if i = 0 then
FUndoActs.Prev := @FUndoActs[FMaxUndo]
else
FUndoActs.Prev := @FUndoActs[i-1];
FUndoActs.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.Next := @FRedoActs[0]
else
FRedoActs.Next := @FRedoActs[i+1];
if i = 0 then
FRedoActs.Prev := @FRedoActs[FMaxUndo]
else
FRedoActs.Prev := @FRedoActs[i-1];
FRedoActs.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.
 
请问MiniHex的原代码,哪里有下载?
 
//请问MiniHex的原代码
我给你发了一个到你的信箱里,请注意接收。
 
多人接受答案了。
 
后退
顶部