سؤال

I'm trying to realize a code to add the syntax-highlighting to the richedit of winapi, so I search ranges of text that I must colorize, but if I select the range with the EM_EXSETSEL message to format with the EM_SETCHARFORMAT message, it's very slow and all is saw by users. How I can change the character formatting more quickly ?

هل كانت مفيدة؟

المحلول

I did it via RTF: it's a markup language, conceptually similar to HTML. Insert the color directives at once and reload the buffer. To be true I used MFC, but I think that CRichEdit it's a thin layer that adds no further functionality (apart framework integration, of course). Here some code (very old, I'm sorry):

....

// reformat line
//
void RichEditSyntaxColor::FmtLine(CRichEditCtrl &c, int nLine)
{
    int iLine = c.LineIndex(nLine),
        lLine = c.LineLength(iLine);
    if (lLine > 0)
    {
        fmt(c, nLine, lLine);

        long ss, es;
        c.GetSel(ss, es);
        c.ShowWindow(SW_HIDE);
        stream(c, iLine, lLine);
        c.ShowWindow(SW_SHOW);
        c.SetSel(ss, es);
    }
}

// apply formatted streaming to selected pos
//
void RichEditSyntaxColor::stream(CRichEditCtrl &c, int iLine, int lLine)
{
    c.SetSel(iLine, iLine + lLine);
    EDITSTREAM eds = { DWORD(this), 0, fmtLineCb };
    c.StreamIn(SF_RTF|SFF_SELECTION, eds);
}       

// required callback
//
DWORD CALLBACK RichEditSyntaxColor::fmtLineCb(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
    RichEditSyntaxColor* pCookie = (RichEditSyntaxColor*)dwCookie;
    memcpy(pbBuff, pCookie->obuf, *pcb = pCookie->os.pcount());
    return 0;
}

// colors data, useful to configure
//
SyntaxColor::aColor SyntaxColor::_colorsDef[] = {
    {"Atom",    RGB( 16, 16, 32)},
    {"Number",  RGB(128, 32,128)},
    {"Var", RGB( 16, 16,255)},
    {"String",  RGB(128,128,128)},
    {"Comment", RGB(128,128, 20)}, //RGB( 32,128, 32)},
    {"SepChar", RGB(196, 32, 32)}
};
char SyntaxColor::_colorsStr[];

void SyntaxColor::Table2String()
{
    ostringstream s(_colorsStr);//, sizeof _colorsStr);

    s << "{\\colortbl;";
    for (int i = 0; i < __maxTag__; i++)
    {
        COLORREF c = _colorsDef[i].value;
        s << "\\red"    << int(GetRValue(c))
          << "\\green"  << int(GetGValue(c))
          << "\\blue"   << int(GetBValue(c))
          << ';';
    }
    s << '}' << ends;
}
...
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top