#include <APIDlgConstants.au3>
#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIRichEdit.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIDlg.au3>
#include <WindowsConstants.au3>
;#AutoIt3Wrapper_Run_Debug_Mode=Y
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)
	_Bug(@ScriptLineNumber, @error, $aPos)
    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)))
	_Bug(@ScriptLineNumber, @error, $aPos)
    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'))
	If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $sReplace --> " & $sReplace & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
    Local $sFind = _WinAPI_GetString(DllStructGetData($tFINDREPLACE, 'FindWhat'))
	If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $sFind --> " & $sFind & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
    Local $hRichEdit = Ptr(DllStructGetData($tFINDREPLACE, 'lParam'))
    Local $iFlags = DllStructGetData($tFINDREPLACE, 'Flags')
    ;Local $aPos, $iCur = -1, $iError = 0	; benenne ich eine Variable $a... ist es bei mir ein Array... und da die Größe konstant bleibt, wieso nicht direkt mit sinnvollen Startwerten füllen???
    Local $aPos[2] = [-2, -2], $iCur = -1, $iError = 0
	_Bug(@ScriptLineNumber, @error, $aPos)
    Select
        ; The user clicked the "Replace" button in a Replace dialog box
        Case BitAND($iFlags, $FR_REPLACE)
            If _IsMatchSelection($hRichEdit, $sFind, $iFlags) Then
                $iError = _GUICtrlRichEdit_ReplaceText($hRichEdit, $sReplace)
				If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $iError --> " & $iError & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
            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)
			_Bug(@ScriptLineNumber, @error, $aPos)
            If @error Then Return
			; --> Bei Failure liefert _GUICtrlRichEdit_FindTextInRange kein Array [-1, -1] zurück, sondern "Int32"
            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)
				_Bug(@ScriptLineNumber, @error, $aPos)
            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))
				_Bug(@ScriptLineNumber, @error, $aPos)
            EndIf
			_Bug(@ScriptLineNumber, @error, $aPos)
            ;If @error Or ($aPos[0] = -1) Or ($aPos[1] = -1) Then
            If @error Or (VarGetType($aPos)) = "Int32" Then
				_Bug(@ScriptLineNumber, @error, $aPos)
				Local $WinTitle = WinGetTitle($g_hDlg)
				ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $WinTitle --> " & $WinTitle & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
                ;$iError = MsgBox(BitOR($MB_ICONINFORMATION, $MB_SYSTEMMODAL), WinGetTitle($g_hDlg), '$FR_FINDNEXT --> Cannot find "' & $sFind & '" (' & $iError & ')', 0, $g_hDlg)
                $iError = MsgBox(BitOR($MB_ICONINFORMATION, $MB_SYSTEMMODAL), $WinTitle, '$FR_FINDNEXT --> Cannot find "' & $sFind & '" (' & $iError & ')', 0, $g_hDlg)
				_Bug(@ScriptLineNumber, @error, $aPos)
                Return
            EndIf
            ; Here and below used the EM_SETSEL message directly because _GUICtrlRichEdit_SetSel() sets a focus to the Rich Edit control
            $iError = _SendMessage($hRichEdit, $EM_SETSEL, $aPos[0], $aPos[1])
			If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $iError --> " & $iError & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
            ;           _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
				; --> Bei Failure liefert _GUICtrlRichEdit_FindTextInRange kein Array [-1, -1] zurück, sondern "Int32"
                $aPos = _GUICtrlRichEdit_FindTextInRange($hRichEdit, $sFind, $aPos[0], -1, BitAND($iFlags, $FR_MATCHCASE) = $FR_MATCHCASE, BitAND($iFlags, $FR_WHOLEWORD) = $FR_WHOLEWORD)
				_Bug(@ScriptLineNumber, @error, $aPos)
                ;If ($aPos[0] = -1) Or ($aPos[1] = -1) Then
				If @error Or (VarGetType($aPos)) = "Int32" Then
                    If $iCur = -1 Then
						_Bug(@ScriptLineNumber, @error, $aPos)
                        MsgBox(BitOR($MB_ICONINFORMATION, $MB_SYSTEMMODAL), WinGetTitle($g_hDlg), '$FR_REPLACEALL --> Cannot find "' & $sFind & '"', 0, $g_hDlg)
						_Bug(@ScriptLineNumber, @error, $aPos)
                        Return
                    EndIf
                    ExitLoop
                EndIf
                If $iCur = -1 Then
                    $iError = _GUICtrlRichEdit_PauseRedraw($hRichEdit)
					If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $iError --> " & $iError & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
                EndIf
                $iError = _SendMessage($hRichEdit, $EM_SETSEL, $aPos[0], $aPos[1])
				If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $iError --> " & $iError & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
                If _GUICtrlRichEdit_ReplaceText($hRichEdit, $sReplace) Then
                    $iCur = $aPos[0] + StringLen($sReplace)
                Else
					If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
                    ExitLoop
                EndIf
            WEnd
            $iError = _SendMessage($hRichEdit, $EM_SETSEL, $iCur, $iCur)
			If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $iError --> " & $iError & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
            ;           _GUICtrlRichEdit_ScrollToCaret($hRichEdit)
            $iError = _GUICtrlRichEdit_ResumeRedraw($hRichEdit)
			If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $iError --> " & $iError & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
		; The dialog box is closing
        Case BitAND($iFlags, $FR_DIALOGTERM)
            ; Destroy internal buffer, and free allocated memory
            $iError = _WinAPI_FlushFRBuffer()
			If @error Then ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & "   var: $iError --> " & $iError & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
            ; Enable "Find..." and "Replace..." menu items
            GUICtrlSetState($idReplaceItem, $GUI_ENABLE)
            GUICtrlSetState($idFindItem, $GUI_ENABLE)
    EndSelect
