Zeichen unter Cursor im EditorGadget

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Zeichen unter Cursor im EditorGadget

Beitrag 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)
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag 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
Zuletzt geändert von edel am 04.02.2007 01:15, insgesamt 1-mal geändert.
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag von Thorsten1867 »

Super! Danke! Ich wusste doch das es einfacher geht, wenn man weiß wie. :D
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag 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
Zuletzt geändert von Thorsten1867 am 04.02.2007 01:03, insgesamt 2-mal geändert.
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

ttr\chrg\cpMin - 1 mit ttr\chrg\cpMax + 1 ersetzen.
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag von Thorsten1867 »

Danke! Habe es nach dem Trial & Error gerade selber herausgefunden. (siehe oben)
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag 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.
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag 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
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag von TomS »

Das is ja cool. Danke sehr!!
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag 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 
Antworten