#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPIShellEx.au3>

; Hauptprogramm
Global $hWh = GUICreate("RichEdit Link Test", 600, 400)
Global $hRichEdit1 = _ChatBoxCreate($hWh, "Hier ist ein Link: https://www.google.de" & @CRLF, 10, 10, 580, 180)
Global $hRichEdit2 = _ChatBoxCreate($hWh, "Hier ist ein anderer Link: https://www.bing.com" & @CRLF, 10, 200, 580, 180)
GUISetState()

	While 1
		$nMsg = GUIGetMsg()
		Switch $nMsg
			Case $GUI_EVENT_CLOSE
				ExitLoop
		EndSwitch
		Sleep(10)
	WEnd

	_ChatBoxDestroy($hRichEdit1)
	_ChatBoxDestroy($hRichEdit2)
	GUIDelete($hWh)
	Exit

;#########################################################################

	Func _ChatBoxCreate($gui, $txt = "", $x = 0, $y = 0, $w = 100, $h = 100, $bgc = "0xFFFFFF", $readonly = True, $autodetecturl = True, $autoscroll = True)
		Local $ret

		If $autoscroll Then
			$ret = _GUICtrlRichEdit_Create($gui, "", $x, $y, $w, $h, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
		Else
			$ret = _GUICtrlRichEdit_Create($gui, "", $x, $y, $w, $h, $ES_MULTILINE)
		EndIf
		_GUICtrlRichEdit_AutoDetectURL($ret, $autodetecturl)
		_GUICtrlRichEdit_SetLimitOnText($ret, -1)
		_GUICtrlRichEdit_SetBkColor($ret, $bgc)
		_GUICtrlRichEdit_SetReadOnly($ret, $readonly)
		If $txt <> "" Then _ChatBoxAdd($ret, $txt)

		_GUICtrlRichEdit_SetEventMask($ret, $ENM_LINK) ; Setzt das Ereignismask, um Link-Benachrichtigungen einzuschließen
		GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
		Return $ret
	EndFunc

	Func _ChatBoxClear($box)
		If Not IsHWnd($box) Then Return SetError(101, 0, False)
		_GUICtrlRichEdit_SetText($box, "")
	EndFunc

	Func _ChatBoxDestroy($box)
		If Not IsHWnd($box) Then Return SetError(101, 0, False)
		_GUICtrlRichEdit_Destroy($box)
	EndFunc

	Func _ChatBoxAdd($box, $txt)
		If Not IsHWnd($box) Then Return SetError(101, 0, False)
		If $txt = "" Then Return 0
		$txt = __ChatBoxConvert($txt)
		_GUICtrlRichEdit_AppendText($box, $txt)
	EndFunc

	Func __ChatBoxConvert($txt)
		$txt = StringReplace($txt, @CRLF, "\line ")
		$txt = StringRegExpReplace($txt, "(?i)\[b\](.*?)\[/b\]", "{\\b $1}")
		$txt = StringRegExpReplace($txt, "(?i)\[i\](.*?)\[/i\]", "{\\i $1}")
		$txt = StringRegExpReplace($txt, "(?i)\[u\](.*?)\[/u\]", "{\\ul $1}")
		$txt = StringRegExpReplace($txt, "(?i)\[s\](.*?)\[/s\]", "{\\strike $1}")
		$txt = StringRegExpReplace($txt, "(?i)\[size=(\d+?)\](.*?)\[/size\]", "{\\fs$1 $2}")


		Local $aColor = StringRegExp($txt, "(?i)\[c=#([0-9A-Fa-f]{6})\].*?\[/c\]", 3)
		Local $sColor, $iColors
		If Not @error Then
			For $i = 0 To UBound($aColor) - 1
				$sColor &= "\red" & Dec(StringMid($aColor[$i], 1, 2)) & "\green" & Dec(StringMid($aColor[$i], 3, 2)) & "\blue" & Dec(StringMid($aColor[$i], 5, 2)) & ";" & @CRLF
				$iColors += 1
				$txt = StringRegExpReplace($txt, "\[c=#" & $aColor[$i] & "\](.*?)\[/c\]", "\\cf" & $iColors & " $1\\cf0 ")
			Next
		EndIf

		$txt = StringRegExpReplace($txt, "(https?://[^\s]+)", "{""field{""*""fldinst HYPERLINK ""$0""}{""fldrslt{""ul""cf2 $0}}}")
		;$txt = StringRegExpReplace($txt, '(https?://[^\s]+)', '{\field{\*\fldinst HYPERLINK "' & "$0" & '"}{\fldrslt{\ul\cf2 ' & "$0" & '}}}')


		Local $sRTFString = "{\rtf1\ansi\deff0{\colortbl;\red0\green0\blue255;" & $sColor & "}" & $txt & "}"
		Return $sRTFString
	EndFunc

	Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
		#forceref $hWnd, $iMsg, $wParam, $lParam
		; Struktur für NMHDR
		Local $tNMHDR = DllStructCreate("struct;hwnd hWndFrom;uint_ptr idFrom;int code;endstruct", $lParam)
		Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
		Local $iCode = DllStructGetData($tNMHDR, "code")

		; Identifizieren des RichEdit-Felds anhand des Handles
		If $iCode = $EN_LINK Then
			Local $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam)
			If DllStructGetData($tMsgFilter, "msg") = $WM_LBUTTONUP Then
				Local $tEnLink = DllStructCreate($tagENLINK, $lParam)
				Local $iCpMin = DllStructGetData($tEnLink, "cpMin")
				Local $iCpMax = DllStructGetData($tEnLink, "cpMax")
				Local $sLink = _GUICtrlRichEdit_GetTextInRange($hWndFrom, $iCpMin, $iCpMax)
				ShellExecute($sLink)
			EndIf
		EndIf
	EndFunc

