AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Suchergbenisse farblich hinterlegen (TSynMemo)
Thema durchsuchen
Ansicht
Themen-Optionen

Suchergbenisse farblich hinterlegen (TSynMemo)

Ein Thema von RWarnecke · begonnen am 29. Aug 2009 · letzter Beitrag vom 14. Sep 2009
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#11

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 31. Aug 2009, 15:54
Hallo Hawkeye, Hallo Satty67,

das wäre natürlich noch eine Idee, die beiden Ansätze zu kombinieren. Ich werde es mal ausprobieren, da ich es ja für eine Suche gebrauche.
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#12

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 6. Sep 2009, 10:14
Hallo zusammen, die Funktion von Hawkeye funktioniert jetzt bestens. Ich habe Sie für mein Programm angepasst. Um mit den normalen SearchEngines für SynMemo zu arbeiten, habe ich noch keine Möglichkeit gefunden. Aber ich habe das Problem mit der Groß- und Kleinschreibung so gelöst, dass ich im Vergleich alles auf UpperCase stelle. Jetzt bleibt lediglich nur noch die Frage, wie ich die Schriftart des Wortes erkennen kann um diese dann mit Canvas entsprechend zeichnen zu können. Denn jetzt ist es so, dass bei Kommentaren das hinterlegte Word von kursiv in normal gestellt wird.
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#13

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 8. Sep 2009, 12:05
Hallo,

auch wenn Du schon eine Lösung hast, habe es für mich so gelöst:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
Var
  i: Integer;
  P: TPoint;
begin
  With SynMemo1 Do Begin
    SearchEngine := TSynEditSearch.Create(self);
    SearchEngine.Pattern := InputBox('Suchbegriff','Was sollen wir suchen?','');
    SearchEngine.Options := [ssoReplace, ssoReplaceAll];
    SearchEngine.FindAll(Text);
    For i := 0 To SearchEngine.ResultCount - 1 Do begin
      Canvas.Brush.Color := clYellow;
      Canvas.Font := Font;
      Canvas.Font.Color := clRed;
      P := RowColumnToPixels(BufferToDisplayPos(CharIndexToRowCol(SearchEngine.Results[i] - 1)));
      Canvas.TextOut(P.X, P.Y, SearchEngine.Pattern);
    end;
  end;
end;
Nachteil dieser Lösung: Beim Blättern im Memo gehen die Hervorhebungen verloren.

Ansonsten schau Dir mal den PyScripter an, der ist mit den SynEdit-Komponenten geschrieben und hat das von Dir gewünschte Feature.

Du bekommst die Quelltexte dazu über http://code.google.com/p/pyscripter/source/checkout. Das compilierte Programm ist über http://code.google.com/p/pyscripter/downloads/list zu erhalten. Damit es läuft, muss Python installiert sein (http://www.python.org/download/releases/)
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#14

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 8. Sep 2009, 19:47
Zitat von naphets:
Nachteil dieser Lösung: Beim Blättern im Memo gehen die Hervorhebungen verloren.
. Ich möchte ja meine farblichen Hervorhebungen auch beim scrollen im Text behalten. Mir stellt sich gerade nur die Frage, wie diese Zeile funktionieren soll :
Canvas.Font := Font; Wo wird Font defniert und befüllt ? Könnte das eventuell ein Tippfehler sein oder hast Du etwas vergessen ?
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#15

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 9. Sep 2009, 09:51
Hallo,
Zitat von RWarnecke:
Zitat von naphets:
Nachteil dieser Lösung: Beim Blättern im Memo gehen die Hervorhebungen verloren.
. Ich möchte ja meine farblichen Hervorhebungen auch beim scrollen im Text behalten. Mir stellt sich gerade nur die Frage, wie diese Zeile funktionieren soll :
Canvas.Font := Font; Wo wird Font defniert und befüllt ? Könnte das eventuell ein Tippfehler sein oder hast Du etwas vergessen ?
das ist der Font vom with Syndemo1 do begin, ohne diese Zuweisung wird der Text sonst in einem anderen Schrifttyp dargestellt.

Der PyScripter macht das so, wie Du es möchtest, habe aber keine Zeit, da jetzt zu forschen, wie die das genau machen, es sind jedenfalls mehrere Units, die dazu gebraucht werden. Da der Quelltext aber verfügbar ist, sollte es möglich sein, eine analoge Lösung für Dein Programm zu finden.
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#16

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 10. Sep 2009, 10:09
Hallo,

bei meinem Editor klappt das mit der Hervorhebung nun, sie bleibt auch beim Blättern erhalten.

