【问题标题】:wxWidgets / wxStyledTextCtrl - Highlight all occurrences when doubleclickingwxWidgets / wxStyledTextCtrl - 双击时突出显示所有事件
【发布时间】:2016-01-29 23:13:23
【问题描述】:

我在 Windows 10 上的静态 unicode 构建中使用 wxWidgets 3.0.2。我使用的是 wxStyledTextCtrl,它是 Scintilla 的 near 一对一映射。

我正在寻找类似于 Notepad++ 的功能,在编辑器中双击某些内容时,该项目的所有出现都会突出显示。很难找到真正展示样式的好例子。我查看了 wxWidgets 文档、Scintilla 文档、Notepad++ 源代码和 Code::Blocks 源代码(后两者使用 Scintilla 作为其文本编辑器),但仍然运气不佳。

我尝试了以下代码的许多不同变体,但始终无法正常工作。要么没有突出显示,要么突出显示整个文档。我知道我错过了一些东西,但我不知道是什么。

//textarea is a wxStyledTextCtrl*
textarea->StyleSetBackground(styleHightlightAllSelected, wxColor(80, 255, 80));

wxString selectedText = textarea->GetSelectedText();
int selSize  = selectedText.size();
int selStart = textarea->GetSelectionStart();

int pos    = 0;
int curr   = 0;
int maxPos = textarea->GetLastPosition();
while(pos != -1){
    pos = textarea->FindText(curr, maxPos, selectedText);
    if(pos == selStart){ //skip the actual highlighted item
        curr = pos + selSize;
    } else if(pos != -1){
        textarea->StartStyling(pos, 0x1F);
        textarea->SetStyling(selSize, styleHightlightAllSelected);
        curr = pos + selSize;
    }
}

循环的搜索部分确实成功地找到了选定的文本;只是造型似乎并没有占据上风。

所以我无法真正找到答案的问题是:

  1. styleHightlightAllSelected 是 int 设置为 100。当我将其设置为 0 时,双击时整个文档变为绿色。我看到样式 32-39 是预定义的。是否还有其他预定义但未真正记录的样式?意思是100可以吗?
  2. 我必须设置整个样式,还是可以像上面那样设置背景颜色?
  3. 当我发现一个事件并处理它时,执行StartStyling() 和SetStyling() 就足够了吗,还是还有更多?
  4. wxWidgets 中的StartStyling() 有一个掩码参数,但 Scintilla 对应项没有。我无法清楚地确定我应该将其设置为什么。保留 5 个现有的样式/词法分析器位似乎是 31 (00011111)?本质上,如果我只想修改每次出现的背景颜色,我不确定将其设置为什么。
  5. 我的程序会定期处理几十兆或更多兆字节的文件,所以我是否应该只突出显示可见的事件,并在滚动/跳跃时根据需要进行调整?目前它搜索并(未能)在每次出现时设置样式,并且在 50MB 文件上大约需要一秒钟。我观察到,在 Notepad++ 中加载的同一个文件上,它会立即发生,所以我假设它是在可见的基础上完成的?

【问题讨论】:

  • 您阅读过 Scintilla 文档中的 Styling 部分吗?它似乎回答了你的大部分问题。
  • 正如我在问题中提到的,我确实读过。它并没有真正帮助,因为 Scintilla 文档在大多数情况下只不过是函数/消息名称的冗长版本。

标签: c++ wxwidgets scintilla wxstyledtextctrl


【解决方案1】:

我最终在 Notepad++ 项目的 github 问题页面上询问了这个问题,正确的方法是不使用样式,而是使用指示器。所以我上面的代码变成了这样:

int maxPos = textarea->GetLastPosition();

textarea->IndicatorClearRange(0, maxPos);
textarea->IndicatorSetStyle(styleHightlightAllSelected, wxSTC_INDIC_ROUNDBOX);
textarea->IndicatorSetAlpha(styleHightlightAllSelected, 100);
textarea->IndicatorSetUnder(styleHightlightAllSelected, true);
textarea->IndicatorSetForeground(styleHightlightAllSelected, wxColor(0, 255, 0));

wxString selectedText = textarea->GetSelectedText();
int selSize  = selectedText.size();
int selStart = textarea->GetSelectionStart();

int pos    = 0;
int curr   = 0;
vector<int> selectionList;
while((pos = textarea->FindText(curr, maxPos, selectedText)) != -1){
    selectionList.push_back(pos);
    curr = pos + selSize;
}

textarea->SetIndicatorCurrent(styleHightlightAllSelected);
for(unsigned int i = 0; i < selectionList.size(); i++){
    if(selectionList[i] != selStart){
        textarea->IndicatorFillRange(selectionList[i], selSize);
    }
}

但是,这并没有考虑到,仅突出显示可见范围,并且仅在滚动到视图中时突出显示新出现的事件(我稍后会添加),因此对于数十兆字节大小的文件,它将需要 2 -3 秒完成高亮显示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-16
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多