Introduction

Needing a quick and dirty colorizing edit control, I went to all of my favorite MFC source sites.
Unfortunately, most of what I found was based on CView - not what I needed. I was sad.

Then, I found Randy More's "Syntax Coloring Text Edit Window Class" on
CodeGuru. This was a start. Sadly,
it had serious problems. So, I sat down and started hacking. Three days later, after replacing at least
90% of the original code, I decided I had something good enough to use. So, here it is.

What it does

Text editing. That's right, you can use it to edit text.

Syntax highlighting. Well, more specifically, it can color the text in any way you tell it to.
It's up to you (the programmer) to tell it how to color things. It has built-in "keyword" support,
but anything more complex than simple word matching is something you'll have to do yourself (which
is no big surprise, since there's no way I could possibly know all the different syntaxes people
might want to use this with). The sample code shows how to do some simple things aside from just the
keyword matching.

Full undo/redo support. Just like the VC++ editor, you can undo all the way back to the start and
redo all undo's from the last edit.

Auto scroll support.

Flicker-free scrolling

Variable character and line spacing

Full select, copy, cut, paste support, with keyboard accelerators and a context menu.

Mouse wheel support. Vertical only.

What it doesn't do

Variable-width font support. This only works with fixed width fonts. I needed a code editor,
not a word processor. Adding variable width font support would be a huge undertaking and I'm not interested
in doing it.

It's not CEdit. Nope, it's a different control altogether. It's not derived from CEdit and
it's not a drop-in replacement. It can do many of the same things, but it does them differently. For example,
this is a line-based editor; so to set the selection range, you need to specify lines, not just characters
like with CEdit.

Boring scroll bars. Scroll bar thumb sizing could use some work.

Unicode. I don't need it.

There might be bugs! Yep, you heard it here first - there might be a bug or two in here. Feel free to let me
know if you find anything. Even better, feel free to fix it and tell me what you did. I'll keep the source updated.

What does the sample do?

Load and save a text file.

Keywords. The sample has a small keyword file ("while", "if", "else", and "for"). These words will be highlighted automatically.

The sample colorizer shows off some special syntax handling for the following symbols:

Symbol

Rule

Color

# text

any line that starts with "#" is a comment

green

@+

must be the only text on the line

blue, but red if there is any other text on the line

@-

must be the only text on the line

blue, but red if there is any other text on the line

@:text

must be at the start of the line

red

How to use it in your app

Add these files to your project:

ColorEditWnd.cpp, .h

Colorizer.cpp, .h

ScriptText.cpp, .h

UndoFrame.cpp, .h

Copy the IDR_COLOREDITCTX context menu from the sample into your app.

Copy the IDR_EDIT_ACCELS accelerators from the sample into your app.

Add a ColorEditWnd* member to your dialog class.

Add a new resource ID for the control. Go to the resource editor, right-click on your project's resource file.
Choose "Resource Symbols". Add a new symbol ID_EDIT_WND.

Well, almost... You also need to write a custom Colorizer object to handle your specific syntax
coloring needs. :) In the sample this is demonstrated by the SampleColorizer class. It does the syntax
coloring as described above, and calls the base class (CColorizer) to handle keyword coloring.

API

Here are a few of the interesting member functions:

// clear and set text to pInText
void LoadText(constchar *pInText);

// get a single string copy of the contents
void UnloadText(CString &pText) const;

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Comments and Discussions

I do what the text tells me. then I find declare_control can`t be used ,so I just use "//" to ignore it. And I use your code in MFC SDI application. But,words I type are all invisible .I don`t know why. Can you tell me some possible reasons.I use visual stdio 2012.thank you very much. and sorry for my poor English.

"declare_control" is in the "ColorEditWnd.h" line 53 and "implement_control" in "ColorEditWnd.cpp" line 62.I try your project in VC6.0 .and I also ignore "declare_control" by using "//",the project runs well.

Just Now ,I know the reason ! I use LPCTSTR to cast char to CString.a small mistake wastes me a week.and sorry for disturbing you.your code is very useful , I use it in my homework.thank you very much !

I have created a grid and in my Mainfrm.cpp im trying to call dat grid using DoModal function,my code is running without errors, but im unable to call my grid control. I will be thankful, if u help me..

Hello.I'm a beginner in visual c++.I'm using an editor named "Colorizing edit control" in my project, but Idon´t know what is missing in my code, because when i click on the left mouse button and try to select my text until the end, the vertical bar doesn't move, and can´t select the text until the end.

Hi, I try to write a string in color edit by doubleclick on one item in a treeview; my project contain a CMDIChildWnd window with two element, one is a treeview and other is a color editor.On doubleclick on tree, i send a message to editor with the string to write, I do this:

We had to do the same issue in VC8.0. For VC7.1, we only had to comment out DECLARE_CONTROL(). VC7.1 thinks that IMPLEMENT_CONTROL(); is a forward declared function, however VC8.0 requires forward declared functions to have a return type defined, and then fails to compile in this case.

I believe these two macros are from Stingray's library. And both should be eliminated from the source(unless you have Stingray's library).

Hi, I have find a strange operation in function LoadText(const char *buffer); if you try to load a text of 2 line where in the first line there is only "\n" char, function don't load the second string.For load correctly this text i have modify the code in this way, but I'm not sure that this is the best way!

Hi, I know this isn't a word processor, but i think that upgrade this class with function like "Find" and "Replace" or handle bookmark can improvement the usability of class.This is a beautiful control and with this function, in my opinion, will be complete!Have you any idea how I can add "Find" function?Thanks a lot!

