Seite 1 von 2

Scintilla-Editor in Panelgadget

Verfasst: 15.12.2006 09:07
von John Doe
Hallo an alle,
ich wollte in ein Panelgadget mehrere Scintilla-Editoren einbauen.Nun hab ich aber Probleme mit den Callbacks. Wenn ich den Editor nicht in ein Panelgadget setze, funktioniert alles; sobald er im Panelgadget sitzt, klappt der Callback nicht mehr. Ich raff das alles noch nicht und bitte um Hilfe.

Code: Alles auswählen

#SCI_GETCHARAT = 2007
#SCI_GETCURRENTPOS = 2008
#SCI_GETANCHOR = 2009
#SCI_GOTOLINE = 2024
#SCI_GOTOPOS = 2025
#SCI_SETANCHOR = 2026
#SCI_GETENDSTYLED = 2028
#SCI_STARTSTYLING = 2032
#SCI_SETSTYLING = 2033
#SCI_MARKERDEFINE = 2040
#SCI_MARKERSETFORE = 2041
#SCI_MARKERSETBACK = 2042
#SCI_STYLESETSIZE = 2055
#SCI_STYLESETFONT = 2056
#SCI_STYLECLEARALL = 2050
#SCI_STYLESETFORE = 2051
#SCI_STYLESETBOLD = 2053
#SCI_STYLESETITALIC = 2054
#SCI_GETLENGTH = 2006
#SCI_SETSEL = 2160
#SCI_LINEFROMPOSITION = 2166
#SCI_POSITIONFROMLINE = 2167
#SCI_SETTEXT = 2181
#SCI_GETTEXT = 2182
#SCI_GETDIRECTPOINTER = 2185
#SCI_SETCARETLINEVISIBLE = 2096
#SCI_SETCARETLINEBACK = 2098
#SCI_SETFOLDLEVEL = 2222
#SCI_GETFOLDLEVEL = 2223
#SCI_SETMARGINTYPEN = 2240
#SCI_APPENDTEXT = 2282
#SCI_TOGGLEFOLD = 2231
#SCI_SETMARGINWIDTHN = 2242
#SCI_SETMARGINMASKN = 2244
#SCI_SETMARGINSENSITIVEN = 2246
#SCI_SEARCHANCHOR = 2366
#SCI_SEARCHNEXT = 2367
#SCI_SETLEXER = 4001

#SC_MARGIN_NUMBER = 1
#SC_FOLDLEVELBASE = $400
#SC_FOLDLEVELHEADERFLAG = $2000
#SC_MASK_FOLDERS = $FE000000

#STYLE_DEFAULT = 32

#SCLEX_CONTAINER = 0
#SCLEX_PUREBASIC = 67

#SC_MARK_CIRCLE = 0
#SC_MARK_ROUNDRECT = 1
#SC_MARK_ARROW = 2
#SC_MARK_SMALLRECT = 3
#SC_MARK_SHORTARROW = 4
#SC_MARK_EMPTY = 5
#SC_MARK_ARROWDOWN = 6
#SC_MARK_MINUS = 7
#SC_MARK_PLUS = 8
#SC_MARK_VLINE = 9
#SC_MARK_LCORNER = 10
#SC_MARK_TCORNER = 11
#SC_MARK_BOXPLUS = 12
#SC_MARK_BOXPLUSCONNECTED = 13
#SC_MARK_BOXMINUS = 14
#SC_MARK_BOXMINUSCONNECTED = 15
#SC_MARK_LCORNERCURVE = 16
#SC_MARK_TCORNERCURVE = 17
#SC_MARK_CIRCLEPLUS = 18
#SC_MARK_CIRCLEPLUSCONNECTED = 19
#SC_MARK_CIRCLEMINUS = 20
#SC_MARK_CIRCLEMINUSCONNECTED = 21
#SC_MARK_BACKGROUND = 22
#SC_MARK_DOTDOTDOT = 23
#SC_MARK_ARROWS = 24
#SC_MARK_PIXMAP = 25
#SC_MARK_FULLRECT = 26
#SC_MARK_CHARACTER = 10000

#SC_MARKNUM_FOLDEREND = 25
#SC_MARKNUM_FOLDEROPENMID = 26
#SC_MARKNUM_FOLDERMIDTAIL = 27
#SC_MARKNUM_FOLDERTAIL = 28
#SC_MARKNUM_FOLDERSUB = 29
#SC_MARKNUM_FOLDER = 30
#SC_MARKNUM_FOLDEROPEN = 31

