"Syntax Highlighting" in a (Rich)Edit Control

Posted on 1997-10-28
Last Modified: 2013-11-20

   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).

-=- James.
Question by:jtwine100697
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

Expert Comment

ID: 1308994
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

Author Comment

ID: 1308995
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.

Expert Comment

ID: 1308996
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.
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

ID: 1308997
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.


Expert Comment

ID: 1308998
You could try using StreamIn and StreamOut with RTF codes.

Author Comment

ID: 1308999
(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
LVL 10

Accepted Solution

RONSLOW earned 200 total points
ID: 1309000
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 !!

Expert Comment

ID: 1309001
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.

Author Comment

ID: 1309002
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.

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

Suggested Solutions

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

730 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