SyntaxHighlighting für PB4.10 (ScintillaGadget)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

SyntaxHighlighting für PB4.10 (ScintillaGadget)

Beitrag von ts-soft »

Da die Frage immer wieder aufkommt, hab ich mal den folgenden Code
aus einem anderen Projekt extrahiert und angepaßt.
Erstellt wird ein Fenster mit 2 ScinttillaGagets in einem Splitter. (SplitView)
SyntaxHighlightning durch Nutzung der DLL aus dem PB-SDK.

Farben werden aus den Preferences der PB-IDE gelesen.

Code: Alles auswählen

EnableExplicit

Define.s HighLightDLLPath = #PB_Compiler_Home + "Library SDK\Syntax Highlighting\SyntaxHilighting.dll"

If OpenLibrary(0, HighLightDLLPath) = #False : Debug "HL-DLL nicht gefunden" : End : EndIf
If InitScintilla("scintilla.dll") = #False : Debug "Scintilla-DLL nicht gefunden" : End : EndIf

Prototype SyntaxHighlight(*Buffer, len.l, callback.l, asm.l)
Global SyntaxHighlight.SyntaxHighlight = GetFunction(0, "SyntaxHighlight")

Enumeration; Gadgets
  #SciID
  #SciID2
  #Splitter
EndEnumeration

Enumeration; Syntax
  #SYNTAX_Text
  #SYNTAX_Keyword
  #SYNTAX_Comment
  #SYNTAX_Constant
  #SYNTAX_String
  #SYNTAX_Function
  #SYNTAX_Asm
  #SYNTAX_Operator
  #SYNTAX_Structure
  #SYNTAX_Number
  #SYNTAX_Pointer
  #SYNTAX_Separator
  #SYNTAX_Label
EndEnumeration

Define.l start_pos, Buffer, Editor

