' find and replace common dialog boxes demonstration program
'
' your comments and suggestions are most welcome in this link:
http://www.powerbasic.com/support/pb...ad.php?t=11740
'
' version 1.
'
' this small code illustrates the use of the built-in find and replace
' dialog boxes.
' from the the win32api help file:
'
' common dialog box library provides a creation function and a structure
' for each type of common dialog box. to use a common dialog box in its
' simplest form, you call its creation function and specify a pointer to a
' structure containing initial values and option flags. after initializing
' the dialog box, the dialog box procedure uses the structure to return
' information about the user's input.
' find
' displays a dialog box in which the user can type the string to find. the
' user can also specify search options, such as the search direction,
' whether to search for a whole word and whether the search is case
' sensitive. you create and display a find dialog box by initializing a
' findreplace structure and passing the structure to the findtext function.
'
' replace
' displays a dialog box in which the user can type the string to find and
' the replacement string. the user can specify search options, such as
' whether to search for a whole word and whether the search is case
' sensitive, and replacement options, such as the scope of replacement.
' you create and display a replace dialog box by initializing a findreplace
' structure and passing the structure to the replacetext function.
'
' unlike other common dialog boxes, the find and replace dialog boxes are
' modeless. a modeless dialog box allows the user to switch between the
' dialog box and the window that created it. this is useful for letting the
' user search for a string, switch to the application window to work on the
' string, and switch back to the dialog box to search for another string
' without repeating the command needed to open the dialog box.
' if the findtext or replacetext function successfully creates the dialog
' box, it returns the handle of the dialog box. you can use this handle to
' move and communicate with the dialog box. if the function cannot create
' the dialog box, it returns null. you can determine the cause of an error
' by calling the commdlgextendederror function to retrieve the extended
' error value.
' before creating a find or replace dialog box, you must call the
' registerwindowmessage function to get a message identifier for the
' findmsgstring registered message. you can then use the identifier to
' detect and process messages sent from the dialog box. when the user
' clicks the find next, replace, or replace all button in a dialog box, the
' dialog box procedure sends a findmsgstring message to the window
' procedure of the owner window. when you create the dialog box, the
' hwndowner member of the findreplace structure identifies the owner
' window.
'
' the lparam parameter of a findmsgstring message is a pointer to the
' findreplace structure that you specified when you created the dialog box.
' before sending the message, the dialog box sets the members of this
' structure with the latest user input, including the string to search for,
' the replacement string (if any), and options for the find-and-replace
' operation.
'
' thanks to borje hagsten for an inspiring skeleton code in the forum.
'
' best regards,
'
' erik christensen ------- march 24, 2005
'
' p.s. improved markedly march 29 and somewhat april 9, 2005
'
' august 29, 2005: unimportant small change made.
[this message has been edited by erik christensen (edited august 29, 2005).]
'
' your comments and suggestions are most welcome in this link:

http://www.powerbasic.com/support/pb...ad.php?t=11740
'
' version 1.
'
' this small code illustrates the use of the built-in find and replace
' dialog boxes.
' from the the win32api help file:
'
' common dialog box library provides a creation function and a structure
' for each type of common dialog box. to use a common dialog box in its
' simplest form, you call its creation function and specify a pointer to a
' structure containing initial values and option flags. after initializing
' the dialog box, the dialog box procedure uses the structure to return
' information about the user's input.
' find
' displays a dialog box in which the user can type the string to find. the
' user can also specify search options, such as the search direction,
' whether to search for a whole word and whether the search is case
' sensitive. you create and display a find dialog box by initializing a
' findreplace structure and passing the structure to the findtext function.
'
' replace
' displays a dialog box in which the user can type the string to find and
' the replacement string. the user can specify search options, such as
' whether to search for a whole word and whether the search is case
' sensitive, and replacement options, such as the scope of replacement.
' you create and display a replace dialog box by initializing a findreplace
' structure and passing the structure to the replacetext function.
'
' unlike other common dialog boxes, the find and replace dialog boxes are
' modeless. a modeless dialog box allows the user to switch between the
' dialog box and the window that created it. this is useful for letting the
' user search for a string, switch to the application window to work on the
' string, and switch back to the dialog box to search for another string
' without repeating the command needed to open the dialog box.
' if the findtext or replacetext function successfully creates the dialog
' box, it returns the handle of the dialog box. you can use this handle to
' move and communicate with the dialog box. if the function cannot create
' the dialog box, it returns null. you can determine the cause of an error
' by calling the commdlgextendederror function to retrieve the extended
' error value.
' before creating a find or replace dialog box, you must call the
' registerwindowmessage function to get a message identifier for the
' findmsgstring registered message. you can then use the identifier to
' detect and process messages sent from the dialog box. when the user
' clicks the find next, replace, or replace all button in a dialog box, the
' dialog box procedure sends a findmsgstring message to the window
' procedure of the owner window. when you create the dialog box, the
' hwndowner member of the findreplace structure identifies the owner
' window.
'
' the lparam parameter of a findmsgstring message is a pointer to the
' findreplace structure that you specified when you created the dialog box.
' before sending the message, the dialog box sets the members of this
' structure with the latest user input, including the string to search for,
' the replacement string (if any), and options for the find-and-replace
' operation.
'
' thanks to borje hagsten for an inspiring skeleton code in the forum.
'
' best regards,

