Solved

How to perform a Search with a TMemo?

Posted on 1998-10-03
13
319 Views
Last Modified: 2010-04-06
I would like to know how to perform a search in a tmemo component with a Tfinddialog.  You know, exactly like when you choose the "Find..." function in a word processor or in a text editor.  I've got this code but it doesn't works properly, i think something is missing in the code:

procedure TForm1.Find1Click(Sender: TObject);
begin
  I := 0;
  IF FindDialog1.Execute then
  begin
    while (Pos(FindDialog1.FindText, Memo1.Lines[I]) = 0)
      AND (I <= (Memo1.Lines.Count+1)) do Inc(I);
  end;
end;

If you need some specifications to this question just ask me.
0
Comment
Question by:elbaid
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
  • +2
13 Comments
 

Author Comment

by:elbaid
ID: 1341590
Edited text of question
0
 
LVL 5

Expert Comment

by:inter
ID: 1341591
Hi,
this code works for case sensitive search and it can not detect wrapping words. The casre insensitive version can be as follows:

procedure TForm1.Find1Click(Sender: TObject);
    begin
      I := 0;
      IF FindDialog1.Execute then
      begin
        while (Pos(LowerCase(FindDialog1.FindText), LowerCase(Memo1.Lines[I])) = 0)
          AND (I <= (Memo1.Lines.Count+1)) do Inc(I);
      end;
    end;
igor
0
 
LVL 5

Expert Comment

by:inter
ID: 1341592
More code from Delphi help is as follows:
(associate this with the find dialog find event and remove the previous code)

procedure TForm1.FindDialog1Find(Sender: TObject);

var
  I, J, PosReturn, SkipChars: Integer;
begin
  for I := 0 to Memo1.Lines.Count do
  begin
    // I added case insensitive search here
    PosReturn := Pos(LowerCase(FindDialog1.FindText),LowerCase(Memo1.Lines[I]));
    if PosReturn <> 0 then {found!}
    begin
      Skipchars := 0;
      for J := 0 to I - 1 do
        Skipchars := Skipchars + Length(Memo1.Lines[J]);
      SkipChars := SkipChars + (I*2);
      SkipChars := SkipChars + PosReturn - 1;
      Memo1.SetFocus;
      Memo1.SelStart := SkipChars;
      Memo1.SelLength := Length(FindDialog1.FindText);
      Break;
    end;
  end;
end;
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 10

Expert Comment

by:viktornet
ID: 1341593
you could also do something like this:

it does not use TFindDialog..Just a simple procedure....

procedure GoTo(Memo : TMemo; sWord : string);
var
  nPos : Integer;
begin
  nPos := Pos(sWord, Memo.Text);
  if nPos > 0 then begin
    Memo.SetFocus;
    Memo.SelStart := nPos;
    Memo.SelLength(Length(sWord));
  end;
end;

Example call: GoTo(Memo1, 'Anything');

Note: Haven't tested this so you might need a bit of modification...

Regards,
Viktor Ivanov
0
 
LVL 1

Expert Comment

by:BlackDeath
ID: 1341594
hi, elbaid.
try this:


procedure TForm1.FindDialog1Find(Sender: TObject);
var Buff, P, FT : PChar;
    BuffLen     : Word;
begin
  with Sender as TFindDialog do begin
    GetMem(FT, Length(FindText) + 1);
    StrPCopy(FT, FindText);
    BuffLen := Memo1.GetTextLen + 1;
    GetMem(Buff, BuffLen);
    Memo1.GetTextBuf(Buff, BuffLen);
    if Memo1.SelStart <> 0 then
      P:= Buff + Memo1.SelStart + Memo1.SelLength
    else
      P := Buff;
    P:= StrPos(P, FT);
    if P = NIL then MessageBeep(0)
    else
    begin
       Memo1.SelStart:= P - Buff;
       Memo1.SelLength:= Length(FindText);
    end;
    FreeMem(FT, Length(FindText) + 1);
    FreeMem(Buff,BuffLen);
    Memo1.SetFocus;
  end;
end;

this ain't case insensitive. to do this, you gotta change it a little bit.
if you want to find wrapping words, you will have to replace each #13#10 with nothing i.e. an empty string. if you need a StrReplace func, tell us.

you will also have to implement the "searching upwards" by yourself.
anyway, this is quite fast.

i'll see if i find some time tonight to improve it.

so long,

Black Death.

0
 
LVL 1

Expert Comment

by:BlackDeath
ID: 1341595
hi, elbaid.
try this:


procedure TForm1.FindDialog1Find(Sender: TObject);
var Buff, P, FT : PChar;
    BuffLen     : Word;
begin
  with Sender as TFindDialog do begin
    GetMem(FT, Length(FindText) + 1);
    StrPCopy(FT, FindText);
    BuffLen := Memo1.GetTextLen + 1;
    GetMem(Buff, BuffLen);
    Memo1.GetTextBuf(Buff, BuffLen);
    if Memo1.SelStart <> 0 then
      P:= Buff + Memo1.SelStart + Memo1.SelLength
    else
      P := Buff;
    P:= StrPos(P, FT);
    if P = NIL then MessageBeep(0)
    else
    begin
       Memo1.SelStart:= P - Buff;
       Memo1.SelLength:= Length(FindText);
    end;
    FreeMem(FT, Length(FindText) + 1);
    FreeMem(Buff,BuffLen);
    Memo1.SetFocus;
  end;
end;

this ain't case insensitive. to do this, you gotta change it a little bit.
if you want to find wrapping words, you will have to replace each #13#10 with nothing i.e. an empty string. if you need a StrReplace func, tell us.

you will also have to implement the "searching upwards" by yourself.
anyway, this is quite fast.

i'll see if i find some time tonight to improve it.

so long,

Black Death.

0
 

Author Comment

by:elbaid
ID: 1341596
My answer was a mix with inter's second answer and Black Death's answer, so thanks guys.  Is it possible to give some points to Black Death?

Elbaid
0
 
LVL 1

Expert Comment

by:BlackDeath
ID: 1341597
i think you could ask linda to let her split the points between us as you desire.

have a nice day,
:-)
Black Death.
0
 
LVL 1

Expert Comment

by:BlackDeath
ID: 1341598
btw:

if you look at delphi 1 - demo "textdemo", there's a unit "search.pas" which implements just what you want the borland style. i found this last night.
if you ain't got delphi 1, post your email address here and i'll mail you the sources.

so long,

Black Death.

0
 

Author Comment

by:elbaid
ID: 1341599
k cool, you can send this to elbaid@hotmail.com

thanks!

elbaid
0
 
LVL 7

Expert Comment

by:linda101698
ID: 1341600
elbaid sent me the following email:
I want to split my 150 points given to question Q.10085824 to inter and
Black Death.  50 to inter and 100 to Black Death because the question
isn't actualy answered.  They send their answers by comments.

So this question can be saved, I'd like BlackDeath to post an answer to the question.  The question can then be graded and saved in the Previously Asked Questions (PAQ).  

I'll post another question in this topic area for  inter to award him/her points for the contribution to this question.

Linda Gardner
Customer Service @ Experts Exchange.
0
 
LVL 1

Expert Comment

by:BlackDeath
ID: 1341601
ok, linda-darling. here we go.
thanx to elbaid.
greetings to inter. is this ok for you?
have a nice day - all of you,

Black Death.
0
 
LVL 1

Accepted Solution

by:
BlackDeath earned 150 total points
ID: 1341602
...
Black Death.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question