Autor Beitrag
hRb
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Fr 06.11.15 22:06 
Hallo,
ich habe für eine Richedit-Komponente eine Undo-/Redo-Procedure wie folgt (beispielhaft für Undo)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.EditUndo(Sender: TObject);
{ letzte Bedieneingabe rückgängig }
begin
 with Richedit1 do
   if HandleAllocated then
      SendMessage(Handle, EM_UNDO, 00);
end;

Meine Frage ist, wie so etwas aussehen müsste um nicht nur einen Schritt zurückzugehen, sondern mehrere.
Vielleicht findet sich die Antwort schon in den 10000 bisherigen Antworten, dann sorry; habe sie aber nicht gefunden.
Danke für hilfreiche Tipps
hRb
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 07.11.15 19:50 
Gerd Kayser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Mo 09.11.15 12:17 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Meine Frage ist, wie so etwas aussehen müsste um nicht nur einen Schritt zurückzugehen, sondern mehrere.

msdn.microsoft.com/e...ibrary/bb787873.aspx
Multilevel Undo steht laut Microsoft erst ab RichEdit Version 2 zur Verfügung. Wenn ein mehrfaches Undo / Redo nicht funktioniert, dann dürfte es wohl daran liegen, dass Riched32.dll statt Riched20.dll angezogen wird. Aber das kann man ändern (Beispiel):
delphi-kb.blogspot.d...use-riched20dll.html
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mo 09.11.15 18:18 
Zunächst mal beiden Schreibern Danke. Da ich kein Profi bin, muss ich nachhaken.
1. zu Perlsau: habe mir den Vorschlag angesehen. Scheint, wie der Verfasser selber schreibt, mit \"Kanonon nach Spatzen\" zu schießen. Bei jeder Änderung das gesamte Richedit speichern? Habe einen Editor mit bis 10 Vorlagen und je 2GB Länge max. Diese Variante - wenn ich sie richtig verstanden habe - scheidet m.E. aus.
2. zu G.K.: Wie erkenne ich denn, welche Richedit-Version verwendet wird?
Anmerkung: Ich nutze derzeit immer noch Delphi7, weil mir dieses Produkt für Tests besser geeignet erscheint und mehr Hilfen bietet. Habe allerdings seit ca. 3 Jahren auch XE3 (ruhend). Beim ersten Versuch mein Programm zu übersetzen erhielt ich mindestens 70-80 Fehlermeldungen, weil ich noch mit ANSI-String arbeite und dabei mit Systemroutinen kollidiere oder noch nicht UTF8-Code bearbeiten kann. So wollte ich \"meinem Werk\" zuerst noch einige Schmankerl verpassen, bevor ich mich diesem Thema zuwende. Vielleicht muss ich doch (endlich) umsteigen.

Daher die Nachfrage: Wäre mein Problem gelöst wenn ich XE3 nutze oder muss dann trotzdem anstelle TRichEdit ein anderes Objekt verwendet werden - und wenn Ja - wie nennt sich dies?
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 09.11.15 19:31 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
zu Perlsau: habe mir den Vorschlag angesehen. Scheint, wie der Verfasser selber schreibt, mit \"Kanonon nach Spatzen\" zu schießen. Bei jeder Änderung das gesamte Richedit speichern? Habe einen Editor mit bis 10 Vorlagen und je 2GB Länge max. Diese Variante - wenn ich sie richtig verstanden habe - scheidet m.E. aus.

Den Vorschlag? Auf welches von den ca. 36.000 Suchergebnissen bezieht sich deine Behauptung? Dieses oder dieses oder dieses oder dieses ...

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Wie erkenne ich denn, welche Richedit-Version verwendet wird?

Du suchst in deinem Windows-Verzeichnis nach Richedit20.dll und schaust dir die Eigenschaften an. Dort steht die Versionsnummer. Eine der Quelle für diese Information

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Ich nutze derzeit immer noch Delphi7, weil mir dieses Produkt für Tests besser geeignet erscheint und mehr Hilfen bietet. Habe allerdings seit ca. 3 Jahren auch XE3 (ruhend). Beim ersten Versuch mein Programm zu übersetzen erhielt ich mindestens 70-80 Fehlermeldungen, weil ich noch mit ANSI-String arbeite und dabei mit Systemroutinen kollidiere oder noch nicht UTF8-Code bearbeiten kann. So wollte ich \"meinem Werk\" zuerst noch einige Schmankerl verpassen, bevor ich mich diesem Thema zuwende. Vielleicht muss ich doch (endlich) umsteigen. Daher die Nachfrage: Wäre mein Problem gelöst wenn ich XE3 nutze oder muss dann trotzdem anstelle TRichEdit ein anderes Objekt verwendet werden - und wenn Ja - wie nennt sich dies?

