一个有意思的给代码染色的类:CSyntaxColorizer

可以给C++代码染色,演示程序运行后如图所示:

其主页在:http://mypage.uniserve.com/~jeffsch/computing/visualC++/CSyntaxColorizer.html

Description

The CSyntaxColorizer class described here is a fast and versatile class for the syntax highlighting of code. The class is very simple to use, very fast, and highly flexible. The default highlighting mode is VC++, with comments in green, strings in dark blue, and keywords in light blue. The class exposes several methods that can be used for changing these defaults - and color is not the only option. Highlighted words can be made bold, italic, underlined, and more. The exposed methods take a CHARFORMAT structure as a parameter, so whatever text formatting changes can be made with a CHARFORMAT structure can also be made with the keyword, comment, and string formats in CSyntaxColorizer. As well, you are not limited to a predefined and fixed set of keyword groupings. The keywords can be grouped in any way you like, and then manipulated by group. For example, you could assign all compiler directives the group ID of 723 (or whatever) and then set all keywords with group ID 723 to the color red.

The default groupings for the CSyntaxColorizer class are as follows:

Group 0: VC++ keywords such as for, if, while, void, etc 
Group 1: VC++ compiler directives such as #define, #include, etc 
Group 2: VC++ compiler pragmas such as once, auto_inline, etc

CSyntaxColorizer maintains member variables, (m_cfDefault, m_cfComment and m_cfString), of type CHARFORMAT. These defaults are used when the class initializes its internal lists, and whenever the keyword, comment or string colors are changed using the methods that take a COLORREF parameter instead of a CHARFORMAT parameter. These default structures have a font of Courier New, 10pt size. Naturally, the class exposes methods for changing the defaults (see below).

Here are the declarations in CSyntaxColorizer.h for the exposed methods:

    void Colorize(long StartChar, long nEndChar, CRichEditCtrl *pCtrl);
void Colorize(CHARRANGE cr, CRichEditCtrl *pCtrl);
void GetCommentStyle(CHARFORMAT &cf) { cf = m_cfComment; };
void GetStringStyle(CHARFORMAT &cf) { cf = m_cfString; };
void GetGroupStyle(int grp, CHARFORMAT &cf);
void GetDefaultStyle(CHARFORMAT &cf) { cf = m_cfDefault; };
void SetCommentStyle(CHARFORMAT cf) { m_cfComment = cf; };
void SetCommentColor(COLORREF cr);
void SetStringStyle(CHARFORMAT cf) { m_cfString = cf; };
void SetStringColor(COLORREF cr);
void SetGroupStyle(int grp, CHARFORMAT cf);
void SetGroupColor(int grp, COLORREF cr);
void SetDefaultStyle(CHARFORMAT cf) { m_cfDefault = cf; };
void AddKeyword(LPCTSTR Keyword, CHARFORMAT cf, int grp = 0);
void AddKeyword(LPCTSTR Keyword, COLORREF cr, int grp = 0);
void ClearKeywordList();
CString GetKeywordList();
CString GetKeywordList(int grp);

[Back to Top]

Using CSyntaxColorizer

The simplest and quickest way to use this class is to first declare it, then call one of the overloaded Colorize member functions. For example, this code

    CSyntaxColorizer sc;
sc.Colorize(0, -1, &m_cRichEditCtrl);

first creates the object, then calls its Colorize method, which in this case colorizes all of the text in the specified rich edit box, using CSyntaxColorizer's default font, keyword groupings, and colors described above.

If you don't like the default colors, you can change them:

    sc.SetCommentColor(RGB(255,0,0));
sc.SetStringColor(RGB(0,255,0));
sc.SetGroupColor(nMyGroup,RGB(0,0,255));

The preceding methods change the color using the CHARFORMAT structures that would be returned by their respective "Get..." methods.

If it's more than just colors you don't like, then you can set the CHARFORMAT structures using

    sc.SetCommentStyle(cfMyStyle);
