Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Select string of text in RichEdit

Status
Not open for further replies.

cyprus106

Programmer
Apr 30, 2001
654
I've got a syntax highlighting code that works great with one exception. It can't highlight dynamic code. it can highlight things like <html> but it can't highlight things like <font color=green> because the color could change and it can't automatically detect that kind of thing.

With that in mind, basically here's what I cant figure out:
I need to select text in a rich edit from the beginning of a 'tag' to the end character in a tag. For example, if I ran across something that said '<font' then it would start selecting the text at the '<' and wouldn't stop until it hit it's first '>'
I tried a few different methods but didn't come up with much. I was hoping somebody around here would? Cyprus
 
Howdy, I dont intend to be a hamper on your question, but I have had the EXACT same problem, and could find no answer. I tinkered w/ everything I could think of and got no results. I hope someone can help you, as that could save one of my projects. I have presently filed it under &quot;hopeless&quot;.

I am intested what the problem is...

Good Luck,
onrdbandit
 
Have either of you looked at They have some FAQ and CAQ (commonly asked questions) that might help. I've never used rich text much so I'm not much help otherwise. James P. Cottingham

When a man sits with a pretty girl for an hour, it seems like a minute. But let him sit on a hot stove for a minute and it's longer than any hour. That's relativity.
[tab][tab]Albert Einstein explaining his Theory of Relativity to a group of journalists.
 
I go there a lot, but they don't have anything anywhere near what I need. Thanks, anyways though. Cyprus
 
It would Seem that this is a common problem. I too have a text editor in progress that would greatly be enhanced by what you are referring to. I have spent some little time on this problem and have put it on the back burner for now. It would seem that the task at hand is to test the characters before and after the selected text up to the delimiting character(s). and then ensure that the modified text has the proper color. I am comtemplating testing the text selected for a highlight color and if this is detected check the surrounding characters for the delimit. The brain refuses to pursue this any further and I will not fight it for now. I will post any results if I can find some time to work on it.

so far

bool tokenflag;
bool go;
char buff1 [256];
char buff2 [2];

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

}

void __fastcall TForm1::RichEdit1Change(TObject *Sender)
{

if (go)
{
int x = strlen (buff1);
int y = RichEdit1->SelStart - x;

RichEdit1->SelStart = y;
RichEdit1->SelLength = x;
RichEdit1->SelAttributes->Color = clBlue;
RichEdit1->SelAttributes->Style = RichEdit1->SelAttributes->Style << fsBold;
RichEdit1->SelStart = y + x;
RichEdit1->SelAttributes->Assign (RichEdit1->DefAttributes);

go = false;
}

else
{
//if (RichEdit1->SelAttributes->Color != clBlue)
// RichEdit1->SelAttributes->Assign (RichEdit1->DefAttributes);
}
}

void __fastcall TForm1::RichEdit1KeyPress(TObject *Sender, char &Key)
{
if (tokenflag)
{
buff2 [0] = Key;
buff2 [1] = NULL;
strcat (buff1, buff2);

if (Key == '>')
{
tokenflag = false;
go = true;
}
Edit1->Text = buff1;
}

if (!tokenflag)
{
if (Key == '<')
{
tokenflag = true;
buff1 [0] = '<';
buff1 [1] = NULL;
}
}
}

tomcruz.net
 
Hello,

I have done some thinking, and I hope this is what you need:
Code:
bool OpenTag = false;
bool GoBack = false;

void __fastcall TForm1::RichEdit1KeyPress(TObject *Sender, char &Key)
{
 int start = RichEdit1->SelStart - 1;
 if(OpenTag == false)
 {
  if(Key == '<')
  {
   RichEdit1->SelStart = start;
   RichEdit1->SelLength++;
   RichEdit1->SelAttributes->Color = clBlue;
   OpenTag = true;
  }
 }
 else if(OpenTag == true)
 {
  if(Key == '>')
  {
   RichEdit1->SelLength = 1;
   RichEdit1->SelAttributes->Color = clBlack;
   GoBack = true;
   OpenTag = false;
  }
 }
 RichEdit1->SelStart++;
}