Die Verwendung einer neueren Version macht aus dir keinen besseren Programmierer, ebenso wie sich deine Fähigkeiten, Google zu bedienen, dadurch nicht verbessern würden.

All diese Informationen habe ich nun für dich via Google recherchiert. Das hättest du auch selber machen können. Rechnung folgt :P
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Di 10.11.15 14:57 
Hallo P,
Du machst mit Deiner bissigen Antwort richtig Mut, weiterhin Fragen zu stellen. Ich habe ja geschrieben, dass ich kein Profi bin. Also bitte etwas Nachsicht mit Personen, die sich nicht so gut auskennen wie Du. Natürlich habe ich zuvor in Google gesucht, bin aber nicht wirklich weitergekommen was mehrfaches Undo/Redo erfordert (bis - wie erwähnt - auf eine Lösung, die bei jeder Änderung das Richedit speichert). Habe mich vielleicht auch in der Vielzahl nutzloser Antworten verheddert. Kleine Hinweise, wie die Verwendung von
ausblenden Delphi-Quelltext
1:
2:
  RichEdit1.Perform(EM_SETUNDOLIMIT, 1000);   // oder
  SendMessage(RichEdit1.Handle, EM_SETUNDOLIMIT, 1000);

haben nichts gebracht (muss aber später vermutlich auch irgendwo gesetzt werden).
Obwohl im Ordner Windows\System32 beide Dateien vorhanden sind, nämlich Riched32.dll (V1.0) und Riched20.dll (V3.1), bindet der Compiler vermutlich V1.0 ein. Die Verwendung von Riched20.dll scheint wohl die Lösung zu bringen. Nur, wie binde ich diese anstelle von Riched32 ein?
- in Uses: Richedit ersetzen durch ?
- weitere Unit, welche?
- oder?
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 10.11.15 17:28 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Hallo P,
Du machst mit Deiner bissigen Antwort richtig Mut, weiterhin Fragen zu stellen. Ich habe ja geschrieben, dass ich kein Profi bin. Also bitte etwas Nachsicht mit Personen, die sich nicht so gut auskennen wie Du. Natürlich habe ich zuvor in Google gesucht, bin aber nicht wirklich weitergekommen was mehrfaches Undo/Redo erfordert (bis - wie erwähnt - auf eine Lösung, die bei jeder Änderung das Richedit speichert). Habe mich vielleicht auch in der Vielzahl nutzloser Antworten verheddert.

Was ist denn an meiner Antwort bissig? Ich habe lediglich darauf hingewiesen, daß du dir die Antworten auch selbst ergoogeln kannst, statt das von anderen erledigen zu lassen. Daß du dich mit Delphi noch nicht besonders gut auskennst, habe ich nirgendwo auch nur ansatzweise thematisiert. Dagegen darf man von einem Programmierer durchaus erwarten, daß er zumindest eine Suchmaschine zu bedienen weiß und in der Lage ist, im Internet nach Antworten zu recherchieren. Ich kann deine Fragen auch nicht aus dem Stegreif beantworten und muß googeln, und offenbar hat hier sonst niemand Lust, Laune und Zeit dazu.

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Obwohl im Ordner Windows\System32 beide Dateien vorhanden sind, nämlich Riched32.dll (V1.0) und Riched20.dll (V3.1), bindet der Compiler vermutlich V1.0 ein. Die Verwendung von Riched20.dll scheint wohl die Lösung zu bringen. Nur, wie binde ich diese anstelle von Riched32 ein?

Mit den Suchbegriffen Delphi+RichEdit+DLL fand ich innerhalb weniger Sekunden zahlreiche Stellen im Netz, wo genau diese Problematik diskutiert wurde, z.B.:
How to get TRichEdit to use the RichEd20.dll

Nun hab ich weder Zeit noch Lust, dir weiterhin den Googler zu machen, vielleicht hilft dir ja jemand anders weiter uind recherchiert für dich im Netz nach deinen Antworten ...
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 10.11.15 17:45 
Moin!