sc.SetStringStyle(cfMyStyle);
sc.SetGroupStyle(nMyGroup,cfMyStyle);

where cfMyStyle is a CHARFORMAT structure that you have created yourself from scratch, or have retrieved using one of the "Get..." methods and then modified to suit.

Adding keywords is easy too. The two AddKeyword methods each take an LPCTSTR as a parameter. The parameter is a NULL terminated list of words separated by commas. For example,

   sc.AddKeyword("for,if,while", RGB(255,0,0), 4);

will add the three keywords to the sc object's list, give them the color red and place them in group 4, using the CHARFORMAT structure currently in m_cfDefault. You can also send a single word as the LPCTSTR parameter. If the keyword already exists in the list, its color and group attributes are overwritten by those passed in the AddKeyword method. The AddKeyword method that takes a CHARFORMAT as a parameter instead of a COLORREF works in a similar fashion.

A word about comments...

By default, CSyntaxColorizer deals with C++ and Java multiline comments starting with /* and single line comments starting with //. If you want single line comments as in VB, (starting with ' or REM), simply add "REM" as one of the keywords. For example:

    sc.AddKeyword("REM",cfMyStyle,nMyGroup);

CSyntaxColorizer will ignore any style or color settings you specify for the REM keyword, and instead will set them to whatever attributes you have set for the comments. CSyntaxColorizer will automatically treat the ' as the start of a single line comment once "REM" is added to the keyword list. Note: if you add only "REM", then "rem", "Rem", etc will not be recognized - you will have to add these as well.

Where a comment starts with // and ends with '\' + '\n' (the line continuation character immediately followed by a newline character) CSyntaxColorizer will recognize it, and treat the next line as a comment line.

[Back to Top]

Speed

CSyntaxColorizer is pretty fast. Small files under 20K or so are colorized practically instantaneously on my 466MHz machine. Larger files, over 100K, take four or five seconds. CSyntaxColorizer can locate and identify words to be colorized fairly quickly, but the big time hog is not in the algorithm itself - it's in the text formatting functions of CRichEditCtrl. If you comment out the two lines (line #494 & 495)

    pCtrl->SetSel(iStart,iOffset + x);
pCtrl->SetSelectionCharFormat(pskTemp->cf);

then a 100K file takes less than a second, but only comments and strings are colorized.

About the Demo

The demo project is a quick and dirty dialog box with a rich edit control. It has a rather crude editing capablity, the minimum required to show off some of CSyntaxColorizer's abilities. In particular, if you type in \* to start off a multiline comment, only the one line with the cursor on it will be reformatted. In this case, press the "Format" button. As well, you can load files, but you can't save them.

For those of you who don't have Visual C++ or just don't feel like compiling the thing, an executable is also available for download.

时间: 2024-10-03 15:09:08

一个有意思的给代码染色的类:CSyntaxColorizer的相关文章

关于JAVA的Comparable类不是很理解,写了一个有关比较的代码,但出现了异常,大神帮我看看

问题描述 关于JAVA的Comparable类不是很理解,写了一个有关比较的代码,但出现了异常,大神帮我看看 关于JAVA的Comparable类,我不是很理解,于是,我写了一个有关比较的代码,但出现了异常,大神帮我看看 解决方案 需要实现Comparable接口 Comparable implements Comparable 解决方案二: 首先,Java的array的sort方法要求传入的集合元素必须实现Comparable或者Comparator接口,其次,主要就是提供compareTo方

link下如何给Collectio类添加一个Changed事件,代码怎么写?

问题描述 link下如何给Collectio类添加一个Changed事件,代码怎么写? link下如何给Collectio类添加一个Changed事件,代码怎么写? 解决方案 http://www.360doc.com/content/13/0418/22/9316347_279324054.shtml 解决方案二: http://www.cnblogs.com/scottckt/archive/2012/06/15/2550440.html

一个PHP针对数字的加密解密类

 这篇文章主要介绍了一个PHP针对数字的加密解密类,该类仅支持加密数字.比较适用于数据库中id字段的加密解密,以及根据数字显示url的加密,需要的朋友可以参考下 代码如下: <?php /**  * 加密解密类  * 该算法仅支持加密数字.比较适用于数据库中id字段的加密解密,以及根据数字显示url的加密.  * @author 深秋的竹子  * @version alpha  * @加密原则 标记长度 + 补位 + 数字替换  * @加密步骤:  * 将a-z,A-Z,0-9 62个字符打乱,

一个经典的PHP文件上传类分享_php实例

文件上传是项目开发中比较常见的功能,但文件上传的过程比较繁琐,只要是有文件上传的地方就需要编写这些复杂的代码.为了能在每次开发中降低功能的编写难度,也为了能节省开发时间,通常我们都会将这些反复使用的一段代码封装到一个类中.帮助开发者在以后的开发中,通过编写几条简单代码就可以实现复杂的文件上传功能.对于基础薄弱的读者,只要会使用本类即可,而对一些喜欢挑战的朋友,可以尝试去读懂它,并能开发一个属于自己的文件上传类. 一.需求分析 要球自定义文件上传类,即在使用非常简便的前提下,又可以完成以下几项功能

互斥量-一个有意思的关于进程间通信的小问题

问题描述 一个有意思的关于进程间通信的小问题 题目要求: 两个进程Bob与Jack,能够互相看到对方,若对方进程结束,能够唤醒对方进程. 我的思路: 两个进程利用一个公共文件mail.txt,互斥地访问对方的状态,若发现对方不在线,则启动对方进程.mail文件中 1表示进程在线,0表示进程不在线. 现象: 进程间可以相互启动,但总是莫名终止,并且终止后mail文件中的两个进程的状态并不都为0. 我的实现如下:Bob进程 #include #include #include #include us

一个java生产者消费者代码的问题

问题描述 一个生产者消费者的代码,使用lock和condition实现.import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;//生产/消费者模式public class Basket {Lock lock = new ReentrantLock();// 产生Condition对象Cond

“一个只有行为,没有属性的类是线程安全的” 请问各位这句话对吗?请举出实例。

问题描述 "一个只有行为,没有属性的类是线程安全的" 请问各位这句话对吗?一直在迷惑中.请详细解释下,谢谢. 问题补充:牟盖东 写道 解决方案 引用请如果将这个类设计为单例的工具类,其中的方法都为静态的.然后其他的类使用这些方法处理数据,或者通过这些方法获取资源,是否会出现线程问题呢? 正如之前说过的:引用而作为一个线程中的临时变量使用的话,这个类去访问别的共享数据仍然是能产生共享冲突的. 完全有可能出现,关键在于共享数据上.阁下问这样的问题,相比也是多线程程序没有写过多少.需要好好体

java 集合-求大神,发一个简易的银行系统代码,谢谢 急急急!!!

问题描述 求大神,发一个简易的银行系统代码,谢谢 急急急!!! 用txt存取用户信息,把用户信息放到ArrayList集合进行操作 包含 开户 存款 转账 谢谢 急急急!!! 解决方案 ArrayList用法: ArrayList是接口List的实现类,所以推荐以List接口来使用. 1.创建ArrayList的List接口 例: List books = new ArrayList(); Java支持泛形后,创建的同时可以指定元素的类型. 例: Class Book { ...... } Li

c#如何把下面代码写在类里面作为函数供外界随意调用?

问题描述 c#如何把下面代码写在类里面作为函数供外界随意调用?privateconstintWM_NCLBUTTONDOWN=0x00A1;privateconstintWM_NCHITTEST=0x84;privateconstintHT_CAPTION=0x2;privateconstintHT_CLIENT=0x1;privatevoidpictureBox1_MouseDown(objectsender,MouseEventArgse){pictureBox1.Capture=false