0

I write a program on WINAPI. I must to implement syntax highlight. At this moment the I using following algorithm:

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

This code is too slow, because this is not best option, flicker is visible.

I interested in other variants.

xrnd
  • 1

2 Answers2

0

I think you need to use double buffering to reduce the flicker. Other than that, you should not use SendMessage (or even PostMessage) to any window (within same thread). Why selection must happen in your syntax-highlighting paint code?

One of the article on double buffer is this.

Ajay
  • 18,086
  • 12
  • 59
  • 105
0

I have come across this project's RichTextbox, which is used as an xml editor: http://xpathvisualizer.codeplex.com/SourceControl/changeset/view/42057#XPathVisualizer/CustomControls/RichTextBoxEx.cs

it's in C#, but the messages sent are visible.

When using this TextBox, before highlighting the text the BeginUpdateAndSuspendEvents function should be called.

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

This function prevents redrawing while you are working on the text, after you finish editing, you should call

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

Double buffering does not solve this problem because it will not stop the paints from occurring, highlighting an editor without disabling the paint event can cause the program to halt for more than 5 minutes depending on the size of the file and the number of words to be highlighted.

Eduardo Wada
  • 2,606
  • 19
  • 31