void __fastcall TForm1::RichEdit1Change(TObject *Sender)
{
 if(GoBack == true)
 {
  RichEdit1->SelStart--;
  RichEdit1->SelLength = 1;
  RichEdit1->SelAttributes->Color = clBlue;
  RichEdit1->SelStart++;
  RichEdit1->SelAttributes->Color = clBlack;
  GoBack = false;
 }
}

This makes all HTML
Code:
<>
tags turn Blue... The key was the OnChange event. If a '>' character gets added to the string, it is first turned black, and the bool GoBack is set true. Then the OnChange event is called, and returns its color to blue, then resets the SetAttribute->Color to clBlack after the SelStart property has been incremented past it. This is necessary, as the '>' character is not entered into the string until after the OnKeyPress event function is terminated.

From this, you should be able to make different tags different colors, but I dont have code for that right now...

Hope I could be of some help...
onrdbandit
 
NOTE: There are a few bugs that need to be worked out, but this should set us on the right track...

EXAMPLES:
1) If you add a &quot;<&quot; character, then delete it, the color is still blue, as the code thinks it still exists...


This is my revised code, I got a little hasty and posted some older code that had a few more bugs...
Code:
bool OpenTag = false;
bool GoBack = false;

void __fastcall TForm1::RichEdit1KeyPress(TObject *Sender, char &Key)
{
 int start = RichEdit1->SelStart;
 if(OpenTag == false)
 {
  if(Key == '<')
  {
   RichEdit1->SelStart = start;
   RichEdit1->SelLength++;
   RichEdit1->SelAttributes->Color = clBlue;
   OpenTag = true;
  }
 }
 else if(OpenTag == true)
 {
  if(Key == '>')
  {
   RichEdit1->SelLength = 1;
   GoBack = true;
   OpenTag = false;
  }
 }
 RichEdit1->SelStart++;
}

void __fastcall TForm1::RichEdit1Change(TObject *Sender)
{
 if(GoBack == true)
 {
  RichEdit1->SelStart--;
  RichEdit1->SelLength = 1;
  RichEdit1->SelAttributes->Color = clBlue;
  RichEdit1->SelStart++;
  RichEdit1->SelAttributes->Color = clBlack;
  GoBack = false;
 }
}

Hope I was helpful...
onrdbandit
 
Hello again...
If anyone needs it, I figured out the code needed to make different tags different colors...

I can post it if anyone wants it...

Good Luck everyone!
onrdbandit
 
POST IT! :-D

Thanks, onrdbandit! I'm going to put the code in tonight. Could it be?? somebody actually cracked the tag challenge?!??

Cyprus
 
Howdy,

Has this issue been a widespread problem? Just wondering...

I'll post the total code for the app tonight when I get home... I wrote the tag colorizing code, and there are 10 colors that different tags become. There are not enough colors to give each tag its own, but I tried to group associated tags with the same colors, and all closing tags are the same color as the opening tags.

EX:
-all table tags i.e. table, tr, and td are teal
-all font manipulating tags i.e. font, b, u, center, br, hr, etc are purple
-script tags are red
-html, head, and body tags are blue
-img tags are green
-anchors are olive greenish yellowish nasty color
-title tags are gray
-style tags are light blue i believe, but am not sure off hand

i think there are more that I colorized, but any that the code cannot recognize stay black... May I should make those a special color... That could help debug someone's problems with their code...? Well, I'll think about that.

I manipulated the same algorithm to run when you open an existing HTML document as well. It uses the same OnKeyPress and OnChange functions. A loop passes each character in the file you open to the OnKeyPress funcition, and that function colorizes them accordingly. The only problem is that the loop is slow, and takes several seconds to complete in a large file.

Well I hope my code helps...

Catch ya later,

onrdbandit
 
Here it is:
This is my intire Unit1.cpp. Enjoy...

Code:
//----------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include &quot;Unit1.h&quot;
//----------------------------------------------------------
#pragma package(smart_init)
#pragma link &quot;SHDocVw_OCX&quot;
#pragma resource &quot;*.dfm&quot;
TForm1 *Form1;
bool OpenTag = false;
bool GoBack = false;
int Color = 0;
bool GetNextChar = true;
bool NeedMoreChar = false;
int start;
int end;
char PreviousChar;
bool WaitForGreater = false;
bool GotGreater = false;
int SlashCount = 0;
int PreviousStart = 0;

