TFindDialog / Wortsuche im Memo1-Fenster...

Für Fragen von Einsteigern und Programmieranfängern...
Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

Hi Pluto,

das Beispiel scheint mir keins für SynEdit1 zu sein, Da ich ja mit SynEdit1 kein Memo1 Fenster nutze und in deiner Procedure auch kein SynMemo1 enthalten ist... :roll:
Mein Versuch, deine Zeilen irgendwie für das SynEdit1 Fenster zu nutzen, bringt mir sofort Fehlermeldungen, die ich leider nicht verstehe und die ich im Memo1 nicht habe...

Im Grunde tausche ich doch das alte Memo1 Fenster gegen ein SynEdit1 Fenster aus, richtig?!
- Wenn ja, dann müsste ich nun die folgende Prozedure(Befehle) gegen eine für SynEdit1 entsprechend angepasste Procedure ersetzen, um zu den gleichen bzw. ähnlichen Erfolg zu kommen, den ich im Code unten in einem Memo1 erhalte... ?!

Hier nochmal die für mich ausreichend funktionierende Such-Abfrage-Procedure des Memo1 Fenster:

Code: Alles auswählen

procedure TForm7.BitBtn2Click(Sender: TObject);
begin//Namen Suchen! Button... (HSRM ALLE Zusammen)
  Form7.Memo1.SelStart:=Pos(Form7.Edit1.Text, Form7.Memo1.Text);
  Form7.Memo1.SelLength:=Length(Form7.Edit1.Text);
  // Sucht innerhalb des Memo1-Fenster nach der Eingabe vom Edit1-Eingabefeld...
end;


Wie gesagt, SynEdit1 kann wohl mit SelLength nichts anfangen, so daß diese Art zu suchen nicht funktioniert... :roll:

P.S.: Sorry, dass ich hierfür wohl zu bleed bin... :oops:

Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

Hi Pluto,

die Frage darüber wegen SynEdit bzw. SynMemo1 hat sich erledigt... bin doch net ganz soooo bleed, hab es hin bekommen... :lol:

Und zwar mit diesem hier für SynMemo1:

Code: Alles auswählen

procedure TForm1.BitBtn2Click(Sender: TObject);
begin //Namen Suchen! Button... (HSRM ALLE Zusammen)
  Form1.SynMemo1.SelStart:=Pos(Form1.Edit1.Text, Form1.SynMemo1.Text);
  Form1.SynMemo1.SelText;
  //Form1.SynMemo1.SelText:=('*');   //Stern vor dem gefundenen Text stellen...
  // Sucht innerhalb des SynMemo1-Fenster nach der Eingabe vom Edit1-Eingabefeld...
end;


Wenn ich hier hinter SelText ein :=('*'); setze, wird an der Suchstelle das Zeichen * davor gesetzt... und damit wiederum, erscheint beim SynMemo hinter der Zeilen-Nr. eine gelbe Markierung ... und dann weiß ich noch schneller, wo meine Fundstelle ist... tolle Sache, was?! :mrgreen: :wink:

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von pluto »

Es geht noch besser: Du kannst eine komplette Zeile beliebig einfärben *G*.
Schön das, dass Beispiel ausreicht hat *freu*. Wo genau der Unterschied zwischen SynEdit und SynMemo ist weiß ich nicht. Beide sind von der gleichen Bases Klasse abgeleitet(Ich meine jetzt nicht TCustomControl. davon auch, aber nur Indirekt). Jedenfalls kann SynEdit deutlich mehr als das normale Memo, unterstützt jedoch noch kein Automatischen Zeilenumbruch, müsste man dort mal einbauen *G*....
MFG
Michael Springwald

Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

