#include-once
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>

Global $sInputs_Array[1][2]

If Not IsDeclared("WM_COMMAND") Then Global Const $WM_COMMAND = 0x0111
If Not IsDeclared("WM_MOVE") Then Global Const $WM_MOVE = 0x0003
If Not IsDeclared("WM_LBUTTONDOWN") Then Global Const $WM_LBUTTONDOWN = 0x0201
If Not IsDeclared("WM_RBUTTONDOWN") Then Global Const $WM_RBUTTONDOWN = 0x0204

Global $sToolTip_Text[2] = ["You can only type certain characters.", "Unacceptable Character:"]

GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")
GUIRegisterMsg($WM_MOVE, "WM_CLEAR_TOOLTIP")
GUIRegisterMsg($WM_LBUTTONDOWN, "WM_CLEAR_TOOLTIP")
GUIRegisterMsg($WM_RBUTTONDOWN, "WM_CLEAR_TOOLTIP")

Func _InputBox($iCount, $sTitle, $sText, $sDefault, $iRows = 1, $sRegExp = "", $iMode = 0, $sDelim = "|")
	;Author: SEuBo
	;$iCount: Anzahl der "Inputgruppen"
	;$sTitle: Titel der _InputBox
	;$sText: Text für die einzelnen Gruppen. Hier wird ein Trennzeichenseperierter String benötigt
	;BSP: "1|2|3". Das Trennzeichen kann in $sDelim selbst bestimmt werden, falls das erwünscht ist
	;$sDefault: Default-Text für die Input felder. Hier wird wieder ein seperierter String benötigt.
	;$iMode: Der Rückgabemodus. 0 (Standard) = Array. 1 = mit $sDelim seperierter String.
	Dim $sInputs_Array[1][2]
	$OnEvent = Opt("GUIOnEventMode", 0)
	Local $aData[$iCount + 1][2], $ifCount = 0, $aText = StringSplit($sText, $sDelim, 2), $aDefault = StringSplit($sDefault, $sDelim, 2), $aRegExp = StringSplit($sRegExp, $sDelim, 2)
	If $iCount = "" Or $iCount < 1 Or $iMode < 0 Or $iMode > 1 Or $sDelim = "" Then
		Return SetError(2, 0, "")
	EndIf
	If $aDefault[0] < $iCount + 1 Or $aDefault[0] > $iCount + 1 Then
		ReDim $aDefault[$iCount + 1]
	EndIf
	If $aText[0] < $iCount + 1 Or $aText[0] > $iCount + 1 Then
		ReDim $aText[$iCount + 1]
	EndIf
	If $aRegExp[0] < $iCount + 1 Or $aRegExp[0] > $iCount + 1 Then
		ReDim $aRegExp[$iCount + 1]
	EndIf
	$_InputBox = GUICreate($sTitle, 220 * $iRows, 65 + $iCount / $iRows * 95, -1, -1, -1, 0x00000008)
	For $r = 1 To $iRows
		For $i = 1 To $iCount / $iRows
			$aData[$ifCount][0] = GUICtrlCreateLabel($aText[$ifCount], 20 + (($r - 1) * 190), (($i - 1) * 95) + 25, 180, 55)
			$aData[$ifCount][1] = GUICtrlCreateInput($aDefault[$ifCount], 20 + (($r - 1) * 190), (($i - 1) * 95) + 75, 180, 25)
			_GUIInputSetRegExp($aData[$ifCount][1], $aRegExp[$ifCount])
			$ifCount += 1
		Next
	Next
	$hButton = GUICtrlCreateButton("Ok", 20, ((($ifCount/$iRows) - 1) * 95) + 110, 80, 25)
	$hCancel = GUICtrlCreateButton("Cancel", 120, ((($ifCount/$iRows) - 1) * 95) + 110, 80, 25)
	GUISetState()
	While 1 * Sleep(50)
		$nMsg = GUIGetMsg()
		Switch $nMsg
			Case -3, $hCancel
				GUIDelete($_InputBox)
				Return SetError(1, 0, "")
			Case $hButton
				Switch $iMode
					Case 0
						Local $aRet[$iCount]
						For $i = 0 To $iCount-1
							$aRet[$i] = GUICtrlRead($aData[$i][1])
						Next
						GUIDelete($_InputBox)
						Return $aRet
					Case 1
						Local $aRet
						For $i = 0 To $iCount-1
							$aRet &= GUICtrlRead($aData[$i][1]) & $sDelim
						Next
						GUIDelete($_InputBox)

						Return StringTrimRight($aRet, 1)
				EndSwitch
		EndSwitch
	WEnd
	Opt("GUIOnEventMode", $OnEvent)