Was habe ich dazu gemacht?

Eine Klasse angelegt:
Delphi-Quellcode:
type
  TFoundItem = class
    Result : Integer;
  end;
Das Frame, das die Syneditkomponente enthält hat folgende Änderungen erfahren:
Delphi-Quellcode:
TFrameEditor = class(TFrame)
  ...
  procedure SynEditPaint(Sender: TObject; ACanvas: TCanvas);
  procedure SynEditChange(Sender: TObject);

  private
  { Private-Deklarationen }
  ...
  fHighlightedTerm : String; // hierin merken wir uns den Suchbegriff für die Hervorhebung.
  fFoundItems: TObjectList; // Liste der Fundstellen.

public
  { Public-Deklarationen }
  ...
  property FoundItems : TObjectList read fFoundItems Write fFoundItems;
  property HighlightedTerm : String read fHighlightedTerm Write fHighlightedTerm;
end;
Die Prozedure SynEditPaint wird dem OnPaint-Ereignis des SynEdits zugewiesen.
Delphi-Quellcode:
procedure TFrameEditor.SynEditPaint(Sender: TObject; ACanvas: TCanvas);
var
  i : Integer;
  FoundItem : TFoundItem;
  P : TPoint;
begin
  with SynEdit do begin
    for i := 0 to fFoundItems.Count - 1 do begin
      FoundItem := fFoundItems[i] as TFoundItem;
      P := RowColumnToPixels(BufferToDisplayPos(CharIndexToRowCol(FoundItem.Result - 1)));
      ACanvas.Font := Font;
      ACanvas.Brush.Color := clYellow;
      ACanvas.Brush.Style := bsSolid;
      ACanvas.TextOut(P.X, P.Y, HighlightedTerm);
    end;
  end;
end;
Bei Änderungen im Editor, werden die Markierungen aufgehoben, da sie ihre Position ändern und daher neu gesucht werden müssten, bevor man sie neu zeichnet. Das ließe sich nur verhindern, wenn man bei jeder Änderung die Suche wiederholt, um die Markierungen an den neuen Stellen zu setzen.
Delphi-Quellcode:
procedure TFrameEditor.SynEditChange(Sender: TObject);
begin
  // Bei Änderungen im Editor die Markierungen aufheben,
  // da ansonsten das Neuzeichnen der Markierung nicht mehr
  // gelingt, da sich die Positionen der markierten
  // Stellen verändern und daher neu gesucht werden müssten.
  If FoundItems.Count > 0 then begin
    FoundItems.Clear;
    SynEdit.Repaint; // Damit alte Markierungen entfernt werden.
  end;
end;
Beim Erstellen des Formulars/Frames darf das Erstellen der Objektliste nicht vergessen werden und bei der Freigabe das Free (was ich immer wieder so mache).

Die Routine für die Suche sieht folgendermaßen aus:
Delphi-Quellcode:
procedure TfmMain.acTestactionExecute(Sender: TObject);
Var
          i : Integer;
          FoundItem : TFoundItem;
begin
  with ActiveFrameEditor.SynEdit Do begin
    // Liste der "alten" Markierungen löschen.
    ActiveFrameEditor.FoundItems.Clear;
    Repaint; // Damit alte Markierungen auch optisch entfernt werden.
    ActiveFrameEditor.HighlightedTerm := InputBox('Eingabe','Suchbegriff','');
    SearchEngine := SynEditSearch;
    SearchEngine.Pattern := ActiveFrameEditor.HighlightedTerm;
    SearchEngine.Options := [ssoReplace, ssoReplaceAll];
    SearchEngine.FindAll(Text);
    for i := 0 to SearchEngine.ResultCount - 1 do begin
      FoundItem := TFoundItem.Create;
      FoundItem.Result := SearchEngine.Results[i];
      ActiveFrameEditor.FoundItems.Add(FoundItem);
    end;
    Repaint; // Damit neue Markierungen gesetzt werden, einmal neu zeichnen.
  end;
end;
Bei der Verwendung von SynEdit.TopLine und SynEdit.LinesInWindow könnte man eventuell durch zeilenweises Suchen und Markieren, die Markierungen auch bei Änderungen aufrechterhalten, das habe ich aber (noch) nicht ausprobiert.

Hoffe, dass das ein bisserl weiterhilft.
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#17

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 10. Sep 2009, 10:19
Wie wärs wenn Du einen TSynGeneralSyn als Highlighter nimmst und dort den Suchtext unter "Keywords" hinzufügst? Den Stil wie das gezeichnet werden soll kannst Du ja auch direkt festlegen dort
Also zumindest für eine einfache Texte ohne RegEx müsste das gehen.
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#18

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 10. Sep 2009, 11:21
Hallo David,