Hi Pluto (oder wer's weiss...)!

Wie kann ich nun beim SynMemo mein gefundener String WEITER suchen lassen?

Dank der Suche, kann ich den 1. gefundenen String in der Liste aufspüren... aber leider nicht weiter zum evtl. nächsten gleichen String springen lassen...
- FRAGE: Wie gehts'

Ich komme mit SelectNext nicht weiter und weiß auch nicht, ob das der richtige Befehl ist...
SO, mit dem Befehl bei einem "Weiter-Suchen" Button, geht's leider nicht... :(

Code: Alles auswählen

Form1.SynMemo1.SelectNext(Form1.Edit2.Text, Form1.SynMemo1.Text);


Bitte nochmals um Hilfe... wäre super, wenn ich das noch mit einbauen könnte... :P

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von pluto »

Ich zitiere mal eine Code stelle aus meinem Editor-Tutorial, was ich demäst Hochladen werde

Code: Alles auswählen

procedure TForm1.AC_NextFindExecute(Sender: TObject);
var
  Editor:TEditor;
  SO:TSynSearchOptions;
  w:Integer;
begin
  Editor:=ActiveEditor;
  if Assigned(Editor) then begin
    if Editor.SearchReplace(FindFrom.ComboBox1.Text,'',FindFrom.GetOptions) = 0 then
      ShowMessage(Format('Suchbegrieff %s wird nicht gefunden !',[FindFrom.ComboBox1.Text]));
end;


TEditor ist eine Abgeleitet Klasse von TSynEdit bzw. TSynMemo.
MFG
Michael Springwald

Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

@Pluto:
Habe was in einem Delphi-Forum gefunden... das hier, ergibt zwar keine Fehlermeldung, aber es funktioniert auch nichts... :cry:

Inhalt auf einen Weitersuchen-Button:

Code: Alles auswählen

procedure TForm1.BitBtn1Click(Sender: TObject);
begin // Weiter suchen!
      Form1.SynMemo1.SelectNext(Edit2, True, True );
      Form1.SynMemo1.SelectLine();
end;


Ich dachte, daß der Inhalt von Edit2, nun zur nächsten Fundstelle springt und anschließend mir diese Zeile wieder Markiert (mit SelectLine)
- Aber leider tut sich überhaupt nichts... :(

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von pluto »

Probiere mal meinen Code aus. Ich denke SelectNext ist eine Interne Methode von TSynEdit, die von SearchReplace genutzt wird. Schau dir mal den Code dazu an. Einfach ein Rechten-Maustasten Klick auf die Methode und den ersten Menupunkt wählen.
MFG
Michael Springwald

Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

pluto hat geschrieben:Probiere mal meinen Code aus. Ich denke SelectNext ist eine Interne Methode von TSynEdit, die von SearchReplace genutzt wird. Schau dir mal den Code dazu an. Einfach ein Rechten-Maustasten Klick auf die Methode und den ersten Menupunkt wählen.

Hi Pluto,

sorry, ich komme mit deinem Code leider nicht weiter... zu viele Fehlermeldungen, die ich wiederum nicht verstehe bzw. nicht wirklich nachvollziehen kann... :(

Kennt sich denn niemand mit synmemo1 darin aus, wie man das hier richtig zum weitersuchen eines Strings anwendet?

Code: Alles auswählen

Form1.SynMemo1.SelectNext(Edit2, True, True );

Das erste true steht ja für vorwärs-suchen... ein false = rückwärts suchen...
Für was das 2. true steht, keine Ahnung... und ob Edit2 in der Klammer richtig ist, weiß ich auch nicht wirklich... so oder so, passiert mit der Zeile nichts, auch wenn keine Fehlermeldung damit auftreten... :roll:

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von pluto »

Was genau für Fehler Meldungen kommen bei meinem Code ? was kannst du nicht nachvollziehen ? Meiner Meinung nach ist der Code selbsterklärend. Sogar in dieser Form. Das Problem ist, wenn du meinen Code verwendest würde es Sinn machen, so ein Such Dialog wie von der Lazarus-IDE Zu verwenden nicht TFindDialog, dass geht zwar auch, aber dort sind nicht alle Options Einstellbar, die im Such-Dialog von Lazarus einstellbar sind.
MFG
Michael Springwald

Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

pluto hat geschrieben:Was genau für Fehler Meldungen kommen bei meinem Code ? was kannst du nicht nachvollziehen ? Meiner Meinung nach ist der Code selbsterklärend.

Hi Pluto, hier anbei meine ganzen Fehlermeldungen mit meinen Code, der auf einen Button (Weiter-Suchen) funktionieren sollte...
- Die ComboBox1 in deinem Code, habe ich lediglich gegen die SynMemo1 vom Namen ausgetauscht... da ich eher Anfängerstatus habe, raffe ich leider nicht viel mehr und habe schnell Probleme mit der Deklaration, wobei es hier nur so an Fehlermeldungen hagelt... siehe selbst... :oops:
Dateianhänge
Errors.jpg

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von pluto »

Die ComboBox1 in deinem Code, habe ich lediglich gegen die SynMemo1

In der ComboBox steht der Suchtext drin. Also wäre SynMemo nicht unbedingt Richtig oder ?

Du kannst die Fehler Meldung mit der Rechten Maustaste Angeklickten und alle in die Zwischenablage Kopieren und die kannst du hier dann einfügen.
Fangen wir mal an:
01) Editor muss bei dir TSynMemo heißen. Du kannst diese Variable ganz löschen. Bei mir war sie notwendig, bei dir jedoch nicht. Überall wo bei mir Editor vorkommt, kannst du alles mit SynMemo1 ersetzten.
02) Die Klasse TSynSearchOptions ist in SynEditTypes drin. Diese Unit musst du bei deiner Uses Klausel hinzufügen. Du kannst es auch ganz weglassen und einfach ein [] hinschreiben, wo FindFrom.GetOptions verwendet wird.
03) Wenn du das gemacht hast müsstest du folgenden Code bekommen haben:

