• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 565
  • Last Modified:

"Syntax Highlighting" in a (Rich)Edit Control

OK...

   I have taking on a personal task of trying to create an edit control that will do "syntax highlighting" a'la every decent IDE out there.

   My first approach was using a RichEdit control, and then starting a thread that looks for specific keywords and turns them blue.  This thread would start (starting at the current line, or last word) whenever <SPACE>, <TAB> or <ENTER> was hit.  Another thread would start (when scrolling occured) at the first visible line. (Redraws are disabled while the thread is running.)

   This works OK, but is a tad slow, and holding down a key produces unexpected results because a character can be entered while the thread has something selected, and then that selection gets replaced.

   My problem?  There has GOT to be a faster, and/or easier way to do this.  I can deal with the speed issue if I can guarantee that the actual text will not get changed if a user holds down a key.  Right now, setting and unsetting Read Only and/or waiting for the thread to finish produce undiserable results.

   1: Is there a way to apply a CHARFORMAT effect without actually causing a selection to take place?

   2: Is threre a better way for me to be doing this?   Making the user wait for the thread to finish is not acceptable.

   3: Currently, I am applying a "Normal" (color black) style to words that are being types (worrd that have the caret in them), to prevent "false highlighting".  This, too is slow.

   Thoughts on this one?

BTW: I have tried using both AfxBeginThread() and CreateThread(), both give the same results (of course, CreateThread() is faster).
   Peace!

-=- James.
0
jtwine100697
Asked:
jtwine100697
1 Solution
 
MikeP090797Commented:
You can intercept the keypress message of the rich edit box. When your treahd is proccessing the selection, set a flag, and when this flag is true, redirect the character to appear after the selected word
0
 
jtwine100697Author Commented:
A Good idea, although it does not solve all of the problems.  The problem that I have with your answer is that the thread needs to excute a SetSel on a keyword to be able to change the color to Blue.

   In order for me to place the character after the selection, I need to move the caret, and the only way that I know how to do that is using SetSel.  If I change the selection while the thread is about to change the color...  Well...  

   Lastly...   You are assuming that the thread will always be processing the "previous" word (word to the left of the caret).  This is not the case.

-=- James.
0
 
taryn092997Commented:
Your main problem with using a rich-edit control is that you need to edit the contents synchronously. Instead, why not derive your own class (like all IDEs do) and then you can use a bit-blt from your synchronous thread to the screen when you want. It'd be a lot faster, wouldn't be affected by inserting characters into the buffer, and isn't too hard to implement. I've done a similar thing with a custom listbox. It's especially easy if you use a fixed size font for the display, but it's up to you.
0
Technology Partners: 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!

 
RONSLOWCommented:
If you want to spend some money - or rather, don't mind doing so - get ObjectiveEdit from Stingsoft which is a configurable sytax-higlighting editor class(es) for MFC.  It does both a view and a control class (so you have a full app that does editing in a view or just use it for a control in a dialog).

It also derives from CWnd directly and does its own drawing.

Unfortunately, the rich edit control just isn't fat/powerful enough to do syntax editing - rolling your own is the only feasible solution.

0
 
gav061697Commented:
You could try using StreamIn and StreamOut with RTF codes.
0
 
jtwine100697Author Commented:
(ROnslow): I know of the classes/controls from StingSoft.  I wish to see if I can achieve something similar without going out to another product.  This is for fun!  No profit involved, hence no cost involved.

(Taryn): I thought of an owner drawn control, but I do not know how to acheive an owner drawn edit control.  Know of any source that I can take a look at?

(Gav): Are you suggesting that after every char (or word delimiter) that I StreamOut the contents (or recent words) in RTF, and then apply the RTF codes?  This is not as easy as it seems, as I will need to pre-define the "colortbl" entries, and the entries tend to change positions in the table.

(All): It seems that an owner drawn edit control is the way to go.  But I have never done a owner drawn edit control.  I can understand using TextOut (saving the last position) to colorize specific words, what about drawing the caret?

-=- James
0
 
RONSLOWCommented:
You can create and set the caret for any window with the caret commands (CreateCaret etc).

Looks like you've come to the same conclusion as my answer suggested - doing it yourself.

Of course, the tricky stuff is in parsing and recognising the syntax (which you've already done).

The really tricky stuff is creating a structure that records (say) colour changes by text position - or maybe a list of records with text and colour with one record per colour change or line.  Then your paint routin for the window could traverse this list and draw the text in the required colour.

Good luck !!
0
 
JohnWeidnerCommented:
I recently wrote an entire CWnd derived class similar to CEdit, except that mine also will do numbered, bulleted, and definition lists.  I'd share the code, but since it was for work, I don't think I have the rights to give it away.  But I'd be glad to answer any questions if you run in to trouble.
0
 
jtwine100697Author Commented:
ROnslow: I did not come to the same conslusion, really...  You and "Taryn" just pointed me in the right direction.

   I am awarding you the points.  If you have anything further to tell me, please email me directly.

JohnWeidner: If possible, do you know where I can see an example of painting a CEdit (derived) control?  Besides using the default processing, of course! :)

   Thanx to all...

-=- James.
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now