Hi, first of all.. thank for this nice control!I have a problem: when I run in 'Debug' and try to write char like "ò" or "è", the code goes in assert in file "isctype.c" at this line "_ASSERTE((unsigned)(c + 1) <= 256);"Why?In 'Release' all run correctly; I can't understand this behavior.

Hello,First of all, this job is really nice and esasy to be integrated, I dont need word wrapping and this seems what I need.Unfortunately, I observed that it goes really slow when opening and loading long text files. I also observed a memory leak!Is there any limit in text size used !!

Hi, sorry for disturbing, It seems to be a memory leak ...Here what I done I copy paste a text the text from the ColorEditWnd.cpp up to more than 23000 lines(what is equivalent to a file of 580 KO, And the editor has really a difficulty (time needed) to manage the operations.

The memory consumed by the application is increased than if erase all the edited by a backspace or delete, the memory do not back to its initial value (or around it).

But really, this is not what disturbed me, what disturbed me is that I I continue the same operation (copy paste) with the 23000 lines, the application get into a not responding state.

If I try to do that with Notepad I success.

May be it is due to the buffer that guarantee the undo operation.

Sorry Chris, If I allowed my self to do some remarks, it is only because your code interested me and - is very rich in methods, - is very flexible and extensible- easy to be implemented,I only find it today and did not tested it for days.

It worked perfectly well on small files and small texts, but then I tried loading in a text-file of about 200 K and it took ages to load.

Also saw a memory huge leak, didn't track it though...

Another strange behaviour is that pasting text in performs way faster than using the LoadText function.

Shame about the performance, because this stopped me from using it in my app (which is going to have to deal with long file). If you happen to fix it in the future, I'd love to have the fix, because besides the performance it functions really well

Can I set the style of the "m_pColorWnd" object to be multiline without inserting a new line character "\n" in a long sentence.(sure, the long of sentence is greater than the width of the frameRectBonne chance!!!!

write a gdi tutorial because you did some nice things with this control .you should write about scrolling , coordinates , how DCs are redrawn and some of these things you are good at and are poorely explained elsewhere .

gr8 job !

I am the MIGHTY KEEPER of the BOOK OF KNOWLEGDE . Contact me to get your copy .

i found your program very usefull but i have a problemif i use the dialog not as the main wnd but pop it up with domodal and then put about 1000, lines i can see in the task menager that it use some memory in each line i enterthe problem is that after closing the dialog, the task manager show the memory was not release

Chris,I don't want to supply a list of keywords in an external file. I'd like to supply it as either a delimited string or CStringArray or something like that so that it's hard coded. Any idea on a quick solution to do this?

Yup - I did this but with a CString vs. CStringList. I think this is my code. hehe, I can't remember since it's been so long.<pre lang=c++>void CColorizer::LoadKeywordString(CString &keywordsString){ if (keywordsString.IsEmpty()) { return; }

I'm having major problems integrating this into my vc7 dialog app. vc7 is whining about DECLARE_CONTROL and the _DrawLine function - specifically some crap about TextOut not being able to convert parm3 to a const CString &. I'm not sure what's going on. It's probably freakin microsofts fault because they screwed up CString in vc7.

Ya, I tried that obvious stuff - no go. Here's what I did to fix it. I noticed that your app would compile, although with warnings, where mine would not. My first thought was some project setting or switch. Nope, that wasn't it. I then looked at your stdafx.h and noticed a difference. I changed mine to look like yours and now it compiles with warnings just like yours. See if you can make heads or tails out of the stdafx.h code.<pre lang=c++>#pragma once#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

//#ifndef VC_EXTRALEAN//#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers//#endif////// Modify the following defines if you have to target a platform prior to the ones specified below.//// Refer to MSDN for the latest info on corresponding values for different platforms.//#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.//#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.//#endif////#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.//#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.//#endif ////#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.//#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.//#endif////#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.//#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.//#endif////#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit////// turns off MFC's hiding of some common and often safely ignored warning messages//#define _AFX_ALL_WARNINGS////#include "afxwin.h" // MFC core and standard components//#include "afxext.h" // MFC extensions////#include "afxdtctl.h" // MFC support for Internet Explorer 4 Common Controls//#ifndef _AFX_NO_AFXCMN_SUPPORT//#include "afxcmn.h" // MFC support for Windows Common Controls//#endif // _AFX_NO_AFXCMN_SUPPORT

Note, the commented out stuff is the default from the app wizard. Also, I had to replace the aligators after #include with quotes becuase the pre tag was taking them out.

If you are feeling bored, a good way (I would think) to do syntax coloring more complex than keywords would be regular expression matching. Like, the tagged part of the RegEx gets colored. It just popped into my mind and seemed perfect!

Just an idea if you want it, I don't even have a use for it currently but thought it'd be a natural fit for this control.

this would be a rather trivial add-on. all that would be required is a Colorizer that used regexps to choose the colors.

know of any good regexp parsers?

-c

"I am angry that so many of the sons of the powerful and well-placed... managed to wangle slots in Reserve and National Guard units...Of the many tragedies of Vietnam, this raw class discrimination strikes me as the most damaging to the ideal that all Americans are created equal and owe equal allegiance to their country."--Colin Powell, not talking about his boss

First of all, thanks Chris, this is a great control and I'm dying to use it in my app for the very modest purpose of alternating colors between words. But even with this simple task, I'm bumping into the wall.

Trying to use VC5.0 to compile the sample project (I know, shake your heads) and I get this error for ColorEdit, ColorEditDlg, ColorEditWnd and UndoFrame...

The errors in xutility are in a template function listed as "lexicographical_compare"

Do I just need to get version 6.0, or can someone suggest a tweak to fix/circumvent the problem. Again, I don't need keyword compare (is that related to the lexicoblahblah-compare?), I just want to toggle the colors whenever there's a space.