Syntax-Highlighting mit RichEdit



  • Hallo Leute,

    ich habe mir ja mit der WinAPI einen MDI-Texteditor geschrieben.
    dafür habe ich, wie im Titel zu erkennen, RichEdit-Controls benutzt.

    Jetzt wollte ich da gerne noch Syntax-Highlighting einbauen.
    Das hatte ich schon mal mit VB 2005 .NET versucht, hatte aber einige Probleme:
    - das ganze lief nicht in Echtzeit, soll heißen, wenn man etwas eingibt, wird
    das nicht automatisch entsprechend hervorgehoben
    - das ganze war seeehhhhhrrrr langsam
    also kurz gesagt: nicht zu gebrauchen

    Jetzt habe ich etwas gefunden, wo so etwas angewendet wird:
    Iczelion's Win32-ASM Tutorial.
    Da wird ein RichEdit gesubclassed, um Syntax-Highlighting zu unterstützen.
    Außerdem wird für das Highlighten ein Wordfile verwendet.
    Leider ist das ganze für Assembler und ich blicke da nicht so ganz durch 😞

    würde mich freuen, wenn jemand mir das in C++ mit WinAPI erklären könnte.
    Tutorials dazu wären auch nicht schlecht.
    aber bitte nichts mit MFC, da bin ich absolut dagegen^^

    thx schonmal

    MfG DrakoXP



  • Ich habe mich damit auch mal befasst und muss sagen, daß sich RichEdit nicht wirklich vernünftig eignet für Syntax Highlighting und solche Dinge. Ich weiß nicht mehr genau, aber ich meine mich auch zu erinnern, daß es einfach zu langsam dafür war und außerdem hatte es allerlei Einschränkungen.

    Ich kann dir nur das Scintilla Control dafür empfehlen. Das kann Syntax Highlighting, Einrücken und noch allerlei andere tolle Dinge und ist zu normalen Edit Controls und zu RichEdit Controls beinahe vollständig abwärtskompatibel.

    http://sourceforge.net/projects/scintilla/



  • danke erstmal xD (wenn auch spät^^)

    hab das jetzt mal ausprobiert und funktioniert SEHR schön!
    also bin sehr erfreut darüber!

    aber: ich schaff es nicht, dass das Ding die Zeilennummern anzeigt?
    also:

    Wie bringe ich das Scintilla-Control dazu, Zeilennummern anzuzeigen?

    MfG DrakoXP



  • guck dir doch mal den quellcode von Scite an http://www.scintilla.org/SciTE.html

    schirrmie



  • Das ist schon ewig her, daß ich damit was gemacht hab. Du musst eine SCI_SETMARGINWIDTHN ans Control schicken, damit kannst du glaube ich die Breite des Rahmens bestimmen, oder so ähnlich. Naja hier ist mal die Funktion, die ich dafür damals geschrieben habe, damit müsstest du es hinbekommen.

    Ansonsten musst du hier mal genauer nachlesen: http://scintilla.sourceforge.net/ScintillaDoc.html

    /*
     * SetLineNumbersWidth
     *
     * hwndEdit - Handle of Scintilla control
     * bShow	- TRUE to display, FALSE to hide line numbers
     */
    void SetLineNumbersWidth( HWND hwndEdit, BOOL bShow ) {
    	int pixelWidth;
    	int lineCount;
    	int lineNumWidth;
    
    	if( !bShow ) {
    		SendMessage( hwndEdit, SCI_SETMARGINWIDTHN, 1, 0 );
    		return;
    	}
    
    	lineCount = SendMessage( hwndEdit, SCI_GETLINECOUNT, 0, 0 );
    	lineNumWidth = 1;
    
    	while( lineCount >= 10 ) {
    		lineCount /= 10;
    		lineNumWidth++;
    	}
    
    	pixelWidth = 8 + lineNumWidth * SendMessage( hwndEdit, SCI_TEXTWIDTH, STYLE_LINENUMBER, (LPARAM) "9" );
    	SendMessage( hwndEdit, SCI_SETMARGINWIDTHN, 1, pixelWidth );
    }
    

  • Mod

    www.bcgsoft.com hat auch eine kommerzielle Version eines Editor-Controls. Allerdings mit MFC, aber dafür extrem flexibel.



  • thx für die Antworten, zu der Funktion:
    ich kann jetzt zwar den Balken verschwinden lassen und auch wieder anzeigen,
    aber Zeilennummern erscheinen seltsamer Weise trotzdem nicht 😞



  • Hast du dir mal das manuel durchgelesen? Kann mir nicht vorstellen das das da nicht drinnsteht! Hast du denn schon was versucht oder kennst du die Message/Funktion garnicht?

    schirrmie



  • bin jetzt mal durch den Quellcode von ScITE gegangen und hab die Lösung gefunden.
    Bis auf kleine Unterschiede entsprach es sogar der oben geposteten Funktion.
    Auf jeden Fall funktioniert es jetzt.

    Danke an alle, die mitgeholfen haben 😃



  • Servus,

    Syntaxhighlighting auf nem RT-Control ist eigentlich ganz einfach aber recht aufwendig zu lösen.
    Am besten geht das per Drüberzeichnen.
    Ja, richtig gelesen.
    Der sichtbare Textbereich des RT-Controls muss bei WM_Paint nur geparst werden.
    Sprich in einzelne Tokens zerlegt und diese mit einer Liste zu highlightender Wörter gegengeprüft werden.
    Per Textout müssen entsprechende Tokens auf dem RT-Control anschliessend überzeichnet werden.
    Die Positionen der Wörter lassen sich über eine Kalkulation der Textmetriken mit der jeweiligen Zeichenposition ermitteln.
    Ich hatte mir auf diesem Wege schon ein paar kleine Editoren für eigene Zwecke gebastelt.
    Das Ergebnis ist zufriedenstellen.

    Zeilennummerierungen lassen sich ganz ähnlich lösen.
    Hierzu muss ein Marginbereich im RT-Control definiert werden.
    Auf diesem Bereich müssen die Zeilennummer relativ zur jeweiligen Zeilenposition (Carret) gezeichnet werden.

    Dinge wie Auf-/Zuklappen sind nicht so einfach zu lösen.

    Jedoch Breakpoints setzen und Markerlines, sind ähnlich leicht machbar wie die Zeilennummerierung und das Syntaxhighlighting.

    MfG

    Wolf


  • Mod

    Dann kann man auch eine eigene Klasse bauen, wenn man sich diese Mühe macht.



  • Hroudtwolf schrieb:

    Per Textout müssen entsprechende Tokens auf dem RT-Control anschliessend überzeichnet werden.

    Also, alleine dadurch bekomme ich Bauchschmerzen. Denn dieses Konstrukt verursacht zwangsläufig ein IMHO störendes Flickern!

    Daher lieber eine eigene Klasse schreiben (wie Martin Richter bereits vorgeschlagen hat) oder ein fertiges Edit-Control wie Scintilla (es gibt im Web natürlich mehr Varianten) verwenden.

    Vielleicht interessiert Dich auch das Tutorial "Design and Implementation of a Win32 Text Editor": http://www.catch22.net/tuts/editor01.asp
    Es ist wirklich lesenswert und anschaulich erläutert. Der Editor beachtet ziemlich viele Aspekte, einschließlich Unicode, mehrere Fonts und natürlich auch Syntax-Highligting!

    Gruß
    Martin


Anmelden zum Antworten