2014-03-01 25 views
1

我需要你的幫助!所以,我創建與語法高亮顯示一個RichEdit的,我做這樣:RichEdit語法Highligh

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); 
      } 

但我看到,有很多亮點它得到laggy的大文件,你是否有這樣做的更好的辦法那個?我檢查了Iczelion's Assembly,但是那個代碼是一團糟,他似乎是在文字前面畫出亮點,但是這樣選擇不起作用,對嗎?如果是這樣,你能給我一些提示如何做是什麼?謝謝!

回答

1

我發現的最快方式是構建原始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

1

您使用的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); 
0

最終PERF的方法是做的TextOut API鉤子。

要正確指定100%。

  • riched32.dll(richedit v1.0)從riched20.dll導入。

  • RICHED20.DLL(RichEdit中V2.0)用途:ExtTextOutAExtTextOutW

  • msftedit.dll(RichEdit中V4.1)使用:ExtTextOutAExtTextOutWTextOutW

+0

我迷上了,什麼都沒有發生...... RichEdit不會觸發它 – user3124543

+0

@ user31 24543看我的編輯 – JonPall