我需要你的帮助! 所以,我创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)使用: ExtTextOutA和ExtTextOutW
msftedit.dll(richedit v4.1)使用: ExtTextOutA , ExtTextOutW和TextOutW