#SCN_STYLENEEDED = 2000
#SCN_CHARADDED = 2001
#SCN_SAVEPOINTREACHED = 2002
#SCN_SAVEPOINTLEFT = 2003
#SCN_MODIFYATTEMPTRO = 2004
#SCN_KEY = 2005
#SCN_DOUBLECLICK = 2006
#SCN_UPDATEUI = 2007
#SCN_MODIFIED = 2008
#SCN_MACRORECORD = 2009
#SCN_MARGINCLICK = 2010
#SCN_NEEDSHOWN = 2011
#SCN_PAINTED = 2013
#SCN_USERLISTSELECTION = 2014
#SCN_URIDROPPED = 2015
#SCN_DWELLSTART = 2016
#SCN_DWELLEND = 2017
#SCN_ZOOM = 2018
#SCN_HOTSPOTCLICK = 2019
#SCN_HOTSPOTDOUBLECLICK = 2020
#SCN_CALLTIPCLICK = 2021
#SCN_AUTOCSELECTION = 2022

#INDICS_MASK = $E0

Structure NotifyHeader
    *hwndFrom.l
    idFrom.l
    code.l
EndStructure

Structure SCNotification
    nmhdr.NotifyHeader
    position.l
    ch.l
    modifiers.l
    modificationType.l
    *text.l
    length.l
    linesAdded.l
    message.l
    wParam.l
    lParam.l
    line.l
    foldLevelNow.l
    foldLevelPrev.l
    margin.l
    listType.l
    x.l
    y.l
EndStructure

Enumeration 0
    #LexerState_Space
    #LexerState_Comment
    #LexerState_Keyword
    #LexerState_FoldKeyword
    #MainWin
    #Editor1
    #Editor2
    #Panel
EndEnumeration

Prototype.l ScintillaDirect(sciptr.l, msg.l, param1.l = 0, param2.l = 0)
Global Scintilla.ScintillaDirect, sciptr.l
Global scihWnd1.l, oldproc.l