@user profile iconPerlsau: Ich empfinde deinen Ton (nicht nur hier, in letzter Zeit tendenziell eher generell) auch unnötig gereizt und deine Beiträge wenig freundlich. Daher halte ich es für unwahrscheinlich, dass sich user profile iconhRb das einbildet. :nixweiss: So wie es im Moment läuft, entspricht es auch nicht unseren Foren-Regeln, die hier für Fragesteller und für Helfer gelten (bei Interesse hier nachlesen). :| Das ist auch der Grund, warum ich hier etwas dazu sage. Sicher, wir ertrinken z.Zt. nicht gerade in Beiträgen, aber das sollte kein Grund sein, sich von dem in unserer Community geschätzten "guten Ton" zu entfernen. :idea:


Bitte, wir diskutieren hier im Fach-Thread ab jetzt freundlich und sachlich weiter über die Fragen des TE oder halten uns alternativ einfach raus, wenn man dazu nichts sinnvolles beizutragen hat. ;)

Was wir hier im Thread nicht tun werden: über diese Aufforderung von mir diskutieren oder diese ignorieren. Wer das tun möchte, kann sich gerne im OffTopic, per VA oder zur Not auch per PN mit mir darüber unterhalten. Ich gehe davon aus, dass ich mich verständlich ausgedrückt habe. :beer:

cu
EE-Team (Narses)

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: jasocul, Nersgatt
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 10.11.15 19:49 
@hRb: Es lag nicht in meiner Absicht, dich zu entmutigen, zu beleidigen oder sonstwie emotional zu verletzen. Allerdings fand ich meine Fragen z.B. nach dem Suchergebnis, das du ausprobiert haben willst, durchaus berechtigt. Immerhin hattest du von einem einzigen Suchergebnis bzw. Link geschrieben, während ich dir einen Link zu zig-Tausenden von Suchergebnissen übermittelt hatte. Dadurch entstand bei mir der Eindruck, daß du diesen Link gar nicht angeklickt hast, denn sonst würdest du ja nicht davon schreiben, daß der Vorschlag in diesem Link nichts bringen würde, weil da ja gar kein Vorschlag drin war, sondern über 30.000 Suchergebnisse. Auch hat es mich geärgert, daß du nicht zuvor selbst erst einmal Google bemühst, ich dagegen innerhalb weniger Sekunden sofort zahlreiche Lösungsvorschläge via Google erhalte. Das verstärkte bei mir den Eindruck, daß du notwendige Recherchearbeit auf andere abzuwälzen suchst, und das wäre durchaus ärgerlich.

Wie bereits erläutert weiß ich keine Lösung für dein Problem aus dem Stegreif, habe aber dennoch versucht, dir Wege zu eröffnen, auf denen du früher oder später selbst auf hilfreiche Lösungsvorschläge triffst. Das Problem, das du schilderst, ist ja nicht wirklich neu, sondern hat im Gegenteil schon sehr viele Delphi-Programmierer beschäftigt. Diese Diskussionen gilt es zu finden und auszuwerten. Das traue ich dir zu ... womit ich dir ein wenig Mut machen möchte, selbst tätig zu werden.

@Narses: Dafür erhältst du meine Zustimmung, auch wenn ich selbst meinen "Ton" nicht so empfinde, wie du es hier darstellst. Grundsätzlich gebe ich dir selbstverständlich darin recht, daß Freundlichkeit oberstes Gebot sein und bleiben sollte. Ich hoffe, obiger Versuch einer Klarstellung findet nicht ebenfalls dein Mißfallen.
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2510
Erhaltene Danke: 44

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 04.12.15 19:39 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Meine Frage ist, wie so etwas aussehen müsste um nicht nur einen Schritt zurückzugehen, sondern mehrere.

