Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Wort suchen und markieren in einem TMemo (https://www.delphipraxis.net/168414-wort-suchen-und-markieren-einem-tmemo.html)

Noobmaster 19. Mai 2012 20:51

Wort suchen und markieren in einem TMemo
 
Hallo Leute!

Folgenden Code habe ich mir nach Internetrecherche zusammengebaut. Er soll in einem Memo ein bestimmtes Wort suchen und die gesamte Zeile, in der dieses Wort auftaucht markieren.
Irgendwie macht er das aber nur für die ersten Zeilen, danach werden Zeichen aus der Zeile davor mitmarkiert.

Delphi-Quellcode:
     //Zeile im Memo ermitteln
     Zeile := 0;
     while Pos(Suchtext,MemoWortbaum.Lines[Zeile]) = 0 do
     begin
        Inc(Zeile);
     end;
     //Das wievielte Zeichen im Memotext ist der Anfangsbuchstabe des Wortes?
     StringPos := 0;
     for i := 0 to Zeile - 1 do
     begin
        StringPos := StringPos + Length(MemoWortbaum.Lines[i]);
     end;
     //Markieren
     MemoWortbaum.SelStart := StringPos;
     MemoWortbaum.SelLength := Length(MemoWortbaum.Lines[Zeile]);
     MemoWortbaum.SetFocus;
Danke schonmal-

jaenicke 19. Mai 2012 21:33

AW: Wort suchen und markieren in einem TMemo
 
Du hast bei der Positionsberechnung die Zeilenumbruchszeichen vergessen. ;-)

Bei Delphi und Windows hätte ich einfach EM_LINEINDEX vorgeschlagen, aber inwiefern das für Lazarus sinnvoll ist, weiß ich nicht:
http://msdn.microsoft.com/en-us/libr.../bb761611.aspx
Damit kannst du direkt das erste Zeichen einer Zeile ermitteln bzw. mit EM_LINEFROMCHAR umgekehrt.

himitsu 19. Mai 2012 23:11

AW: Wort suchen und markieren in einem TMemo
 
Und Aufpassen ... Lines/TStrings muß nicht den selben Zeilenumbruch benutzen, wie das Control.

z.B. TRichEdit in Delphis seit D2009.
RitchEdit.Text (mit #13) <> RichEdit.Lines.Text (mit sLineBreak, also #13#10)


Wenn nur etwas gesucht wird, dann also unbedingt Control.Text nutzen, aber da hier dei ganze Zeile nötig ist, dann die erwähnte WinAPI nutzen.
- über Pos in C.Text suchen
- die Zeile des Zeichens erfragen
- und dann noch die Länge der Zeile

Noobmaster 20. Mai 2012 15:36

AW: Wort suchen und markieren in einem TMemo
 
Danke für die Antworten.
Ich glaube ich verstehe nicht ganz, worauf ihr hinauswollt mit der WinApi.
Die Zeile des Zeichens bekomme ich doch über Pos?
Delphi-Quellcode:
     while Pos(Suchtext,MemoWortbaum.Lines[Zeile]) = 0 do
     begin
        Inc(Zeile);
     end;
Tut mir leid, aber ich hab noch nie wirklich mit der WinApi gearbeitet...

jaenicke 21. Mai 2012 18:32

AW: Wort suchen und markieren in einem TMemo
 
Ja, man kann zeilenweise suchen, muss aber nicht. Du brauchst danach aber die Position des ersten Zeichens der Zeile im Gesamttext, da du sonst ja gar nicht weißt was du in SelStart schreiben musst...
Und dafür dient EM_LINEINDEX. ;-)

himitsu 21. Mai 2012 20:17

AW: Wort suchen und markieren in einem TMemo
 
Zitat:

Zitat von Noobmaster (Beitrag 1167338)
Delphi-Quellcode:
     while Pos(Suchtext,MemoWortbaum.Lines[Zeile]) = 0 do
     begin
        Inc(Zeile);
     end;

Tipp: Rate mal was passiert, wenn das Suchwort nicht gefunden wird.

Noobmaster 22. Mai 2012 09:52

AW: Wort suchen und markieren in einem TMemo
 
Zitat:

Zitat von himitsu (Beitrag 1167492)
Zitat:

Zitat von Noobmaster (Beitrag 1167338)
Delphi-Quellcode:
     while Pos(Suchtext,MemoWortbaum.Lines[Zeile]) = 0 do
     begin
        Inc(Zeile);
     end;

Tipp: Rate mal was passiert, wenn das Suchwort nicht gefunden wird.

Dann würde das Programm natürlich abschmieren, weil irgendwann eine Zugriffsverletzung stattfindet.
Der Fall ist aber abgedeckt. Ich habe alle Wörter in einer Baumstruktur gespeichert und er prüft vorher, ob das Wort in dem Baum existiert. Das Memo visualisiert meine Baumstruktur.

Noobmaster 22. Mai 2012 10:00

Lösung
 
Danke Leute!

Lösung:

Delphi-Quellcode:
     //Zeile im Memo ermitteln
     Zeile := 0;
     while Pos(Suchtext,MemoWortbaum.Lines[Zeile]) = 0 do
     begin
        Inc(Zeile);
     end;
     //Markieren
        //Position des ersten Zeichens der gefundenen Zeile im Gesamttext ermitteln
        MemoWortbaum.SelStart := SendMessage(MemoWortbaum.Handle, EM_LINEINDEX, Zeile, 0);
        MemoWortbaum.SelLength := Length(MemoWortbaum.Lines[Zeile]);
        MemoWortbaum.SetFocus;

himitsu 22. Mai 2012 10:31

AW: Lösung
 
Zitat:

Dann würde das Programm natürlich abschmieren, weil irgendwann eine Zugriffsverletzung stattfindet.
Fast.

Bei TStringList und Co. gibt es eine Exception ala EListError (oder so), sobald der Index nicht verfügbar ist, also ein Indexfehler.
Die MemoAPI, bzw das interne TMemoStrings (TStrings) gibt immer einen Leerstring zurück.


Aber OK, eine Endlosschleife ist auch nicht besser. :angle2:


Tipp:
Delphi-Quellcode:
MemoWortbaum.SelStart := SendMessage(MemoWortbaum.Handle, EM_LINEINDEX, Zeile, 0);
//aka
MemoWortbaum.SelStart := MemoWortbaum.Perform(EM_LINEINDEX, Zeile, 0);
Grade gesehn, SetCaretPos nutzt auch EM_LINEINDEX.
Delphi-Quellcode:
Memo.CaretPos := Point(0, Zeile); // X, Y aka Spalte, Zeile
Memo.SelLength := Length(MemoWortbaum.Lines[Zeile]);

Noobmaster 22. Mai 2012 11:04

AW: Wort suchen und markieren in einem TMemo
 
Danke, ich werds berücksichtigen :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz