MFC. Quickly highlight all matches in RichEditCtrl

I have a very large text (>50mb).

FindText, SetSel and SetSelectionCharFormat is too slow for me. I tried to formulate the text and then display but it was even slower.

Can I work with RichEditCtrl in memory and then just display? Or can I speed up the first option or you can solve my problem in another way?

Upvotes: 0

Views: 273

Answers (1)

Vlad Feinstein
Vlad Feinstein

Reputation: 11321

My measurements of improvement are different than yours.

Here is my code:

void CRichEditAppView::OnEditHighlight()
{
    FINDTEXTEX ft = {};
    ft.chrg = { 0, -1 };
    ft.lpstrText = L"Lorem ipsum";
    DWORD dwFlags(FR_DOWN);
    CHARFORMAT2 cf = {};
    cf.cbSize = sizeof cf;
    cf.dwMask = CFM_BACKCOLOR;
    cf.crBackColor = RGB(255, 255, 0);
    CRichEditCtrl& ctrl = GetRichEditCtrl();
    ctrl.HideSelection(TRUE, FALSE);
    ctrl.SetRedraw(FALSE);
    int count(0);
    while (ctrl.FindTextW(dwFlags, &ft) >= 0)
    {
        ctrl.SetSel(ft.chrgText);
        ctrl.SetSelectionCharFormat(cf);
        ft.chrg.cpMin = ft.chrgText.cpMax + 1;
        count++;
    }
    ctrl.HideSelection(FALSE, FALSE);
    ctrl.SetRedraw(TRUE);
    ctrl.Invalidate();
}

I have tested it on a file with 3,000 copies of "Lorem ipsum" text (file size 1,379 KB).

The "naive" implementation (without calls to HideSelection() and SetRedraw()) took 11 seconds.

Calling HideSelection() reduced the time to 9 seconds, adding SetRedraw() - to 1.2 seconds. So I expect to see a 10-times improvement.

Just to compare, if I remove a call to SetSelectionCharFormat(), I'm only saving 0.4 seconds.

Upvotes: 1

Related Questions