Function Reference


_WinAPI_FindTextDlg

Creates a system-defined modeless Find dialog box to search for text in a document

#include <WinAPIDlg.au3>
_WinAPI_FindTextDlg ( $hOwner [, $sFindWhat = '' [, $iFlags = 0 [, $pFindProc = 0 [, $lParam = 0]]]] )

Parameters

$hOwner A handle to the window that owns the dialog box. The window procedure of the specified window receives FINDMSGSTRING messages from the dialog box. This parameter can be any valid window handle, but it must not be 0.
$sFindWhat [optional] The search string that is displayed when you initialize the dialog box.
$iFlags [optional] A set of bit flags that used to initialize the dialog box.
The dialog box sets these flags when it sends the FINDMSGSTRING registered message to indicate the user's input.
This parameter can be one or more of the following values.
    $FR_DIALOGTERM
    $FR_DOWN
    $FR_ENABLEHOOK
    $FR_ENABLETEMPLATE
    $FR_ENABLETEMPLATEHANDLE
    $FR_FINDNEXT
    $FR_HIDEUPDOWN
    $FR_HIDEMATCHCASE
    $FR_HIDEWHOLEWORD
    $FR_MATCHCASE
    $FR_NOMATCHCASE
    $FR_NOUPDOWN
    $FR_NOWHOLEWORD
    $FR_REPLACE
    $FR_REPLACEALL
    $FR_SHOWHELP
    $FR_WHOLEWORD
$pFindProc [optional] Pointer to an hook procedure that can process messages intended for the dialog box.
This parameter is ignored unless the $FR_ENABLEHOOK flag is not set.
(See MSDN for more information)
$lParam [optional] Application-defined data that the system passes to the hook procedure.

Return Value

Success: The window handle to the dialog box.
Failure: 0 and sets the @error flag to non-zero, @extended flag may contain the dialog box error code.

Remarks

The _WinAPI_FindTextDlg() does not perform a search operation. Instead, the dialog box sends FINDMSGSTRING registered messages to the window procedure of the owner window of the dialog box.

Before calling _WinAPI_FindTextDlg(), you must call the _WinAPI_RegisterWindowMessage() function to get the identifier for the FINDMSGSTRING message. The dialog box procedure uses this identifier to send messages when the user clicks the "Find Next" button, or when the dialog box is closing. The "lParam" parameter of the FINDMSGSTRING message contains a pointer to a $tagFINDREPLACE structure. The "Flags" member of this structure indicates the event that caused the message. Other members of the structure indicate the user's input.

The _WinAPI_FindTextDlg() uses an internal buffer to hold the string that the user typed in the "Find What" edit controls. You can increase the size of this buffer by using the _WinAPI_SetFRBuffer() function. In addition to free the memory allocated for the internal buffer, you must call the _WinAPI_FlushFRBuffer() in response to the FINDMSGSTRING message with $FR_DIALOGTERM flag set.

Related

_WinAPI_FlushFRBuffer, _WinAPI_RegisterWindowMessage, _WinAPI_SetFRBuffer

See Also

Search FindText in MSDN Library.

Example

#include <APIDlgConstants.au3>
#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <MsgBoxConstants.au3>
#include <SendMessage.au3>
#include <WinAPIDlg.au3>
#include <WinAPIGdi.au3>
#include <WinAPIMisc.au3>
#include <WinAPISysWin.au3>
#include <WindowsConstants.au3>

Local Const $e_sText = 'AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting. It uses a combination of simulated keystrokes, mouse movement and window/control manipulation in order to automate tasks in a way not possible or reliable with other languages (e.g. VBScript and SendKeys). AutoIt is also very small, self-contained and will run on all versions of Windows out-of-the-box with no annoying "runtimes" required!' & @CRLF & @CRLF & _
                'AutoIt was initially designed for PC "roll out" situations to reliably automate and configure thousands of PCs. Over time it has become a powerful language that supports complex expressions, user functions, loops and everything else that veteran scripters would expect.'

; Create GUI
Local $hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'), 800, 600)

