Syntaxhighlighting



  • Hallo,

    ich bin gerade dabei einen Texteditor zu erstellen, der Syntax highlighten soll. Da CEditView keine verschiedenfarbige Texte anzeigen kann und CRichTextEditView (oder wie es heißt) für mich zu kompliziert ist, will ich mir das in einem CScrollView selbst bauen. Da TextOut bei '\n' keine neue Zeile anfängt, speichere ich jede Zeile einzeln in einem CString und gebe die dann aus.

    Zuerst will ich die Syntaxhighlighting-Funktion einbauen, das habe ich jetzt auch, mein Problem ist, dass es einfach viel zu langsam ist. Bei 50 Zeilen und 400 definierten Keywords sieht man richtig, wie der Text geschrieben wird. Das ist mir eindeutig zu langsam, vielleicht hat einer von euch ne Idee, wie das schneller geht. Das habe ich im Moment:

    void C4ScripterView::OnDraw(CDC* pDC)
    {
        C4ScripterDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
    
        CFont* pFont = new CFont;
        pFont->CreateFont(FONT_WIDTH,FONT_HEIGHT,0,0,0,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH | FF_DONTCARE,FONT_NAME);
        CFont* pOldFont = pDC->SelectObject(pFont);
    
        CString str;
            // Zum Testen 50 Zeilen ausgeben
        for(int i=0;i<50;++i)
        {
            WriteText(pDC, i,"Greif if while(if while) if(whilewhile) whileif");
        }
        pDC->SelectObject(pOldFont);
    }
    

    WirteText übernimmt dann das eigene Highlighting:

    void C4ScripterView::WriteText(CDC *pDC, int iLine, const CString &rString)
    {
        // Erst das Zeug hinschreiben, danach Schlüsselwörter highleiten
        pDC->TextOut(50,iLine * FONT_WIDTH,rString);
    
        pDC->SetTextColor(RGB(0,0,192) );
        CStringArray& saKeywords = GetDocument()->GetKeywordArray();
    
        // Syntaxhighligthing... dazu jedes Keyword durchgehen
        for(int i=0;i<saKeywords.GetSize();++i)
        {
            // Alle Vorkommen suchen
            int iStart = 0;
            while((iStart = rString.Find(saKeywords[i],iStart)) != -1)
            {
                // Prüfen, ob das Wort nicht Teil eines anderen Wortes ist...
                if(iStart != 0)
                    if(!ValidChar(rString[iStart-1] ))
                    {
                        iStart += saKeywords[i].GetLength();
                        continue;
                    }
    
                if(iStart+saKeywords[i].GetLength() < rString.GetLength() )
                    if(!ValidChar(rString[iStart+saKeywords[i].GetLength()] )) 
                    {
                        iStart += saKeywords[i].GetLength();
                        continue;
                    }
    
                // Nein, also highlighten
                pDC->TextOut(50+iStart*(FONT_HEIGHT-1),iLine*FONT_WIDTH,saKeywords[i] );
                iStart += saKeywords[i].GetLength();
            }
        }
        pDC->SetTextColor(RGB(0,0,0) );
    }
    

    ValidChar letztendlich prüft, ob ein Zeichen neben einem Schlüsselwort gültig ist, damit zum Beispiel bei Greif das Gre'if' nicht gehighleitet wird, aber zum Beispiel bei 'while(':

    BOOL C4ScripterView::ValidChar(TCHAR tChar)
    {
        if(tChar == ' ' || tChar == '(' || tChar==')') return TRUE;
        return FALSE;
    }
    

    Das Kommentare gehighleitet werden, baue ich dann später ein, auch ein Grund, warum das so noch schneller werden muss.

    Also, ich hoffe einer von euch kann mir weiterhelfen, auf jeden Fall mal Danke im Voraus und so...


Anmelden zum Antworten