EndFunc   ;==>_InputBox
;MrCreator========>
;Edited by SEuBo
Func _GUIInputSetRegExp($CtrlId, $sRegExp)
	Local $iUbound = UBound($sInputs_Array)
	ReDim $sInputs_Array[$iUbound + 1][2]
	$sInputs_Array[$iUbound][0] = $CtrlId
	$sInputs_Array[$iUbound][1] = $sRegExp
EndFunc   ;==>_GUIInputSetRegExp

Func _Input_Changed($hWnd, $CtrlId, $iIndex)
	ToolTip("")
	If $sInputs_Array[$iIndex][1] = "" Then Return
	Local $Read_Input = GUICtrlRead($CtrlId)
	If StringRegExp($Read_Input, $sInputs_Array[$iIndex][1]) Then
		GUICtrlSetData($CtrlId, StringRegExpReplace($Read_Input, $sInputs_Array[$iIndex][1], ''))

		Local $Gui_Get_Pos = WinGetPos($hWnd)
		Local $Ctrl_Get_Pos = ControlGetPos($hWnd, "", $CtrlId)

		Local Const $SM_CYCAPTION = 4 ;Titelbar heigth
		Local Const $SM_CXFIXEDFRAME = 7 ;Window border size

		Local $X_Pos = $Gui_Get_Pos[0] + $Ctrl_Get_Pos[0] + $Ctrl_Get_Pos[2] + GetSystemMetrics($SM_CXFIXEDFRAME)
		Local $Y_Pos = $Gui_Get_Pos[1] + $Ctrl_Get_Pos[1] + $Ctrl_Get_Pos[3] + GetSystemMetrics($SM_CYCAPTION)

		ToolTip($sToolTip_Text[0], $X_Pos, $Y_Pos, $sToolTip_Text[1], 3, 1 + 4)
		DllCall("user32.dll", "int", "MessageBeep", "int", 0x0)
	EndIf
EndFunc   ;==>_Input_Changed

Func WM_CLEAR_TOOLTIP($hWnd, $iMsg, $wParam, $lParam)
	ToolTip("")
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_CLEAR_TOOLTIP

Func MY_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
	If $hWnd = 0 Or Not WinExists($hWnd) Then Return $GUI_RUNDEFMSG

	Local $nNotifyCode = BitShift($wParam, 16)
	Local $nID = BitAND($wParam, 0xFFFF)
	Local Const $EN_CHANGE = 0x300
	Local Const $EN_UPDATE = 0x400
	Local Const $EN_SETFOCUS = 0x100
	Local Const $EN_KILLFOCUS = 0x200

	For $i = 1 To UBound($sInputs_Array) - 1
		If $nID = $sInputs_Array[$i][0] Then
			Switch $nNotifyCode
				Case $EN_UPDATE ;$EN_CHANGE
					_Input_Changed($hWnd, $sInputs_Array[$i][0], $i)
				Case $EN_SETFOCUS, $EN_KILLFOCUS
					ToolTip("")
			EndSwitch
			ExitLoop
		EndIf
	Next

	Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_WM_COMMAND

Func GetSystemMetrics($Flag)
	Local $iRet = DllCall('user32.dll', 'int', 'GetSystemMetrics', 'int', $Flag)
	Return $iRet[0]
EndFunc   ;==>GetSystemMetrics
;<==========