; Create main menu
Local $idMenu = GUICtrlCreateMenu('&File')
Local $idExitItem = GUICtrlCreateMenuItem('E&xit...', $idMenu)
$idMenu = GUICtrlCreateMenu('&Edit')
Local $idFindItem = GUICtrlCreateMenuItem('&Find...', $idMenu)
Local $idReplaceItem = GUICtrlCreateMenuItem('R&eplace...', $idMenu)

; Create Rich Edit control with always visible text selection, and set "Courier New" font to the control
Local $hRichEdit = _GUICtrlRichEdit_Create($hForm, $e_sText, 0, 0, 800, 600, BitOR($ES_AUTOVSCROLL, $ES_NOHIDESEL, $ES_MULTILINE, $WS_VSCROLL), 0)
Local $hFont = _WinAPI_CreateFont(17, 0, 0, 0, $FW_NORMAL, 0, 0, 0, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $ANTIALIASED_QUALITY, $DEFAULT_PITCH, 'Courier New')
_SendMessage($hRichEdit, $WM_SETFONT, $hFont, 1)
_SendMessage($hRichEdit, $EM_SETSEL)

; Register FINDMSGSTRING message to receive the messages from the dialog box
GUIRegisterMsg(_WinAPI_RegisterWindowMessage('commdlg_FindReplace'), 'WM_FINDMSGSTRING')

; Show GUI
GUISetState(@SW_SHOW)

Global $g_hDlg
Local $iMsg, $sText
While 1
        $iMsg = GUIGetMsg()
        Switch $iMsg
                Case $GUI_EVENT_CLOSE, $idExitItem
                        ExitLoop
                Case $idFindItem, $idReplaceItem
                        $sText = _GUICtrlRichEdit_GetSelText($hRichEdit)
                        If @error Then
                                $sText = ''
                        EndIf
                        ; Disable "Find..." and "Replace..." menu items, otherwise, the script maay crash
                        GUICtrlSetState($idFindItem, $GUI_DISABLE)
                        GUICtrlSetState($idReplaceItem, $GUI_DISABLE)
                        Switch $iMsg
                                Case $idFindItem
                                        $g_hDlg = _WinAPI_FindTextDlg($hForm, $sText, $FR_DOWN, 0, $hRichEdit)
                                Case $idReplaceItem
                                        $g_hDlg = _WinAPI_ReplaceTextDlg($hForm, $sText, '', 0, 0, $hRichEdit)
                        EndSwitch
                Case $idReplaceItem
        EndSwitch
WEnd

GUIDelete()

Func _IsMatchSelection($hWnd, $sText, $iBehavior)
        Local $aPos = _GUICtrlRichEdit_GetSel($hWnd)
        If @error Then Return 0

        $aPos = _GUICtrlRichEdit_FindTextInRange($hWnd, $sText, $aPos[0], $aPos[1], BitAND($iBehavior, $FR_MATCHCASE) = $FR_MATCHCASE, BitAND($iBehavior, $FR_WHOLEWORD) = $FR_WHOLEWORD, BitAND($iBehavior, BitOR($FR_MATCHALEFHAMZA, $FR_MATCHDIAC, $FR_MATCHKASHIDA)))
        If @error Or ($aPos[0] = -1) Or ($aPos[1] = -1) Then
                Return 0
        Else
                Return 1
        EndIf
EndFunc   ;==>_IsMatchSelection