Vielleicht kommt der Tipp zu spät, aber vieleicht hilft er ja dir auch. Ob das auch mit einem RichEdit funktioniert, weiss ich nicht!
development.mwcs.de/tutundoredo.html

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mo 11.01.16 13:35 
Hallo,
gelagher: Es ist nie zu spät. Danke auch für den Link auf development.mwcs.de/tutundoredo.html. Dort ist aber der weitere Verweis auf Undo/Redo nicht mir aktiv (zumindest heute).
Ich habe über die Feiertage das Problem nur etwas zur Seite gelegt und Alternativen untersucht. Einen Lösungsansatz den ich fand (überladene Routinen), überforderten meine Laien-Fähigkeiten. Da sind Textbeschreibungen (statt fertiger Code) für mich zu unklar in der Umsetzung. Ärgerlich nur, dass ich Riched20.dll auf meinem PC habe (system32). Delphi7 verwendet diese aber nicht - bzw ich weiß nicht wie man dies einbinden könnte.
Da ich auch noch von Embarcadero den XE3-Compiler habe, ist dies die Alternative. In einem kleinen Testprogramm funktioniert dort Mehrfach-Undo. Allerdings versteht der XE3-Compiler die Redo-Funktion nicht. Warum??? - noch keine Ahnung! Auch die XE3-Hilfe verweist bei Undo nicht auf die alternative Redo-Funktion (Grund warum ich lieber mit D7 arbeite).
Es kann allerdings sein, dass ich dies als neue Frage bei Delphi-Language stellen muss. Ich halte daher meine Frage noch einige Zeit offen.
PS: Perlsau: Entschuldigung angenommen! und Ärger verdaut. Kann nur sagen, dass ich tagelang gesucht habe. Aber bei den "30000" Suchergebnissen habe ich wohl nicht die richtige gefunden - oder wie oben angedeutet: für mich zu kompliziert.
Danke dennoch für alle Antworten
hRb
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mi 13.01.16 22:14 
Ich habe den Entwickler der Homepage development.mwcs.de/tutundoredo.html angeschrieben. Er hatte einen Fehler auf der Homepage, der nun beseitigt ist. Dort beschreibt er eine Methode zu mehrfachem Undo/Redo. Der Weg ist aber recht "steinig". Ich werde jetzt wohl endgültig umsteigen von Delphi7 auf XE3 (den ich auch habe), denn dort funktioniert es wohl. Allerdings muss ich nun erst x-Anpassungen vornehmen (Umstellung von AnsiString zu UTF8). Dennoch schließe ich das Thema hier ab.
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2510
Erhaltene Danke: 44

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: So 17.01.16 21:17 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
gelagher: Es ist nie zu spät. Danke auch für den Link auf development.mwcs.de/tutundoredo.html. Dort ist aber der weitere Verweis auf Undo/Redo nicht mir aktiv (zumindest heute).
Entschuldige, dass ich mich erst jetzt melde, habe erst jetzt gesehen, dass du gepostet hast.
Ja, nun ist das Undo/Redo wieder da!

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Dort beschreibt er eine Methode zu mehrfachem Undo/Redo. Der Weg ist aber recht "steinig".
Ja, steinig trifft es genau! Ich habe mich da mal durchgebissen und werde mal sehen, ob ich den Code noch finde bzw. irgendwie "extrahieren" kann und poste ihn dann hier, wenn du ihn noch benötigst!

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
XE3 (den ich auch habe), denn dort funktioniert es wohl.
Vielleicht mit XE3, ja. Ich habe XE2, da geht's auch nicht!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mo 18.01.16 21:48 
Hallo Gelagher,
wenn Du Dir die Mühe machen könntest, wäre dies super. Da würden sich sicher viele freuen, denn dann wäre wenigstens einmal im Forum (im Internet?) eine fertige ButtonUndo/Redo-Klick-Lösung. Ich habe inzwischen ein weiteres festgestellt: In XE3 funktioniert zwar mehrfaches Undo. ABER die Funktion REDO kennt der Compiler nicht, weder EM_CANREDO noch EM_REDO

ausblenden Delphi-Quelltext
1:
2:
   if SendMessage(Handle, EM_CANREDO, 00) <> 0 then
      SendMessage(Handle, EM_REDO, 00);

kann übersetzt werden.
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2510
Erhaltene Danke: 44

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Mo 18.01.16 22:20 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Hallo Gelagher,
wenn Du Dir die Mühe machen könntest, wäre dies super.
Werde ich (wahrscheinlich) ab morgen machen! Zwar habe ich dazu TWideHLEditorX von TJvWideHLEditor abgeleitet, aber das sollte sich ja auf ein RichEdit umändern lassen.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19273
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 19.01.16 08:14 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
In XE3 funktioniert zwar mehrfaches Undo. ABER die Funktion REDO kennt der Compiler nicht, weder EM_CANREDO noch EM_REDO
Das ist auch in Delphi 10 Seattle noch so. Und schlimmer noch:
Statt wie in der Doku empfohlen EM_UNDO zu benutzen, ruft die Funktion Undo des TRichEdit WM_UNDO auf. Ob das Folgen hat, steht allerdings nicht dabei.