'
' erik christensen ------- march 24, 2005
'
' p.s. improved markedly march 29 and somewhat april 9, 2005
'
' august 29, 2005: unimportant small change made.
Code:
#compile exe #register none #dim all ' #include "win32api.inc" #include "comdlg32.inc" ' %textbox1 = 100 %buttonfind = 105 %buttonreplace = 110 %buttonexit = 115 ' global hform1& global msgfindreplace as long global hdlgmodeless as long global oldtextproc as long global flgs as long ' for saving of find or replace flags between calls. ' ' function openfindorreplacetextdialog (byval hwnd as long, byval ind as long) as long static fr as findreplace, ztxt as asciiz * 256, ztxt2 as asciiz * 256 ' ' the dialog remembers the find-string and replace-string between calls. ' there is no need to set them here. ' fr.lstructsize = sizeof(fr) fr.hwndowner = hwnd fr.hinstance = %null ' first time set flags to downward search direction - else to previous values. if istrue flgs then fr.flags = flgs else fr.flags = %fr_down fr.lpstrfindwhat = varptr(ztxt) fr.wfindwhatlen = sizeof(ztxt) fr.lpstrreplacewith = varptr(ztxt2) fr.wreplacewithlen = sizeof(ztxt2) fr.lcustdata = 0 fr.lpfnhook = %null fr.lptemplatename = %null ' if ind = 1 then function = findtext(fr) if ind = 2 then function = replacetext(fr) ' end function ' ' function dofindreplaceaction(byval llparam as long,byval hwnd as long, byval id as long) as long static txt as string static ipos as long, prpos as long static match as long static sel1 as long, sel2 as long static przt as string static sta as long static delim as string static lppfr as findreplace ptr static zt as asciiz ptr, zt2 as asciiz ptr delim = "!"#¤%&/()=?`´|@£${[]}+^¨~*',;.:-_ " ' word delimiting characters. this may be modified if you so wish. lppfr = llparam if (@lppfr.flags and %fr_dialogterm) then ' find or replace dialog is closed hdlgmodeless = %null : function = 0 : exit function end if flgs = @lppfr.flags ' save flags for next call zt = @lppfr.lpstrfindwhat ' text to search for zt2 = @lppfr.lpstrreplacewith ' replacing text if any control get text hwnd, id to txt ' text to search in control send hwnd, id, %em_getsel, varptr(sel1), varptr(sel2) ipos = sel1 ' set position to caret or start of selection if any if (@lppfr.flags and %fr_findnext) then ' find next if (ucase$(mid$(txt,sel1+1,sel2-sel1))=przt and sel2>sel1) or sel2=len(txt) then incr ipos ' necessary adjustment to prevent from being stuck in the same position. gosub find if istrue match then control send hwnd, id, %em_setsel, prpos-1, prpos + len(@zt)-1 control send hwnd, id, %em_scrollcaret,0,0 przt = ucase$(trim$(@zt)) else msgbox "no match found",%mb_iconinformation, "find" end if elseif (@lppfr.flags and %fr_replace) then ' replace gosub find if istrue match then txt = left$(txt,prpos-1)[email protected]+mid$(txt,prpos+len(@zt)) ' replace @zt with @zt2 control set text hwnd, id, txt ' set changed text in textbox gosub find if istrue match then control send hwnd, id, %em_setsel, prpos-1, prpos + len(@zt)-1 control send hwnd, id, %em_scrollcaret,0,0 else msgbox "no further match found",%mb_iconinformation, "find" end if else msgbox "no match found",%mb_iconinformation, "find" end if elseif (@lppfr.flags and %fr_replaceall) then ' replace all gosub find if istrue match then do txt = left$(txt,prpos-1)[email protected]+mid$(txt,prpos+len(@zt)) ' replace @zt with @zt2 gosub find loop until isfalse match ' loop until no more matches control set text hwnd, id, txt ' set changed text in textbox control send hwnd, id, %em_setsel, prpos-1, prpos+len(@zt2)-1 ' select last replacement control send hwnd, id, %em_scrollcaret,0,0 else msgbox "no match found",%mb_iconinformation, "find" end if end if function = 1 : exit function ' find: ' subroutine find ' do again: ' establish search direction - up or down - and start position for instr-search. if (@lppfr.flags and %fr_down) then sta=ipos+1 else sta=ipos-len(txt)-2 if (@lppfr.flags and %fr_matchcase) then ' match case ipos = instr(sta, txt, @zt) else ' no matching of case is necessary ipos = instr(sta, ucase$(txt), ucase$(@zt)) end if if ipos then ' if result if (@lppfr.flags and %fr_wholeword) then ' check for whole word ' this may seem too simple, but it works - also at the start and end of the text. if istrue verify(mid$(txt,ipos-1,1),delim) or _ istrue verify(mid$(txt,ipos+len(@zt),1),delim) then goto again end if ' match found - set previous position for next search match = %true : prpos = ipos end if loop until istrue match or isfalse ipos ' match not found - set pos to previous position if isfalse ipos then ipos = prpos : match = %false ' return ' end function ' ' ' main callback callback function dlgproc() as long local res as long ' select case cbmsg case %wm_command select case cbctlmsg case %bn_clicked select case cbctl case %buttonfind res = openfindorreplacetextdialog(getdlgitem(cbhndl, %textbox1), 1) ' find case %buttonreplace res = openfindorreplacetextdialog(getdlgitem(cbhndl, %textbox1), 2) ' replace case %buttonexit dialog end cbhndl, 0 end select ' end select function = 1 ' case %wm_destroy setwindowlong getdlgitem(cbhndl, %textbox1), %gwl_wndproc, oldtextproc end select end function ' ' ' create dialog and controls, etc function pbmain () as long local txt as string 'register a message for the find or replace dialog. msgfindreplace = registerwindowmessage ("commdlg_findreplace") dialog new 0, "find and replace common dialogs demonstration", 0, 0, 357, 246, _ %ws_popup or %ds_modalframe or %ws_caption or %ws_minimizebox or %ws_sysmenu or %ds_center, 0 to hform1& control add button, hform1&, %buttonfind, "&find", 32, 219, 80, 15, _ %ws_child or %ws_visible or %bs_pushbutton or %ws_tabstop control send hform1&, %buttonfind, %wm_setfont, getstockobject(%system_fixed_font), %true control add button, hform1&, %buttonreplace, "&replace", 139, 219, 80, 15, _ %ws_child or %ws_visible or %bs_pushbutton or %ws_tabstop control send hform1&, %buttonreplace, %wm_setfont, getstockobject(%system_fixed_font), %true control add button, hform1&, %buttonexit, "e&xit", 245, 219, 80, 15, _ %ws_child or %ws_visible or %bs_pushbutton or %ws_tabstop control send hform1&, %buttonexit, %wm_setfont, getstockobject(%system_fixed_font), %true txt ="common dialog box library provides a creation function and a structure"+ _ " for each type of common dialog box. to use a common dialog box in its"+ _ " simplest form, you call its creation function and specify a pointer to a"+ _ " structure containing initial values and option flags. after initializing"+ _ " the dialog box, the dialog box procedure uses the structure to return"+ _ " information about the user's input."+ $crlf+$crlf+_ "find"+$crlf+ _ "displays a dialog box in which the user can type the string to find. the"+ _ " user can also specify search options, such as the search direction,"+ _ " whether to search for a whole word and whether the search is case"+ _ " sensitive. you create and display a find dialog box by initializing a"+ _ " findreplace structure and passing the structure to the findtext function."+$crlf+$crlf+ _ "replace"+$crlf+ _ "displays a dialog box in which the user can type the string to find and"+ _ " the replacement string. the user can specify search options, such as"+ _ " whether to search for a whole word and whether the search is case"+ _ " sensitive, and replacement options, such as the scope of replacement."+ _ " you create and display a replace dialog box by initializing a findreplace"+ _ " structure and passing the structure to the replacetext function."+$crlf+$crlf+ _ "unlike other common dialog boxes, the find and replace dialog boxes are"+ _ " modeless. a modeless dialog box allows the user to switch between the"+ _ " dialog box and the window that created it. this is useful for letting the"+ _ " user search for a string, switch to the application window to work on the"+ _ " string, and switch back to the dialog box to search for another string"+ _ " without repeating the command needed to open the dialog box."+ _ " if the findtext or replacetext function successfully creates the dialog"+ _ " box, it returns the handle of the dialog box. you can use this handle to"+ _ " move and communicate with the dialog box. if the function cannot create"+ _ " the dialog box, it returns null. you can determine the cause of an error"+ _ " by calling the commdlgextendederror function to retrieve the extended"+ _ " error value."+$crlf+$crlf+ _ "before creating a find or replace dialog box, you must call the"+ _ " registerwindowmessage function to get a message identifier for the"+ _ " findmsgstring registered message. you can then use the identifier to"+ _ " detect and process messages sent from the dialog box. when the user"+ _ " clicks the find next, replace, or replace all button in a dialog box, the"+ _ " dialog box procedure sends a findmsgstring message to the window"+ _ " procedure of the owner window. when you create the dialog box, the"+ _ " hwndowner member of the findreplace structure identifies the owner"+ _ " window."+$crlf+$crlf+ _ "the lparam parameter of a findmsgstring message is a pointer to the"+ _ " findreplace structure that you specified when you created the dialog box."+ _ " before sending the message, the dialog box sets the members of this"+ _ " structure with the latest user input, including the string to search for,"+ _ " the replacement string (if any), and options for the find-and-replace"+ _ " operation." control add textbox, hform1&, %textbox1, txt, 32, 27, 293, 180, _ %ws_child or %ws_visible or %es_multiline or %es_nohidesel or %ws_vscroll or %ws_tabstop or %es_wantreturn or %es_left or %es_autovscroll, _ %ws_ex_clientedge control send hform1&, %textbox1, %wm_setfont, getstockobject(%system_fixed_font), %true control set focus hform1&, %textbox1 oldtextproc = setwindowlong(getdlgitem(hform1&, %textbox1), %gwl_wndproc, codeptr(textproc)) dialog show modal hform1& call dlgproc end function ' ' ' text control subclass callback function textproc static res as long ' select case cbmsg case msgfindreplace ' this is the message we registered ' do actions in response to your input in the dialog box function = dofindreplaceaction(cblparam, getparent(cbhndl), %textbox1) ' case %wm_keydown if hiwrd(getkeystate(%vk_control)) and cbwparam = 70 then ' ctrl+f pressed in textbox, res = openfindorreplacetextdialog(cbhndl, 1) ' so popup find dialog. elseif hiwrd(getkeystate(%vk_control)) and cbwparam = 82 then ' ctrl+r pressed in textbox, res = openfindorreplacetextdialog(cbhndl, 2) ' so popup replace dialog. textbox needs to have the focus for this to work. end if end select function = callwindowproc(oldtextproc, cbhndl, cbmsg, cbwparam, cblparam) end function
[this message has been edited by erik christensen (edited august 29, 2005).]
Comment