Func WM_FINDMSGSTRING($hWnd, $iMsg, $wParam, $lParam)
        #forceref $hWnd, $iMsg, $wParam

        Local $tFINDREPLACE = DllStructCreate($tagFINDREPLACE, $lParam)
        Local $sReplace = _WinAPI_GetString(DllStructGetData($tFINDREPLACE, 'ReplaceWith'))
        Local $sFind = _WinAPI_GetString(DllStructGetData($tFINDREPLACE, 'FindWhat'))
        Local $hRichEdit = Ptr(DllStructGetData($tFINDREPLACE, 'lParam'))
        Local $iFlags = DllStructGetData($tFINDREPLACE, 'Flags')
        Local $aPos, $iCur = -1

        Select
                ; The user clicked the "Replace" button in a Replace dialog box
                Case BitAND($iFlags, $FR_REPLACE)
                        If _IsMatchSelection($hRichEdit, $sFind, $iFlags) Then
                                _GUICtrlRichEdit_ReplaceText($hRichEdit, $sReplace)
                        EndIf
                        ContinueCase
                        ; The user clicked the "Find Next" button in a Find or Replace dialog box
                Case BitAND($iFlags, $FR_FINDNEXT)
                        $aPos = _GUICtrlRichEdit_GetSel($hRichEdit)
                        If @error Then Return

                        If BitAND($iFlags, $FR_DOWN) Then
                                $aPos = _GUICtrlRichEdit_FindTextInRange($hRichEdit, $sFind, $aPos[1], -1, BitAND($iFlags, $FR_MATCHCASE) = $FR_MATCHCASE, BitAND($iFlags, $FR_WHOLEWORD) = $FR_WHOLEWORD)
                        Else
                                $aPos = _GUICtrlRichEdit_FindTextInRange($hRichEdit, $sFind, $aPos[0], 0, BitAND($iFlags, $FR_MATCHCASE) = $FR_MATCHCASE, BitAND($iFlags, $FR_WHOLEWORD) = $FR_WHOLEWORD, BitAND($iFlags, $FR_DOWN))
                        EndIf
                        If @error Or ($aPos[0] = -1) Or ($aPos[1] = -1) Then
                                Local $iError = @error
                                MsgBox(($MB_ICONINFORMATION + $MB_SYSTEMMODAL), WinGetTitle($g_hDlg), 'Cannot find "' & $sFind & '" (' & $iError & ')', 0, $g_hDlg)
                                Return
                        EndIf
                        ; Here and below used the EM_SETSEL message directly because _GUICtrlRichEdit_SetSel() sets a focus to the Rich Edit control
                        _SendMessage($hRichEdit, $EM_SETSEL, $aPos[0], $aPos[1])
                        ;                       _GUICtrlRichEdit_ScrollToCaret($hRichEdit)
                        ; The user clicked the "Replace All" button in a Replace dialog box
                Case BitAND($iFlags, $FR_REPLACEALL)
                        Dim $aPos[2] = [0, -1]
                        While 1
                                $aPos = _GUICtrlRichEdit_FindTextInRange($hRichEdit, $sFind, $aPos[0], -1, BitAND($iFlags, $FR_MATCHCASE) = $FR_MATCHCASE, BitAND($iFlags, $FR_WHOLEWORD) = $FR_WHOLEWORD)
                                If ($aPos[0] = -1) Or ($aPos[1] = -1) Then
                                        If $iCur = -1 Then
                                                MsgBox(($MB_ICONINFORMATION + $MB_SYSTEMMODAL), WinGetTitle($g_hDlg), 'Cannot find "' & $sFind & '"', 0, $g_hDlg)
                                                Return
                                        EndIf
                                        ExitLoop
                                EndIf
                                If $iCur = -1 Then
                                        _GUICtrlRichEdit_PauseRedraw($hRichEdit)
                                EndIf
                                _SendMessage($hRichEdit, $EM_SETSEL, $aPos[0], $aPos[1])
                                If _GUICtrlRichEdit_ReplaceText($hRichEdit, $sReplace) Then
                                        $iCur = $aPos[0] + StringLen($sReplace)
                                Else
                                        ExitLoop
                                EndIf
                        WEnd
                        _SendMessage($hRichEdit, $EM_SETSEL, $iCur, $iCur)
                        ;                       _GUICtrlRichEdit_ScrollToCaret($hRichEdit)
                        _GUICtrlRichEdit_ResumeRedraw($hRichEdit)
                        ; The dialog box is closing
                Case BitAND($iFlags, $FR_DIALOGTERM)
                        ; Destroy internal buffer, and free allocated memory
                        _WinAPI_FlushFRBuffer()
                        ; Enable "Find..." and "Replace..." menu items
                        GUICtrlSetState($idReplaceItem, $GUI_ENABLE)
                        GUICtrlSetState($idFindItem, $GUI_ENABLE)
        EndSelect
EndFunc   ;==>WM_FINDMSGSTRING