RichEdit语法Highligh

我需要你的帮助! 所以,我创build一个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的程序集,但是这个代码是一团糟,他似乎是在文本前画的亮点,这样的select是行不通的,对吗?如果是这样,你能给我一些如何做的提示?谢谢!

我发现最快的方法是构建原始的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规范

您使用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%正确。

  • riched32.dll(richedit v1.0)从riched20.dll导入。

  • riched20.dll(richedit v2.0)使用: ExtTextOutAExtTextOutW

  • msftedit.dll(richedit v4.1)使用: ExtTextOutAExtTextOutWTextOutW