彩色化编辑控件






4.89/5 (30投票s)
2001 年 10 月 1 日
4分钟阅读

380673

10476
一个可着色的文本编辑控件,具有完整的撤销/重做、剪贴板支持等功能。
引言
需要一个快速简单的着色编辑控件,我浏览了我最喜欢的 MFC 源码网站。不幸的是,我找到的大部分都基于 CView
- 这不是我需要的。我很伤心。
然后,我在 CodeGuru 上发现了 Randy More 的“语法着色文本编辑窗口类”。这算是一个开始。遗憾的是,它存在严重的问题。于是,我坐下来开始修改。三天后,在替换了原代码至少 90% 的内容后,我觉得我已经做出了足够好的东西可以使用了。所以,它就在这里了。
它的作用
- 文本编辑。没错,你可以用它来编辑文本。
- 语法高亮。嗯,更具体地说,它可以按照你告诉它的任何方式为文本着色。这取决于你(程序员)来告诉它如何着色。它内置了“关键字”支持,但任何比简单单词匹配更复杂的事情都需要你自己完成(这不足为奇,因为我不可能知道人们可能想用它处理的所有不同语法)。示例代码展示了除了关键字匹配之外,还可以做一些简单的事情。
- 完整的撤销/重做支持。就像 VC++ 编辑器一样,你可以一直撤销到开始,然后重做最后一次编辑以来的所有撤销。
- 自动滚动支持。
- 无闪烁滚动
- 可变的字符和行间距
- 完整的选择、复制、剪切、粘贴支持,带有键盘快捷键和上下文菜单。
- 鼠标滚轮支持。仅垂直。
它不支持的功能
- 可变宽度字体支持。这只适用于等宽字体。我需要的是一个代码编辑器,而不是文字处理器。添加可变宽度字体支持将是一项艰巨的任务,我对此不感兴趣。
- 它不是
CEdit
。不,它是一个完全不同的控件。它不派生自CEdit
,也不是一个即插即用的替代品。它可以做很多相同的事情,但方式不同。例如,这是一个基于行的编辑器;因此,要设置选定范围,你需要指定行,而不是像CEdit
那样只指定字符。 - 枯燥的滚动条。滚动条滑块的大小还有待改进。
- Unicode。我不需要它。
- 可能存在 bug!是的,你没听错——这里可能存在一两个 bug。如果你发现了任何问题,请随时告诉我。更好的是,你可以自己修复它,然后告诉我你做了什么。我会保持源码的更新。
示例程序做了什么?
- 加载和保存文本文件。
- 关键字。示例包含一个小的关键字文件(“while”、“if”、“else”和“for”)。这些单词会自动高亮显示。
- 示例着色器展示了以下符号的一些特殊语法处理
符号 规则 Color # 文本 任何以“#”开头的行都是注释 green @+ 必须是行上的唯一文本 蓝色,但如果行上有任何其他文本,则为红色 @- 必须是行上的唯一文本 蓝色,但如果行上有任何其他文本,则为红色 @:文本 必须在行首 red
如何在你的应用程序中使用它
- 将这些文件添加到你的项目中
- ColorEditWnd.cpp, .h
- Colorizer.cpp, .h
- ScriptText.cpp, .h
- UndoFrame.cpp, .h
将示例中的
IDR_COLOREDITCTX
上下文菜单复制到你的应用程序中。将示例中的
IDR_EDIT_ACCELS
加速器复制到你的应用程序中。在你的对话框类中添加一个
ColorEditWnd*
成员。为该控件添加一个新的资源 ID。转到资源编辑器,右键单击你项目的资源文件。选择“资源符号”。添加一个新符号
ID_EDIT_WND
。在你的对话框的
OnInitDialog
中初始化该对象m_pColorWnd = new ColorEditWnd( this, //parent window frameRect, //initial size and position ID_EDIT_WND, //id value iTabSize, //size of a tab iFontSize, //font size * 10 (I.E. 100 = 10) csFontName); //the font name
在对话框析构函数中删除该对象
就是这样!
嗯,差不多……你还需要编写一个自定义的 Colorizer
对象来处理你特定的语法着色需求。 :) 在示例中,这由 SampleColorizer
类演示。它执行上述语法着色,并调用基类(CColorizer
)来处理关键字着色。
API
以下是一些有趣的成员函数
// clear and set text to pInText void LoadText(const char *pInText);
// get a single string copy of the contents void UnloadText(CString &pText) const;
// number of text lines in the buffer int GetLineCount();
// set selection from char1, line1 to char2, line2 void SetSelection(int charPos1, int line1, int charPos2, int line2);
// replace the current selection with this text void ReplaceSelText(const char *pText);
// en/disable keyboard accelerators void UseKeyboardAccelerators(bool b);
就是这样。
请负责任地享用!
历史
01 年 10 月 01 日 - 首次发布
01 年 10 月 04 日 - 进行了许多修复、改进和更改:更好的滚动、更好的选择、向父窗口发送 EN_*
事件、更好的插入符号处理、动态更改着色器和高亮颜色、修正了注释以正确归功于 Randy More 而非 Keith Rule,以及更多。
01 年 10 月 10 日 - LoadText
的性能提速,对 OnVScroll
(带 SB_THUMBTRACK
)进行了调整
01 年 10 月 15 日 - 双击选中单词。小修复以删除选中的内容(光标位置在末尾)。更多实用函数(GetLine
、SetLine
等)。
01 年 10 月 22 日 - 修复了在文本末尾的 Shift 键选择范围检查。
01 年 10 月 30 日 - 比例滚动条大小,使用 std::set 进行关键字查找,Create(...)
方法等。
02 年 01 月 06 日 - 移除了部分闪烁。
02 年 01 月 09 日 - 添加了一个强制重新着色文本的函数
02 年 01 月 11 日 - 修复了粘贴问题。移除了更多闪烁。
02 年 03 月 13 日 - 使用 MemDC,感谢 Robert Bouwens。02 年 09 月 05 日 - 更新了源代码