//----------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//----------------------------------------------------------
void ColorChange()
{
 if(GoBack == true)
 {
  Form1->RichEdit1->SelStart = start;
  Form1->RichEdit1->SelLength = end - start;
  Form1->RichEdit1->SelLength++;
  Form1->RichEdit1->SelAttributes->Style = Form1->RichEdit1->DefAttributes->Style;
  switch(Color)
  {
   case 0:
         Form1->RichEdit1->SelAttributes->Color = clBlack;
         break;
   case 1:
        Form1->RichEdit1->SelAttributes->Color = clBlue;
        break;
   case 2:
        Form1->RichEdit1->SelAttributes->Color = clRed;
        break;
   case 3:
        Form1->RichEdit1->SelAttributes->Color = clPurple;
        break;
   case 4:
        Form1->RichEdit1->SelAttributes->Color = clGreen;
        break;
   case 5:
        Form1->RichEdit1->SelAttributes->Color = clTeal;
        break;
   case 6:
        Form1->RichEdit1->SelAttributes->Color = clOlive;
        break;
   case 7:
        Form1->RichEdit1->SelAttributes->Color = clDkGray;
        break;
   case 8:
        Form1->RichEdit1->SelAttributes->Color = clLime;
        break;
   case 9:
        Form1->RichEdit1->SelAttributes->Color = clSkyBlue;
        break;
   default:
        break;
  }

  Form1->RichEdit1->SelStart = end + 1;
  Form1->RichEdit1->SelAttributes->Color = clBlack;
  Color = 0;
  GoBack = false;
 }
}
//----------------------------------------------------------
void TForm1::ColorizeTags()
{
 int OldStart = RichEdit1->SelStart;
 WaitForGreater = false;
 int Counter = 0;
 char Key;
 int Length = Form1->RichEdit1->Text.Length();
 AnsiString Char = &quot; &quot;;
 Screen->Cursor = crHourGlass;
 while(Counter < Length)
 {
  Form1->RichEdit1->SelStart = Counter;
  Form1->RichEdit1->SelLength = 1;
  Char = Form1->RichEdit1->SelText;
  if(Char != &quot;&quot;)
  {
   Key = Char[1];
   Form1->RichEdit2KeyPress(Form1,Key);
   Form1->RichEdit2Change(Form1);
  }
  Counter++;
 }
 RichEdit1->SelStart = OldStart;
 Screen->Cursor = crDefault;
}
//----------------------------------------------------------
void __fastcall TForm1::RichEdit2KeyPress(TObject *Sender, char &Key)
{
 if(OpenTag == false)
 {
  if(Key == '<')
  {
   start = RichEdit1->SelStart;
   OpenTag = true;
   GetNextChar = true;
   SlashCount = 0;
  }
  if(Key == '>')
  {
   GotGreater = true;
  }
 }
 else if(OpenTag == true)
 {
  if(NeedMoreChar == true)
  {
   if((PreviousChar == 'a')||(PreviousChar == 'A'))
   {
    if((Key == 'p')||(Key == 'P'))
    {//<applet>
     Color = 2;
    }
    if((Key == 'r')||(Key == 'R'))
    {//<area>
     Color = 8;
    }
    if((Key == '>')||(Key == ' '))
    {//<a>
     Color = 6;
    }
   }
   if((PreviousChar == 'b')||(PreviousChar == 'B'))
   {
    if((Key == 'o')||(Key == 'O'))
    {//<body>
     Color = 1;
    }
    if((Key == 'r')||(Key == 'R'))
    {//<br>
     Color = 3;
    }
    if((Key == '>'))
    {//<b>
     Color = 3;
    }
   }
   if((PreviousChar == 'c')||(PreviousChar == 'C'))
   {
    if((Key == 'e')||(Key == 'E'))
    {//<center>
     Color =  3;
    }
    if((Key == 'o')||(Key == 'O'))
    {//<code>
     Color = 0;
    }
   }
   if((PreviousChar == 'h')||(PreviousChar == 'H'))
   {
    if((Key == '1')||(Key == '2')||(Key == '3')||(Key == '4')||(Key == '5')||(Key == '6'))
    {//<H#>
     Color = 3;
    }
    if((Key == 'e')||(Key == 'E'))
    {//<head>
     Color = 1;
    }
    if((Key == 'r')||(Key == 'R'))
    {//<hr>
     Color = 3;
    }
    if((Key == 't')||(Key == 'T'))
    {//<html>
     Color = 1;
    }
   }
   if((PreviousChar == 'i')||(PreviousChar == 'I'))
   {
    if((Key == 'm')||(Key == 'M'))
    {//<img>
     Color = 4;
    }
    if((Key == 'n')||(Key == 'N'))
    {//<input>
     Color = 8;
    }
    if((Key == '>'))
    {//<i>
     Color = 3;
    }
   }
   if((PreviousChar == 'm')||(PreviousChar == 'M'))
   {
    if((Key == 'a')||(Key == 'A'))
    {//<map>
     Color = 0;
    }
    if((Key == 'e')||(Key == 'E'))
    {//<meta>
     Color = 0;
    }
   }
   if((PreviousChar == 'p')||(PreviousChar == 'P'))
   {
    if((Key == 'a')||(Key == 'A'))
    {//<Param>
     Color = 2;
    }
    if((Key == '>'))
    {//<p>
     Color = 3;
    }
   }
   if((PreviousChar == 's')||(PreviousChar == 'S'))
   {
    if((Key == 'c')||(Key == 'C'))
    {//<script>
     Color = 2;
    }
    if((Key == 't')||(Key == 'T'))
    {//<style>
     Color = 9;
    }
   }
   if((PreviousChar == 't')||(PreviousChar == 'T'))
   {
    if((Key == 'a')||(Key == 'A'))
    {//<table>
     Color =  5;
    }
    if((Key == 'd')||(Key == 'D'))
    {//<td>
     Color = 5;
    }
    if((Key == 'e')||(Key == 'E'))
    {//<textarea>
     Color = 8;
    }
    if((Key == 'i')||(Key == 'I'))
    {//<title>
     Color = 7;
    }
    if((Key == 'r')||(Key == 'R'))
    {//<tr>
     Color = 5;
    }
   }
   NeedMoreChar = false;
  }
  if(GetNextChar == true)
  {
   if(Key == ' ')
   {
    GetNextChar = true;
   }
   else if(Key == '/')
   {
    if(SlashCount < 1)
    {
     SlashCount++;
     GetNextChar = true;
    }
    else
    {
     GetNextChar = false;
     Color = 10;
    }
   }
   else
   {
    //---  Tags that only need one character to define
    if((Key == 'D')||(Key == 'd'))
    {
     Color = 8;
    }
    if((Key == 'F')||(Key == 'f'))
    {
     Color = 3;
    }
    if((Key == 'U')||(Key == 'u'))
    {
     Color = 3;
    }
    if((Key == 'V')||(Key == 'v'))
    {
     Color = 2;
    }
    if((Key == 'E')||(Key == 'e'))
    {
     Color = 0;
    }
    //---  Tags that need more characters to define

    if((Key == 'a')||(Key == 'A')||(Key == 'B')||(Key == 'b')
                   ||(Key == 'c')||(Key == 'C')||(Key == 'h')||(Key == 'H')
                   ||(Key == 'i')||(Key == 'I')||(Key == 'm')||(Key == 'M')
                   ||(Key == 'p')||(Key == 'P')||(Key == 's')||(Key == 'S')
                   ||(Key == 't')||(Key == 'T'))
    {
     NeedMoreChar = true;
     PreviousChar = Key;
    }
    GetNextChar = false;
   }
  }
  if(Key == '>')
  {
   end = RichEdit1->SelStart;
   RichEdit1->SelLength = 1;
   GoBack = true;
   OpenTag = false;
   if(WaitForGreater == true)
   {
    GotGreater = true;
   }
  }
 }
}

