Code : Tout sélectionner
; EnableExplicit
; from ts soft
; https://www.purebasic.fr/german/viewtopic.php?f=11&t=19580&hilit=ScintillaHelper
#SCI_STYLEGETFORE = 2481
#SCI_STYLEGETBACK = 2482
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
Prototype SyntaxHighlight(*Buffer, len, callback, asm)
Global SyntaxHighlight.SyntaxHighlight
Define SCI_start_pos, SCI_Buffer, SCI_Editor
Procedure SHCallback(pos.l, len.l, id)
Shared SCI_start_pos, SCI_Buffer, SCI_Editor
ScintillaSendMessage(SCI_Editor, #SCI_STARTSTYLING, (pos - SCI_Buffer) + SCI_start_pos, $1F)
ScintillaSendMessage(SCI_Editor, #SCI_SETSTYLING, len, id)
EndProcedure
Procedure ScintillaCallBack(EditorGadget, *scinotify.SCNotification)
Protected line_number.l
Protected txtr.TEXTRANGE
Protected end_pos.l
Shared SCI_start_pos, SCI_Buffer, SCI_Editor
SCI_Editor = EditorGadget
If *scinotify\nmhdr\code = #SCN_STYLENEEDED
line_number = ScintillaSendMessage(EditorGadget, #SCI_LINEFROMPOSITION, ScintillaSendMessage(EditorGadget, #SCI_GETENDSTYLED))
SCI_start_pos = ScintillaSendMessage(EditorGadget, #SCI_POSITIONFROMLINE, line_number)
end_pos = *scinotify\Position
txtr\chrg\cpMin = SCI_start_pos
txtr\chrg\cpMax = end_pos
txtr\lpstrText = AllocateMemory(end_pos - SCI_start_pos + 1)
SCI_Buffer = txtr\lpstrText
ScintillaSendMessage(EditorGadget, #SCI_GETTEXTRANGE, 0, txtr)
SyntaxHighlight(SCI_Buffer, end_pos - SCI_start_pos, @SHCallback(), #False)
FreeMemory(SCI_Buffer)
EndIf
EndProcedure
Declare SCI_GetTextFormat(ID)
ProcedureDLL ScintillaGadgetPB(ID, x, y, w, h , SyntaxHilightingDLL.s)
Protected hDLL, result
Protected buffer.s, Font.s
hDLL = OpenLibrary(#PB_Any, SyntaxHilightingDLL)
If hDLL
SyntaxHighlight = GetFunction(hDLL, "SyntaxHighlight")
If SyntaxHighlight
result = ScintillaGadget(ID, x, y, w, h, @ScintillaCallBack())
If ID = #PB_Any
ID = result
EndIf
OpenPreferences(GetEnvironmentVariable("APPDATA") + "\PureBasic\PureBasic.prefs")
PreferenceGroup("Editor")
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #STYLE_DEFAULT, $000000)
ScintillaSendMessage(ID, #SCI_STYLESETBACK, #STYLE_DEFAULT, ReadPreferenceLong("BackgroundColor", 14680063))
Font = ReadPreferenceString("EditorFontName", "courier")
buffer = Space(StringByteLength(Font, SCI_GetTextFormat(ID)))
PokeS(@buffer, Font, -1, SCI_GetTextFormat(ID))
ScintillaSendMessage(ID, #SCI_STYLESETFONT, #STYLE_DEFAULT, @buffer)
ScintillaSendMessage(ID, #SCI_STYLESETSIZE, #STYLE_DEFAULT, ReadPreferenceLong("EditorFontSize", 10))
ScintillaSendMessage(ID, #SCI_SETSELFORE, #STYLE_DEFAULT, ReadPreferenceLong("SelectionFrontColor", 16777215))
ScintillaSendMessage(ID, #SCI_SETSELBACK, #STYLE_DEFAULT, ReadPreferenceLong("SelectionColor", 8388608))
ScintillaSendMessage(ID, #SCI_STYLECLEARALL)
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Text, ReadPreferenceLong("NormalTextColor", 0))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Keyword, ReadPreferenceLong("BasicKeywordColor", 6710784))
ScintillaSendMessage(ID, #SCI_STYLESETBOLD, #SYNTAX_Keyword, #True)
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Comment, ReadPreferenceLong("CommentColor", 11184640))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Constant, ReadPreferenceLong("ConstantColor", 7490450))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_String, ReadPreferenceLong("StringColor", 16744448))
ScintillaSendMessage(ID, #SCI_STYLESETITALIC, #SYNTAX_String, #True)
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Function, ReadPreferenceLong("PureKeywordColor", 6710784))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Asm, ReadPreferenceLong("ASMKeywordColor", 7490450))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Operator, ReadPreferenceLong("OperatorColor", 0))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Structure, ReadPreferenceLong("StructureColor", 0))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Number, ReadPreferenceLong("NumberColor", 8421504))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Pointer, ReadPreferenceLong("PointerColor", 0))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Separator, ReadPreferenceLong("SeparatorColor", $000000))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #SYNTAX_Label, ReadPreferenceLong("LabelColor", 0))
ScintillaSendMessage(ID, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
ScintillaSendMessage(ID, #SCI_SETMARGINWIDTHN, 0, 40)
ScintillaSendMessage(ID, #SCI_STYLESETBACK, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberBackColor", 14155775));GetSysColor_(15)))
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberColor", 8421504))
ScintillaSendMessage(ID, #SCI_SETMARGINWIDTHN, 1, 5)
ClosePreferences()
ProcedureReturn result
EndIf
EndIf
ProcedureReturn #False
EndProcedure
ProcedureDLL SCI_GetTextFormat(ID)
Protected result
Select ScintillaSendMessage(ID, #SCI_GETCODEPAGE)
Case #SC_CP_UTF8
result = #PB_UTF8
Case 65001
result = #PB_Unicode
Default
result = #PB_Ascii
EndSelect
ProcedureReturn result
EndProcedure
ProcedureDLL.s SCI_GetCurrentSelection(ID)
Protected len, buffer.s = ""
len = ScintillaSendMessage(ID, #SCI_GETSELECTIONEND) - ScintillaSendMessage(ID, #SCI_GETSELECTIONSTART)
If len > 0
buffer = Space(len)
ScintillaSendMessage(ID, #SCI_GETSELTEXT, 0, @buffer)
ProcedureReturn PeekS(@buffer, -1, SCI_GetTextFormat(ID))
EndIf
EndProcedure
ProcedureDLL.s SCI_GetCurrentWord(ID)
Protected pos, startPos, endPos, len, buffer.s
Protected tr.TEXTRANGE
pos = ScintillaSendMessage(ID, #SCI_GETCURRENTPOS)
startPos = ScintillaSendMessage(ID, #SCI_WORDSTARTPOSITION, pos, #True)
endPos = ScintillaSendMessage(ID, #SCI_WORDENDPOSITION, pos, #True)
len = endPos - startPos
buffer = Space(len) ; diese größe haben wir vom Scintilla ermittelt, also ist keine Umrechnung erforderlich!
tr\chrg\cpMin = startPos
tr\chrg\cpMax = endPos
tr\lpstrText = @buffer
ScintillaSendMessage(ID, #SCI_GETTEXTRANGE, 0, tr)
; hier wirds rausgepeeked, unter Berücksichtigung des Format,
; das Ergebnis ist ein String im aktuellem Compilerformat!
ProcedureReturn PeekS(@buffer, -1, SCI_GetTextFormat(ID))
EndProcedure
ProcedureDLL SCI_AddGadgetItem(ID, pos, Text.s)
Protected _pos, buffer.s
; eine Zeile enthält keine #CRLF$, falls doch werden die erstmal entfernt
Text = RemoveString(Text, #LF$)
Text = RemoveString(Text, #CR$)
If pos = #PB_Default
Text = #LF$ + Text
Buffer = Space(StringByteLength(Text, SCI_GetTextFormat(ID)))
PokeS(@Buffer, Text, -1, SCI_GetTextFormat(ID))
ScintillaSendMessage(ID, #SCI_GOTOLINE, ScintillaSendMessage(ID, #SCI_GETLINECOUNT))
ProcedureReturn ScintillaSendMessage(ID, #SCI_ADDTEXT, Len(text), @Buffer)
Else
Text + #LF$
Buffer = Space(StringByteLength(Text, SCI_GetTextFormat(ID)))
PokeS(@Buffer, Text, -1, SCI_GetTextFormat(ID))
ScintillaSendMessage(ID, #SCI_GOTOLINE, pos)
_pos = ScintillaSendMessage(ID, #SCI_GETCURRENTPOS)
ProcedureReturn ScintillaSendMessage(ID, #SCI_INSERTTEXT, _pos, @Buffer)
EndIf
EndProcedure
ProcedureDLL SCI_CountGadgetItems(ID)
Protected result = 0
If ScintillaSendMessage(ID, #SCI_GETLENGTH) ; auch ein leeres Scintilla hat eine Zeile, aber keine Länge!
result = ScintillaSendMessage(ID, #SCI_GETLINECOUNT)
EndIf
ProcedureReturn result
EndProcedure
ProcedureDLL.s SCI_GetGadgetItemText(ID, pos)
Protected length, buffer.s
; wie groß ist die Zeile
length = ScintillaSendMessage(ID, #SCI_LINELENGTH, pos)
; buffer reservieren
buffer = Space(length)
; die Zeile abfragen
ScintillaSendMessage(ID, #SCI_GETLINE, pos, @buffer)
; Ergebnis aus dem Buffer peeken, unter Berücksichtigung der Scintilla Codepage!
ProcedureReturn PeekS(@buffer, -1, SCI_GetTextFormat(ID))
EndProcedure
ProcedureDLL SCI_RemoveGadgetItem(ID, pos)
Protected length, _pos, Buffer.s = ""
ScintillaSendMessage(ID, #SCI_GOTOLINE, pos)
_pos = ScintillaSendMessage(ID, #SCI_GETCURRENTPOS)
length = ScintillaSendMessage(ID, #SCI_LINELENGTH, pos)
ScintillaSendMessage(ID, #SCI_SETSELECTIONSTART, _pos)
ScintillaSendMessage(ID, #SCI_SETSELECTIONEND, _pos + length)
ProcedureReturn ScintillaSendMessage(ID, #SCI_REPLACESEL, 0, @Buffer)
EndProcedure
ProcedureDLL SCI_ClearGadgetItems(ID)
Protected text.s = ""
; wichtig: Adresse zu einem leerem String übergeben! #Null o.ä. funktioniert nicht
ProcedureReturn ScintillaSendMessage(ID, #SCI_SETTEXT, 0, @text)
EndProcedure
ProcedureDLL SCI_SetGadgetItemText(ID, pos, Text.s)
Protected Buffer.s, length, _pos
; eine Zeile enthält keine #CRLF$, falls doch werden die erstmal entfernt
Text = RemoveString(Text, #LF$)
Text = RemoveString(Text, #CR$)
If pos = #PB_Default
; wir fügen eine Zeile an, die Letzte Zeile enthält kein #CRLF$, also bauen wir es ein
Text = #LF$ + Text
Buffer = Space(StringByteLength(Text, SCI_GetTextFormat(ID)))
PokeS(@Buffer, Text, -1, SCI_GetTextFormat(ID))
ScintillaSendMessage(ID, #SCI_GOTOLINE, ScintillaSendMessage(ID, #SCI_GETLINECOUNT))
ProcedureReturn ScintillaSendMessage(ID, #SCI_ADDTEXT, Len(text), @Buffer)
Else
Buffer = Space(StringByteLength(Text, SCI_GetTextFormat(ID)))
PokeS(@Buffer, Text, -1, SCI_GetTextFormat(ID))
ScintillaSendMessage(ID, #SCI_GOTOLINE, pos)
_pos = ScintillaSendMessage(ID, #SCI_GETCURRENTPOS)
length = ScintillaSendMessage(ID, #SCI_LINELENGTH, pos) - 1
ScintillaSendMessage(ID, #SCI_SETSELECTIONSTART, _pos)
ScintillaSendMessage(ID, #SCI_SETSELECTIONEND, _pos + length)
ProcedureReturn ScintillaSendMessage(ID, #SCI_REPLACESEL, 0, @Buffer)
EndIf
EndProcedure
ProcedureDLL.s SCI_GetGadgetText(ID)
Protected length, buffer.s
; der Buffer muß ein Zeichen größer sein, als die tatsächliche länge
; hierfür ist immer in die Scintilla Documentation zu sehen. ( Manchmal hilft auch probieren ;) )
; le tampon doit avoir un caractère plus grand que la longueur réelle
; Cela est toujours visible dans la documentation Scintilla. (Parfois, il est utile d'essayer;))length = ScintillaSendMessage(ID, #SCI_GETLENGTH) + 1
length = ScintillaSendMessage(ID, #SCI_GETLENGTH) + 1
buffer = Space(length)
ScintillaSendMessage(ID, #SCI_GETTEXT, length, @buffer)
ProcedureReturn PeekS(@buffer, -1, SCI_GetTextFormat(ID))
EndProcedure
ProcedureDLL SCI_SetGadgetText(ID, Text.s)
Protected Buffer.s
; Wir erzeugen einen Stringbuffer in der größte, wie das
; Scintilla in bei der momentan eingestellten Codepage benötigt!
Buffer = Space(StringByteLength(Text, SCI_GetTextFormat(ID)))
PokeS(@Buffer, Text, -1, SCI_GetTextFormat(ID))
ProcedureReturn ScintillaSendMessage(ID, #SCI_SETTEXT, 0, @Buffer)
EndProcedure
ProcedureDLL SCI_GetGadgetAttribute(ID, Attribute)
Select Attribute
Case #PB_Editor_ReadOnly
ProcedureReturn ScintillaSendMessage(ID, #SCI_GETREADONLY)
EndSelect
EndProcedure
ProcedureDLL SCI_SetGadgetAttribute(ID, Attribute, Value)
Select Attribute
Case #PB_Editor_ReadOnly
ProcedureReturn ScintillaSendMessage(ID, #SCI_SETREADONLY, Value)
EndSelect
EndProcedure
ProcedureDLL SCI_GetGadgetColor(ID, Type)
Select Type
Case #PB_Gadget_FrontColor
ProcedureReturn ScintillaSendMessage(ID, #SCI_STYLEGETFORE, #STYLE_DEFAULT)
Case #PB_Gadget_BackColor
ProcedureReturn ScintillaSendMessage(ID, #SCI_STYLEGETBACK, #STYLE_DEFAULT)
EndSelect
EndProcedure
ProcedureDLL SCI_SetGadgetColor(ID, Type, Color)
Select Type
Case #PB_Gadget_FrontColor
ScintillaSendMessage(ID, #SCI_STYLESETFORE, #STYLE_DEFAULT, Color)
ScintillaSendMessage(ID, #SCI_STYLECLEARALL)
Case #PB_Gadget_BackColor
ScintillaSendMessage(ID, #SCI_STYLESETBACK, #STYLE_DEFAULT, Color)
ScintillaSendMessage(ID, #SCI_STYLECLEARALL)
EndSelect
EndProcedure
ProcedureDLL SCI_SetGadgetFont(ID, FontName.s, Size)
Protected Buffer.s
Buffer = Space(StringByteLength(FontName, SCI_GetTextFormat(ID)))
PokeS(@Buffer, FontName, -1, SCI_GetTextFormat(ID))
ScintillaSendMessage(ID, #SCI_STYLESETFONT, #STYLE_DEFAULT, @Buffer)
ScintillaSendMessage(ID, #SCI_STYLESETSIZE, #STYLE_DEFAULT, Size)
ScintillaSendMessage(ID, #SCI_STYLECLEARALL)
EndProcedure
ProcedureDLL SCI_LoadFile(ID, FileName.s)
Protected FF, Format, length, *mem, Text.s
FF = ReadFile(#PB_Any, FileName)
If FF
Select ReadStringFormat(FF)
; hier wird das StringFormat ermittelt und entsprechend gleich die Codepage eingestellt
Case #PB_Unicode
Format = #PB_Unicode
ScintillaSendMessage(ID, #SCI_SETCODEPAGE, 65001)
Case #PB_UTF8
Format = #PB_UTF8
ScintillaSendMessage(ID, #SCI_SETCODEPAGE, #SC_CP_UTF8)
Default
Format = #PB_Ascii
ScintillaSendMessage(ID, #SCI_SETCODEPAGE, 0)
EndSelect
length = Lof(FF)
If length
*mem = AllocateMemory(length)
If *mem
ReadData(FF, *mem, length)
Text = PeekS(*mem, length, Format)
SCI_SetGadgetText(ID, Text.s)
FreeMemory(*mem)
CloseFile(FF)
ProcedureReturn #True
EndIf
EndIf
CloseFile(FF)
EndIf
EndProcedure
ProcedureDLL SCI_SaveFile(ID, FileName.s)
Protected length, *mem, FF
FF = CreateFile(#PB_Any, FileName.s)
If FF
; jetzt schreiben wir den BOM
WriteStringFormat(FF, SCI_GetTextFormat(ID))
length = ScintillaSendMessage(ID, #SCI_GETLENGTH) + 1
*mem = AllocateMemory(length)
; jetzt holen wir den Text in den Speicher,
; wo er auch in dem Format vorliegt, das wir schreiben wollen.
ScintillaSendMessage(ID, #SCI_GETTEXT, length, *mem)
WriteData(FF, *mem, length - 1); der Speicher mußte ein Byte größer sein, aber schreiben wollen wir das nicht ;)
CloseFile(FF)
FreeMemory(*mem)
ProcedureReturn #True
EndIf
EndProcedure