65.9K
CodeProject 正在变化。 阅读更多。
Home

彩色化编辑控件

2001 年 10 月 1 日

4分钟阅读

viewsIcon

380673

downloadIcon

10476

一个可着色的文本编辑控件,具有完整的撤销/重做、剪贴板支持等功能。

Sample Image - ColorEdit.gif

引言

需要一个快速简单的着色编辑控件,我浏览了我最喜欢的 MFC 源码网站。不幸的是,我找到的大部分都基于 CView - 这不是我需要的。我很伤心。

然后,我在 CodeGuru 上发现了 Randy More 的“语法着色文本编辑窗口类”。这算是一个开始。遗憾的是,它存在严重的问题。于是,我坐下来开始修改。三天后,在替换了原代码至少 90% 的内容后,我觉得我已经做出了足够好的东西可以使用了。所以,它就在这里了。

它的作用

  • 文本编辑。没错,你可以用它来编辑文本。
  • 语法高亮。嗯,更具体地说,它可以按照你告诉它的任何方式为文本着色。这取决于你(程序员)来告诉它如何着色。它内置了“关键字”支持,但任何比简单单词匹配更复杂的事情都需要你自己完成(这不足为奇,因为我不可能知道人们可能想用它处理的所有不同语法)。示例代码展示了除了关键字匹配之外,还可以做一些简单的事情。
  • 完整的撤销/重做支持。就像 VC++ 编辑器一样,你可以一直撤销到开始,然后重做最后一次编辑以来的所有撤销。
  • 自动滚动支持。
  • 无闪烁滚动
  • 可变的字符和行间距
  • 完整的选择、复制、剪切、粘贴支持,带有键盘快捷键和上下文菜单。
  • 鼠标滚轮支持。仅垂直。

它不支持的功能

  • 可变宽度字体支持。这只适用于等宽字体。我需要的是一个代码编辑器,而不是文字处理器。添加可变宽度字体支持将是一项艰巨的任务,我对此不感兴趣。
  • 它不是 CEdit。不,它是一个完全不同的控件。它不派生自 CEdit,也不是一个即插即用的替代品。它可以做很多相同的事情,但方式不同。例如,这是一个基于行的编辑器;因此,要设置选定范围,你需要指定行,而不是像 CEdit 那样只指定字符。
  • 枯燥的滚动条。滚动条滑块的大小还有待改进。
  • Unicode。我不需要它。
  • 可能存在 bug!是的,你没听错——这里可能存在一两个 bug。如果你发现了任何问题,请随时告诉我。更好的是,你可以自己修复它,然后告诉我你做了什么。我会保持源码的更新。

示例程序做了什么?

  • 加载和保存文本文件。
  • 关键字。示例包含一个小的关键字文件(“while”、“if”、“else”和“for”)。这些单词会自动高亮显示。
  • 示例着色器展示了以下符号的一些特殊语法处理
    符号规则Color
    # 文本任何以“#”开头的行都是注释green
    @+必须是行上的唯一文本蓝色,但如果行上有任何其他文本,则为红色
    @-必须是行上的唯一文本蓝色,但如果行上有任何其他文本,则为红色
    @:文本必须在行首red

如何在你的应用程序中使用它

  1. 将这些文件添加到你的项目中
    • ColorEditWnd.cpp, .h
    • Colorizer.cpp, .h
    • ScriptText.cpp, .h
    • UndoFrame.cpp, .h

  2. 将示例中的 IDR_COLOREDITCTX 上下文菜单复制到你的应用程序中。

  3. 将示例中的 IDR_EDIT_ACCELS 加速器复制到你的应用程序中。

  4. 在你的对话框类中添加一个 ColorEditWnd* 成员。

  5. 为该控件添加一个新的资源 ID。转到资源编辑器,右键单击你项目的资源文件。选择“资源符号”。添加一个新符号 ID_EDIT_WND

  6. 在你的对话框的 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
  7. 在对话框析构函数中删除该对象

就是这样!

嗯,差不多……你还需要编写一个自定义的 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 日 - 双击选中单词。小修复以删除选中的内容(光标位置在末尾)。更多实用函数(GetLineSetLine 等)。
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 日 - 更新了源代码

© . All rights reserved.