//----------------------------------------------------------
void __fastcall TForm1::RichEdit2Change(TObject *Sender)
{
 PreviousStart = RichEdit1->SelStart;
 if(GoBack == true)
 {
  Form1->RichEdit1->SelStart = start;
  Form1->RichEdit1->SelLength = end - start;
  Form1->RichEdit1->SelLength++;
  Form1->RichEdit1->SelAttributes->Style = Form1->RichEdit1->DefAttributes->Style;
  switch(Color)
  {
   case 0:
         Form1->RichEdit1->SelAttributes->Color = clBlack;
         break;
   case 1:
        Form1->RichEdit1->SelAttributes->Color = clBlue;
        break;
   case 2:
        Form1->RichEdit1->SelAttributes->Color = clRed;
        break;
   case 3:
        Form1->RichEdit1->SelAttributes->Color = clPurple;
        break;
   case 4:
        Form1->RichEdit1->SelAttributes->Color = clGreen;
        break;
   case 5:
        Form1->RichEdit1->SelAttributes->Color = clTeal;
        break;
   case 6:
        Form1->RichEdit1->SelAttributes->Color = clOlive;
        break;
   case 7:
        Form1->RichEdit1->SelAttributes->Color = clDkGray;
        break;
   case 8:
        Form1->RichEdit1->SelAttributes->Color = clLime;
        break;
   case 9:
        Form1->RichEdit1->SelAttributes->Color = clSkyBlue;
        break;
   case 10:
        Form1->RichEdit1->SelAttributes->Color = clNavy;
        break;
   default:
        break;
  }

  Form1->RichEdit1->SelStart = end + 1;
  Form1->RichEdit1->SelAttributes->Color = clBlack;
  Color = 0;
  GoBack = false;
 }
 else
 {
  Form1->StatusBar1->SimpleText = &quot;&quot;;
 }
 if((WaitForGreater == true)&&(GotGreater == true)&&(OpenTag == false))
 {
  RichEdit1->Lines->BeginUpdate();
  ColorizeTags();
  RichEdit1->Lines->EndUpdate();
  RichEdit1->SelLength = 0;
  RichEdit1->SelAttributes->Color = clBlack;
  GotGreater = false;
  WaitForGreater = false;
 }
 RichEdit1->SelStart = PreviousStart;
}
//----------------------------------------------------------
void __fastcall TForm1::SaveWebPage1Click(TObject *Sender)
{
 if((RichEdit1->Modified == true)&&(SaveBox->FileName != &quot;&quot;))
 {
  RichEdit1->PlainText = true;
  RichEdit1->Lines->SaveToFile(SaveBox->FileName);
  RichEdit1->PlainText = false;
 }
 else if((RichEdit1->Modified == true)&&(SaveBox->Execute()))
 {
  RichEdit1->PlainText = true;
  RichEdit1->Lines->SaveToFile(SaveBox->FileName);
  Form1->Caption = &quot;HTML Editor-  &quot; + SaveBox->FileName;
  RichEdit1->PlainText = false;
 }
}
//----------------------------------------------------------