Code: Alles auswählen

procedure AC_NextFindExecute(SuchText:String; Editor:TSynMemo);
begin
    if Editor.SearchReplace(SuchText,[]) = 0 then
      ShowMessage(Format('Suchbegrieff %s wird nicht gefunden !',[SuchText]));
end;

Aufgerufen wird diese Procedure dann so: NextFindExecute('Mein Toller Suchstring', SynMemo1); Die Funktion: ShowMessage ist in der Unit Dialogs drin, die aber in Unit1 schon erhalten sein dürfte.
MFG
Michael Springwald

Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

@Pluto: Du bist KLASSE !!!

Erneut ein großes DANKESCHÖN für deine Hilfe :!: :!: :!:

Zwar hatte ich erst wieder einpaar Fehlermeldungen, doch ich hab meine "Hausaufgaben" gemeistert, die Du mir heimlich mit gegeben hast... :mrgreen:
a) Es fehlte in deinem letzten Code die ' ' vor den []
b) Beim Aufruf mit NextFindExecute fehlte das AC_ davor, es musste also heissen: AC_NextFindExecute ...bla-bla :wink:
c) Mir ist aufgefallen, daß ich die Procedure AC_Next... vor der BitBtn1Click-Procedure setzen musste, da sonst die Aufrufzeile nicht funktioniert hat... irgendwo auch logisch, daß erst die AC_ .. Procedure initialisiert werden muss und erst danach dann der Aufruf funktioniert... war für mich zwar nicht einfach, daß bissel Zeugs da hin zu basteln, aber um so fröhlicher bin ich jetzt, daß ich nun doch noch meine "Hausaufgaben" hinbekommen habe! :lol:

Nun funktioniert also alles so, wie ich es gerne hätte!
Hier nun mein kompletter Ergebnis-Code der Weiter-Suche:

Code: Alles auswählen

procedure AC_NextFindExecute(SuchText:String; Editor:TSynMemo);
begin // Weiter-Suchen-Prozedure von SynMemo1-ListenInhalt...
    if Editor.SearchReplace(SuchText,'',[]) = 0 then
      ShowMessage(Format('Suchbegriff %s wurde nicht gefunden !',[SuchText]));
    // Aufruf der Procedure mit: AC_NextFindExecute(Form1.Edit2.Text,Form1.SynMemo1);
end;
 
