I
import
Unregistered / Unconfirmed
GUEST, unregistred user!
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
自己实现,不过很麻烦
每次改变都把改变的 开始位置、长度、字符串和类型 添加到一个 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.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.
在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
自己实现,不过很麻烦
每次改变都把改变的 开始位置、长度、字符串和类型 添加到一个 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.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.