void __fastcall TForm1::LoadWebPage1Click(TObject *Sender)
{
 int selection;
 if(RichEdit1->Modified)
 {
  selection = Application->MessageBoxA(&quot;File has been modified... Save Changes?&quot;,&quot;Save Changes?&quot;,MB_YESNO);
  if(selection == 6)
  {
   Form1->SaveWebPage1Click(Form1);
  }
 }
 if(OpenBox->Execute())
 {
  RichEdit1->Lines->Clear();
  RichEdit1->SelAttributes->Color = clBlack;
  RichEdit1->Lines->LoadFromFile(OpenBox->FileName);
  Form1->Caption = &quot;HTML Editor-  &quot; + OpenBox->FileName;
  SaveBox->FileName = OpenBox->FileName;
  ColorizeTags();
 }
}
//----------------------------------------------------------void __fastcall TForm1::NewWebPage1Click(TObject *Sender)
{
 int selection;
 if(RichEdit1->Modified)
 {
  selection = Application->MessageBoxA(&quot;File has been modified... Save Changes?&quot;,&quot;Save Changes?&quot;,MB_YESNO);
  if(selection == 6)
  {
   Form1->SaveWebPage1Click(Form1);
  }
 }
 RichEdit1->Lines->Clear();
 SaveBox->FileName = &quot;&quot;;
 OpenBox->FileName = &quot;&quot;;
}
//---------------------------------------------------------

