EditorGadget text search not working

Just starting out? Need help? Post your questions and find answers here.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4749
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

EditorGadget text search not working

Post by Fangbeast »

Fairly certain this worked years ago and I am missing the obvious because I am tired but has anyone used this routine below and got it to work?

Code: Select all

; Find text strings inside an editorgadget

Procedure Editor_FindText(Gadget.i, TextToFind.s, ResetFlag.i)
  If Gadget.i <> 0
    If GadgetType(Gadget.i) = #PB_GadgetType_Editor
      Debug "EditorGadget being passed correctly"
      Debug TextToFind.s
    EndIf
  Else
    Debug "No editorgadget passed, what's going on??"
  EndIf
  editFind.FINDTEXT 
  ; Reset search to beginning
  SendMessage_(GadgetID(Gadget.i), #EM_SETSEL, 0, 0)
  ; For resetting to default text
  If ResetFlag.i
    SendMessage_(GadgetID(Gadget.i), #EM_SETCHARFORMAT, #SCF_ALL, defaultFormat)
  EndIf
  editFind\chrg\cpMin = 0
  editFind\lpstrText  = @TextToFind
  Repeat
    found.i = SendMessage_(GadgetID(Gadget.i), #EM_FINDTEXT, #FR_DOWN, editFind)
    If found.i > - 1
      editFind\chrg\cpMin = found.i + 1
      SendMessage_(GadgetID(Gadget.i), #EM_SETSEL, found.i, found.i + Len(TextToFind.s))               ; Set the selection to highlight
      format.CHARFORMAT
      format\cbSize     = SizeOf(CHARFORMAT)
      format\dwMask     = #CFM_ITALIC  | #CFM_BOLD      | #CFM_STRIKEOUT | #CFM_UNDERLINE
      format\dwEffects  = #CFM_BOLD    | #CFM_UNDERLINE
      SendMessage_(GadgetID(Gadget.i), #EM_SETCHARFORMAT, #SCF_SELECTION, @format)
    EndIf
  Until found.i = -1
  SendMessage_(GadgetID(Gadget.i), #EM_SETSEL, 0, 0)
EndProcedure

Editor_FindText(#MyGadget, "Bugger!", 1)
Amateur Radio, D-STAR/VK3HAF
infratec
Always Here
Always Here
Posts: 6886
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: EditorGadget text search not working

Post by infratec »

Hi,

try this:

Code: Select all

EnableExplicit


Global defaultFormat.CHARFORMAT

; Find text strings inside an editorgadget

Procedure Editor_FindText(Gadget.i, TextToFind.s, ResetFlag.i)
  
  Protected.i found
  Protected editFind.FINDTEXT, format.CHARFORMAT, Range.CHARRANGE
  
  
  If GadgetType(Gadget.i) = #PB_GadgetType_Editor
    Debug "EditorGadget being passed correctly"
    Debug TextToFind
  Else
    Debug "No editorgadget passed, what's going on??"
  EndIf
  
  ; Reset search to beginning
  SendMessage_(GadgetID(Gadget), #EM_SETSEL, 0, 0)
  ; For resetting to default text
  If ResetFlag
    SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_ALL, @defaultFormat)
  EndIf
  editFind\chrg\cpMin = 0
  editFind\chrg\cpMax = -1
  editFind\lpstrText  = @TextToFind
  Repeat
    found = SendMessage_(GadgetID(Gadget), #EM_FINDTEXT, #FR_DOWN, @editFind)
    If found > - 1
      editFind\chrg\cpMin = found + 1
      Range\cpMin = found
      Range\cpMax = found + Len(TextToFind)
      
      SendMessage_(GadgetID(Gadget), #EM_EXSETSEL, 0, @Range)               ; Set the selection to highlight
      
      format\cbSize     = SizeOf(CHARFORMAT)
      format\dwMask     = #CFM_ITALIC  | #CFM_BOLD      | #CFM_STRIKEOUT | #CFM_UNDERLINE
      format\dwEffects  = #CFM_BOLD    | #CFM_UNDERLINE
      SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format)
    EndIf
  Until found.i = -1
  SendMessage_(GadgetID(Gadget.i), #EM_SETSEL, 0, 0)
EndProcedure



Define.i Exit, Event

OpenWindow(0, 0, 0, 400, 400, "Editor", #PB_Window_SystemMenu)

EditorGadget(0, 10, 10, 380, 340)
ButtonGadget(1, 10, 360, 100, 20, "Search qwe")
ButtonGadget(2, 130, 360, 100, 20, "Search asd")


SendMessage_(GadgetID(0), #EM_GETCHARFORMAT, #SC_DEFAULT, defaultFormat)
defaultFormat\cbSize = SizeOf(CHARFORMAT)
defaultFormat\dwMask = #CFM_ITALIC  | #CFM_BOLD | #CFM_STRIKEOUT | #CFM_UNDERLINE

Repeat
  
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          Editor_FindText(0, "qwe", #True)
        Case 2
          Editor_FindText(0, "asd", #True)
      EndSelect
    Case #PB_Event_CloseWindow
      Exit = #True
  EndSelect
  
Until Exit
Bernd
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4667
Joined: Sun Apr 12, 2009 6:27 am

Re: EditorGadget text search not working

Post by RASHAD »

Hi Fangles
I do not think it will be much difference from infratec snippet :)

Code: Select all

Global Range.CHARRANGE ,PrevText$,_pfrom,_pto

Procedure Editor_Color(Gadget, Color.l)
 format.CHARFORMAT
 format\cbSize = SizeOf(CHARFORMAT)
 format\dwMask = #CFM_COLOR
 format\crTextColor = Color
 SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format)
EndProcedure

Procedure FindText(gad,Text$,_from,_to)
_pfrom = _from
_pto = _to
For row = _from To _to
 Count = CountString(GetGadgetItemText(gad,row), Text$) 
 For x = 1 To Count
    Pos = FindString(GetGadgetItemText(gad,row), Text$ ,Pos)
    Range\cpMin = Pos + Pos_2 - 1
    Range\cpMax = (Pos + Pos_2+Len(Text$) - 1)
    Pos + Len(Text$)
    SendMessage_(GadgetID(Gad),#EM_EXSETSEL,0,@Range)
    Editor_Color(Gad,RGB(255,0,0))
 Next
 Pos = 0
 Pos_2 = Pos_2 + Len(GetGadgetItemText(Gad,row))+1
Next
    Range\cpMin = 0
    Range\cpMax = 0
SendMessage_(GadgetID(Gad),#EM_EXSETSEL,0,@Range)
EndProcedure

Procedure ClearSelect()
For row = _pfrom To _pto
 Count = CountString(GetGadgetItemText(gad,row), PrevText$) 
 For x = 1 To Count
    Pos = FindString(GetGadgetItemText(gad,row), PrevText$ ,Pos)
    Range\cpMin = Pos + Pos_2 - 1
    Range\cpMax = (Pos + Pos_2+Len(PrevText$) - 1)
    Pos + Len(PrevText$)
    SendMessage_(GadgetID(Gad),#EM_EXSETSEL,0,@Range)
    Editor_Color(Gad,RGB(0,0,0))
 Next
 Pos = 0
 Pos_2 = Pos_2 + Len(GetGadgetItemText(Gad,row))+1
Next
    Range\cpMin = 0
    Range\cpMax = 0
SendMessage_(GadgetID(Gad),#EM_EXSETSEL,0,@Range)
EndProcedure

OpenWindow(0, 0, 0, 500, 500, "EditorGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
EditorGadget(0, 10, 10, 480, 450)
Range.CHARRANGE 
For i = 0 To 10 
 Text$ = "[Kcc] Hello" + Trim(Str(i)) + " [Kcc]"
 AddGadgetItem(0, i, Text$)
Next

StringGadget(1,10,470,200,20,"")
ButtonGadget(2,220,470,60,20,"Search")

Repeat
  Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
               Quit = 1
        Case #PB_Event_Gadget
               Select EventGadget()
                     Case 2
                           ClearSelect()
                           FindText(0,GetGadgetText(1),0,10)
                           PrevText$ = GetGadgetText(1)
               EndSelect
  EndSelect
Until Quit = 1
Egypt my love
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4749
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: EditorGadget text search not working

Post by Fangbeast »

Thanks RASHAD and InfraTec. I am working under Windows 10 evaluation and things are sometimes a little strange.

Mostly everything works but sometimes things are very strange. Leaky memory, missing icons, menus go black. Icons don't show for running apps, icons stay in the taskbar for apps NOT running etc.

But it's fun too.
Amateur Radio, D-STAR/VK3HAF
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4749
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: EditorGadget text search not working

Post by Fangbeast »

infratec wrote:Hi,

try this:

Code: Select all

EnableExplicit


Global defaultFormat.CHARFORMAT

; Find text strings inside an editorgadget

Procedure Editor_FindText(Gadget.i, TextToFind.s, ResetFlag.i)
  
  Protected.i found
  Protected editFind.FINDTEXT, format.CHARFORMAT, Range.CHARRANGE
  
  
  If GadgetType(Gadget.i) = #PB_GadgetType_Editor
    Debug "EditorGadget being passed correctly"
    Debug TextToFind
  Else
    Debug "No editorgadget passed, what's going on??"
  EndIf
  
  ; Reset search to beginning
  SendMessage_(GadgetID(Gadget), #EM_SETSEL, 0, 0)
  ; For resetting to default text
  If ResetFlag
    SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_ALL, @defaultFormat)
  EndIf
  editFind\chrg\cpMin = 0
  editFind\chrg\cpMax = -1
  editFind\lpstrText  = @TextToFind
  Repeat
    found = SendMessage_(GadgetID(Gadget), #EM_FINDTEXT, #FR_DOWN, @editFind)
    If found > - 1
      editFind\chrg\cpMin = found + 1
      Range\cpMin = found
      Range\cpMax = found + Len(TextToFind)
      
      SendMessage_(GadgetID(Gadget), #EM_EXSETSEL, 0, @Range)               ; Set the selection to highlight
      
      format\cbSize     = SizeOf(CHARFORMAT)
      format\dwMask     = #CFM_ITALIC  | #CFM_BOLD      | #CFM_STRIKEOUT | #CFM_UNDERLINE
      format\dwEffects  = #CFM_BOLD    | #CFM_UNDERLINE
      SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format)
    EndIf
  Until found.i = -1
  SendMessage_(GadgetID(Gadget.i), #EM_SETSEL, 0, 0)
EndProcedure



Define.i Exit, Event

OpenWindow(0, 0, 0, 400, 400, "Editor", #PB_Window_SystemMenu)

EditorGadget(0, 10, 10, 380, 340)
ButtonGadget(1, 10, 360, 100, 20, "Search qwe")
ButtonGadget(2, 130, 360, 100, 20, "Search asd")


SendMessage_(GadgetID(0), #EM_GETCHARFORMAT, #SC_DEFAULT, defaultFormat)
defaultFormat\cbSize = SizeOf(CHARFORMAT)
defaultFormat\dwMask = #CFM_ITALIC  | #CFM_BOLD | #CFM_STRIKEOUT | #CFM_UNDERLINE

Repeat
  
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          Editor_FindText(0, "qwe", #True)
        Case 2
          Editor_FindText(0, "asd", #True)
      EndSelect
    Case #PB_Event_CloseWindow
      Exit = #True
  EndSelect
  
Until Exit
Bernd
Bernd, how do I just apply just a highlight to the selection (instead of a style) so that if it already had a text style, it would not change it? In the example above, if I keep typing further down, all text is now in the found string style which is italic, bold.
Amateur Radio, D-STAR/VK3HAF
infratec
Always Here
Always Here
Posts: 6886
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: EditorGadget text search not working

Post by infratec »

Hi,

a bit different but more like I know it:

Code: Select all

EnableExplicit


Global defaultFormat.CHARFORMAT

; Find text strings inside an editorgadget

Procedure Editor_FindText(Gadget.i, TextToFind.s, ResetFlag.i)
 
  Protected.i found, Exit
  Protected format.CHARFORMAT, Range.CHARRANGE
  Static editFind.FINDTEXT
  Static LastText$
  
  
  If LastText$ <> TextToFind
    editFind\chrg\cpMin = 0
    LastText$ = TextToFind
  EndIf
  
  editFind\chrg\cpMax = -1
  editFind\lpstrText  = @TextToFind
  Repeat
    found = SendMessage_(GadgetID(Gadget), #EM_FINDTEXT, #FR_DOWN, @editFind)
    If found > - 1
      SendMessage_(GadgetID(Gadget), #EM_SETSEL, found, found + Len(TextToFind))
      editFind\chrg\cpMin = found + 1
      Exit = #True
    Else
      If editFind\chrg\cpMin > 0
        editFind\chrg\cpMin = 0
      Else
        Exit = #True
      EndIf
    EndIf
  Until Exit
EndProcedure



Define.i Exit, Event

OpenWindow(0, 0, 0, 400, 400, "Editor", #PB_Window_SystemMenu)

EditorGadget(0, 10, 10, 380, 340)
ButtonGadget(1, 10, 360, 100, 20, "Search qwe")
ButtonGadget(2, 130, 360, 100, 20, "Search asd")


SendMessage_(GadgetID(0), #EM_GETCHARFORMAT, #SC_DEFAULT, defaultFormat)
defaultFormat\cbSize = SizeOf(CHARFORMAT)
defaultFormat\dwMask = #CFM_ITALIC  | #CFM_BOLD | #CFM_STRIKEOUT | #CFM_UNDERLINE

Repeat
 
  Event = WaitWindowEvent()
 
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          Editor_FindText(0, "qwe", #False)
        Case 2
          Editor_FindText(0, "asd", #True)
      EndSelect
    Case #PB_Event_CloseWindow
      Exit = #True
  EndSelect
 
Until Exit
You get not all location at once (not possile with 'SELECT'), you get each location after an other.

Bernd
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4749
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: EditorGadget text search not working

Post by Fangbeast »

You get not all location at once (not possile with 'SELECT'), you get each location after an other.
No, you are right and thanks for that. It is how I am used to notepads and word processors doing it. A true findfirst/findnext mechanism.

And the highlight vanishes as you start typing, as it should.

You and RASHAD are great, each example gives me possible ideas of further things to add and now I can also update NotePiddle as well as the serial program.

Been working day and night to finish them both.

Just remembered something: In this section:

Code: Select all

found = SendMessage_(GadgetID(Gadget), #EM_FINDTEXT, #FR_DOWN, @editFind)
This is a case insensitive search. Is there a flag for case matching here? And I just figured out that I can replace #FR_DOWN with a variable so that I can set the direction (one day):):)

Ah, never mind. found it:

Code: Select all

found = SendMessage_(GadgetID(Gadget), #EM_FINDTEXTEX, #FR_DOWN | #FR_MATCHCASE, @editFind)
Should do it

**Update** Tested my theory, works great!
Amateur Radio, D-STAR/VK3HAF
ZX80
Enthusiast
Enthusiast
Posts: 331
Joined: Mon Dec 12, 2016 1:37 pm

Re: EditorGadget text search not working

Post by ZX80 »

Hi, infratec.
Your last code works well, but I have two questions about it.
1st. I want to add a "search from the beginning" button. And for this need forget the last found value. How can I do that?
2nd. Please, could you rewrite/add the search procedure to search from ending to beginning (reverse searh mechanism)?

As a result it should be look like in IE: one step "forward" / "backward". If cursor position is located at beginning and "backward" button pressed then search is made from the end of document. If cursor position is located at middle (for example, "forward" button was already used several times) and "backward" button pressed then mark previous found word. The rest is unchanged.
ZX80
Enthusiast
Enthusiast
Posts: 331
Joined: Mon Dec 12, 2016 1:37 pm

Re: EditorGadget text search not working

Post by ZX80 »

First question resolved. Forced setup "editFind\chrg\cpMin = 0"
What about the second?
Post Reply