Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 154
  • Last Modified:

improving my function

Hello guys,

I have this function

procedure TForm1.pesquisaPalavra(st: string; cor: Tcolor; Bold: Boolean=True);
var
  FoundAt: LongInt;
  StartPos, ToEnd: Integer;

begin
  with RxRichEdit1 do
  begin
    StartPos := 0;
    { ToEnd is the length from StartPos to the end of the text in the rich edit control }
    ToEnd := Length(RxRichEdit1.Text) - StartPos;
    FoundAt :=  FindText(St, StartPos, ToEnd, [stWholeWord]); // stMatchCase
    while FoundAt <> -1 do
    begin
      SetFocus;
      SelStart := FoundAt;
      SelLength := Length(St);
      SelAttributes.Color := cor;
      If Bold Then SelAttributes.Style := [fsBold];
      StartPos := SelStart + SelLength; // ready to search for the next
      ToEnd := Length(Text) - StartPos;
      FoundAt := FindText(St, StartPos, ToEnd, [stWholeWord]);
    end;
    SelStart := 0; // unselect
    Sellength := 0;
  end;
end;


My function find a word in my richedit and colors it.  I need to know if the prior word is already colored in the same color, if so, then I can color the word found.
My problem is that I don't know how to get the prior word :((

I thank your help

alex
0
hidrau
Asked:
hidrau
  • 5
  • 4
  • 2
  • +1
1 Solution
 
rfwoolfCommented:
"My function find a word in my richedit and colors it.  I need to know if the prior word is already colored in the same color, if so, then I can color the word found. "
Do you mean:
"I need to know if the prior FOUND word is already colored in the same color as the current FOUND word"
or do you mean
"I need to know if the prior word is already colored in the same color as the current FOUND word"
?

For example.
Let's say that the text in the Richedit is this sentence:
"I eat food all the time. My favorite food is cake"
The first "food" is at 7, the second "food" as at 35.
Do you want to know what color the food @ 7 is, so that the food @ 35 is a different color?
OR
Do you want to know what color the word "first" is @ 3-6 so that the food @ 7 is a different color?
0
 
rfwoolfCommented:
Bad example, I meant to say:
Do you want to know what color the food @ 7 is, so that the food @ 35 is a different color?
OR
Do you want to know what color the word "eat" is @ 3-6 so that the food @ 7 is a different color?
0
 
hidrauAuthor Commented:
ok, sorry my poor english :))

let me tell you for what is this function so that you can understand better my need.

I am working with recognizer, you read a sentence and the computer recognize your voice and try to find the word that you are telling. but you need to read in sequence the sentence. then, using the sentence you gave me by example:

I eat food all the time. My favorite food is cake

the word eat is already in blue color, the color represents that I already read the word, so the next word MUST be food, but as you can see, I have two "food"  in my sentence, the system must recognize that the next word to be highlighted is food that comes after eat and not food that comes after favorite.

Now imagine that I speak the word "food" and the first "food" is already in blue, so the system must find the next and when it find it, it must check if the prior word is already colored, this way, the system can knows if I am in the sequence or not. then, if the prior word is not colored, the system can't color the word.

Did you get it?

0
Industry Leaders: 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!

 
TheRealLokiSenior DeveloperCommented:
I would think a better way would be for the "reader" to keep track of the word it just read.
ie. store it in memory...
if you really need it to work as you request though, let me know and I will post some code tomorrow when I am back at Delphi
0
 
2266180Commented:
hello hidrau :)

it is pretty simple actually. you don't store the word, but the position of the last word. you start with 0, and work your way up.

declare a
- lastWordIndex:integer; in your private section of your form and in the button click or whatever you have there that starts reading, initialize it to 0.
- nextWord:string; in your private section of your form and in the button click or whatever you have there that starts reading, initialize it to '' (empty string).

