Board index » cppbuilder » AnsiString insert?

AnsiString insert?


2005-05-20 04:08:14 PM
cppbuilder17
I would have thought the that following code would insert "test" once it
finds "here" in one of the lines? Can anyone see what I'm doing wrong?
I'm sure its something to do with the way I'm using Insert()?
void __fastcall TForm1::Button1Click(TObject *Sender)
{
for(int i=0;i<RichEdit1->Lines->Count;i++)
{
if(RichEdit1->Lines->Strings[i].AnsiPos("here"))
{
RichEdit1->Lines->Strings[i].Insert("test", 10);
}
}
}
 
 

Re:AnsiString insert?

Rory Walsh < XXXX@XXXXX.COM >wrote:
Quote
I would have thought the that following code would insert
"test" once it finds "here" in one of the lines? Can anyone
see what I'm doing wrong?
I'm sure its something to do with the way I'm using Insert()?

void __fastcall TForm1::Button1Click(TObject *Sender)
{
for(int i=0;i<RichEdit1->Lines->Count;i++)
{
if(RichEdit1->Lines->Strings[i].AnsiPos("here"))
{
RichEdit1->Lines->Strings[i].Insert("test", 10);
}
}
}
You are suffering from the most typical VCL problem:
__properties don't always inform their owner when they get
changed, so the change is temporarly and doesn't get through.
In your case: the RichEdit never changes the real string that
lies behind the string property. You must tell it explicitly:
RichEdit1->Lines->Strings[i] = RichEdit1->Lines->Strings[i].Insert("test", 10);
 

Re:AnsiString insert?

Thank you, I can't tell you how often I have made this mistake. Never again!
Rory.
Quote
You are suffering from the most typical VCL problem:
__properties don't always inform their owner when they get
changed, so the change is temporarly and doesn't get through.
In your case: the RichEdit never changes the real string that
lies behind the string property. You must tell it explicitly:

RichEdit1->Lines->Strings[i] = RichEdit1->Lines->Strings[i].Insert("test", 10);

 

{smallsort}

Re:AnsiString insert?

"Rory Walsh" < XXXX@XXXXX.COM >wrote in message
Quote
I would have thought the that following code would insert "test" once it
finds "here" in one of the lines? Can anyone see what I'm doing wrong?
I'm sure its something to do with the way I'm using Insert()?
You are not taking into account that String[] returns a temporary
AnsiString. You are performing your operations on temporary instance, not
the actual Lines data directly. Do this instead:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
for(int i = 0; i < RichEdit1->Lines->Count; ++i)
{
AnsiString s = RichEdit1->Lines->Strings[i];
if( s.AnsiPos("here") != 0 )
{
s.Insert("test", 10);
RichEdit1->Lines->Strings[i] = s;
}
}
}
Even better would be to not use any AnsiStrings at all, since TRichEdit has
native search and insert features of its own. For example (untested):
void __fastcall TForm1::Button1Click(TObject *Sender)
{
RichEdit1->Lines->BeginUpdate();
try
{
int pos = RichEdit1->FindText("here", 0,
RichEdit1->GetTextLen(), TSearchTypes());
while( pos != -1 )
{
int line = RichEdit1->Perform(EM_EXLINEFROMCHAR, 0, pos);
int index = RichEdit1->Perform(EM_LINEINDEX, line, 0);
CHARRANGE range;
range.cpMin = (index + 10);
range.cpMax = range.cpMax;
RichEdit1->Perform(EM_EXSETSEL, 0, (int) &range);
RichEdit1->SelText = "here";
++line;
if( line == RichEdit1->Lines->Count )
break;
pos = RichEdit1->Perform(EM_LINEINDEX, line, 0);
pos = RichEdit1->FindText("here", pos,
RichEdit1->GetTextLen()-pos, TSearchTypes());
}
}
__finally {
RichEdit1->Lines->EndUpdate();
}
}
Gambit
 

Re:AnsiString insert?

Thorsten Kettner wrote:
Quote
Rory Walsh < XXXX@XXXXX.COM >wrote:
>I would have thought the that following code would insert
>"test" once it finds "here" in one of the lines? Can anyone
>see what I'm doing wrong?
>I'm sure its something to do with the way I'm using Insert()?
>
>void __fastcall TForm1::Button1Click(TObject *Sender)
>{
>for(int i=0;i<RichEdit1->Lines->Count;i++)
>{
>if(RichEdit1->Lines->Strings[i].AnsiPos("here"))
>{
>RichEdit1->Lines->Strings[i].Insert("test", 10);
>}
>}
>}

You are suffering from the most typical VCL problem:
__properties don't always inform their owner when they get
changed, so the change is temporarly and doesn't get through.
In your case: the RichEdit never changes the real string that
lies behind the string property. You must tell it explicitly:

RichEdit1->Lines->Strings[i] =
RichEdit1->Lines->Strings[i].Insert("test", 10);
It's not a problem with the VCL. It's just now the Strings[] are
implemented. They are set when the string is SET, as in
RichEdit1->Lines->Strings[i] = "abc";
But just
RichEdit1->Lines->Strings[i].Insert("test", 10);
alone causes the propertie's GETTER to be called, and according to the
docs,
__property AnsiString Strings[int Index] = {read=Get, write=Put};
AnsiString, not AnsiString&, is returned.
So I conclude that the behavior is correct for how it's being returned,
and not a bug, nor a "VLC problem."