Seite 2 von 2

Re: Syntax Highlighting im EditorGadget???

Verfasst: 22.08.2016 20:35
von edel
Oh mein Gott... Was hast du denn da ausgegraben?!

wenn es denn unbedingt sein muss... heute wuerde ich aber lieber scintilla oder sowas nehmen. :lol:

Code: Alles auswählen

  ; PB V4.0keine_ahnung

  Prototype PrevProc(hwnd,uMsg,wParam,lParam)
  Define PrevEditProc.PrevProc = 0
  Define hwnd
  Define hEdit
  Define i
  Define event
 
  Macro DrawWord(word,color)
   
    If Not CompareMemoryString(*ptr_char,@word,#PB_String_NoCase,Len(word)) ;  wort vergleichen
      SetTextColor_(hdc,color)                                              ; farbe setzen
      SendMessage_(hwnd, #EM_POSFROMCHAR, @rect, first_index + ((*ptr_char - @Buffer)/SizeOf(character))) ; aktuelle Position des Chars holen      
      DrawText_(hdc,*ptr_char,Len(word), rect, 0) ; und strng ueber den alten malen
    EndIf
   
  EndMacro
 
  Procedure EditCallback(hwnd,uMsg,wParam,lParam)
    Shared PrevEditProc.PrevProc
   
    Protected Buffer.s
    Protected first_index.l
    Protected last_index.l
    Protected rect.RECT
    Protected TextRange.TEXTRANGE
    Protected *ptr_char.Character
    Protected hdc.l , hreg.l
    Protected hFont.l = GetStockObject_(#DEFAULT_GUI_FONT)
    Protected result
   
    ; WM_PAINT abfangen
    If uMsg = #WM_PAINT
      
      ; alten Calback aufrufen um alles zu zeichnen
      result = PrevEditProc(hwnd,uMsg,wParam,lParam)
     
      SendMessage_(hwnd,#EM_GETRECT,0,@rect)
     
      ; Charakter index des ersten und letzten Zeichens auslesen.
      first_index = SendMessage_(hwnd,#EM_CHARFROMPOS,0,rect)
      last_index  = SendMessage_(hwnd,#EM_CHARFROMPOS,0,@rect\right)
            
      If (last_index-first_index) > 0 ; mehr als 0 Zeichen
       
        Buffer = Space(last_index-first_index) ; PB String genug speicher geben
       
        TextRange\chrg\cpMin = first_index     
        TextRange\chrg\cpMax = last_index
        TextRange\lpstrText  = @Buffer
       
        SendMessage_(hwnd,#EM_GETTEXTRANGE,0,TextRange) ; Text in buffer schreiben lassen
       
        hdc = GetDC_(hwnd)
       
        hreg = CreateRectRgn_(rect\left,rect\top,rect\right,rect\bottom) ; eine Region erstellen
       
        SelectObject_(hdc,hreg)      ; Region zuweisen
        SetBkMode_(hdc,#TRANSPARENT) ; hintergrund auf transparent setzen
        SelectObject_(hdc,hFont)     ; !Wichtig , Font setzen
                                     ; Es muss der gleiche Font sein, inc. Eigenschaften
                                     ; er darf weder breiter noch groesser sein, als der normale Font.       
        *ptr_char = @Buffer
       
        While *ptr_char\c
          
          DrawWord("hallo",$0000FF) ; Achtung Macro ! 
          DrawWord("du",$FF0000)    ; Achtung Macro ! 
          DrawWord("da",$008000)    ; Achtung Macro !
          
          *ptr_char + SizeOf(Character)
        Wend
       
        DeleteObject_(hreg) ; region wieder loeschen
        ReleaseDC_(hwnd,hdc)
       
      EndIf
      ; und raus hier
      ProcedureReturn result
    EndIf
   
    ; sonstige Nachrichten an den alten Callback weiterleiten
    ProcedureReturn PrevEditProc(hwnd,uMsg,wParam,lParam)
  EndProcedure
 
  hwnd = OpenWindow(0,0,0,500,500,"TEST")
  
  hEdit = EditorGadget(0,0,0,500,500)
 
  PrevEditProc = SetWindowLong_(hEdit,#GWL_WNDPROC,@EditCallback())
 
  For i = 0 To 1000
    AddGadgetItem(0,i,"  Hallo du da")
  Next
 
  Repeat
    event = WaitWindowEvent()
  Until event = #PB_Event_CloseWindow

Re: Syntax Highlighting im EditorGadget???

Verfasst: 25.08.2016 19:22
von lite
@Edel

Danke fürs konvertieren.
Ja, war auch schwer zu finden. :roll:

Momentan bin ich neu mit dem Thema.
Ich weiß gar nicht welche Methode besser ist.
API+Rich oder Scintilla.
Zu beiden Themen gibt es relativ wenig Infos.
Hast du ein fertiges Syntax Highlighting mit API umgesetzt ?

Grüße
Lite

Re: Syntax Highlighting im EditorGadget???

Verfasst: 25.08.2016 20:00
von edel
Also hier im Forum gibt es recht viele Infos zum Thema Scintilla, einfach mal suchen. 8)

Re: Syntax Highlighting im EditorGadget???

Verfasst: 09.09.2016 10:12
von lite
Hallo

Ein paar Tests mit den Beispielode ergaben, daß

Code: Alles auswählen

first_index = SendMessage_(hwnd,#EM_CHARFROMPOS,0,rect)
nicht richtig arbeitet. Bei verschieben des Scrollbalkens wird das erste lange Wort
erst wieder eingefärbt, wen er Scrollbalken ganz links ist. Die Funktion nimmt nur die Zeichen des sichtbaren Bereich. Richtig wäre die Zeichen von Zeilenanfang.
Gibts dafür eine Lösung ?

Code: Alles auswählen

  ; PB V4.0keine_ahnung

  Prototype PrevProc(hwnd,uMsg,wParam,lParam)
  Define PrevEditProc.PrevProc = 0
  Define hwnd
  Define hEdit
  Define i
  Define event
 
  Macro DrawWord(word,color)
   
    If Not CompareMemoryString(*ptr_char,@word,#PB_String_NoCase,Len(word)) ;  wort vergleichen
      SetTextColor_(hdc,color)                                              ; farbe setzen
      SendMessage_(hwnd, #EM_POSFROMCHAR, @rect, first_index + ((*ptr_char - @Buffer)/SizeOf(character))) ; aktuelle Position des Chars holen     
      DrawText_(hdc,*ptr_char,Len(word), rect, 0) ; und strng ueber den alten malen
    EndIf
   
  EndMacro
 
  Procedure EditCallback(hwnd,uMsg,wParam,lParam)
    Shared PrevEditProc.PrevProc
   
    Protected Buffer.s
    Protected first_index.l
    Protected last_index.l
    Protected rect.RECT
    Protected TextRange.TEXTRANGE
    Protected *ptr_char.Character
    Protected hdc.l , hreg.l
    Protected hFont.l = GetStockObject_(#DEFAULT_GUI_FONT)
    Protected result
   
    ; WM_PAINT abfangen
    If uMsg = #WM_PAINT
     
      ; alten Calback aufrufen um alles zu zeichnen
      result = PrevEditProc(hwnd,uMsg,wParam,lParam)
     
      SendMessage_(hwnd,#EM_GETRECT,0,@rect)
     
      ; Charakter index des ersten und letzten Zeichens auslesen.
      first_index = SendMessage_(hwnd,#EM_CHARFROMPOS,0,rect)
      last_index  = SendMessage_(hwnd,#EM_CHARFROMPOS,0,@rect\right)
           
      If (last_index-first_index) > 0 ; mehr als 0 Zeichen
       
        Buffer = Space(last_index-first_index) ; PB String genug speicher geben
       
        TextRange\chrg\cpMin = first_index     
        TextRange\chrg\cpMax = last_index
        TextRange\lpstrText  = @Buffer
       
        SendMessage_(hwnd,#EM_GETTEXTRANGE,0,TextRange) ; Text in buffer schreiben lassen
       
        hdc = GetDC_(hwnd)
       
        hreg = CreateRectRgn_(rect\left,rect\top,rect\right,rect\bottom) ; eine Region erstellen
       
        SelectObject_(hdc,hreg)      ; Region zuweisen
        SetBkMode_(hdc,#TRANSPARENT) ; hintergrund auf transparent setzen
        SelectObject_(hdc,hFont)     ; !Wichtig , Font setzen
                                     ; Es muss der gleiche Font sein, inc. Eigenschaften
                                     ; er darf weder breiter noch groesser sein, als der normale Font.       
        *ptr_char = @Buffer
       
        While *ptr_char\c
         
          DrawWord("einlaaaaaaaaaaangeswort",$0000FF) ; Achtung Macro !
          DrawWord("hallo",$FF0000)    ; Achtung Macro !
          DrawWord("du",$008000)    ; Achtung Macro !
         
          *ptr_char + SizeOf(Character)
        Wend
       
        DeleteObject_(hreg) ; region wieder loeschen
        ReleaseDC_(hwnd,hdc)
       
      EndIf
      ; und raus hier
      ProcedureReturn result
    EndIf
   
    ; sonstige Nachrichten an den alten Callback weiterleiten
    ProcedureReturn PrevEditProc(hwnd,uMsg,wParam,lParam)
  EndProcedure
 
  hwnd = OpenWindow(0,0,0,500,500,"TEST")
 
  hEdit = EditorGadget(0,0,0,500,500)
 SendMessage_(hEdit, #EM_LIMITTEXT, -1, 0) 
  PrevEditProc = SetWindowLong_(hEdit,#GWL_WNDPROC,@EditCallback())
 
  For i = 0 To 0
    AddGadgetItem(0,i,"einlaaaaaaaaaaangeswort mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm einlaaaaaaaaaaangeswort")
  Next
 
  Repeat
    event = WaitWindowEvent()
  Until event = #PB_Event_CloseWindow

Re: Syntax Highlighting im EditorGadget???

Verfasst: 10.09.2016 03:26
von es_91
Warum machst Du/macht Ihr das nicht mit Messages wie EM_SETCHARFORMAT, wozu drüberzeichnen? Klar spart das Zeit, aber keinen Aufwand...

#EM_SETCHARFORMAT mit #SCF_SELECTION und die Selektion über den Bildausschnitt iterieren lassen (#EM_SETSEL und #EM_POSFROMCHAR).

Re: Syntax Highlighting im EditorGadget???

Verfasst: 10.09.2016 17:20
von lite
Hallo

Danke für den Hinweis. Hast Du ein Beispiel dafür ?

Grüße
Lite
--

Re: Syntax Highlighting im EditorGadget???

Verfasst: 24.09.2016 11:48
von es_91
lite,

es ist zwar schon eine ganze Zeit her, aber vielleicht besteht das alte Problem immernoch:

das CodeArchiv und die PB-Foren enthalten eine Menge Speicherungen, die dieses Thema so angehen wie von mir beschrieben.

Hier ein paar links:

http://www.purearea.net/pb/CodeArchiv/G ... +Styles.pb
http://www.purearea.net/pb/CodeArchiv/G ... oloring.pb
(^^ bestes Beispiel ... seit es den Datentyp Integer gibt muss .l mit .i ersetzt werden)
http://www.purearea.net/pb/CodeArchiv/G ... Styles2.pb

Prinzipiell kann dir das CodeArchiv bei API-Fragen stark weiterhefen.
Auch in den Foren tut sich eine Suche nach einigen Konstanten wie #EM_GETSEL oder #EM_SETCHARFORMAT gut.

Vielleicht ist Dein Problem ja schon längst gelöst.

Grüße

es_91

Re: Syntax Highlighting im EditorGadget???

Verfasst: 28.01.2017 22:44
von oc42
[removed post - not needed anymore]

Very nice code. Danke!

Re: Syntax Highlighting im EditorGadget???

Verfasst: 04.05.2017 21:56
von oc42
(Google Translate...)

Ich versuche, die unten Optimierung zu verwenden, um Flimmern zu beseitigen, aber es hat keine Wirkung.

(based on "optimization #1" in this article http://bcbjournal.org/articles/vol3/991 ... ghting.htm )

Weiß jemand was warum?

Danke!!

Code: Alles auswählen

SendMessage_(GadgetID(0), #WM_SETREDRAW, 0,0)
SendMessage_(GadgetID(0), #WM_SETREDRAW, 1,0)
InvalidateRect_(GadgetID(0), 0, #True)

Re: Syntax Highlighting im EditorGadget???

Verfasst: 16.06.2018 08:45
von oc42
Wie konnen wir diesen code optimieren?