RichEdit中怎样用最简单的方法实现无限Undo?

lscxp 2005-08-18 09:59:12
记得好像在从RichEdit 2.0 开始,无限撤消已经成为RichEdit组件的默认设置,可以直接调用的.

但是Delphi7中好像不行,只能撤消1步

但是我在VB6,VB.NET中试了,就可以无限撤消.应该不是组件的问题.


我开始搜索了一下,方法好像都很复杂.有没有简单的方法?
...全文
222 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hangguojun 2005-08-20
  • 打赏
  • 举报
回复
微软的RichEdit2.0的DLL或OCX
delphi没有支持吧
ccrun.com 2005-08-20
  • 打赏
  • 举报
回复
RichEdit1.perform(EM_SETUNDOLIMIT, 100, 0);

100 - undo limit(works just for RichEdit 2, does not work on Memo and Edit)
onebody 2005-08-19
  • 打赏
  • 举报
回复
与 hqhhh(枫叶) 相同,,,发送一个 EM_UNDO 消息就行了,
lscxp 2005-08-19
  • 打赏
  • 举报
回复
不行
编译要出错

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的源码例子下载。

谢谢大家。
hqhhh 2005-08-19
  • 打赏
  • 举报
回复
转贴:

无限 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.
lscxp 2005-08-19
  • 打赏
  • 举报
回复
UP

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