Seite 1 von 2

Zeichen unter Cursor im EditorGadget

Verfasst: 03.02.2007 23:30
von Thorsten1867
Gibt es eine einfachere Möglichkeit (WinAPI) das Zeichen unter (bzw. links vom) Cursor im Editorgadget zu ermitteln?

Code: Alles auswählen

Procedure EditorGadgetCursorX(gadget) 
  ; returns X-Pos of Cursor 
  REG = GadgetID(gadget) 
  SendMessage_(REG,#EM_EXGETSEL,0,Range.CHARRANGE) 
  ProcedureReturn (Range\cpMax-(SendMessage_(REG,#EM_LINEINDEX,SendMessage_(REG,#EM_EXLINEFROMCHAR,0,Range\cpMin),0))+1) 
EndProcedure 

Procedure EditorGadgetCursorY(gadget) 
  ; returns Y-Pos of Cursor 
  REG = GadgetID(gadget) 
  SendMessage_(REG,#EM_EXGETSEL,0,Range.CHARRANGE) 
  ProcedureReturn SendMessage_(REG,#EM_EXLINEFROMCHAR,0,Range\cpMin)+1 
EndProcedure

Char$ = Mid(GetGadgetItemText(1, EditorGadgetCursorY(1)-1, #Null),EditorGadgetCursorX(1)-1,1)

Verfasst: 03.02.2007 23:43
von edel

Code: Alles auswählen

  Procedure.s noname(gadget)
    Protected ttr.TEXTRANGE
    Protected buffer.s = space(1) 
    
    ttr\lpstrText = @buffer
    REG = GadgetID(gadget)
    
    SendMessage_(REG,#EM_EXGETSEL,0,ttr\chrg)
    
    ttr\chrg\cpMin - 1
    
    SendMessage_(REG,#EM_GETTEXTRANGE,0,ttr)
    
    ProcedureReturn buffer
    
  EndProcedure 
  
  
  hwnd = OpenWindow(0,0,0,300,300,"")

  If CreateGadgetList(hwnd)
    hedit = EditorGadget(0,10,10,280,280)
  EndIf
  
  Repeat
    event = WaitWindowEvent()
    
    if event = #pb_event_gadget
      
      if eventgadget() = 0
        
        debug noname(0)
        
      EndIf
      
    endIf
    
  Until event = 16

Verfasst: 04.02.2007 00:07
von Thorsten1867
Super! Danke! Ich wusste doch das es einfacher geht, wenn man weiß wie. :D

Verfasst: 04.02.2007 00:25
von Thorsten1867
Es ist vollbracht. Einfügen von Text (an der Cursorposition) in ein Editorgadget. Wenn nötig werden davor und/oder danach Leerzeichen eingefügt.

Code: Alles auswählen

Procedure.s Editor_GetCursorChar(Gadget_ID, opt.b=0)
  ; opt = 0 -> Character left from the cursor
  ; opt = 1 -> Character right from the cursor
  Protected ttr.TEXTRANGE
  Protected Buffer.s = Space(1)
  ttr\lpstrText = @Buffer
  SendMessage_(GadgetID(Gadget_ID),#EM_EXGETSEL,0,ttr\chrg)
  If opt
    ttr\chrg\cpMax + 1
  Else
    ttr\chrg\cpMin - 1
  EndIf
  SendMessage_(GadgetID(Gadget_ID),#EM_GETTEXTRANGE,0,ttr\chrg)
  ProcedureReturn Buffer
EndProcedure

Procedure InsertEG(Gadget_ID, text$)
  ; Insert text with spaces (if needed) in EditorGadget
  text$ = Trim(text$)
  If Editor_GetCursorChar(Gadget_ID, 0) <> " "
    text$ = " " + text$
  EndIf
  If Editor_GetCursorChar(Gadget_ID, 1) <> " "
    text$ + " "
  EndIf
  SendMessage_(GadgetID(Gadget_ID), #EM_REPLACESEL, 0, text$) 
EndProcedure

Verfasst: 04.02.2007 00:38
von edel
ttr\chrg\cpMin - 1 mit ttr\chrg\cpMax + 1 ersetzen.

Verfasst: 04.02.2007 01:04
von Thorsten1867
Danke! Habe es nach dem Trial & Error gerade selber herausgefunden. (siehe oben)

Verfasst: 04.02.2007 01:16
von TomS
Hallo. Könnte man deinen Code so anpassen, dass er die ganze Zeile ermittelt oder den Ausdruck (getrennt von Leerzeichen oder Klammer)?

Ich möchte in einen eigenen editor eine Hilfefunktion, wie in der PB-IDE einbauen. F1 drücken und Hilfe zur Funktion bekommen, wo der Cursor steht.

Verfasst: 04.02.2007 02:11
von Thorsten1867
Vielleicht gibt es ja einen einfacheren Weg, aber ich würde es so machen:

Code: Alles auswählen

Procedure EGCursorLine(gadget) 
  SendMessage_(GadgetID(gadget),#EM_EXGETSEL,0,Range.CHARRANGE) 
  ProcedureReturn SendMessage_(REG,#EM_EXLINEFROMCHAR,0,Range\cpMin) 
EndProcedure

Procedure EGCursorCharPos(gadget) ; returns X-Pos of Cursor 
  REG = GadgetID(gadget) 
  SendMessage_(REG,#EM_EXGETSEL,0,Range.CHARRANGE) 
  ProcedureReturn (Range\cpMax-(SendMessage_(REG,#EM_LINEINDEX,SendMessage_(REG,#EM_EXLINEFROMCHAR,0,Range\cpMin),0))+1)
EndProcedure

Procedure.w GetWordStartPos(thText.s, thPos.w) ; Search position of first character from word
  If Mid(thText, thPos, 1) < "A" Or Mid(thText, thPos, 1) > "z" : ProcedureReturn thPos : EndIf
  Repeat
    thPos - 1
  Until Mid(thText, thPos, 1) = " " Or thPos <= 1
  If Mid(thText, thPos, 1) = " "
    ProcedureReturn thPos + 1
  Else
    ProcedureReturn 1
  EndIf
EndProcedure

Procedure.w GetWordEndPos(thText.s, thPos.w) ; Search position of last character from a word
  If Mid(thText, thPos, 1) < "A" Or Mid(thText, thPos, 1) > "z" : ProcedureReturn thPos : EndIf
  Repeat
    thPos + 1
  Until Asc(Mid(thText, thPos, 1)) < 65 Or Asc(Mid(thText, thPos, 1)) > 122 Or thPos >= Len(thText)
  If thPos <= Len(thText)
    ProcedureReturn thPos - 1 
  Else
    ProcedureReturn Len(thText)
  EndIf
EndProcedure

Procedure.s GetWord(text$, pos.w)
  wpos1.w = GetWordStartPos(text$, pos)
  ProcedureReturn Mid(text$, wpos1, GetWordEndPos(text$, pos) - wpos1 +1)
EndProcedure


hwnd = OpenWindow(0,0,0,300,300,"")

If CreateGadgetList(hwnd)
  hedit = EditorGadget(0,10,10,280,280)
EndIf
SetGadgetText(0, "Das ist ein Testtext.")
Repeat
  event = WaitWindowEvent()
  
  If event = #PB_Event_Gadget
    ; ......
  EndIf
  
  zeile$ = GetGadgetItemText(0,EGCursorLine(0),#Null)
  wort$ = GetWord(zeile$, EGCursorCharPos(0))
  SetWindowText_(WindowID(0), "Wort: " + wort$ + "  ("+Str(EGCursorCharPos(0))+")")
  
Until event = 16

Verfasst: 04.02.2007 02:47
von TomS
Das is ja cool. Danke sehr!!

Verfasst: 04.02.2007 04:46
von edel

Code: Alles auswählen

  Procedure.s getcurrblabla(gadget)
    Protected textr.TEXTRANGE 
    Protected *Bufptr.Character
    Protected *Gadget.long = IsGadget(gadget)
    
    Protected buffer.s
    Protected index.l
    Protected length.l 
    Protected start.l
    
    if *Gadget
      
      SendMessage_(*Gadget\l,#EM_EXGETSEL,0,textr)
      
      index     = SendMessage_(*Gadget\l,#EM_LINEINDEX,-1,0)
      length    = SendMessage_(*Gadget\l,#EM_LINELENGTH,textr\chrg\cpMax,0)
      
      if length
        
        currpos   = textr\chrg\cpMin
        buffer    = space(index + length)
        
        textr\chrg\cpMin = index
        textr\chrg\cpMax = index + length
        textr\lpstrText  = @buffer
        
        SendMessage_(*Gadget\l,#EM_GETTEXTRANGE,0,textr)
        
        *Bufptr = @buffer + (currpos - index - SizeOf(Character)) 
        
        Repeat 
          select *Bufptr\c
            case 'a' to 'z' , 'A' to 'Z' , '0' to '9' , '_'
              *Bufptr - SizeOf(Character) 
            default
              start = *Bufptr + SizeOf(Character)
              break
          EndSelect
        ForEver
        
        *Bufptr = @buffer + (currpos - index)
        
        Repeat 
          select *Bufptr\c
            case 'a' to 'z' , 'A' to 'Z' , '0' to '9' , '_'
              *Bufptr + SizeOf(Character)
            default
              *Bufptr\c = 0 
              break 
          EndSelect  
        ForEver
        
        buffer = peeks(start)
        
      endif 
      
    endif 
    
    ProcedureReturn buffer 
  EndProcedure