怎样在memo中提供无限次数的undo,redo功能? stiwin(战无不胜) 请问在哪里下载? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 问题:请问RichEdit控件怎样实现RxRichEdit的无限UnDo功能? ( 积分:225, 回复:9, 阅读:138 )分类:控件 - 使用 ( 版主:amo, cAkk ) 来自:Bao, 时间:2001-5-20 1:26:00, ID:536746 [显示:小字体 | 大字体] RichEdit控件怎样实现RxRichEdit的无限UnDo功能?在RxRichEdit里的查找对话框如果遮住了选定的文字时,会自动移开,请问是怎样实现的?请给出代码可以吗?!最好有说明,谢谢~答案希望可以E-mail到[email protected](不E也行),只要可行,马上给分,请勿灌水! 来自:Lera, 时间:2001-5-20 3:03:00, ID:536787 看它的源码吧. 来自:panyongze, 时间:2001-5-20 8:25:00, ID:536828 http://www.delphibbs.com/delphibbs/dispq.asp?lid=216618 来自:htw, 时间:2001-5-20 9:03:00, ID:536859 无限undo功能,可以自己开一个动态数组或者巨大数组,每做一次操作,执行SaveThisStep过程,undo时, 执行 loadlastStep函数, redo时执行loadNextStep操作函数的写法,应该不难。多想想,就做个通用的出来!。 来自:beta, 时间:2001-5-20 11:02:00, ID:536939 自己实现,不过很麻烦 :-p每次改变都把改变的 开始位置、长度、字符串和类型 添加到一个 TList 里面(用一个record)Undo也就是提出某次操作的这些信息然后实现就可以了,你想,有了这些信息,完全可以重现原来的操作了不过好像Redo还要用一个 TList,和Undo的不是同一个。我曾经想做过,不过无法截获文字拖拽的消息,于是放弃 :-( 来自:mantousoft, 时间:2001-5-29 19:33:00, ID:546071 去下载MiniHex的源代码看看,下面是我从里面抄的:){**********************************************************}{ }{ 功能:管理 Undo 和 Redo. }{ 说明:采用循环队列记录Undo动作和Redo动作, }{ Undo和Redo是两个不同的队列。 }{ }{**********************************************************}unit ActsMgr;interfaceuses 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;implementationconstructor 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. 大家做管理软件一个ADOConnection控件最多带几个ADOQuery? 关于ini文件的读取问题 如何在已经关联到数据库集上的ClientDataSet控件增加一个字段,并且该字段允许编辑 Delphi中哪个函数可以表示多个相同字符的字符串? 寻求图形的缩放算法! 求救DBGridEh1中根据奇偶行来改变颜色 急啊!!!!!!到底有谁能告诉我为什么调用失败啊 ??? 全部分相赠!60!一个简单的问题! 一个DBGrid的问题!!!急急急 我是新手! 如何遍历所有mdi子窗口? 窗体之间如何传递值呢(小问题,只给50)!
分类:控件 - 使用 ( 版主:amo, cAkk )
来自:Bao, 时间:2001-5-20 1:26:00, ID:536746 [显示:小字体 | 大字体]
RichEdit控件怎样实现RxRichEdit的无限UnDo功能?
在RxRichEdit里的查找对话框如果遮住了选定的文字时,会自动移开,请问是怎样实现的?请给出代码可以吗?!最好有说明,谢谢~
答案希望可以E-mail到[email protected](不E也行),只要可行,马上给分,请勿灌水!
来自:Lera, 时间:2001-5-20 3:03:00, ID:536787
看它的源码吧.
来自:panyongze, 时间:2001-5-20 8:25:00, ID:536828
http://www.delphibbs.com/delphibbs/dispq.asp?lid=216618
来自:htw, 时间:2001-5-20 9:03:00, ID:536859
无限undo功能,可以自己开一个动态数组或者巨大数组,每做一次操作,执行S
aveThisStep过程,undo时, 执行 loadlastStep函数, redo时执行loadNextStep操作
函数的写法,应该不难。多想想,就做个通用的出来!。
来自:beta, 时间:2001-5-20 11:02:00, ID:536939
自己实现,不过很麻烦 :-p
每次改变都把改变的 开始位置、长度、字符串和类型 添加到一个 TList 里面
(用一个record)
Undo也就是提出某次操作的这些信息然后实现就可以了,你想,有了这些信息,
完全可以重现原来的操作了
不过好像Redo还要用一个 TList,和Undo的不是同一个。我曾经想做过,不过无法截获文字拖拽的消息,于是放弃 :-(
来自:mantousoft, 时间:2001-5-29 19:33:00, ID:546071
去下载MiniHex的源代码看看,下面是我从里面抄的:)
{**********************************************************}
{ }
{ 功能:管理 Undo 和 Redo. }
{ 说明:采用循环队列记录Undo动作和Redo动作, }
{ Undo和Redo是两个不同的队列。 }
{ }
{**********************************************************}unit ActsMgr;interfaceuses
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;implementationconstructor 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.