我需要你的帮助!所以,我正在创建一个带语法高亮显示的RichEdit,我这样做:
SendMessage(hWin, WM_SETREDRAW, false, 0);
CHARFORMAT2 format, old;
format.cbSize = sizeof(format);
old.cbSize = sizeof(format);
MainRich.GetFormat(SCF_DEFAULT, &format);
MainRich.GetFormat(SCF_DEFAULT, &old);
format.dwMask = CFM_BOLD;
format.dwEffects = CFE_BOLD;
CHARRANGE* c = MainRich.GetSelectionRange();
int length = MainRich.GetLength();
string str = string(MainRich.GetText());
#define hl "true" //Example of syntax for highlight
int last = 0;
while (str.find(hl, last)!=string::npos)
{
MainRich.Select(str.find(hl, last), str.find(hl, last)+strlen(hl));
MainRich.SetFormat(SCF_SELECTION, &format);
last = str.find(hl, last)+strlen(hl);
}
MainRich.Select(c->cpMin, c->cpMax);
MainRich.SetFormat(SCF_SELECTION, &old);
SendMessage(hWin, WM_SETREDRAW, true, 0);
UpdateWindow(hWin);
}
但是我看到在大文件中有很多突出显示它会变得迟钝,你有更好的方法吗?我检查了Iczelion's Assembly但是代码是一团糟,他似乎在文本前面画了亮点但是选择不起作用的方式,对吧?如果确实如此,你能给我一些如何做到这一点的提示吗?谢谢!
我找到的最快的方法是构建原始RTF文档,然后通过EM_STREAMIN消息将其流式传输到控件。
EDITSTREAM stream;
stream.dwCookie = (DWORD_PTR)&streamData; // pointer your rtf data
stream.dwError = 0;
stream.pfnCallback = (EDITSTREAMCALLBACK)RtfStreamCallback; // callback which will push down the next chunk of rtf data when needed
LRESULT bytesAccepted = 0;
bytesAccepted = SendMessage(hWindow, EM_STREAMIN, SF_RTF, (LPARAM)&stream);
另外要记住的是,您使用的RTF控件对性能有严重影响。当我这样做时,我发现默认控件(由Windows XP提供)非常慢,但Microsoft Office提供的RICHED20.DLL速度提高了几个数量级。您应该尝试可以访问的版本并进行一些性能比较。
链接到1.6 RTF Specification
你使用MainRich.GetText()
和冗余调用std::string::find()
是瓶颈。根本不检索文本。请改用CRichEditCtrl::FindText()
。
最后不要恢复原始选择的原始格式。如果在应用突出显示之前选择了突出显示的关键字,该怎么办?您可以撤消突出显示它。
你可以做的另一个加速RichEdit的优化是使用CRichEditCtrl::SetEventMask()
在更改文本时关闭事件(如EN_SELCHANGE
),然后在完成后恢复它们。
试试这个:
SendMessage(hWin, WM_SETREDRAW, false, 0);
CHARFORMAT2 format, old;
format.cbSize = sizeof(format);
MainRich.GetFormat(SCF_DEFAULT, &format);
old = format;
format.dwMask |= CFM_BOLD;
format.dwEffects |= CFE_BOLD;
CHARRANGE* c = MainRich.GetSelectionRange();
DWORD mask = MainRich.GetEventMask();
MainRich.SetEventMask(0);
FINDTEXTEX ft;
ft.chrg.cpMin = 0;
ft.chrg.cpMax = MainRich.GetLength();
ft.lpstrText = "true";
while (MainRich.FindText(FR_DOWN | FR_MATCHCASE | FR_WHOLEWORD, &ft) != -1)
{
MainRich.Select(ft.chrgText.cpMin, ft.chrgText.cpMax);
MainRich.SetFormat(SCF_SELECTION, &format);
ft.chrg.cpMin = ft.chrgText.cpMax;
}
MainRich.Select(ft.chrg.cpMax, ft.chrg.cpMax);
MainRich.SetFormat(SCF_SELECTION, &old);
MainRich.Select(c->cpMin, c->cpMax);
MainRich.SetEventMask(mask);
SendMessage(hWin, WM_SETREDRAW, true, 0);
UpdateWindow(hWin);
最终的perf方法是在TextOut上进行API挂钩。
要正确指定100%。