void __fastcall TForm1::RichEdit2KeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if((Key == VK_DELETE)||(Key == VK_BACK))
 {
  WaitForGreater = true;
 }
}
//----------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
 int selection;
 if(RichEdit1->Modified == true)
 {
  selection = Application->MessageBoxA(&quot;File has been modified... Save Changes?&quot;,&quot;Save Changes?&quot;,MB_YESNO);
  if(selection == 6)
  {
   Form1->SaveWebPage1Click(Form1);
  }
 }
}
//----------------------------------------------------------

void __fastcall TForm1::PageControl1Change(TObject *Sender)
{
 Form1->SaveWebPage1Click(Form1);
 CppWebBrowser1->Navigate((WideString)SaveBox->FileName);
}
//----------------------------------------------------------

void __fastcall TForm1::Exit1Click(TObject *Sender)
{
 Form1->Close();
}
//----------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
 Form1->PageControl1->TabIndex = 0;
}
//----------------------------------------------------------
 
I cut and pasted and I got no newline. just 1 long string.
I'll spend the next week formatting it. Might be worth it though if it solves our problem.

tomcruz.net
 
I'm sorry, I dont quite understand what you mean.

All my code does is add color to specific tags. It does not format the document in any way. It does not insert '\n' anywhere. I don't know what is happening or what you think should happen, but if you are getting formatting problems text from trying to load a document, that would be interesting to me as I have had no such issues. I dont think there is anything in my code that could cause that, but I'm sure I'm not the first person to say that...

Let me know more, and I'll try to help.

onrdbandit
 
I cut your code from this thread and pasted it into my editor. I got one long string that went on and on and on...
I'll have to go through the code to reindent and reformat.
I think you can wrap your code in tgml tags when you post it to allow for proper formating. Your code is not at fault. dont wory we'll get it straight. :)

tomcruz.net
 
Sorry butthead, didn't quite catch what you were saying. I got it now thought... There are no newline chars in my post making it difficult to copy the thread off of this page, right?

If so, I'm not sure what I can do to make it better. I did embed the code between &quot;code&quot; and &quot;/code&quot; tgml tags... Sorry about that. I hope my code endsup being worth the effort.

onrdbandit
 
I am sure it will be a welcome bit to my code snippets.

Thanks

tomcruz.net
 
First off, sorry to bring this thread back up from the dead...

Second, you can copy and paste the code into a text file, which should get rid of all of the html tags

Finally, my question: onrdbandit. Your code works great! I love it, thanks a lot! But I've got one question... When a file gets loaded nothing is highlighted, of course. But I tried to get your code to go through and automatically hihlight any tags... but it wont. Any suggestions?

Cyprus
 
Hi guys,

cyprus106, for Your last post I have a suggestion:

Is there a difference in the settings of Your RichEdit compared to the one from onrdbandit?
Maybe You set it to PlainText and onrdbandit not?
Or You maybe have set something like &quot;HideSelection&quot; to true?

As far as I understand now Your problem might be there, as I sometimes also had the effect, that 2 similar objects were not really similar after the third watch. (e.g. I forgot to set a hfUSE_RTS flag in a ApdComport and I would not get any data... ;) )

Just check whether You have REALLY similar RichEdits, ok?
 
Howdy cyprus...

I have not looked at the code in a while, so I will have to review it some, but I will look at what I did and what you can do to highlight tags...

NOTE: If you are wanting to highlight (i.e. select) ALL the tags at once, that can't be done (at least not to my knowledge). Otherwise I am not sure quite what you mean.
I dont remember if I included this, but I wrote a function that passes each character in the document to the KeyPress function and adds color to each tag just as if you were typing in the tags. If it is not in the post, I will post it...(if that is what you needing).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top