Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   RichEdit markiert nicht mehrere unterschiedliche Einträge. (https://www.delphipraxis.net/180916-richedit-markiert-nicht-mehrere-unterschiedliche-eintraege.html)

Bjoerk 30. Jun 2014 20:43

RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Ich wollte mehre verschiedene Wörter in einem RichEdit markieren. "Er" macht aber immer nur das erste Suchwort (zwar im ganzen Text), aber keine weiteren? Gibst da irgendeinen Trick? (Nur falls Zeit und Lust so während dem Fußball)

Delphi-Quellcode:
function TFindSourceMainForm.RichEditPos(const S: string): integer;
begin
  if WholeWordsCheckBox.Checked then
    Result := TStrUtils.WordPos(FSubStr, S)
  else
    Result := TStrUtils.Pos(FSubStr, S);
end;

procedure TFindSourceMainForm.HighlightResults;
var
  I, J, APos, ACount, K, SubStrCount: Integer;
  ARichEdit: TRichEdit;
begin
  for I := 0 to PageControl.PageCount - 1 do
  begin
    ACount := 0;
    ARichEdit := RichEdit(I);
    ARichEdit.Lines.BeginUpdate;
    try
      if GraphicObjectTypesCheckBox.Checked then
        SubStrCount := FGraphicObjectTypes.Count
      else
        SubStrCount := 1;
      for K := 0 to SubStrCount - 1 do // ***
      begin
        if GraphicObjectTypesCheckBox.Checked then
          FSubStr := FGraphicObjectTypes[K];
        for J := 0 to ARichEdit.Lines.Count - 1 do
        begin
          APos := RichEditPos(ARichEdit.Lines[J]);
          if APos > 0 then
          begin
            ARichEdit.SelStart := ACount + APos - 1;
            ARichEdit.SelLength := Length(FSubStr);
            ARichEdit.SelAttributes.Color := clBlack;
            ARichEdit.SelAttributes.Style := [fsBold];
          end;
          ACount := ACount + Length(ARichEdit.Lines[J]) + 2; // 2 = Zeilenumbruch;
          if FCancel then
            Exit;
        end;
      end;
    finally
      ARichEdit.Lines.EndUpdate;
      ARichEdit.SelStart := 0;
      ARichEdit.SelLength := 0;
    end;
  end;
end;

himitsu 30. Jun 2014 21:12

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Was sagt denn der Debugger?
* Geht der Code mehrmals in
Delphi-Quellcode:
if APos > 0 then
rein?
* Wenn ja, was passiert da drin? (die Variablen/Positionen)

Soll wirklich immer nur das erste jeweilige Wort pro Zeile behandelt werden?
Wenn nicht, dann ist es erst Recht einfacher über den gesamten Text zu suchen (PosEx und Co.)

Zitat:

Delphi-Quellcode:
// 2 = Zeilenumbruch;

Wer behauptet das?

Und ich bezieh mich nichmal auf iOS/Android, wo auch noch sows wie
Delphi-Quellcode:
APos > 0
falsch wäre, da Strings nicht mehr mit Index 1 beginnen. :wall:
Ich weiß nicht mehr genau seit wann, aber spätestens in D2009 wurde das Richedit auf eine neuerere API-Version umgestellt und seitdem sind intern die Zeilenumbrüche auf #13 (Mac), seitens der WinAPI und auch im SelStart/SelLength, auch wenn man blöder Weise nur im .Text das durch sLineBreak (#13#10 im Windows) ersetzt wird, was dann falsche Positionen erzeugt, wenn man die Position im String 1:1 auf SelStart anwendet. :doppel-wall:

Wenn du die anhand der Zeilenposition die gesamtposition haben willst, dann solltest du die WinAPI fragen.

Bjoerk 30. Jun 2014 21:34

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
APos findet alle. Die 2 stimmt auch. Es ist mir ein Rätsel?

Bjoerk 30. Jun 2014 21:53

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Achso, jetzt weiß ich was du meinst, Klar da sollte man auch ein PosEx mit While Schleife draus machen. Löst aber das problem nicht.

Ich hab mir den Algo jetzt mal näher angeschaut. Kann so nicht funktionieren. Vergiss es. Sorry. #schäm#

Bjoerk 1. Jul 2014 08:11

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Wenn du magst kannst du ja mal das durchlaufen lassen und kur Bescheid geben ob das auch für > D2007 jeht?. Thanx!
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FSelList: TStringList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure Highlight(RichEdit: TRichEdit;
  SelList: TStrings; SelColor: TColor; SelStyle: TFontStyles);
var
  I, J, Pos, Index: Integer;
begin
  RichEdit.Lines.BeginUpdate;
  try
    Index := 0;
    for I := 0 to RichEdit.Lines.Count - 1 do
    begin
      for J := 0 to SelList.Count - 1 do
      begin
        Pos := PosEx(SelList[J], RichEdit.Lines[I], 1);
        while Pos > 0 do
        begin
          RichEdit.SelStart := Index + Pos - 1;
          RichEdit.SelLength := Length(SelList[J]);
          RichEdit.SelLength := Length(SelList[J]);
          RichEdit.SelAttributes.Color := SelColor;
          RichEdit.SelAttributes.Style := SelStyle;
          Pos := PosEx(SelList[J], RichEdit.Lines[I], Pos + 1);
        end;
      end;
      Index := Index + Length(RichEdit.Lines[I]) + Length(sLineBreak);
    end;
  finally
    RichEdit.Lines.EndUpdate;
    RichEdit.SelStart := 0;
    RichEdit.SelLength := 0;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  RichEdit1.Font.Color := clLtGray;

  RichEdit1.Lines.Add('+++ Liveticker Deutschland gegen Algerien +++');
  RichEdit1.Lines.Add('Löw ist restlos bedient - wie reagiert er?');
  RichEdit1.Lines.Add('Deutschland, der klare Favorit im WM-Achtelfinale? Denkste!');
  RichEdit1.Lines.Add('Algerien ist überlegen, hat viele Großchancen.');
  RichEdit1.Lines.Add('Deutschland spielt unsicher und konfus.');
  RichEdit1.Lines.Add('Löw ist restlos bedient - hat er ist einen Plan?');
  RichEdit1.Lines.Add('Verfolgen Sie die Partie im Liveticker.');

  FSelList.Clear;
  FSelList.Add('Löw');
  FSelList.Add('ist');
  FSelList.Add('Liveticker');

  Highlight(RichEdit1, FSelList, clBlack, [fsBold]);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FSelList := TStringList.Create;
  // RichEdit1.HideSelection := false;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FSelList.Free;
end;

DeddyH 1. Jul 2014 08:26

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Unter XE laufen lassen (siehe Screenshot).

Bjoerk 1. Jul 2014 09:12

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Gut. Dann ist Length(sLineBreak) um 1 falsch (zu groß). Was ist denn bei dir Length(sLineBreak)?

DeddyH 1. Jul 2014 09:15

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Erwartungsgemäß 2. Allerdings glaube ich, dass das RichEdit in Delphi XE ziemlich verbuggt ist, ich hatte mit ähnlichen Routinen auch schon schier unlösbare Probleme.

Bjoerk 1. Jul 2014 09:47

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Ok. Danke. Ich glaub ich wird mir erst dann eine neue Delphiversion holen wenn es einen Compilerschalter $Ansistrings gibt. :)

DeddyH 1. Jul 2014 09:54

AW: RichEdit markiert nicht mehrere unterschiedliche Einträge.
 
Also im Klartext nie :twisted:


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:30 Uhr.
Seite 1 von 2  1 2      

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