Procedure.s GetSpecialFolder(CSIDL.l)
  Protected *itemid.ITEMIDLIST
  Protected location.s = Space(#MAX_PATH)

  If SHGetSpecialFolderLocation_ (0, CSIDL, @*itemid) = #NOERROR
    If SHGetPathFromIDList_(*itemid, @location)
      If Right(location, 1) <> "\" : location + "\" : EndIf
      ProcedureReturn location
    EndIf
  EndIf
EndProcedure

Procedure SHCallback(pos, len, id)
  Shared start_pos,Buffer, Editor

  ScintillaSendMessage(Editor, #SCI_STARTSTYLING, (pos - Buffer) + start_pos, $1F)
  ScintillaSendMessage(Editor, #SCI_SETSTYLING, len, id)
EndProcedure

Procedure ScintillaCallBack(EditorGadget.l, *scinotify.SCNotification)
  Protected line_number.l
  Protected txtr.TEXTRANGE
  Protected end_pos.l
  Shared start_pos, Buffer, Editor
  
  Editor = EditorGadget
  If *scinotify\nmhdr\code = #SCN_STYLENEEDED
    line_number = ScintillaSendMessage(EditorGadget, #SCI_LINEFROMPOSITION, ScintillaSendMessage(EditorGadget, #SCI_GETENDSTYLED))
    start_pos = ScintillaSendMessage(EditorGadget, #SCI_POSITIONFROMLINE, line_number)
    end_pos     = *scinotify\Position

    txtr\chrg\cpMin = start_pos
    txtr\chrg\cpMax = end_pos
    txtr\lpstrText  = AllocateMemory(end_pos - start_pos + 1)
    Buffer          = txtr\lpstrText

    ScintillaSendMessage(EditorGadget, #SCI_GETTEXTRANGE, 0, txtr)
    SyntaxHighlight(Buffer, end_pos - start_pos, @SHCallback(), #False)

    FreeMemory(Buffer)
  EndIf
EndProcedure

Procedure CreatePBSourceView()
  Protected WFlags.l = #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_Invisible | #PB_Window_SystemMenu | #PB_Window_SizeGadget
  Protected temp.s
  If OpenWindow(1, #PB_Ignore, 0, 640, 480, "Scintilla Beispiel", WFlags)
    SmartWindowRefresh(1, #True)
    CreateGadgetList(WindowID(1))
    ScintillaGadget(#SciID, 0, 0, 0, 0, @ScintillaCallBack())
    ScintillaGadget(#SciID2, 0, 0, 0, 0, 0)
    ScintillaSendMessage(#SciID2, #SCI_SETDOCPOINTER, 0, ScintillaSendMessage(#SciID, #SCI_GETDOCPOINTER))
    SplitterGadget(#Splitter, 0, 0, 0, 0, #SciID, #SciID2)
    SetGadgetState(#Splitter, 0)

    ScintillaSendMessage(#SciID, #SCI_SETLEXER, #SCLEX_CONTAINER)
    ScintillaSendMessage(#SciID2, #SCI_SETLEXER, #SCLEX_CONTAINER)

    OpenPreferences(GetSpecialFolder(#CSIDL_APPDATA) + "PureBasic\PureBasic.prefs")
    PreferenceGroup("Editor")
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE,#STYLE_DEFAULT, $000000)
    ScintillaSendMessage(#SciID, #SCI_STYLESETBACK, #STYLE_DEFAULT, ReadPreferenceLong("BackgroundColor", $FFFFFF))
    temp = ReadPreferenceString("EditorFontName", "Courier New")
    ScintillaSendMessage(#SciID, #SCI_STYLESETFONT, #STYLE_DEFAULT, @temp)
    ScintillaSendMessage(#SciID, #SCI_STYLESETSIZE, #STYLE_DEFAULT, ReadPreferenceLong("EditorFontSize", 10))
    ScintillaSendMessage(#SciID, #SCI_STYLECLEARALL)

    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Text, ReadPreferenceLong("NormalTextColor", 0))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Keyword, ReadPreferenceLong("BasicKeywordColor", $9D030D))
    ScintillaSendMessage(#SciID, #SCI_STYLESETBOLD, #SYNTAX_Keyword, #True)
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Comment, ReadPreferenceLong("CommentColor", $6F884A))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Constant, ReadPreferenceLong("ConstantColor", $0B46AE))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_String, ReadPreferenceLong("StringColor", $413C33))
    ScintillaSendMessage(#SciID, #SCI_STYLESETITALIC, #SYNTAX_String, #True)
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Function, ReadPreferenceLong("PureKeywordColor", $EF303D))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Asm, ReadPreferenceLong("ASMKeywordColor", $400080))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Operator,  ReadPreferenceLong("OperatorColor", $0000FF))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Structure, ReadPreferenceLong("StructureColor", $0548B4))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Number, ReadPreferenceLong("NumberColor", $0000FF))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Pointer,  ReadPreferenceLong("PointerColor", $0507B4))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Separator,  ReadPreferenceLong("SeparatorColor", $000000))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Label,  ReadPreferenceLong("LabelColor", $804000))
    ScintillaSendMessage(#SciID, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
    ScintillaSendMessage(#SciID, #SCI_SETMARGINWIDTHN, 0, 40)
    ScintillaSendMessage(#SciID, #SCI_STYLESETBACK, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberBackColor", GetSysColor_(15)))
    ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberColor", 0))
    ScintillaSendMessage(#SciID, #SCI_SETMARGINWIDTHN, 1, 5)

    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #STYLE_DEFAULT, $000000)
    ScintillaSendMessage(#SciID2, #SCI_STYLESETBACK, #STYLE_DEFAULT, ReadPreferenceLong("BackgroundColor", $FFFFFF))
    temp = ReadPreferenceString("EditorFontName", "Courier New")
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFONT, #STYLE_DEFAULT, @temp)
    ScintillaSendMessage(#SciID2, #SCI_STYLESETSIZE, #STYLE_DEFAULT, ReadPreferenceLong("EditorFontSize", 10))
    ScintillaSendMessage(#SciID2, #SCI_STYLECLEARALL)

    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Text, ReadPreferenceLong("NormalTextColor", 0))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Keyword, ReadPreferenceLong("BasicKeywordColor", $9D030D))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETBOLD, #SYNTAX_Keyword, #True)
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Comment, ReadPreferenceLong("CommentColor", $6F884A))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Constant, ReadPreferenceLong("ConstantColor", $0B46AE))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_String, ReadPreferenceLong("StringColor", $413C33))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETITALIC, #SYNTAX_String, #True)
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Function, ReadPreferenceLong("PureKeywordColor", $EF303D))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Asm, ReadPreferenceLong("ASMKeywordColor", $400080))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Operator,  ReadPreferenceLong("OperatorColor", $0000FF))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Structure, ReadPreferenceLong("StructureColor", $0548B4))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Number, ReadPreferenceLong("NumberColor", $0000FF))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Pointer,  ReadPreferenceLong("PointerColor", $0507B4))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Separator,  ReadPreferenceLong("SeparatorColor", $000000))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #SYNTAX_Label,  ReadPreferenceLong("LabelColor", $804000))
    ScintillaSendMessage(#SciID2, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
    ScintillaSendMessage(#SciID2, #SCI_SETMARGINWIDTHN, 0, 40)
    ScintillaSendMessage(#SciID2, #SCI_STYLESETBACK, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberBackColor", GetSysColor_(15)))
    ScintillaSendMessage(#SciID2, #SCI_STYLESETFORE, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberColor", 0))
    ScintillaSendMessage(#SciID2, #SCI_SETMARGINWIDTHN, 1, 5)
    ClosePreferences()

    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure

If CreatePBSourceView()
  HideWindow(1, #False)
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow : Break
      Case #PB_Event_SizeWindow
        ResizeGadget(#Splitter, #PB_Ignore, #PB_Ignore, WindowWidth(1), WindowHeight(1))
    EndSelect
  ForEver  
EndIf 
Am besten einen Source reinpasten, da keine Load- oder Save-Routinen
implementiert sind

// Nachtrag:
angepaßt an PB4.10 Beta 2
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Hilfe zu Scintilla in chm Form erhaltet ihr hier:
http://www.purebasic.fr/german/viewtopi ... 089#156089
Danke an Kai :allright:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

Code: Alles auswählen

InitScintilla("scintilla.dll")
Geht nicht, ist keine Funktion, sagt der Compiler... :(

(Was hab ich denn jetzt schon wieder falsch gemacht? -.-°
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Vermilion hat geschrieben:

Code: Alles auswählen

InitScintilla("scintilla.dll")
Geht nicht, ist keine Funktion, sagt der Compiler... :(

(Was hab ich denn jetzt schon wieder falsch gemacht? -.-°
Lies den Titel!
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Ich hab mithilfe des obigen Codebeispiels mal ein kleines IDE-Addon
gebastelt. Einfach als Werkzeug eintragen, ohne jegliche Parameter. Bei
Aufruf liest es den Text des aktuell geöffneten Tabs (direkt aus dem Control,
Speicherung oder Tempfile nicht erforderlich) und stellt ihn schreibgeschützt
dar.
Dient also nur als Hilfe wenn man mehrere Tabs nebeneinander vergleichen
möchte (breiten Bildschirm vorausgesetzt :wink: )

Download: http://ts-soft.eu/dl/sourceviewer.zip

Vielleicht habt ihr ja noch eine Anregung was man da noch reinbasteln könnte :wink:

Funktioniert nur mit der PB-IDE ab Version 3.94
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Rings
Beiträge: 971
Registriert: 29.08.2004 08:48

Beitrag von Rings »

irgendwie verstehe ich nicht (trotz 2maligen durchsehen des quellcodes)
wie denn nun definiert ist was zum bsp ein keyword,Kommentar oder Basicword währe respektive wie man das selber festlegt.

Ziel ist es einen Highlighter zu haben der zum Bsp auch eigene
Kommandos entsprechend färbt.

any idea ?
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Es wird immer ein Lexer benötigt. Dieser befindet sich entweder fertig in der
SciLexer.dll oder wie hier in einer Extra DLL. (selbstdefiniert hat Nr. 0)

Selbstdefinition ist auch möglich, siehe jaPBe, aber sehr aufwendig.
Das einfachste ist es einen fertigen Lexer wie z.B. #SCLEX_VB für Visual
Basic zu nehmen. Jetzt brauchste noch mehrere Wortlisten, z.B. Funktionen,
alle getrennt durch ein Leerzeichen, die kannste dann übergeben (Memorypointer).

Kommentarzeichen, Stringliterale usw. sind durch den Lexer definiert.
Den Wortgruppen noch die Farbe, Schriftstyle usw. zuordnen und fertig ist
das ganze.

Der Lexer weiß meist auch, was zu falten ist, man muß ihm nur sagen ob
gefaltet werden soll, oder eben nicht.

Fertigen Lexer aus SciLexer.dll nutzen ist recht einfach, selber einen
Lexer schreiben dann nicht mehr :wink:

Wenn es keine fertigen gibt, kann man auch einen ähnlichen verwenden,
solange die Kommentare gleich eingeleitet werden, Strings gleich
gekennzeichnet sind usw.

Ansonsten versuchen die Hilfe zu Scintilla zu verstehen :mrgreen:

Ich hoffe ich habe Dich wenigstens ein kleines bißchen erleuchtet

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Rings
Beiträge: 971
Registriert: 29.08.2004 08:48

Beitrag von Rings »

ok, erstmal danke für deine Mühe hier.
Als ich nutze vbscript, dafür gibts nen eintrag in der lexer.
Eigentlich wäre das so okay, bis auf ein paar (150) eigene
Keywords (Funktionen) die ich auch gerne einfärben würde.
Jetzt brauchste noch mehrere Wortlisten, z.B. Funktionen,
alle getrennt durch ein Leerzeichen, die kannste dann übergeben (Memorypointer).
hättest du evtl. nen Hinweis , denn:

Die Doku ist ja übrigens unter aller Sau (also die von scintilla)
da find ich überhaubt nix.
Wüsste schon mal gerne wie man damit überhaupt arbeiten kann.
(Meinen Hut zieh an alle diedas geschafft haben)


Im Sourcecode gibts dann auch etliche von Konstanten.
Aber auch hier , schlecht dokumentiert.

Das heisst als resüme, ich weis mal wieder nicht wo man
anfangen soll.
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> hättest du evtl. nen Hinweis , denn:
Zieh dir den Source und sieh in die header-dateien :mrgreen:
Lexer setzen siehste im obigen beispiel, genauso wie den font usw.
lediglich die konstanten müssen entsprechend dem lexer (header-dateien)
angepasst werden.
Keywörter:

Code: Alles auswählen

spice_keyword.s =  "blubber blabber sappelei"
ScintillaSendMessage(#Gadget, #SCI_SETKEYWORDS, #SCE_SPICE_KEYWORD, @spice_keyword)
Wobei ich die Sprache SPICE nicht kenne. Die konstanten für die
Wortgruppen liegen meist zwischen 1 - 8

Wenn Du die richtigen Konstanten für VBScript gefunden hast, im
Lexersource o. ä. :mrgreen: ist es eigentlich nicht mehr schwer

Die Doku von Scintilla ist mehr als mies
PS: Keywörter immer kleinschreiben für den Lexer!

// Edit:
Wenn Du die Doku für die Konstante nicht findest, setze eine Konstante
z.B. auf 1, ordne Keywörter, Schrift, Farbe usw. zu. Diese Konstante
solange erhöhen bis z.B. die Funktionen sich färben. Bei dem kleinen
Zahlenbereich (0 - 15 mehr kommt wohl nicht vor) kommste so auch zum Ziel :wink:
Zuletzt geändert von ts-soft am 19.06.2007 19:01, insgesamt 3-mal geändert.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

Bezüglich meinem Post: :oops: hab noch 4.00, ich dachte das geht auch so...
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Antworten