procedure TForm1.BitBtn1Click(Sender: TObject);
begin // Weiter-Such-Button
  AC_NextFindExecute(Form1.Edit2.Text,Form1.SynMemo1);
end;


Ach, hier bei der Aufrufzeile fällt mir noch ein, hatte ich erst auch noch Fehlermeldung erhalten, weil ich quasi das Ziel von Form1 nicht angegeben hatte... also mit nur (Edit2.Text,SynMemo1) gab es Fehlermeldung, mit (Form1.Edit2.Text,Form1.SynMemo1) war das Problem behoben...

Na, hab ich die Hausaufgaben nun gut gemacht, bin ich jetzt ein Held? :mrgreen: :mrgreen: :mrgreen: :wink:

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von pluto »

c) Mir ist aufgefallen, daß ich die Procedure AC_Next... vor der BitBtn1Click-Procedure setzen musste, da sonst die Aufrufzeile nicht funktioniert hat... irgendwo auch logisch, daß erst die AC_ .. Procedure initialisiert werden muss und erst danach dann der Aufruf funktioniert... war für mich zwar nicht einfach, daß bissel Zeugs da hin zu basteln, aber um so fröhlicher bin ich jetzt, daß ich nun doch noch meine "Hausaufgaben" hinbekommen habe! :lol:

Das ist eine Methode, die du auch anders benenn kannst. Wichtig ist "nur" das du sie irgendwo am besten unter Privat in deiner From deklarierst.

Ach, hier bei der Aufrufzeile fällt mir noch ein, hatte ich erst auch noch Fehlermeldung erhalten, weil ich quasi das Ziel von Form1 nicht angegeben hatte... also mit nur (Edit2.Text,SynMemo1) gab es Fehlermeldung, mit (Form1.Edit2.Text,Form1.SynMemo1) war das Problem behoben...

Ja, ich habe es als Funktion geschrieben, aber wie schon oben genannt, kannst du es auch als Methode in From1 hinzufügen. Dann musst du nur zwei Dinge machen:
01: du musst vor den Name: TForm1. Schreiben
02: Du musst die Methode innerhalb von TForm1 deklarieren.

Code: Alles auswählen

AC_NextFindExecute(Form1.Edit2.Text,Form1.SynMemo1);

Das Form1 ist hier nicht unbedingt Notwendig.

Edit01: Schön das es jetzt Klappt.
MFG
Michael Springwald

Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

Hallo zusammen!
- An die Fortgeschrittene (guten) Programmierer hier im Forum :!:

Via INet-Suche, bin ich mehrfach auf eine "Lösung" meiner Ursprünglichen Anfrage gestoßen!
- Die Unit, funktioniert zwar, aber eben nicht korrekt... die Fundstellen-Markierung ist bereits nach 2-3 Zeilen schon vom eigentlichen Fundwort VERSETZT... und je länger die Memo1 Zeilen sind, umso mehr ist die Fundstelle beim Weitersuchen versetzt...

FRAGE an die Cracks hier:
Liegt das Problem der Fundstellen-Versetzung an Lazarus oder ist in dem Unit-Listing ein Fehler ???
- Die CheckBox Funktion ist meiner bescheidenen Meinung nach auch für die Katz... :roll:

Wäre super, wenn jemand von euch das Problem bzw. evtl. die Fehlerstelle erkennen und beheben könnte... :)
Anbei, hier nun das Listing:

Code: Alles auswählen

Memo String suchen und Fundstelle(n) markieren... die LÖSUNG???
 
