Just finished this and thought I should share it with you in case you need something like it in one of your projects

The demo is a bit clunky, but I've just plugged the procedure into a program of my own, and it works as expected so far.
Let me hear it if you experience ANY kind of dislikesor problems with it!
Code: Select all
Procedure findReplace(id)
flags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
win = OpenWindow(#PB_Any, 0, 0, 400, 145, "Find/Replace", flags)
If win
StickyWindow(win, #True)
;draw the find icon
img1 = CreateImage(#PB_Any, 22, 22)
If StartDrawing(ImageOutput(img1))
Box(0, 0, 24, 24, GetSysColor_(15))
;icon index 176, 55
ExtractIconEx_("shell32.dll", 176, 0, @icon, 1)
If icon
DrawImage(icon, 0, 0, 21, 21)
DestroyIcon_(icon)
EndIf
StopDrawing()
EndIf
If 1
ImageGadget(#PB_Any, 10, 15, 0, 0, ImageID(img1))
TextGadget(#PB_Any, 40, 20, 75, 22, "Find:")
Else
TextGadget(#PB_Any, 10, 20, 75, 22, "Find What:")
EndIf
str1 = StringGadget(#PB_Any, 100, 15, 200, 21, "")
TextGadget(#PB_Any, 10, 50, 75, 22, "Replace With:")
str2 = StringGadget(#PB_Any, 100, 45, 200, 21, "")
btn1 = ButtonGadget(#PB_Any, 310, 15, 80, 22, "Find Next", #PB_Button_Default)
DisableGadget(btn1, #True)
btn2 = ButtonGadget(#PB_Any, 310, 45, 80, 22, "Replace")
DisableGadget(btn2, #True)
btn3 = ButtonGadget(#PB_Any, 310, 80, 80, 22, "Replace all")
DisableGadget(btn3, #True)
btn4 = ButtonGadget(#PB_Any, 310, 110, 80, 22, "Cancel")
;get any selected text in the richedit
SendMessage_(GadgetID(id), #EM_EXGETSEL, 0, @text.FINDTEXT\chrg)
If (text\chrg\cpMin <> text\chrg\cpMax)
;selected text range found, check it's length
len = text\chrg\cpMax - text\chrg\cpMin
If len <= 128
char.c
*txt = AllocateMemory((len + 1) * SizeOf(char))
;get the selected text
SendMessage_(GadgetID(id), #EM_GETSELTEXT, 0, *txt)
SetGadgetText(str1, PeekS(*txt))
FreeMemory(*txt)
;focus the replace input field
SetActiveGadget(str2)
;enable the buttons
DisableGadget(btn1, #False)
DisableGadget(btn2, #False)
DisableGadget(btn3, #False)
EndIf
Else
;focus the findstring input field
SetActiveGadget(str1)
EndIf
chk1 = CheckBoxGadget(#PB_Any, 10, 80, 120, 22, "Match Case")
chk2 = CheckBoxGadget(#PB_Any, 10, 112, 120, 22, "Whole Words only")
chk3 = CheckBoxGadget(#PB_Any, 140, 112, 160, 22, "Search From Top")
;no text found yet:
pos = -1
;default search flag
flg | #FR_DOWN
Repeat
event = WaitWindowEvent()
If EventWindow() = win
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case str1
;find string
GadgetToolTip(str1, GetGadgetText(str1))
If Len(GetGadgetText(str1))
DisableGadget(btn1, #False)
DisableGadget(btn2, #False)
DisableGadget(btn3, #False)
Else
DisableGadget(btn1, #True)
DisableGadget(btn2, #True)
DisableGadget(btn3, #True)
EndIf
Case str2
;replace string
GadgetToolTip(str2, GetGadgetText(str2))
Case btn1
;find button
find.s = GetGadgetText(str1)
text.FINDTEXT\lpstrText = @find
;get current position or selected range in the text
SendMessage_(GadgetID(id), #EM_EXGETSEL, 0, @text\chrg)
If (text\chrg\cpMin <> text\chrg\cpMax)
;selected text range found, search from the end of it
text\chrg\cpMin = text\chrg\cpMax
EndIf
If GetGadgetState(chk3)
;reset, search from the top
SetGadgetState(chk3, 0)
text\chrg\cpMin = 0
EndIf
;search to the end of the text:
text\chrg\cpMax = -1
;set the search flags
flg = 0
flg | #FR_DOWN
If GetGadgetState(chk1)
flg | #FR_MATCHCASE
EndIf
If GetGadgetState(chk2)
flg | #FR_WHOLEWORD
EndIf
pos = SendMessage_(GadgetID(id), #EM_FINDTEXT, flg, @text)
If pos <> -1
;found, select the text range
SendMessage_(GadgetID(id), #EM_SETSEL, pos, pos + Len(find))
Else
msg.s = "Cannot find " + find + Chr(13) + Chr(10)
msg + "Search again from the top ?"
flags = #MB_ICONQUESTION | #MB_YESNOCANCEL
Select MessageRequester("Find/Replace", msg, flags)
Case #IDYES
;first position in the text
SendMessage_(GadgetID(id), #EM_SETSEL, 0, 0)
text\chrg\cpMin = 0
;search to the end of the text:
text\chrg\cpMax = -1
pos = SendMessage_(GadgetID(id), #EM_FINDTEXT, flg, @text)
If pos <> -1
;found, select the text range
SendMessage_(GadgetID(id), #EM_SETSEL, pos, pos + Len(find))
Else
msg.s = "Cannot find " + find
flags = #MB_ICONINFORMATION | #MB_OKCANCEL
Select MessageRequester("Find/Replace", msg, flags)
Case #IDCANCEL
Break
EndSelect
EndIf
SetActiveGadget(id)
Case #IDCANCEL
Break
EndSelect
EndIf
Case btn2
;replace button
;get selected range in the text
SendMessage_(GadgetID(id), #EM_EXGETSEL, 0, @text\chrg)
If (text\chrg\cpMin <> text\chrg\cpMax)
;found selected text range
repl.s = GetGadgetText(str2)
If text\chrg\cpMax - text\chrg\cpMin = Len(GetGadgetText(str1))
;same length as the find string, replace it
SendMessage_(GadgetID(id), #EM_REPLACESEL, 1, @repl)
;advance the current position
text\chrg\cpMin + Len(repl)
EndIf
Else
;no selection made yet, search from the current position
text\chrg\cpMin = text\chrg\cpMax
EndIf
If GetGadgetState(chk3)
;reset, search from the top
SetGadgetState(chk3, 0)
text\chrg\cpMin = 0
EndIf
;search to the end of the text:
text\chrg\cpMax = -1
find.s = GetGadgetText(str1)
text\lpstrText = @find
;set the search flags
flg = 0
flg | #FR_DOWN
If GetGadgetState(chk1)
flg | #FR_MATCHCASE
EndIf
If GetGadgetState(chk2)
flg | #FR_WHOLEWORD
EndIf
pos = SendMessage_(GadgetID(id), #EM_FINDTEXT, flg, @text)
If pos <> -1
;found, select the text range
SendMessage_(GadgetID(id), #EM_SETSEL, pos, pos + Len(find))
Else
msg.s = "Cannot find " + find + Chr(13) + Chr(10)
msg + "Search again from the top ?"
flags = #MB_ICONQUESTION | #MB_YESNOCANCEL
Select MessageRequester("Find/Replace", msg, flags)
Case #IDYES
;first position in the text
SendMessage_(GadgetID(id), #EM_SETSEL, 0, 0)
text\chrg\cpMin = 0
;search to the end of the text:
text\chrg\cpMax = -1
pos = SendMessage_(GadgetID(id), #EM_FINDTEXT, flg, @text)
If pos <> -1
;found, select the text range
SendMessage_(GadgetID(id), #EM_SETSEL, pos, pos + Len(find))
Else
msg.s = "Cannot find " + find
flags = #MB_ICONINFORMATION | #MB_OKCANCEL
Select MessageRequester("Find/Replace", msg, flags)
Case #IDCANCEL
Break
EndSelect
EndIf
Case #IDCANCEL
Break
EndSelect
EndIf
Case btn3
;replace all button
Repeat
;get selected range in the text
SendMessage_(GadgetID(id), #EM_EXGETSEL, 0, @text\chrg)
If (text\chrg\cpMin <> text\chrg\cpMax)
;found selected text range
repl.s = GetGadgetText(str2)
If text\chrg\cpMax - text\chrg\cpMin = Len(GetGadgetText(str1))
;same length as the find string, replace it
SendMessage_(GadgetID(id), #EM_REPLACESEL, 1, @repl)
;advance the current position
text\chrg\cpMin + Len(repl)
EndIf
Else
;no selection made yet, search from the current position
text\chrg\cpMin = text\chrg\cpMax
EndIf
If GetGadgetState(chk3)
;reset, search from the top
SetGadgetState(chk3, 0)
text\chrg\cpMin = 0
EndIf
;search to the end of the text:
text\chrg\cpMax = -1
find.s = GetGadgetText(str1)
text\lpstrText = @find
;set the search flags
flg = 0
flg | #FR_DOWN
If GetGadgetState(chk1)
flg | #FR_MATCHCASE
EndIf
If GetGadgetState(chk2)
flg | #FR_WHOLEWORD
EndIf
pos = SendMessage_(GadgetID(id), #EM_FINDTEXT, flg, @text)
If pos <> -1
;found, select the text range
SendMessage_(GadgetID(id), #EM_SETSEL, pos, pos + Len(find))
EndIf
Until pos = -1
msg.s = "Cannot find " + find + Chr(13) + Chr(10)
msg + "Search again from the top ?"
flags = #MB_ICONQUESTION | #MB_YESNOCANCEL
Select MessageRequester("Find/Replace", msg, flags)
Case #IDYES
;first position in the text
SendMessage_(GadgetID(id), #EM_SETSEL, 0, 0)
text\chrg\cpMin = 0
;search to the end of the text:
text\chrg\cpMax = -1
pos = SendMessage_(GadgetID(id), #EM_FINDTEXT, flg, @text)
If pos <> -1
;found, select the text range
SendMessage_(GadgetID(id), #EM_SETSEL, pos, pos + Len(find))
Else
msg.s = "Cannot find " + find
flags = #MB_ICONINFORMATION | #MB_OKCANCEL
Select MessageRequester("Find/Replace", msg, flags)
Case #IDCANCEL
Break
EndSelect
EndIf
Case #IDCANCEL
Break
EndSelect
Case btn4
;cancel button
Break
EndSelect
Case #PB_Event_CloseWindow
Break
EndSelect
EndIf
ForEver
CloseWindow(win)
EndIf
EndProcedure
;demo
flags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
win = OpenWindow(#PB_Any, 0, 0, 600, 400, "", flags)
edt1 = EditorGadget(#PB_Any, 0, 0, 600, 400)
For i = 0 To 40
AddGadgetItem(edt1, i, "Editor gadget line " + Str(i))
Next
SendMessage_(GadgetID(edt1), #EM_SETSEL, 0, 0)
findReplace(edt1)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
EndSelect
ForEver