Syntax Highlighting im EditorGadget???

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Syntax Highlighting im EditorGadget???

Beitrag 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
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Re: Syntax Highlighting im EditorGadget???

Beitrag 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
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Syntax Highlighting im EditorGadget???

Beitrag von edel »

Also hier im Forum gibt es recht viele Infos zum Thema Scintilla, einfach mal suchen. 8)
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Re: Syntax Highlighting im EditorGadget???

Beitrag 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
es_91
Beiträge: 383
Registriert: 25.01.2011 04:48

Re: Syntax Highlighting im EditorGadget???

Beitrag 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).
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Re: Syntax Highlighting im EditorGadget???

Beitrag von lite »

Hallo

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

Grüße
Lite
--
es_91
Beiträge: 383
Registriert: 25.01.2011 04:48

Re: Syntax Highlighting im EditorGadget???

Beitrag 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
oc42
Beiträge: 3
Registriert: 28.01.2017 22:35

Re: Syntax Highlighting im EditorGadget???

Beitrag von oc42 »

[removed post - not needed anymore]

Very nice code. Danke!
oc42
Beiträge: 3
Registriert: 28.01.2017 22:35

Re: Syntax Highlighting im EditorGadget???

Beitrag 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)
oc42
Beiträge: 3
Registriert: 28.01.2017 22:35

Re: Syntax Highlighting im EditorGadget???

Beitrag von oc42 »

Wie konnen wir diesen code optimieren?
Antworten