0

我在 WINAPI 上编写了一个程序。我必须实现语法高亮。此时我使用以下算法:

void PaintWords(const char *SearchWord,COLORREF rgb)
{
    counter = TabCtrl_GetCurSel(TabControl_hWnd);
    ft.chrg.cpMin = 0;
    ft.chrg.cpMax = GetWindowTextLength(hWnd);
    ft.lpstrText = (LPCSTR)SearchWord; //keyword
    do
    {
        int poe_p = SendMessage(hWnd, EM_FINDTEXTEX, FR_DOWN | FR_WHOLEWORD | FR_MATCHCASE, (LPARAM)&ft);
        if(poe_p != -1)
        {
            int selword = SendMessage(hWnd, EM_EXSETSEL,0,(LPARAM)&ft.chrgText);
            ZeroMemory(&chd, sizeof(chd));
            chd.cbSize = sizeof(CHARFORMAT);
            chd.dwMask = CFM_SIZE | CFM_FACE | CFM_COLOR | CFM_CHARSET;
            chd.crTextColor = rgb;
            chd.bPitchAndFamily = FW_THIN;
            lstrcpy(chd.szFaceName , "Courier New");
            SendMessage(hWnd,EM_SETCHARFORMAT,SCF_WORD|SCF_SELECTION,(LPARAM)&chd);
            ft.chrg.cpMin = ft.chrgText.cpMax;
        }
        else
        {
            break;
        }
    }while(ft.chrg.cpMin != ft.chrg.cpMax);
}

这段代码太慢了,因为这不是最好的选择,闪烁是可见的。

我对其他变体感兴趣。

4

2 回答 2

0

我遇到了这个项目的 RichTextbox,它被用作 xml 编辑器:http: //xpathvisualizer.codeplex.com/SourceControl/changeset/view/42057#XPathVisualizer/CustomControls/RichTextBoxEx.cs

它在 C# 中,但发送的消息是可见的。

使用此 TextBox 时,应在突出显示文本之前调用 BeginUpdateAndSuspendEvents 函数。

        public IntPtr BeginUpdateAndSuspendEvents()
        {
            // Stop redrawing:
            User32.SendMessage(this.Handle, (int) User32.Msgs.WM_SETREDRAW, 0, IntPtr.Zero);
            // Stop sending of events:
            IntPtr eventMask = User32.SendMessage(this.Handle, User32.Msgs.EM_GETEVENTMASK, 0, IntPtr.Zero);

            return eventMask;
        } 

此功能可防止在您处理文本时重绘,完成编辑后,您应该调用

        public void EndUpdateAndResumeEvents(IntPtr eventMask)
        {
            // turn on events
            User32.SendMessage(this.Handle, User32.Msgs.EM_SETEVENTMASK, 0, eventMask);
            // turn on redrawing
            User32.SendMessage(this.Handle, User32.Msgs.WM_SETREDRAW, 1, IntPtr.Zero);
            NeedRecomputeOfLineNumbers();
            this.Invalidate();
        }

双缓冲不能解决这个问题,因为它不会阻止绘制的发生,在不禁用绘制事件的情况下突出显示编辑器可能会导致程序停止超过 5 分钟,具体取决于文件的大小和要处理的字数突出显示。

于 2015-04-22T19:29:10.573 回答
0

我认为您需要使用双缓冲来减少闪烁。除此之外,您不应该使用SendMessage(甚至PostMessage)到任何窗口(在同一线程内)。为什么必须在语法高亮绘制代码中进行选择?

关于双缓冲的文章之一是this

于 2013-01-26T12:25:47.523 回答