Zitat von mirage228:
Wie wärs wenn Du einen TSynGeneralSyn als Highlighter nimmst und dort den Suchtext unter "Keywords" hinzufügst? Den Stil wie das gezeichnet werden soll kannst Du ja auch direkt festlegen dort
Also zumindest für eine einfache Texte ohne RegEx müsste das gehen.
Das war auch mein erster Gedanke. Ein kurzer Versuch zeigte jedoch, dass damit beispielsweise Leer- und Sonderzeichen in Suchbegriffen nicht mehr möglich sind. Auch Teile von Wörtern werden auf diese Weise nicht gefunden. Es würde also darauf hinauslaufen, einen eigenen Highlighter zu schreiben, was aber durchaus eine Alternative sein könnte.

Gruß Hawkeye
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#19

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 10. Sep 2009, 11:32
Hallo,

da gibt es nochwas zu bedenken:

Wenn ich bereits einen Highlighter zugewiesen habe und den nun durch einen TSynGeneralSyn ersetzte, dann habe ich zwar die Hervorhebung für die Suchbegriffe, aber die eigentliche Hervorhebung geht verloren, bzw. wird durch die des TSynGeneralSyn ersetzt.
Eigentlich müsste man den Vorfahren TSynCustomHighlighter anpassen, dann haben alle Highlighter diese Funktionalität.

Vermutlich ist der Aufwand noch nicht einmal so riesig.

Dazu fällt mir dann die Frage ein: Wie bekommt man heraus, welcher SynEdit...-Komponente ein Highlighter zugewiesen ist (in der Form, dass eine Methode des Highlighters diese Zugehörigkeit ermittelt)?
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#20

Re: Suchergbenisse farblich hinterlegen (TSynMemo)

  Alt 11. Sep 2009, 10:37
Hallo,

ein paar Stunden später:

Es geht viel einfacher:

Wir brauchen eine Routine, die uns nach dem Suchbegriff fragt:
Delphi-Quellcode:
// Der über die InputBox eingegebene Text wird im SynEdit hervorgehoben.
procedure TfmMain.acFindAndMarkExecute(Sender: TObject);
begin
  with ActiveFrameEditor.SynEdit Do begin
    If Not Assigned(SearchEngine) then begin
      SearchEngine := TSynEditSearch.Create(ActiveFrameEditor.SynEdit);
      SearchEngine.Options := [ssoReplace, ssoReplaceAll];
    end;
    SearchEngine.Pattern := '';
    Repaint; // Damit alte Markierungen entfernt werden.
    SearchEngine.Pattern := InputBox('Eingabe','Suchbegriff','');
    Repaint; // Damit neue Markierungen gesetzt werden, einmal neu zeichnen.
  end;
end;
Das OnPaint-Ereignis des SynEdit bekommt folgende Routine:
Delphi-Quellcode:
procedure TFrameEditor.SynEditPaint(Sender: TObject; ACanvas: TCanvas);
var
  i : Integer;
  j : Integer;
  P : TPoint;
begin
  with SynEdit do begin
    // Ist keine Suchmaschine zugewiesen, raus, dann können wir uns das sparen.
    If Not Assigned(SearchEngine) then Exit;
    If SearchEngine.Pattern = ''  then Exit;
    ACanvas.Font := Font; // Font des SynEdits, sonst stimmt der Schrifttyp nicht.
    ACanvas.Brush.Color := clYellow;
    ACanvas.Brush.Style := bsSolid;
    // Die Suchbegriffe werden nur im sichtbaren Bereich hervorgehoben,
    // spart bei großen Dateien viel Zeit.
    for i := TopLine - 1 to TopLine + LinesInWindow do begin
      SearchEngine.FindAll(Lines[i]);
      for j := 0 to SearchEngine.ResultCount - 1 do begin
        P := RowColumnToPixels(BufferToDisplayPos(BufferCoord(SearchEngine.Results[j], i + 1)));
        ACanvas.TextOut(P.X, P.Y, SearchEngine.Pattern);
      end;
    end;
  end;
end;
Bei Änderungen im SynEdit machen wir folgendes:
Delphi-Quellcode:
procedure TFrameEditor.SynEditChange(Sender: TObject);
begin
  SynEdit.Repaint; // Markierungen neu zeichnen
end;
Das führt dazu, dass Hervorhebungen erhalten bleiben, während man Text eingibt oder löscht...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:50 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