{++++++++++++++++++++++ German +++++++++++++++++++++++++++++++++++++++
Hinweis: Die Checkbox1 ist dazu da, die Groß bzw. Kleinschreibung zu
beachten bzw. nicht beachten.
Der Suchenbutton markiert im Memofeld immer nur das erste Wort.
Der Weitersuchenbutton markiert alle Wörter nacheinander. Bevor man
auf Weitersuchen klickt, muss man auf Suchen klicken.
+++++++++++++++++++++++ english+++++++++++++++++++++++++++++++++++++++
The CheckBox controls the case.
The Find button always look for the 1st occurence.
The FindNext will highlight all the words one after another
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
 
var
  Form1: TForm1;
  x: Integer;
  find: Boolean = False;
 
implementation
 
{$R *.dfm}
 
//Suchenbutton:
 
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  a: string;
begin
  Memo1.Lines.Add('');
  Memo1.Lines.Text := ' ' + Memo1.Lines.Text;
  for i := 0 to Length(Memo1.Lines.Text) - Length(edit1.Text) do
  begin
    a := Copy(Memo1.Lines.Text, i, Length(edit1.Text));
    if CheckBox1.Checked = True then
    begin
      if a = edit1.Text then
      begin
        find := True;
        x    := 2;
        Memo1.Lines.Text := Copy(Memo1.Lines.Text, 2, Length(Memo1.Lines.Text) - 1);
        Memo1.SetFocus;
        Memo1.SelStart  := i - 2;
        Memo1.SelLength := Length(edit1.Text);
        break;
      end;
    end
    else
    begin
      if lowercase(a) = lowercase(edit1.Text) then
      begin
        Memo1.Lines.Text := Copy(Memo1.Lines.Text, 2, Length(Memo1.Lines.Text) - 1);
        find := True;
        x    := 2;
        Memo1.SetFocus;
        Memo1.SelStart  := i - 2;
        Memo1.SelLength := Length(edit1.Text);
        break;
      end;
    end;
  end;
  if find = False then ShowMessage('SuchString nicht gefunden')
  else
    find := False;
end;
 
//Weitersuchenbutton:
 
procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
  a: string;
  d: Integer;
begin
  d := 0;
  for i := 0 to Length(Memo1.Lines.Text) - Length(edit1.Text) do
  begin
    a := Copy(Memo1.Lines.Text, i, Length(edit1.Text));
    if CheckBox1.Checked = True then
    begin
      if a = edit1.Text then
      begin
        d := d + 1;
        if d = x then
        begin
          find := True;
          x    := x + 1;
          Memo1.Lines.Text := Copy(Memo1.Lines.Text, 2, Length(Memo1.Lines.Text) - 1);
          Memo1.SetFocus;
          Memo1.SelStart  := i - 1;
          Memo1.SelLength := Length(edit1.Text);
          break;
          Memo1.Lines.Text := Copy(Memo1.Lines.Text, 2, Length(Memo1.Lines.Text) - 1);
        end;
      end;
    end
    else
    begin
      if lowercase(a) = lowercase(edit1.Text) then
      begin
        d := d + 1;
        if d = x then
        begin
          find := True;
          x    := x + 1;
          Memo1.Lines.Text := Copy(Memo1.Lines.Text, 2, Length(Memo1.Lines.Text) - 1);
          Memo1.SetFocus;
          Memo1.SelStart  := i - 1;
          Memo1.SelLength := Length(edit1.Text);
          break;
          Memo1.Lines.Text := Copy(Memo1.Lines.Text, 2, Length(Memo1.Lines.Text) - 1);
        end;
      end;
    end;
  end;
  if find = False then ShowMessage('SuchString nicht gefunden')
  else
    find := False;
end;

Lollo67
Beiträge: 69
Registriert: Mo 25. Jan 2010, 23:07

Re: TFindDialog / Wortsuche im Memo1-Fenster...

Beitrag von Lollo67 »

Nachtrag zur meiner Frage bez. des Such-Stringes in einem Memo-Fenster:
- Ich habe gerade heraus gefunden, daß sich die Text-Fundstelle mit jedem weiteren Buchstaben VERSCHIEBT, wenn der Memo1 Text-INHALT Umlaute wie ä, Ü, ß etc. enthält...

Demnach müsste man das doch irgendwie lösen können, indem man entweder bei der Eingabe in das Memo sämtliche Umlaute blockiert und nicht zu lässt... oder, die schönere Variante, man den Unit-Code so um programmiert, daß eben die Suchfunktion auch Umlaute berücksichtigt... wer kanns?! :roll: :wink:

Antworten