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.

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
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… nový
Vita1 13.12.2012 16:50
Vita1
nejak takto by to mohlo fungovat (pos( text, UpperCase(MyMemo.Lines[i])) > 0) nový
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… nový
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… nový
Jan Fiala 13.12.2012 19:53
Jan Fiala
jj. a bude to trochu aj rýchlejšie. :-) nový
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… nový
Vita1 13.12.2012 21:11
Vita1
to X ti vrati prave ta funkcia pos X:=pos (text, UpperCase(MyMemo.Lines[i]) nový
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… nový
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… nový
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? nový
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… nový
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… nový
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… nový
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… nový
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… nový
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… nový
Vita1 16.12.2012 10:22
Vita1
Pro barvu pozadi na to musis trosku jinak: Zkus si precist a nastudovat tohle: ibeblog.com nový
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… nový
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ě… nový
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… nový
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… nový
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.

Je to trosku složitější. SelStart je od začátku textu. 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()

MyMemo.SelStart := MyMemo.Perform(EM_LINEINDEX, i, 0) + X;

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