Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Vyhledavani v kompinentě MEMO (Delphi)

Zdravím.
Už 2 dny se trapim s vyhledavaním textu v komponentě Memo.
Da se toho vygoglit hodně ale bud to nefunguje spolehlině nebo to furt dokola najde první text od vrchu.
Nevite o něčem spolehlivem co mate odskoušene.

Toto třeby furt dokola nachazi první text od vrchu a fal nejde.

procedure TForm1.Button3Click(Sender: TObject);
var
  I, L: Integer;

begin
  Memo1.WordWrap:= False;
  Memo1.Lines.LoadFromFile('Windows.pas');
  I:= Pos('finalization', Memo1.Text);
  if I > 0 then begin
    L := SendMessage(Memo1.Handle, EM_LINEFROMCHAR, I - 1, 0);
    ShowMessage('Found at line ' + IntToStr(L));
// if you need to select the text found:
    Memo1.SelStart := I - 1;
    Memo1.SelLength := Length('finalization');
    Memo1.SetFocus;
  end;
end;

Chci něco jak třeba v PSPadu
Zadam text do editu a pak třeba klikanim na buton prolezu cely text a postupně se obarvuje vybrany text.

Předmět Autor Datum
procedure TForm1.TextFound(const text : string; var MyMemo : TMemo ); var i : integer; begin for i :…
pme 13.12.2012 08:01
pme
Tak v tom kodu nehledej od prvniho radku, ale od radku, na kterem stojis. Kod mas od pme o prispevek…
Jan Fiala 13.12.2012 13:32
Jan Fiala
Dik. MyMemo.CaretPos.Y To je vončo, funguje ;-) Ještě dotaz. Jak vyhledavat text, tak aby nerozlišo…
Vita1 13.12.2012 16:50
Vita1
nejak takto by to mohlo fungovat (pos( text, UpperCase(MyMemo.Lines[i])) > 0)
nl12345 13.12.2012 16:59
nl12345
Alebo rovno previesť na veľké písmená aj čo sa má hľadať: if (pos (UpperCase(text), UpperCase(MyMem…
pme 13.12.2012 17:03
pme
Je zbytecne hledany retezec prevadet na velka pismena pri kazdem volani POS() v cyklu Pokud si jej p…
Jan Fiala 13.12.2012 19:53
Jan Fiala
jj. a bude to trochu aj rýchlejšie. :-)
pme 13.12.2012 19:58
pme
No je mi to jasné. V tom mem přikladu jsem hledal text v celém dokumentu. V tom Vašem to postupně pr…
Vita1 13.12.2012 21:11
Vita1
to X ti vrati prave ta funkcia pos X:=pos (text, UpperCase(MyMemo.Lines[i])
nl12345 14.12.2012 00:05
nl12345
to X ti vrati prave ta funkcia pos X:=pos (text, UpperCase(MyMemo.Lines[i]) No jsem jen lama. Delph…
Vita1 14.12.2012 06:22
Vita1
Je to trosku složitější. SelStart je od začátku textu. Takže si zjistíš SelStart pomocí řádku, na kt…
Jan Fiala 14.12.2012 08:17
Jan Fiala
Aj tak si myslím, že na to čo chce/potrebuje spraviť je vhodnejší/lepší TRichEdit, čo povieš JaFi?
pme 14.12.2012 08:33
pme
Takže si zjistíš SelStart pomocí řádku, na kterém je hledaný text (proměnná i z cyklu) a pak k tomu…
Vita1 14.12.2012 16:55
Vita1
Tu Ti dám hotové riešenie ako to funguje mne... vyhľadá všetky výskyty textu a vyfarbí ich červenou…
pme 14.12.2012 18:14
pme
No fungovat to funguje ale neni to vončo co pořebují. Přesto děkují. Prosíl bych odpovědět na puvod…
Vita1 15.12.2012 08:49
Vita1
Odpoveď na pôvodnú otázku: áno pochopil si to správne. :-) Tu Ti dávam modifikovanú verziu, kde sa…
pme 15.12.2012 09:56
pme
S delphi se trapim teprve 4 měsice tak prosim trochu lepe vysvětlit.Pokud jsem to dobše pochopil tak…
Jan Fiala 15.12.2012 10:10
Jan Fiala
pme děkují moc. Po několika upravach docela spokojen. ;-) Jan ještě 2 dotazy. 1. Byl by problem doci…
Vita1 16.12.2012 10:22
Vita1
Pro barvu pozadi na to musis trosku jinak: Zkus si precist a nastudovat tohle: ibeblog.com
Jan Fiala 16.12.2012 12:09
Jan Fiala
No v 17 rokach si toho člověk moc planovat nemuže. Pokud napišu rano dotaz, pak škola, povinnosti a…
pme 16.12.2012 13:31
pme
Děkují mooc oboum, moc jste mi pomohli. Jak tak koukam tak našemu učiteli programovani moc radost dě…
Vita1 16.12.2012 14:07
Vita1
Tak jsem dal do google RichEdit Text Background Color Delphi. Prolezl jsem všechno. Všude se řeší to…
Vita1 16.12.2012 14:23
Vita1
Ako som Ti už dal príklad vyššie s celým riadkom pracuješ v premennej Line - pozeral si to vôbec? Li…
pme 16.12.2012 14:31
pme
Zmenit atributy casti textu muzes pouze tak, ze text oznacis, provedes zmenu a text odoznacis. Je to… poslední
Jan Fiala 17.12.2012 13:02
Jan Fiala

Tak v tom kodu nehledej od prvniho radku, ale od radku, na kterem stojis.
Kod mas od pme o prispevek vys, jen si zmen radek:

  for i := 0 to MyMemo.Lines.count-1 do 

za

  for i := MyMemo.CaretPos.Y to MyMemo.Lines.count-1 do 

a bude ti hledat od radku na kterem stojis do konce

Dik.
MyMemo.CaretPos.Y
To je vončo, funguje ;-)

Ještě dotaz.
Jak vyhledavat text, tak aby nerozlišoval velka a mala posmena.
UpperCase Převede řetězec na velká písmena
LowerCase Převede řetězec na malá písmena
Takže hledany text si lehce převedu třeba jen na mala ale to prohledavaní.

No je mi to jasné.
V tom mem přikladu jsem hledal text v celém dokumentu.
V tom Vašem to postupně proleze řádek po řádku a v nich to hledá text.
I ty mala a velká písmena chápu.
Převedu hledaný text na mala a prohledávány řádek také a pak hledám.
Jak pak však označit vyhledaný text přes SetFocus.
V Memo1.SelStart se zadává počet znaku od začátku řetězce.
Když budu mít hledaný text na 10 řádku a třeba bude začínat na tom řádku na 20 pozici, jak zjistím X

Memo1.SelStart :=  X;
Memo1.SelLength := Length('edit1.Text');
Memo1.SetFocus;

A ještě jeden dotaz doufam že poslední.
Da se zabarvit nějaky řadek.
Třžeba kdybych chtěl 10 řadek žlutě.

to X ti vrati prave ta funkcia pos
X:=pos (text, UpperCase(MyMemo.Lines[i])

No jsem jen lama.
Delphi mam ve škole jen 3 měsice ale řek bych že mi to vreti pozici na konkretním řadku.
Do Memo1.SelStart však musim zadat pozici od začatku textu ne.

Co to obarvovani řadku ??
Jde třeba 10 řadek vybarvit žlutě.
Ne pismo, to umím ale pozadi.

Takže si zjistíš SelStart pomocí řádku, na kterém je hledaný text (proměnná i z cyklu) a pak k tomu přičteš počet znaků, které najdeš pomoci POS()

S delphi se trapim teprve 4 měsice tak prosim trochu lepe vysvětlit.
Pokud jsem to dobše pochopil tak pomoci cyklu for prolezu všechny řadky od o až po předposlední žadek.
S každeho řadku si připočtu do X kolik ma řadek znaku pomoci length a pak přičtu poskedni přes POS().

Na doporučení pme jsem to překopal s memo do TRichEdit.
Nejde zjistit v teto komponentě ty pozici jednoduchšim zpusobem ??

Tu Ti dám hotové riešenie ako to funguje mne... vyhľadá všetky výskyty textu a vyfarbí ich červenou farbou.

Text, ktorý sa má vyhľadať zadávaš do TEdit - netreba rozlišovať veľké a malé písmená - hľadá sa každý výskyt.

V prípade potreby si uprav TSearchType = (stWholeWord, stMatchCase) v metode FindText. Napr.

FoundAt := FindText(edit1.Text, StartPos, ToEnd, [stMatchCase]);
procedure TForm7.Button1Click(Sender: TObject);
var
  FoundAt: LongInt;
  StartPos, ToEnd: Integer;
begin
  with RichEdit1 do
  begin
    StartPos := 0;
    ToEnd := Length(Text) - StartPos;
    FoundAt := FindText(edit1.Text, StartPos, ToEnd, []);
    while FoundAt <> -1 do
    begin
      SetFocus;
      SelStart := FoundAt;
      SelLength := Length(edit1.Text);
      SelAttributes.Color := clRed;
      StartPos := SelStart + SelLength;
      ToEnd := Length(Text) - StartPos;
      FoundAt := FindText(edit1.Text, StartPos, ToEnd, []);
    end;
    SelStart := 0; // skok na začiatok
    Sellength := 0;
  end;
end;

No fungovat to funguje ale neni to vončo co pořebují.
Přesto děkují.

Prosíl bych odpovědět na puvodni otazku.

Pokud jsem to dobše pochopil tak pomoci cyklu for prolezu všechny řadky od o až po předposlední žadek.
S každeho řadku si připočtu do X kolik ma řadek znaku pomoci length a pak přičtu poskedni přes POS().

Na doporučení pme jsem to překopal s memo do TRichEdit.
Nejde zjistit v teto komponentě ty pozici jednoduchšim zpusobem ??

Pokud to jed jed přes ten cyklus tak to dam.

Jak zabarvit nějaky řadek v komponentě TRichEdit ??

Odpoveď na pôvodnú otázku: áno pochopil si to správne. :-)

Tu Ti dávam modifikovanú verziu, kde sa zabarví aj pozadie nájdeného textu:

implementation

uses RichEdit;

{$R *.dfm}

procedure TForm7.Button1Click(Sender: TObject);
var
  FoundAt: LongInt;
  StartPos, ToEnd: Integer;
  Format: CHARFORMAT2;
begin
  FillChar(Format, SizeOf(Format), 0);
  Format.cbSize := SizeOf(Format);
  Format.dwMask := CFM_BACKCOLOR;
  Format.crBackColor := clYellow;  //pozadie nájdeného textu = žlté

  with RichEdit1 do
  begin
    StartPos := 0;
    ToEnd := Length(Text) - StartPos;
    FoundAt := FindText(edit1.Text, StartPos, ToEnd, []);
    while FoundAt <> -1 do
    begin
      SetFocus;
      SelStart := FoundAt;
      SelLength := Length(edit1.Text);
      SelAttributes.Color := clRed;   //farba nájdeného textu
      SelAttributes.Style := [fsBold];  //ak chceš písmo bude tučné
      SelAttributes.Size := 14;   // veľkosť fontu
      Perform(EM_SETCHARFORMAT, SCF_SELECTION, Longint(@Format));
      StartPos := SelStart + SelLength;
      ToEnd := Length(Text) - StartPos;
      FoundAt := FindText(edit1.Text, StartPos, ToEnd, []);
    end;
    SelStart := 0; // skok na začiatok
    Sellength := 0;
  end;
end;

P.S. "Jo a zas se někdy stav..." (Nebaví ma odpovedať, keď sa ukážeš raz za deň, venuj sa tématu a odpovedaj/pýtaj sa hneď!)

S delphi se trapim teprve 4 měsice tak prosim trochu lepe vysvětlit.Pokud jsem to dobše pochopil tak pomoci cyklu for prolezu všechny řadky od o až po předposlední žadek.S každeho řadku si připočtu do X kolik ma řadek znaku pomoci length a pak přičtu poskedni přes POS().

V cykly pracujes s jednotlivymi radky a prohledavas je - od zacatku radku do konce radku. Tam zjistis, ze hledany text se v tom radku vyskytuje.
Ale pokud chces nalezeny text oznacit, musis pouzit SelStart a SelLength. SelStart urcuje pozici od zacatku textu, ne od zacatku radku.
Takze si musis prevest nalezeny radek na globalni pozici od zacatku (pomoci zpravy) a k tomu prictes pozici, kterou ti vratila funkce POS, abys nastavil SelStart na pozici v radku.

RichEdit je jednodussi, obsahuje i funkci pro hledani. Ale pro uceni bys to mohl zvladnout i pomoci toho MEMO

pme děkují moc.
Po několika upravach docela spokojen. ;-)
Jan ještě 2 dotazy.
1. Byl by problem docilit toho aby ta žluta barva podkladu byla přes cely řadek.
2. Jak vratim po ukončeni hledaní vše do puvodniho stavu.
Moh bych znovu načis text soubor ale takto to řešit nechci.

