![]() |
AutoComplete für TMemo, TRichEdit uvm.
Liste der Anhänge anzeigen (Anzahl: 2)
Nachdem ich mir einen "Wolf" gesucht hatte und außer SynEdit nichts passendes gefunden habe (was mir für meine Zwecke etwas zu komplex ist), habe ich mir meine eigene TAutoComplete-Komponente geschrieben.
Ich wollte für eine eigene Anwendung eine AutoComplete-Funktion haben, ähnlich wie sie die Delphi-IDE bietet. Die Unit "autocomplete" kann für Klassen verwendet werden, die auf TEdit basieren, wie z.B. TMemo, TRichEdit, TEdit, TLabeledEdit usw. Die Initialisierung geschieht z.B. folgender Maßen:
Delphi-Quellcode:
Damit wird die Komponente 'Memo1' um AutoComplete erweitert.
AutoComplete1 := TAutoComplete.Create(Form1,'TextDatei',Memo1);
Die Textdatei enthält das für Memo1 wichtige Wörterbuch. In das Wörterbuch sollten nur Wörter eingetragen werden, die länger als 4 Zeichen sind. AutoComplete reagiert erst ab 3 Zeichen Eingabe. Ist für die Edit-Komponente ein Popup-Menu definiert, dann wird dieses um den Menupunkt "Markierten Text in Wörterbuch übernehmen." erweitert Wichtig: Durch AutoComlete werden die Ereignisbehandlungen 'OnChange', 'OnKeyDown', 'OnKeyPress' und 'OnContextPopup'überschrieben. Sollten diese im Hauptprogramm benötigt werden, ist diese Lösung zunächst nicht einsetzbar. In der ZIP-Datei befindet sich die Unit autocomplete.pas und das passende Testprogramm dazu. Hier ein Auszug aus dem Testprogramm:
Delphi-Quellcode:
Wie man sieht, werden hier 3 Komponenten mit 'AutoComplete' erweitert.
procedure TForm1.FormCreate(Sender: TObject);
begin AutoComplete1 := TAutoComplete.Create(self,'worte.txt',Memo1); AutoComplete2 := TAutoComplete.Create(Form1,'plz.txt',LabeledEdit1); AutoComplete3 := TAutoComplete.Create(Form1,'words4.txt',RichEdit1); end; Zugegeben: Das Beispiel mit dem LabeledEdit1 kann man auch mit TComboBox realisieren, aber mir ging es ja hauptsächlich um TMemo und eventuell um TRichEdit. Das Beispiel für TMemo habe ich mit einer Textdatei hinterlegt, wie sie bei mir zum Einsatz kommt(Für ein Dia-Verwaltungsprogramm). Bei dem LabeledEdit1 habe ich eine Postleitzahlendatei hinterlegt (ohne Gewähr :wink: ) Die RichEdit-Box reagiert vielleicht etwas träge. Das liegt daran, das ich hier versucht habe, TAutoComplete auszureizen: Die dazugehörige Textdatei 'words4.txt' ist über 2MB groß (über 150000 Zeilen). Falls sich jemand wundert, warum ich RichEdit auf ein Panel gepackt habe und auf das Panel noch ein TabControl und darauf das Memo: Das hatte ganz einfach den Zweck, die Positionsfindung für AutoComplete zu testen, mit einem einfachen "ClientToParent" war es nicht getan... Im beiliegenden Screenshot kann man das Testprogramm in Aktion sehen. |
Re: AutoComplete für TMemo, TRichEdit uvm.
Was mir nicht so gut gefällt, ist dass der Owner im Konstruktor mitgegeben werden muss.
Gerade dein Beispiel:
Delphi-Quellcode:
zeigt, dass man damit schwerzufindende Fehler begehen kann.
AutoComplete2 := TAutoComplete.Create(Form1,'plz.txt',LabeledEdit1);
Folgendes Beispiel zeigt, dass man Formulare auch mit lokalen Variablen erstellen kann.
Delphi-Quellcode:
Um dieses Problem aus der Welt zu schaffen, würde ich folgende Änderung vorschlagen:
procedure Test;
var x : TForm1; begin x := TForm1.Create(nil); x.ShowModal; x.Free; end; procedure TForm1.FormCreate(Sender: TObject); begin // Fehler: Owner ist Form1 - richtig kann aber nur self sein AutoComplete := TAutoComplete.Create(Form1,'plz.txt',LabeledEdit1); end;
Delphi-Quellcode:
Bei der Zeile mit dem *) könnte sich jetzt ein Problem ergeben, weil vorher der Parent das Formular war und jetzt kann es auch eine Groupbox sein.
constructor TAutoComplete.Create(const Edit: TControl; const TxtFile: String);
begin Assert(Assigned(Edit)); Inherited Create(Edit.Owner); // gleicher Owner, den auch Edit hat Parent := Edit.Parent; // dito *) Dann kann man aber so lange über Parent nach "oben" gehen, bis man auf dem Formular gelandet ist.
Delphi-Quellcode:
var
tmp : TControl; begin tmp := Edit.Parent; while Assigned(tmp.Parent) do tmp := tmp.Parent; Parent := tmp; |
Re: AutoComplete für TMemo, TRichEdit uvm.
Die Idee an sich finde ich gut. Was ich nicht so toll finde ist eben die Umsetzung das es eine Datei sein muss und das die Ereignisse dann nicht mehr nutzbar sind.
Auch die minimale Anzahl von Zeichen, finde ich, sollte einstellbar sein. Insgesamt soll das heißen: Bleib an der Idee dran und versuche es zu verfeiern/verbessern. |
Re: AutoComplete für TMemo, TRichEdit uvm.
Zitat:
Was ist falsch daran, den Owner mit zu geben? Ich will ja gerade, das die unterste Komponente (Form1) der Owner ist. Gerade in meinem Beispiel, bei dem das TMemo auf einem TPanel und dieses wiederum auf einem TTabControl sitzt ist es wichtig, das als Parent für den TListView (TAutoComplete) die Form ist. Zitat:
|
Re: AutoComplete für TMemo, TRichEdit uvm.
Zitat:
ließ die vorherrigen Werte aus und ruf (falls da schon etwas eingetragen ist) dieses in deiner Klasse auf. |
Re: AutoComplete für TMemo, TRichEdit uvm.
Zitat:
Zitat:
Zitat:
Aber: Welche Eventbehandlung führe ich zu erst aus, die vom Hauptprogramm oder die von TAutoComplete? Ober "beißen" sich die beiden Eventbehandlunge gar? Ich fürcht, das muss jeder individuell beurteilen und in seinem Programm anpassen. Zitat:
Zitat:
Zitat:
|
Re: AutoComplete für TMemo, TRichEdit uvm.
Zitat:
|
Re: AutoComplete für TMemo, TRichEdit uvm.
Zitat:
Solange es nur ein Formular dieser Klasse gibt ist alles in Ordnung. Wenn es aber mehrere Formulare der gleichen Klasse gibt, dann können ja nicht alle in der Variable Form1 gespeichert sein. Das würde dann bedeuten, dass die Autocomplete Komponente auf das falsche Formular zugreift. Es könnte sogar sein, dass die Variable Form1 = nil ist. Man kann sich vorstellen, dass das sehr unangenehm werden kann. |
Re: AutoComplete für TMemo, TRichEdit uvm.
Zitat:
Ich denke, das kann sich jeder selber einbauen, letztendlich wird die Datei in eine StrinList geladen. Dann würde natürlich der Event "OnContextPopup" wieder frei, weil dann markierte Wörter nicht mehr abgespeichert werden können. |
Re: AutoComplete für TMemo, TRichEdit uvm.
der Vorteil eines Streams bzw. einer Stringlist anstelle einer Datei ist das mehrere Komponenten das gleiche AutoComplete verwenden könnten ohne das alles 2 mal im Speicher ist.
[edit=TBx]Da war ein Wort zuviel ;-) Mfg, TBx[/edit] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz