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/)
-   -   Delphi Wort gefunden und markiert! (https://www.delphipraxis.net/147856-wort-gefunden-und-markiert.html)

Chakvour 17. Feb 2010 18:48


Wort gefunden und markiert!
 
Hi,

hab ein kleines Problem warum geht dieses nicht?
Er macht gleich die Form größer wenn ich das Programm starte.

Delphi-Quellcode:
procedure TForm1.Timer4Timer(Sender: TObject);
begin
if SearchForText_AndSelect(RichEdit1, 'Whisper') then
label33.caption := 'You Got A Whisper';
form1.Width := 952;
end;
wenn ich es so schreibe

Delphi-Quellcode:
procedure TForm1.Timer4Timer(Sender: TObject);
begin
SearchForText_AndSelect(RichEdit1, 'Whisper')
end;
funktioniert das. Und das Wort wird auch markiert.

Die Muhkuh 17. Feb 2010 18:59

Re: Wort gefunden und markiert!
 
Wo ist nun das Problem?

Ich bin mir nicht sicher, aber ich denke, Du willst das hier erreichen:

Delphi-Quellcode:
procedure TForm1.Timer4Timer(Sender: TObject);
begin
  if SearchForText_AndSelect(RichEdit1, 'Whisper') then
  begin
    label33.caption := 'You Got A Whisper';
    form1.Width := 952;
  end;
end;

Chakvour 17. Feb 2010 19:09

Re: Wort gefunden und markiert!
 
Ne funktioniert auch nicht.
Naja ich möchte erreichen das durch das Wort Whisper, sich die form vergrößert. Durch den Timer wird das die ganze Zeit alle 15s abgerufen.

Wenn ich das mit einem Button mache anstatt einem Timer funktioniert das.
Aber er soll es halt alle 15sec überprüfen ob es dort aufgetaucht ist, in der Richedit.

Matze 17. Feb 2010 20:32

Re: Wort gefunden und markiert!
 
Hast du dir den Code von Manuel genau angesehen? Er hat ein zusätzliches "begin" und "end" eingefügt. Dann werden beide Anweisungen nur dann ausgeführt, wenn die if-Abfrage zutrifft.

Dein bisheriger Code wird so interpretiert:

Delphi-Quellcode:
procedure TForm1.Timer4Timer(Sender: TObject);
begin
  if SearchForText_AndSelect(RichEdit1, 'Whisper') then
  begin
    label33.caption := 'You Got A Whisper';
  end;

  form1.Width := 952; // wird immer ausgeführt, ob "if" zutrifft oder nicht
end;
Grüße, Matze

Chakvour 18. Feb 2010 08:39

Re: Wort gefunden und markiert!
 
Ich weiss, aber ihr habt mich immernoch falsch verstanden :)

Die Form beträgt, wenn ich das Programm starte "594" in der länge.
Durch den Timer, wie gesagt soll er überprüfen ob das Wort "Whisper" in der Richedit auftaucht.
Dafür ist die function "SearchForText_AndSelect" zuständig.

Der Timer ist auf 10s eingestellt. Allerdings, wenn das Programm öffne führt er nach 10s trotzdem den kompletten timer.
Und die Form vergrösster sich obwohl das Wort Whisper garnicht in der RIchEdit aufgetaucht ist.

Und mit dem Button funktioniert es auch nicht :) Er findet zwar das WOrt aber der Rest danach wird nicht ausgeführt

DeddyH 18. Feb 2010 08:47

Re: Wort gefunden und markiert!
 
Dann setz doch einmal einen Haltepunkt und verfolge den Ablauf. Wenn es nicht das begin-end ist, kann das ja eigentlich nur heißen, dass Deine Funktion einen falschen Wert zurückgibt.

p80286 18. Feb 2010 09:42

Re: Wort gefunden und markiert!
 
Zitat:

