Seufz... Da fühlt man sich wieder jung.
Aber ist heute echt dein Glückstag. Die Doku zur API hier ist gerade dermaßen trocken, daß es staubt. Da ist dein "extended Hello World" in der Tat interessanter. Also gehen wir es mal an:
Schritt 1: Der Ausgangspunkt
Damit wir auch beide vom Gleichen reden, habe ich mir nochmal dein .rar runtergeladen, in meine IDE geladen und versucht zu compilieren. Das Ergebnis brachte 10 satte Fehler.
Als erstes wird natürlich der Redo bemängelt. Da dessen programmiertechnische Umsetzung etwas mehr als nur zwei, drei Tastendrucke erfordert, deaktiviere ich ihn erstmal:
Code:
procedure TForm1.Wiederhstellen1Click(Sender: TObject);
begin
//Memo1.Redo;
end;
Der nächste Meckerpunkt ist der Cut. Den wandel ich einfach passend um:
Code:
procedure TForm1.Ausschneiden1Click(Sender: TObject);
begin
Memo1.CutToClipboard;
end;
Das Gleiche geschieht mit dem Copy:
Code:
procedure TForm1.Kopieren1Click(Sender: TObject);
begin
Memo1.CopyToClipboard;
end;
Bleiben noch die Dinger mit OpenDialog1 und SaveDialog1. Da sieht die Reparatur recht einfach aus. Du beziehst dich einfach auf die Dialoge, ohne sie deklariert, geschweige denn initialisiert zu haben. Das lässt sich beheben. Ich wechsel vom Sourcecode in den Desinger. In der Tool-Palette (lass dir nur Zeit und suche sie in Ruhe) gibt es eine Rubrik namens "Dialoge". Die erste Komponente in dieser Rubrik heisst auch schon TOpenDialog, die zweite TSaveDialog. Ich lege jeweils eine TOpenDialog- und und TSaveDialog-Komponente auf das Formular. Beide sind sogenannte "nichtvisuelle Komponenten", d.h. sie werden zur Laufzeit nicht so ohne weiteres angezeigt, weswegen es vollkommen sch**ssegal ist, wo im Formular die Dinger platziert werden. Aufgrund der automatichen Namensvergabe heissen die Teile jetzt OpenDialog1 und SaveDialog1.
Ich werfe einen kurzen Blick in den Sourcecode - anscheinend wird nichts mehr bemängelt.
Und eine Compilierung bestätigt es mir: 0 Warnungen, 0 Fehler.
Schritt 2: Der verdammte Redo
In einem vorhergehenden Post habe ich ja schon erwähnt, wie ich den Redo sehe und was ich glaube, das er können soll. Jetzt gilt es, das Ganze umzusetzen.
Als erstes wird mal das unsichtbare Memo angelegt. Von der Toolpalette (Rubrik "Standard") ziehe ich ein TMemo auf das Formular. Auch hier ist die Platzierung komplett Wumpe, weil ich mit F11 sofort den Objektinspektor aufmache und die Eigenschaft "Visible" der neuen Memokomponente auf "false" setze.
So, tief durchatmen, nachdenken, im Schritt kratzen. Der Redo kann nur funktionieren, wenn vorher ein Undo erfolgte. Also greife ich als erstes beim Undo in den Source ein:
Code:
procedure TForm1.Rckgngig1Click(Sender: TObject);
begin
Memo2.Lines.Text := Memo1.Lines.Text;
Memo1.Undo;
end;
Was hier passiert ist, daß ich mir vor dem Undo den zuletzt aktuellen Text in Memo1 (das ist das sichtbare Textfeld) merke. Da ich zu faul bin, den geschriebenen Text jetzt über Memo1.Lines Zeile für Zeile durchzuackern, greife ich mittels Memo1.Lines.Text einfach auf den gesamten Text zu, als sei er ein einziger String und schaufel in nach Memo2.
Jetzt müsste eigentlich auch der Redo gebastelt werden können. Wenn ich einen Undo mache und es mir doch anders überlege, dann soll mir der Redo ja den Text wiederherstellen. Fluggs in die Tasten gehauen:
Code:
procedure TForm1.Wiederhstellen1Click(Sender: TObject);
begin
//Memo1.Redo;
Memo1.Lines.Text := Memo2.Lines.Text;
end;
Ich stelle einfach in Memo1 (der sichtbaren Memo-Komponente) wieder den Text her, den ich mir in der unsichtbaren Memo-Komponente (Memo2) gemerkt habe.
Mal schauen, was ein Test sagt...
...
...
Tja, prinzipiell funktioniert es bis auf eine Kleinigkeit: Der Cursor wird nach dem Redo nicht auf das Textende positioniert. Aber das ist auch nicht weiter problematisch. Es muß nur eine weitere Zeile in den Redo eingefügt werden:
Code:
procedure TForm1.Wiederhstellen1Click(Sender: TObject);
begin
//Memo1.Redo;
Memo1.Lines.Text := Memo2.Lines.Text;
Memo1.SelStart := Length(Memo1.Lines.Text);
end;
Diese Zeile bewirkt, daß ich einen Text in Memo1 auswähle. Und zwar beginnt die Auswahl beim letzten Zeichen des Textes und ist... ja, wieviel Zeichen ist die Auswahl denn lang? Da ich dem Programm diesbezüglich keine Information mitteile, schmollt es und nimmt eine Länge von 0 an. Das hat zur Folge, daß der Cursor hinter dem letzten Zeichen steht, aber nichts markiert wird/wurde. Bingo. Genau das wollte ich.
Schritt 3: Jetzt bist du dran!
Ich hoffe doch sehr, daß du jetzt ein bißchen ein wenigstens minimales Gefühl dafür bekommen hast, wie du mit dem Sourcecode und dem Designer umzugehen hast. F1 (sprich: Die Hilfe) ist auch ein guter Freund. Wenn du zu einer Komponente Informationen suchst, dann tippe einfach T<Komponente> ein. Also für ein Memo z.B. TMemo oder für eine StringList TStringList. usw. Dann bekommst du in den meisten Fällen bereits eine sehr aussagekräftige Hilfe zu den einzelnen Komponenten.
Was du jetzt noch machen kannst:
- Gib den einzelnen Komponenten vernünftige Namen. Nicht nur Memo1 oder so.
- Gib den einzelnen Komponenten vernünftige Anfangswerte: Lösche beim Neustart des Systems den Inhalt des (jetzigen) Memo1. Lege ordentliche Dateifilter für die Dialoge an etc.
-
Verstehe das Programm. Und wenn du jede einzelne Funktion in der Hilfe nachschlagen musst, dann ist das auch keine Schande. Jeder fängt mal klein an.
- Wenn du wirklich was knabbern willst (aber für 1 Woche Delphi ist das dann schon ein sehr harter Brocken, denke ich), dann schmeiss Memo2 wieder raus und lege dir im Sourcecode als private member des Formulars eine StringList an. Diese ersetzt dann Memo2 (da nur die StringList verwendet wird). Gaaanz ruhig, keine Panik. Hier die Stichwörter, mit deren Hilfe du in der Delphi-Hilfe und im Internet Hilfe dazu finden kannst:
- Dynamische Objekte
- Konstruktor
- Destruktor
- OnFormCreate
- OnFormClose
Wenn dir das hier immer noch nicht weiterhilft, dann weiss ich auch nicht mehr weiter.
So, zurück zur API... seufz...