为文本编辑控件实现缓冲区的最佳方法是什么?

时间:2011-11-12 06:26:25

标签: c++ winapi

所以我正在制作自定义编辑控件。为了跟踪编辑控件的内容,我使用了动态分配的char数组。

  • 现在,我知道我需要在数组的中间插入 某些情况,例如用户点击某个特定情况时 点。所以,我在考虑,而不是字符数组,我可以使用 std :: vector,所以我可以使用.insert函数,也可以 不必太关心内存管理。
  • 我也在考虑将输入流直接存储到 数组/矢量字(不保持连续缓冲区),因为我的 这样做的目的是实现语法高亮。

哪种方法更好?为什么?

5 个答案:

答案 0 :(得分:4)

对于具有今天计算机的文本缓冲区,您确实可以使用单个连续缓冲区(例如向量),因为CPU足够快以使插入时间(使用这种天真方法进行o(n)操作)仍然是可行的选项

在过去,当计算机速度慢了几千倍时,一种常见的简单方法是将文本保留在缓冲区中但是具有与光标位置对应的“孔”,以便插入o(1)操作并移动字符当光标在文本中移动时,从孔的一侧到另一侧(基本上使光标移动为o(k)操作,其中k是跳过的字符数。)

对于为程序员设计的编辑器,文本将细分为逻辑行,因此使用基于行指针数组的方法似乎是合适的。即使这会使某些跨线操作有些烦人,一些基于行的操作也会变得更容易......显示中的行编号变得很简单,特别是如果你不需要实现换行(反正代码可怕)通过截断和水平滚动代替。

答案 1 :(得分:4)

最好的方法是从系统编辑或richedit控制开始,并根据您的需要进行调整。编写自己的编辑控件比您可能实现的工作更多 - 包括处理辅助功能,具有复杂字母的语言的IME,复制和粘贴,滚动条,光标,选择等等。

这两个系统控件提供了许多扩展点,可以让您实现大多数目标。除非你真的在构建一个单词过程或源代码编辑器,否则你应该坚持使用提供的那些。自定义编辑控件是错误的重要来源。我很少看到一个只适用于基本案例的人。

马丁

答案 2 :(得分:3)

如果您正在考虑使用可变后备存储的源代码查看器(参考:“实现语法突出显示”),您可能会发现std::list<std::string>是一个很好的起点,如果字符串可能有点过分很小。

使用连续的文本缓冲区(例如,一个大的std::stringstd::vector),您将在编辑过程中进行大量移动和调整大小,以及重新定位时进行大量扫描。这些移动和调整大小将导致许多大的,连续的分配,缓冲区的初始化,移动和释放旧存储器。它还限制了缓存数据的方式(如果这很重要)。使用列表,您的查找时间会稍微慢一些,但是您的移动和突变将比为整个文件使用连续缓冲区快得多。

std::list<std::string>有一些不错的属性,因为它可以很好地增长并变换为字符串集合(例如,对于每一行或一段)。

此概述详述了列表的优势,并将其与其他容器进行了比较:http://www.cplusplus.com/reference/stl/list/

如果要将某些数据与字符串/行相关联,则只需创建以下列表:

namespace MON {
class t_line {
public:
  /* ... */
private:
  std::string d_string;
  t_lexer_stuff d_lexerStuff;
};
}

答案 3 :(得分:2)

您可能需要双重表示,因此同时使用char矢量和单词矢量(问题是让它们保持同步)。

我建议还要查看,甚至使用一些图形工具包,其源代码是免费提供的,并且可以自定义。 (我不是Windows的人,但是)我在想,例如Qt是一个在Windows,Linux,MacOSX上运行的C ++中的开源图形库...

我无法忍受更多,因为我不知道而且我不使用Windows(我所有的机器都在Linux下)。

答案 4 :(得分:2)

在搜索相同的瘦身时,我遇到了两个非常有用的维基百科页面:

Gap buffer进行简单编辑

Rope (data structure)用于复杂的文字编辑