procedure TForm1.Button3Click(Sender: TObject);
var
FoundAt: LongInt;
StartPos, ToEnd: Integer;
Format: CHARFORMAT2;
begin
FillChar(Format, SizeOf(Format), 0);
Format.cbSize := SizeOf(Format);
Format.dwMask := CFM_BACKCOLOR;
Format.crBackColor := clYellow; //pozadie nájdeného textu = žlté

with RichEdit1 do
begin
StartPos := RichEdit1.SelStart + Length(edit1.Text);
ToEnd := Length(Text) - StartPos;
FoundAt := FindText(edit1.Text, StartPos, ToEnd, []);
while FoundAt <> -1 do
begin
SetFocus;
SelStart := FoundAt;
SelLength := Length(edit1.Text);
SelAttributes.Color := clRed; //farba nájdeného textu
Perform(EM_SETCHARFORMAT, SCF_SELECTION, Longint(@Format));
StartPos := SelStart + SelLength;
ToEnd := Length(Text) - StartPos;
FoundAt := FindText(edit1.Text, StartPos, ToEnd, []);
exit;
end;
SelStart := 0; // skok na začiatok
Sellength := 0;
end;
end;

P.S. "Jo a zas se někdy stav..." (Nebaví ma odpovedať, keď sa ukážeš raz za deň, venuj sa tématu a odpovedaj/pýtaj sa hneď!)