So funktioniert es aber problemlos:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
const
  EM_REDO = WM_USER + 84;
//  EM_UNDO = $C7; // ist in Delphi schon deklariert

  SendMessage(RichEdit1.Handle, EM_UNDO, 00);
// bzw.
  SendMessage(RichEdit1.Handle, EM_REDO, 00);
(Die Konstanten findest du im SDK von Microsoft, daher stammt der Wert für EM_REDO.)
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2510
Erhaltene Danke: 44

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Di 19.01.16 19:06 
Also: Hier wie versprochen der Code. Ich habe ihn aus meinem Projekt extrahiert, und er sollte funktionieren, ich habe ihn allerdings so nicht getestet!

Zunächst braucht man jedenfalls folgende Dateien:
CreateUndoRedoObject.pas
UndoRedo.pas
UndoRedoIntf.pas
InterfacedList.pas
InterfacedListIntf.pas
IntfList.pas
IntfListIntf.pas

Gibt's da, und zwar ganz unten: development.mwcs.de/tutundoredo.html

Auf die Form einen Timer legen und Interval auf 300 setzen.

Ich schreibe hier einfach RichEditX1, wenn ich eine Komponente der Klasse TRichEditX ansprechen will, das muss natürlich, wenn nötig, angepasst werden!
Noch ein Hinweis: SaveStatusForUndoRedo; in allen Prozeduren und Funktion angeben, die Text verändern, also zB. beim Ausschneiden oder Ersetzen von Text! Also zuerst SaveStatusForUndoRedo;, dann Text ändern!
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
{Hier erstmal die neue Klasse, die mehrfaches Undo / Redo unterstützt:}
  TRichEditX = class(TRichEdit)
  private
    FUndoRedo: IUndoRedo;  {Kann zwar direkt verwendet werden,}
  public  {ist aber wohl schlechter Stil, property ist besser!}
    property UndoRedo: IUndoRedo read FUndoRedo write FUndoRedo;
  end;

{Weiter  mit dem MainForm des Programms:}
  TForm1 = class(TForm)
  //...
    {Benötigt werden u. a. folgende Prozeduren:}
    procedure Undo;
    procedure Redo;
    procedure SetUndoRedo;
    procedure SaveStatusForUndoRedo;
  //...

implementation

//...

procedure TForm1.Undo;
begin
  RichEditX1.UndoRedo.Undo;
  SetUndoRedo;
end;

procedure TForm1.Redo;
begin
  RichEditX1.UndoRedo.Redo;
  SetUndoRedo;
end;

procedure TForm1.SetUndoRedo;
begin
  {Angenommen, wir haben Menü-Items mit den Namen Rckgngig1 und Wiederholen1,}
  {dann wollen wir die ja stets sinnvoll darstellen, zB. Enabled oder eben nicht!}
  Rckgngig1.Enabled := not RichEditX1.UndoRedo.IsFirst; (* Sind wir am Anfang unserer Liste? *)
  Wiederholen1.Enabled := not RichEditX1.UndoRedo.IsLast; (* Oder vielleicht am Ende? *)
end;

procedure TForm1.SaveStatusForUndoRedo;
begin
  if Timer1.Enabled then (* Haben wir den Zustand schon gesichert? *)
  begin
    Timer1.Enabled := False; (* Timer zurücksetzen... *)
    Timer1.Enabled := True;
    Exit;                    (* ...und raus *)
  end;

  (* Originalzustand sichern *)
  RichEditX1.UndoRedo.AddActionToUndo(UEDITMEMO, atUndo, Integer(RichEditX1), 0);
  (* Rückgängig einschalten *)

  (* Timer aktivieren *)
  Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  (* Timer deaktivieren *)
  Timer1.Enabled := False;
  
  (* Veränderten Zustand sichern *)
  RichEditX1.UndoRedo.AddActionToUndo(UEDITMEMO, atRedo, Integer(RichEditX1), 0);

  SetUndoRedo;
end;

{Angenommen, wir haben eine Prozedur, die ein neues oder das einzige Textfenster erzeugt:}
procedure TForm1.New(const aRichEditX: TRichEditX);
begin
  (* UndoRedo-Interface erzeugen *)
  aRichEditX.UndoRedo := CreateUndoRedo;
  (* Handler registrieren *)
  UEDITMEMO := aRichEditX.UndoRedo.RegisterAction(GetName, AddMemoAction, UndoMemoAction);

  SetUndoRedo;
end;

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!