Zitat von Chakvour
Und die Form vergrösster sich obwohl das Wort Whisper garnicht in der RIchEdit aufgetaucht ist.

Und genau das hast Du ja auch programmiert!
lies Dir doch bitte einmal #2 und 4 genau durch!

Gruß
K-H

arc 17. Feb 2013 18:17

AW: Wort gefunden und markiert!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Lieber spät als nie, ich habe besagte Funktion auch entdeckt und festgestellt, daß das was da passiert sehr seltsam ist.

Typische Version im Netz:

Delphi-Quellcode:
function SearchForText_AndSelect(RichEdit: TRichEdit; SearchText: string): Boolean;
var
  StartPos, Position, Endpos: Integer;
begin
  StartPos := 0;
  with RichEdit do
  begin
    Endpos := Length(RichEdit.Text);
    Lines.BeginUpdate;
    while FindText(SearchText, StartPos, Endpos, [stMatchCase])<>-1 do
    begin
      Endpos  := Length(RichEdit.Text) - startpos;
      Position := FindText(SearchText, StartPos, Endpos, [stMatchCase]);
      Inc(StartPos, Length(SearchText));
      SetFocus;
      SelStart := Position;
      SelLength := Length(SearchText);
    end;
    Lines.EndUpdate;
  end;
end;
Da ist einiges daneben.
- FindText wird stets doppelt ausgeführt
- Endpos ist keine absolute Position sondern eine relative Textlänge!
- die Funktion gibts nichts zurück
- Inc(StartPos, Length(SearchText)); ist selten dämlich, da FindText die Position des gefundenen Strings zurückliefert, ab da einfach weitersuchen

Das Resultat: Der Code funktioniert zwar, braucht aber EWIG. Meine Variante:

Delphi-Quellcode:
procedure RE_SearchForText_AndSelect(RichEdit: TRichEdit; SearchText: string);
var StartPos, Position, RemainingLength, WordCount, TextSize, SearchSize: Integer;
begin
  if SearchText = '' then Exit;
 
  with RichEdit do
  begin
    Lines.BeginUpdate;

    // reset colors...
    SelStart:=0;
    SelLength:=Length(RichEdit.Text) - 1;
    SelAttributes.Color:=$000000;

    WordCount:=0;
    StartPos:=0;
    TextSize:=Length(RichEdit.Text);
    SearchSize:=Length(SearchText);
    RemainingLength:=TextSize;
    Position:=FindText(SearchText, StartPos, RemainingLength, []);

    if Position <> -1 then
    repeat
      // selects the word and changes color
      SelStart:=Position;
      SelLength:=SearchSize;
      SelAttributes.Color:=$0000FF;
      inc(WordCount);

      // changes startpos to after the current word
      StartPos:=Position + SearchSize;
      // Remaining Text to search for
      RemainingLength:=TextSize - StartPos;
      // find again...
      Position:=FindText(SearchText, StartPos, RemainingLength, []);
    until Position = -1;

    SelLength:=0; // reset selection...
    Lines.EndUpdate;
  end;
  ShowMessage(SearchText + ' found ' + IntToStr(WordCount) + ' times.');
end;
Diese Prozedur ändert die Farbe aller gefundenen Wörter rot und zählt die Anzahl der Fundstellen mit. Ich habe versucht soweit es geht auf Laufzeit zu optimieren. stMatchCase brauche ich nicht. Die Funktion ist bereits recht speziell, aber läßt sich mit wenigen Handgriffen wieder verallgemeinern.

Aufruf z.B. so
Delphi-Quellcode:
  RE_SearchForText_AndSelect(
    RichEdit1,
    InputBox('Find', 'Find What:', '')
  );
Hauptunterschied ist StartPos:=Position + Length(SearchText); statt Inc(StartPos, Length(SearchText)); der Rest ist Geschmacksache. Ich hoffe es hilft dem einen oder anderen.

Viel Spaß!


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:52 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