here is my tets application:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    RxRichEdit1: TRichEdit;
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    lastWordIndeX:integer;
    nextWord:string;
    procedure pesquisaPalavra(st: string; cor: Tcolor; Bold: Boolean=true);
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.pesquisaPalavra(st: string; cor: Tcolor; Bold: Boolean);
const
  WordChars:set of char=['a'..'z','A'..'Z',''''];
var
  s,t:string;
  i,j:integer;
begin
  if (nextWord<>'') and (not sametext(nextWord, st)) then
    exit;// the user has spoken a word that is not the next word
  // now, either we don't have a nextWord cached, OR the user spoken the correct nextWord, so get the next one
  if nextWord='' then// no nextword. get it
  begin
    i:=LastWordIndex+1;
    s:=RxRichEdit1.text;
    while (i<=length(s)) and (not (s[i] in WordChars)) do// jump over any character that does not appear in a word
      inc(i);
    t:='';
    j:=lastWordIndex;
    while (i<=length(s)) and (s[i] in WordChars) do// now get the next word
    begin
      t:=t+s[i];
      inc(i);
    end;
    lastWordIndex:=i;
    nextword:=t;
  end;
  if sametext(nextWord, st) then// user read the correct next word?
    with RxRichEdit1 do//highlight the read word
    begin
      SetFocus;
      SelStart := lastWordIndex-Length(nextWord)-1;// selstart is 0-based
      SelLength := Length(nextWord);
      SelAttributes.Color := cor;
      If Bold Then SelAttributes.Style := [fsBold];
      nextWord:='';// clear the cache
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  nextWord:='';
  lastwordindex:=0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  pesquisaPalavra(edit1.text, clred, true);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  button2.click;
end;

end.

I have used  a normal richedit :P
how the caching works:
- if the user did not read the next word correctly, it will cache the word, so next time he tries to read it, the function will not spend resources getting it again :)

how ot use:
  write some text in the richedit, click start read (to initialize stuff) and then write something in the editbox and click read next.

ugly simulation of a reading :)
0
 
hidrauAuthor Commented:
thanks very much ciuly

0
 
hidrauAuthor Commented:
Hello ciuly,

I tested your function and I am having a problem with it, sometimes I need to find two words, like this example:

Imagine this sentence

" I have a big car and a house at the beach where I spend my weekends"

If I need to find "a big car", the function doesn't work :(

what do you suggest?
0
 
2266180Commented:
why do you need to find 3 words as one word? makes no sence.
the user must read: "a" then "big" and then "car"
I can modify the function to accept any text, but you can say goodby to the word caching :P since there is no way to detect if the next thing to read is one word or a bunch of words.

so .. make sur eyou have the requirements set up properly, I don't want to modify the function 3-5-10 times. think of ebery possible usage and post the needed requirements.
0
 
hidrauAuthor Commented:
hello ciuly,

let me explain why sometimes the function must find two or more words.

I developed a system to recognize the voice and if the user read a group of word, the recognizer will return not one by one but a group as I gave you the example. so that I can get word by word I need to read word by word, you get it?

0
 
2266180Commented:
no need to breaka  good system just because another system is making life harder

procedure process(t:text);
var l:TStringList;
i:integer;
begin
  l:=TStringList.create;
  try
    l.delimiter:=' ';//#32
    l.delimitedtext:=t;
    for i:=1 to l.count do
      .if not pesquisaPalavra(l[i-1], clred, true) then
        break;
  finally
    freeandnil(l);
  end;
end;

get it? break up whatever the recognizer sends you into simple words and feed them to the system.
in order to optimize this situation, just modify the function like:

function TForm1.pesquisaPalavra(st: string; cor: Tcolor; Bold: Boolean):boolean;
const
  WordChars:set of char=['a'..'z','A'..'Z',''''];
var
  s,t:string;
  i,j:integer;
begin
  result:=false;
  if (nextWord<>'') and (not sametext(nextWord, st)) then
    exit;// the user has spoken a word that is not the next word
  // now, either we don't have a nextWord cached, OR the user spoken the correct nextWord, so get the next one
  if nextWord='' then// no nextword. get it
  begin
    i:=LastWordIndex+1;
    s:=RxRichEdit1.text;
    while (i<=length(s)) and (not (s[i] in WordChars)) do// jump over any character that does not appear in a word
      inc(i);
    t:='';
    j:=lastWordIndex;
    while (i<=length(s)) and (s[i] in WordChars) do// now get the next word
    begin
      t:=t+s[i];
      inc(i);
    end;
    lastWordIndex:=i;
    nextword:=t;
  end;
  if sametext(nextWord, st) then// user read the correct next word?
    with RxRichEdit1 do//highlight the read word
    begin
      SetFocus;
      SelStart := lastWordIndex-Length(nextWord)-1;// selstart is 0-based
      SelLength := Length(nextWord);
      SelAttributes.Color := cor;
      If Bold Then SelAttributes.Style := [fsBold];
      nextWord:='';// clear the cache
      result:=true;
    end;
end;

meaning: make it a function returning boolean accordingly.

this solution is optimal for your situation.
0
 
hidrauAuthor Commented:
Hi ciuly,

I understood what you said . Yeah, you are right regarding to my limited point of view :((

I feel that there are still many things that I need to learn regarding to developement.

0
 
2266180Commented:
I didn't say your point of view is limited :) I just took the time to explain things step by step
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 5
  • 4
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now