Procedure LoadFile()
    filename.s = OpenFileRequester("Open a file...", "", "PureBasic (*.pb)|*.pb|All files (*.*)|*.*", 0)
    If filename <> ""
        file.l = ReadFile(#PB_Any, filename)
        If file <> 0
            len.l = Lof(file)
            *mem = AllocateMemory(len)
            If *mem
                ReadData(file, *mem, len)
                Scintilla(sciptr, #SCI_SETTEXT, 0, *mem)
                FreeMemory(*mem)
            EndIf
            CloseFile(file)
        EndIf
    EndIf
EndProcedure

Procedure SaveFile()
    filename.s = SaveFileRequester("Save a file...", "", "PureBasic (*.pb)|*.pb|All files (*.*)|*.*", 0)
    If filename <> ""
        file.l = CreateFile(#PB_Any, filename)
        If file <> 0
            len.l = Scintilla(sciptr, #SCI_GETLENGTH) + 1
            *mem = AllocateMemory(len)
            If *mem
                Scintilla(sciptr, #SCI_GETTEXT, len, *mem)
                WriteData(file, *mem, len)
                FreeMemory(*mem)
            EndIf
            CloseFile(file)
        EndIf
    EndIf
EndProcedure

Procedure FindText()
    text.s = InputRequester("Scintilla test", "Enter text to search for", "")
    If text <> ""
        current.l = Scintilla(sciptr, #SCI_GETCURRENTPOS)
        Scintilla(sciptr, #SCI_SETANCHOR, current)
        Scintilla(sciptr, #SCI_SEARCHANCHOR)
        start.l = Scintilla(sciptr, #SCI_SEARCHNEXT, 0, @text)
        If pos <> -1
            anchor.l = Scintilla(sciptr, #SCI_GETANCHOR)
            Scintilla(sciptr, #SCI_SETSEL, start, anchor)
        EndIf
    EndIf
    SetFocus_(scihWnd1)
EndProcedure

Procedure GotoLine()
    line.s = InputRequester("Scintilla test", "Enter line to go to", "1")
    lineno.l = Val(line)
    If lineno > 0
        Scintilla(sciptr, #SCI_GOTOLINE, lineno - 1)
    EndIf
    SetFocus_(scihWnd1)
EndProcedure

Procedure ToggleCurrentFold()
    pos.l = Scintilla(sciptr, #SCI_GETCURRENTPOS)
    line.l = Scintilla(sciptr, #SCI_LINEFROMPOSITION, pos)
    Scintilla(sciptr, #SCI_TOGGLEFOLD, line)
EndProcedure

Procedure Highlight(sciptr.l, startpos.l, endpos.l)
;     Debug(sciptr)
    If startpos = -1
        endstyled.l = Scintilla(sciptr, #SCI_GETENDSTYLED)
        linenumber.l = Scintilla(sciptr, #SCI_LINEFROMPOSITION, endstyled)
    Else
        linenumber = Scintilla(sciptr, #SCI_LINEFROMPOSITION, startpos)
    EndIf
   
    If linenumber = 0
        level = #SC_FOLDLEVELBASE
    Else
        linenumber - 1
        level = Scintilla(sciptr, #SCI_GETFOLDLEVEL, linenumber) & ~ #SC_FOLDLEVELHEADERFLAG
    EndIf
   
    thislevel.l = level
    nextlevel.l = level
   
    currentpos.l = Scintilla(sciptr, #SCI_POSITIONFROMLINE, linenumber)
    Scintilla(sciptr, #SCI_STARTSTYLING, currentpos, $1f | #INDICS_MASK)
    state = #LexerState_Space
    startkeyword = currentpos
    keyword.s = ""
   
    While currentpos <= endpos
        oldstate = state
        char.l = Scintilla(sciptr, #SCI_GETCHARAT, currentpos)
        If char = ';'
            state = #LexerState_Comment
        ElseIf char = 10 Or char = 13
            state = #LexerState_Space
        ElseIf state <> #LexerState_Comment
            If char = 9 Or char = ' ' Or char = '.'
                state = #LexerState_Space
            Else
                state = #LexerState_Keyword
                keyword + Chr(char)
            EndIf
        EndIf
        If oldstate <> state Or currentpos = endpos
            If oldstate = #LexerState_Keyword
                lkeyword.s = LCase(keyword)
                If lkeyword = "procedure"
                    thislevel | #SC_FOLDLEVELHEADERFLAG
                    nextlevel + 1
                    oldstate = #LexerState_FoldKeyword
                ElseIf lkeyword = "endprocedure"
                    nextlevel - 1
                    If nextlevel < #SC_FOLDLEVELBASE
                        nextlevel = #SC_FOLDLEVELBASE
                    EndIf
                    oldstate = #LexerState_FoldKeyword
                EndIf
                keyword = ""
            EndIf
            Scintilla(sciptr, #SCI_SETSTYLING, currentpos - startkeyword, oldstate)
            startkeyword = currentpos
        EndIf
       
        If char = 10 Or currentpos = endpos
            Scintilla(sciptr, #SCI_SETFOLDLEVEL, linenumber, thislevel)
            thislevel = nextlevel
            linenumber + 1
        EndIf
       
        currentpos + 1
    Wend
EndProcedure

Procedure ScintillaWindowCallback(hWnd.l, Msg.l, wParam.l, lParam.l)
    result.l = 0
    Select Msg
        Case #WM_NOTIFY
            *lpnmhdr.NMHDR = lParam
            *notify.SCNotification = lParam
            Select *lpnmhdr\code
                Case #SCN_STYLENEEDED
                    Highlight(sciptr, -1, *notify\position)
                Case #SCN_MARGINCLICK
                    modifiers = *notify\modifiers
                    position = *notify\position
                    margin = *notify\margin
                    linenumber = Scintilla(sciptr, #SCI_LINEFROMPOSITION, position)
                    Select margin
                        Case 2
                            Scintilla(sciptr, #SCI_TOGGLEFOLD, linenumber)
                    EndSelect
            EndSelect
        Default
            result = CallWindowProc_(oldproc, hWnd, Msg, wParam, lParam)
    EndSelect
    ProcedureReturn result
EndProcedure

file.s = "scilexer.dll"

scihmod = OpenLibrary(#PB_Any, "SciLexer.dll")
If scihmod = 0
    MessageRequester("Error", "Cannot open SciLexer.dll")
    End
EndIf

OpenWindow(#MainWin, 0, 0,1000, 700, "Scintilla example", #PB_Window_SystemMenu)

CreateMenu(0, WindowID(#MainWin))
MenuTitle("File")
MenuItem(1, "Open...")
MenuItem(2, "Save As...")
MenuItem(3, "Quit")
MenuTitle("Edit")
MenuItem(4, "Find...")
MenuItem(5, "Goto...")
MenuItem(6, "Toggle current fold")

GetClientRect_(WindowID(#MainWin), rect.RECT)
If CreateGadgetList(WindowID(#MainWin))
	PanelGadget(#Panel,0,0,WindowWidth(#MainWin),WindowHeight(#MainWin))

	AddGadgetItem(#Panel,-1,"Panel1")
	scihWnd1 = CreateGadget(#Editor1,"Scintilla","",#WS_CHILD | #WS_VISIBLE | #WS_TABSTOP, 0, 0, rect\right, rect\bottom,#WS_EX_CLIENTEDGE)

	AddGadgetItem(#Panel,-1,"Panel2")
; 	scihWnd2 = CreateGadget(#Editor2,"Scintilla","",#WS_CHILD | #WS_VISIBLE | #WS_TABSTOP, 0, 0, rect\right, rect\bottom,#WS_EX_CLIENTEDGE)
	CloseGadgetList() 
EndIf

Scintilla = GetFunction(scihmod, "Scintilla_DirectFunction")
sciptr = SendMessage_(scihWnd1,#SCI_GETDIRECTPOINTER,0,0)
; oldproc.l = SetWindowLong_(WindowID(#MainWin),#GWL_WNDPROC,@ScintillaWindowCallback())

; Choose a lexer
Scintilla(sciptr, #SCI_SETLEXER, #SCLEX_CONTAINER, 0)

; Set default font
Scintilla(sciptr, #SCI_STYLESETFONT, #STYLE_DEFAULT, @"Courier New")
Scintilla(sciptr, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 12)
Scintilla(sciptr, #SCI_STYLECLEARALL)

; Set caret line colour
Scintilla(sciptr, #SCI_SETCARETLINEBACK, $eeeeff)
Scintilla(sciptr, #SCI_SETCARETLINEVISIBLE, #True)

; Set styles for custom lexer
Scintilla(sciptr, #SCI_STYLESETFORE, #LexerState_Comment, $bb00)
Scintilla(sciptr, #SCI_STYLESETITALIC, #LexerState_Comment, 1)
Scintilla(sciptr, #SCI_STYLESETFORE, #LexerState_Keyword, 0)
Scintilla(sciptr, #SCI_STYLESETFORE, #LexerState_FoldKeyword, $ff)

; Margins
Scintilla(sciptr, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
Scintilla(sciptr, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS)
Scintilla(sciptr, #SCI_SETMARGINWIDTHN, 0, 50)
Scintilla(sciptr, #SCI_SETMARGINWIDTHN, 2, 20)
Scintilla(sciptr, #SCI_SETMARGINSENSITIVEN, 2, #True)

; Choose folding icons
Scintilla(sciptr, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEROPEN, #SC_MARK_CIRCLEMINUS)
Scintilla(sciptr, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDER, #SC_MARK_CIRCLEPLUS)
Scintilla(sciptr, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERSUB, #SC_MARK_VLINE)
Scintilla(sciptr, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERTAIL, #SC_MARK_LCORNERCURVE)
Scintilla(sciptr, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEREND, #SC_MARK_CIRCLEPLUSCONNECTED)
Scintilla(sciptr, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEROPENMID, #SC_MARK_CIRCLEMINUSCONNECTED)
Scintilla(sciptr, #SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERMIDTAIL, #SC_MARK_TCORNERCURVE)

; Choose folding icon colours
Scintilla(sciptr, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDER, $FFFFFF)
Scintilla(sciptr, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDER, 0)
Scintilla(sciptr, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDEROPEN, $FFFFFF)
Scintilla(sciptr, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDEROPEN, 0)
Scintilla(sciptr, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDEROPENMID, 0)
Scintilla(sciptr, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERSUB, 0)
Scintilla(sciptr, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERTAIL, 0)
Scintilla(sciptr, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERMIDTAIL, 0)

; Set some sample text
text.s = "A custom Scintilla lexer example" + #CRLF$
text + "Procedure hello()" + #CRLF$
text + "  Debug(" + Chr(34) + "Woo" + Chr(34) + ")" + #CRLF$
text + "EndProcedure"
SetGadgetText(#Editor1,text)

RemoveKeyboardShortcut(#MainWin, #PB_Shortcut_Tab)
RemoveKeyboardShortcut(#MainWin, #PB_Shortcut_Tab | #PB_Shortcut_Shift)

quit.l = #False
Repeat
    event.l = WaitWindowEvent()
    Select event
        Case #PB_Event_CloseWindow
            quit = #True
        Case #PB_Event_Menu
            Select EventMenu()
                Case 1 : LoadFile()
                Case 2 : SaveFile()
                Case 3 : quit = #True
                Case 4 : FindText()
                Case 5 : GotoLine()
                Case 6 : ToggleCurrentFold()
            EndSelect
    EndSelect
Until quit

DestroyWindow_(scihWnd1)
CloseLibrary(scihmod)

Verfasst: 15.12.2006 09:21
von ts-soft
Der obige Code ist nur für ein Scintilla ausgelegt, wären mehrere
Änderungen notwendig. Einfacher haste es, wenn Du die Scintilla-UserLib
nimmst, dort kannste das Scintilla wie jedes Gadget in ein Panel packen.

http://www.purebasic.fr/english/viewtop ... =scintilla

Verfasst: 15.12.2006 09:32
von John Doe
ich werd es mal probieren, muß die Lib zuerst installieren und das ganze dann ausprobieren. Werd mich auf jeden Fall melden.
Erstmal herzlichen Dank für den Link und die schnelle Antwort ...

Verfasst: 15.12.2006 10:03
von John Doe
Hallo ts-soft,
Genau das hatte ich gesucht - funktioniert einwandfrei
herzlichen Dank noch einmal
:allright: :allright: :allright: :allright:

Verfasst: 15.12.2006 10:17
von ts-soft
Freut mich ja dann mal :D (Edel bestimmt auch)

PS: Wenn Du Dein Projekt auf Linux umsetzen möchtest, kann ich Dir eine
dazu kompatible SciLexer.pbi zukommen lassen, so das der Code weitgehend
OS-Unabhängig ist. (In Linux ist ScintillaGadget bereits integriert)

Gruß
Thomas

Verfasst: 15.12.2006 11:43
von John Doe
vielen Dank, aber mit Linux kenne ich mich überhaupt nicht aus.
Ein Problem hab ich aber noch -
Files kleiner 64k kann ich problemlos in das Scintilla-Gadget laden, aber wie ist es mit größeren Files ?
Ich benutze diesen Code:

Code: Alles auswählen

Procedure Load(FileName.s,EditorID.l) 

  If FileName <> ""
    file.l = ReadFile(#PB_Any,FileName)
    If file
      FileLen.l = Lof(file)
     *mem = AllocateMemory(FileLen)
      If *mem
        ReadData(file, *mem,FileLen)
        SCI_SetText(EditorID, *mem)
        FreeMemory(*mem)
      EndIf
      CloseFile(file)
    EndIf
  EndIf

EndProcedure
Als FileLen bringt er immer Null, somit klappt das Laden nicht.
wie kann ich das bewerkstelligen ?

Verfasst: 15.12.2006 11:54
von ts-soft
Hier mal ein kleines Beispiel, das es für linux ist, einfach ignorieren, die
entscheidende Funktion kannste übernehmen :wink:

Code: Alles auswählen

XIncludeFile "scilexer.pbi"

If OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If CreateGadgetList(WindowID(0))
    ScintillaGadget(0, 0, 0, 640, 480, 0, 0)
  EndIf
EndIf

File = ReadFile(#PB_Any, "/usr/share/doc/packages/fuse/ChangeLog")
If File
  Size = Lof(File)
  Mem = AllocateMemory(Size)
  If Mem
    ReadData(File, Mem, Size)
    SCI_SetText(0, Mem)
    FreeMemory(Mem)
  EndIf
  CloseFile(File)
EndIf

SetActiveGadget(0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver
Gruß
Thomas

// Edit
Dein Source ist okay, so, FileLen darf nicht 0 sein, der Fehler liegt woanders.

Verfasst: 15.12.2006 12:01
von John Doe
ich kann machen, was ich will, es klappt nicht.
FileLen ist immer noch null ...
Dann muß ich mal genau durchsehen, wo der Fehler liegt
vielen Dank vorerst mal ...

Verfasst: 15.12.2006 12:05
von ts-soft
Ansonsten mal PB updaten, falls Deine Version nicht aktuell ist. Evtl, Beta
Libs draufmachen.

Verfasst: 15.12.2006 12:08
von John Doe
Das 4.01-Update hab ich schon drauf, wo bekomm ich die Beta-Libs her ?