No v 17 rokach si toho člověk moc planovat nemuže.
Pokud napišu rano dotaz, pak škola, povinnosti a k PC se dostanu až večer.
Sobota a neděle :-( Naši řeknou jedem na chatu a jsem v ?????
Vubec je nezajima že musim sedět na netu a čekat až mi pme poradí :-/

No v 17 rokach si toho člověk moc planovat nemuže.
Pokud napišu rano dotaz, pak škola, povinnosti a k PC se dostanu až večer.
Sobota a neděle :-( Naši řeknou jedem na chatu a jsem v ?????
Vubec je nezajima že musim sedět na netu a čekat až mi pme poradí :-/

Sypem si popol na hlavu, toto som si neuvedomil... :.(

Modifikovaná verzia - pridané ďalšie tlačítko pre vrátenie highlight textu späť.
Uprav si to podľa seba...

uses RichEdit;

{$R *.dfm}

procedure TForm7.Button1Click(Sender: TObject);
var
  FoundAt: LongInt;
  StartPos, ToEnd: Integer;
  Format: CHARFORMAT2;
  Line: Integer;
begin
  FillChar(Format, SizeOf(Format), 0);
  Format.cbSize := SizeOf(Format);
  Format.dwMask := CFM_BACKCOLOR;
  Format.crBackColor := clYellow;  //pozadie nájdeného textu = žlté

  with RichEdit1 do
  begin
    StartPos := 0;
    ToEnd := Length(Text) - StartPos;
    FoundAt := FindText(edit1.Text, StartPos, ToEnd, []);
    while FoundAt <> -1 do
    begin
      SetFocus;
      SelStart := FoundAt;
 //     SelLength := Length(edit1.Text);
      SelAttributes.Color := clRed;   //farba nájdeného textu červená
//      SelAttributes.Style := [fsBold];  //ak chceš písmo bude tučné
//      SelAttributes.Size := 14;   // veľkosť fontu
      Line := Perform(EM_LINEFROMCHAR, SelStart, 0) ;
      SelStart := Perform(EM_LINEINDEX, Line, 0) ;
      SelLength := Length(Lines[Line]) ;
      Perform(EM_SETCHARFORMAT, SCF_SELECTION, Longint(@Format));
      StartPos := SelStart + SelLength;
      ToEnd := Length(Text) - StartPos;
      FoundAt := FindText(edit1.Text, StartPos, ToEnd, []);
    end;
    SelStart := 0; // skok na začiatok
    Sellength := 0;
  end;
end;

procedure TForm7.Button2Click(Sender: TObject);
var
  Format: CHARFORMAT2;
begin
  FillChar(Format, SizeOf(Format), 0);
  Format.cbSize := SizeOf(Format);
  Format.dwMask := CFM_BACKCOLOR;
  Format.crBackColor := clWhite;
  with RichEdit1 do
  begin
    SetFocus;
    SelStart := 0;
    Sellength := Length(Text);
    SelAttributes.Color := clBlack;
    SelAttributes.Style := [];  //  nechcem tučné písmo
//    SelAttributes.Size := 14;   // veľkosť fontu
    Perform(EM_SETCHARFORMAT, SCF_SELECTION, Longint(@Format));
    SelStart := 0; // skok na začiatok
    Sellength := 0;
  end;
end;

Tak jsem dal do google RichEdit Text Background Color Delphi.
Prolezl jsem všechno.
Všude se řeší to obarveni vybraneho textu.
Co když však nemam vybrany žadny text.
Co když chci změnit barvu pisma v celem 5 řadku.
Nebo.
Co když chci změnit barvu pozadi v celem 5 řadku.

Ako som Ti už dal príklad vyššie s celým riadkom pracuješ v premennej Line - pozeral si to vôbec?
Line sa zisťuje tu: Line := Perform(EM_LINEFROMCHAR, SelStart, 0) ;

Ak chceš, rovno si dosaď hodnotu čísla riadku Line := 5-1 (musíš odpočítať 1, lebo riadky sú číslované od 0)

SelStart := Perform(EM_LINEINDEX, Line, 0) ;
SelLength := Length(Lines[Line]) ;

Zpět do poradny Odpovědět na původní otázku Nahoru