EndFunc   ;==>WM_FINDMSGSTRING

Func _Bug($iScriptLineNumber, $iError, $aPos)
	Local $vType = ""
	$vType = VarGetType($aPos)
	If $vType = "Array" Then
		ConsoleWrite("! @@" & $iScriptLineNumber & " var: $aPos[" & 0 & "] --> " & $aPos[0] & @LF & "! @@" & $iScriptLineNumber & " var: $aPos[" & 1 & "] --> " & $aPos[1] & " #Error" & @TAB & $iError & @LF)
	Else
		ConsoleWrite("! @@" & $iScriptLineNumber & " var: $aPos VarType --> " & $vType & " --> " & $aPos & " #Error" & @TAB & $iError & @LF)
	EndIf
	Return SetError($iError)
EndFunc

; ! @@76 var: $aPos[0] --> -2
; ! @@76 var: $aPos[1] --> -2 #Error	0
; ! @@87 var: $aPos[0] --> 0
; ! @@87 var: $aPos[1] --> 0 #Error	0
; ! @@92 var: $aPos VarType --> Int32 --> 0 #Error	102
; ! @@97 var: $aPos VarType --> Int32 --> 0 #Error	102
; !>03:19:56 AutoIt3.exe ended.rc:-1073740771
; >Exit code: -1073740771    Time: 113.113
;
; Problemsignatur:
;   Problemereignisname:	APPCRASH
;   Anwendungsname:	autoit3.exe
;   Anwendungsversion:	3.3.14.0
;   Anwendungszeitstempel:	559f936f
;   Fehlermodulname:	StackHash_f32c
;   Fehlermodulversion:	0.0.0.0
;   Fehlermodulzeitstempel:	00000000
;   Ausnahmecode:	c000041d
;   Ausnahmeoffset:	74e34f5d
;   Betriebsystemversion:	6.1.7601.2.1.0.256.1
;   Gebietsschema-ID:	1031
;   Zusatzinformation 1:	f32c
;   Zusatzinformation 2:	f32c1466aaba17131d8e259c7694e2f8
;   Zusatzinformation 3:	eda0
;   Zusatzinformation 4:	eda0c8bdf3a7da499cb93438447e0534
