sqlite test init db command

sqlite test init db command

#region ====INIT ===============================================================
	Func _ConfigInitial()

;~ 		ConsoleWrite('++ConfigDBInitial() = ' & @CRLF)
		_SQLite_down()
;~ 		_DBvarInit()
		; -------check if SQLIte SubteBA db exist
		SQLite_init()
		$SQLq = "SELECT name FROM sqlite_temp_master WHERE type='table';"
		_SQLITErun($SQLq, $dbfullPath, $quietSQLQuery)
	;~ 	;-------- Init Log
	;~ 	_initLog()
		;------------------------------------------------------------------------------
	EndFunc   ;==>_ConfigDBInitial
#endregion
#region  ==== SQL functions =======================================================================
	Func SQLInsertMessage($TweetID,$TweeMsg,$TweeDate)
;~ 		ConsoleWrite('++InsertMessageSQL() = '& @crlf)
		$query='INSERT INTO messages VALUES (' & $TweetID & ',"' & $TweeMsg & '" ,' & $TweeDate & ') ;'
		if _SQLITErun($query,$dbfullPath,$quietSQLQuery) Then
			return true
		Else
			MsgBox(48+4096,"Error inserting mesages ErrNo 1010" & @CRLF & $query,0,0)
			Return false
		EndIf
	EndFunc
	Func SQLInsertUserMessage($TweetID,$TweeMsg,$UserID,$Fname,$Lname,$TweeDate)
;~ 		ConsoleWrite('++InsertMessageSQL() = '& @crlf)
		$query='INSERT INTO UserMessages VALUES (' & $TweetID & ',"' & _
		$TweeMsg & '" ,' & $UserID & ',"' & $Fname &"_"& $Lname & '",' & $TweeDate & ') ;'
		if _SQLITErun($query,$dbfullPath,$quietSQLQuery) Then
			return true
		Else
			MsgBox(48+4096,"Error inserting mesages ErrNo 1010" & @CRLF & $query,0,0)
			Return false
		EndIf
	EndFunc
	Func SQLGetUsers()
;~ 		ConsoleWrite('++SQLGetUsers() = '& @crlf)
		$query='SELECT * FROM Users ;'
		_SQLITEqry($query,$dbfullPath)
	EndFunc
	Func SQLGetActiveUsers()
;~ 		ConsoleWrite('++SQLGetActiveUsers() = '& @crlf)
		$query='SELECT * FROM Users WHERE Active=1 ;'
		_SQLITEqry($query,$dbfullPath)
	EndFunc
	Func SQLGetDevUsers()
;~ 		ConsoleWrite('++SQLGetDevUsers() = '& @crlf)
		$query='SELECT * FROM Users WHERE Active=1 AND Dev=1 ;'
		_SQLITEqry($query,$dbfullPath)
	EndFunc
	Func SQLExist_Message($TweetID)
;~ 		ConsoleWrite('++Exist_Message() = '&$TweetID& @crlf)
		$query='SELECT id FROM messages WHERE id="'&$TweetID &'";'
		_SQLITEqry($query,$dbfullPath)
		If  IsArray($qryResult) Then
			if UBound($qryResult)>1 then
				return $qryResult[1][0]
			EndIf
			return 0
		endif
		Return 0
	EndFunc
#endregion
#region  ==== send messages =======================================================================
;~  	Func sendmessages($message)  ;~ from file of recipients
;~ 		Local $fileh = FileOpen("secret\recipients.txt", 0)
;~ 		If $fileh = -1 Then
;~ 			Exit 26
;~ 		EndIf
;~ 		While 1
;~ 			Local $chatidLine = FileReadLine($fileh)
;~ 			If @error = -1 Then ExitLoop
;~ 			$chatidArr = StringSplit($chatidLine, ',')
;~ 			$chatid = $chatidArr[1]
;~ 			if $chatID<>"" then
;~ 				ConsoleWrite('- $chatid = ' & $chatid & "  ->  " & $chatidArr[2] & @CRLF)
;~ 				$respuesta = SendTelegramexec($chatid,$message)
;~ 			$respuesta  0 is ok
;~ 			endif
;~ 		WEnd
;~ 		FileClose($fileh)
;~ 	EndFunc   ;==>_sendmessages
	Func TelegramInitialMessage($UserID)
;~ 	ConsoleWrite('++TelegramInitialMessage() = '& @crlf)
		$message ="SubteBA BOT , lee los informes de Subte BA en Twitter, y los manda por este canal. "
		$message&='Este canal no es official del subte de Buenos Aires Ni de Metrovias.'  & $nuevaLinea
		$message&= $nuevaLinea
		$message&='Commandos:'  & $nuevaLinea
		$message&='/START -> Activa la recepcion de alertas. '  & $nuevaLinea
		$message&='/STOP  -> Desactiva la recepcion de alertas. '  & $nuevaLinea
		$message&='/INFO -> Muestra este mensage'  & $nuevaLinea
		$message&= $nuevaLinea
		$message&='Futuros Comandos:'  & $nuevaLinea
		$message&='/ACTIVAR A B -> Recepcion de alertas de la Linea A, B (C, D, E, H, P, U)'  & $nuevaLinea
		$message&='/DESACTIVAR A B -> Recepcion de alertas de la Linea A, B (C, D, E, H, P, U)'  & $nuevaLinea
		$message&='/ESTACIONES A -> lista de estaciones de la linea A( B, C, D, E, H, P, U)'  & $nuevaLinea
		$message&='/HORARIOS  -> Horarios de actividad'  & $nuevaLinea
		$message&='/MAPA  -> Mapa de lineas de subte'  & $nuevaLinea
		$message&='/PROPUESTA propuesta -> Enviar propuestas'  & $nuevaLinea

		$respuesta = SendTelegramexec($UserID,$message)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : $respuestaInitialMessage = ' & $respuesta & @crlf )
	EndFunc
	Func TelegramSTOPMessage($UserID)
		$message ="Los mensajes de alertas han sido deshabilitados" & $nuevaLinea
		$message&='/START -> Para habilitar la recepcion de alertas'  & $nuevaLinea
		$message&='INFO -> para mas informacion.'  & $nuevaLinea

		$respuesta = SendTelegramexec($UserID,$message)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : TelegramSTOPMessage = ' & $respuesta & @crlf )
	EndFunc
	Func TelegramSTARTMessage($UserID)
		$message ="Los mensajes de alertas han sido habilitados" & $nuevaLinea
		$message&='/STOP-> Para deshabilitar la recepcion de alertas'  & $nuevaLinea
		$message&='INFO -> para mas informacion.'  & $nuevaLinea

		$respuesta = SendTelegramexec($UserID,$message)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : TelegramSTARTMessage = ' & $respuesta & @crlf )
	EndFunc
	Func TelegramErrorMessage($UserID)
		$message ="No se ha registrado el cambio requerido." & $nuevaLinea
		$message&='Reintente enviar el comando nuevamente.'  & $nuevaLinea
		$message&='INFO -> para mas informacion.'  & $nuevaLinea

		$respuesta = SendTelegramexec($UserID,$message)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : TelegramErrorMessage = ' & $respuesta & @crlf )
	EndFunc
	Func TelegramBaseMessage($TweetID,$USRmsg,$UserID,$Fname,$Lname,$epoch)
		$message ="No logro entender el mensaje."
		$message&='Reintente enviar el comando nuevamente.'  & $nuevaLinea
		$message&='INFO -> para mas informacion.'& $nuevaLinea & $nuevaLinea
		$message&="Su mensage:" & $nuevaLinea & $USRmsg
		$respuesta = SendTelegramexec($UserID,$message)
		SQLInsertUserMessage($TweetID,$USRmsg,$UserID,$Fname,$Lname,$epoch)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : TelegramErrorMessage = ' & $respuesta & @crlf )
	EndFunc
	Func ReformatMessage($message)
;~ 	ConsoleWrite('++ReformatMessage() = '& @crlf)
		$msgArr=StringSplit($message,"Actualizado",1)
		$diaHoraArr=stringsplit(StringStripWS($msgArr[2],1+2)," ")
		$hora=$diaHoraArr[2]
		$dia=$diaHoraArr[1]
		$msg=""&$hora&""&"     " & $dia & $nuevaLinea & StringStripWS($msgArr[1],1+2)
		return $msg
	EndFunc
	Func sendmessages($message)
		$message=ReformatMessage($message)
		SQLGetActiveUsers()
		If  IsArray($qryResult) Then
			for $i=1 to UBound($qryResult)-1
				$isDev = $qryResult[$i][4]
				$chatid = $qryResult[$i][0]
				$ChatUser = $qryResult[$i][1] & " " & $qryResult[$i][2]
				if $chatID<>"" then
					select
						Case $SendToAll = 1
							ConsoleWrite('- $chatid = ' & $chatid & "  ->  " & $ChatUser & @CRLF)
							$respuesta = SendTelegramexec($chatid,$message)
						Case $isDev = 1 AND $SendToAll = 0
							ConsoleWrite('- $chatid = ' & $chatid & "  ->  " & $ChatUser & @CRLF)
							$respuesta = SendTelegramexec($chatid,$message)
					endSelect
					;~ $respuesta  0 is ok
				endif
			next
			return true
		endif
		Return false
	EndFunc   ;==>_sendmessages
	Func SendTelegramexec($chatid,$msgtext="testeo harcoded",$DisableNotification=True)
		$urlMSG="https://api.telegram.org/" & $token & "/sendMessage?chat_id=" & $chatid & _
		"&text=" & $msgtext & "&parse_mode=HTML"
		If $DisableNotification = True Then $urlMSG &= "&disable_notification=True"
		$sGet = HttpGet($urlMSG)

		if $sget<>"0"  then
			ConsoleWrite('Tlgm sent = ' & $msgtext & @crlf )
			return 0
		Else
			$s_text="Error sending message to Telegram = " & $sGet
			ConsoleWrite('!! ' & $s_text & @crlf )
			return 1
		endif
	EndFunc
#endregion
#region  ==== Tweeter scrapping ===================================================================
	Func TweeterMessages($Username)
		ConsoleWrite('++TweeterMessages() = '& $Username &@crlf)
		$htmltxt=_ScrapTweetMessages($Username)
		if $htmltxt<>"" then
			$TweetArr = _gettweetArr($htmltxt)
			if IsArray($TweetArr) then
				$newMessagesFlag=0
				_ArraySort($TweetArr, 0, 0, 0, 2)
				For $i = 0 To UBound($TweetArr) -1
					$TweetID = $TweetArr[$i][0]
					$TweeMsg = $TweetArr[$i][1]
					$TweeDate = $TweetArr[$i][2]
					if not SQLExist_Message($TweetID) then
						SQLInsertMessage($TweetID,$TweeMsg,$TweeDate)
						$TweetMinOld= (_GetUnixTime() - $TweeDate)/60
						if $TweetMinOld < 60 then
							sendmessages($TweeMsg)
							$newMessagesFlag=1
							ConsoleWrite('+ New messages ' & _NowTime(4) & "   ")
						Else
							ConsoleWrite('+ Old messages ' & $TweetMinOld & "   ")
						endif
					endif
					sleep(2000)
				Next
				if $newMessagesFlag=0 then ConsoleWrite('  No new messages ' & _NowTime(4) & @CRLF)
			endif
		endif
	EndFunc
	func _ScrapTweetMessages($Username)
		Local $sData = InetRead("https://twitter.com/"&$Username)
		Local $nBytesRead = @extended
		ConsoleWrite('@@ BytesRead = ' & $nBytesRead &"   ")
		$htmltxt = BinaryToString($sData)
		If $nBytesRead < 100000 or StringInStr($htmltxt,"subteba")<1 Then
			ConsoleWrite('  Connection issue contacting  ' & "https://twitter.com/"&$Username& @crlf)
			$htmltxt=""
			Return $htmltxt
		endif
		return $htmltxt
	EndFunc
	Func _gettweetArr($htmltxt)
		$MSGArr = StringRegExp($htmltxt, '(?s)(?i)
(.*?)
', 3)
		if IsArray($MSGArr) then
			dim  $TweetMSGArr[UBound($MSGArr)]
			For $i = 0 To UBound($MSGArr) -1
				$TweetMessage = StringRegExp($MSGArr[$i], '(?s)(?i)
(.*?)
', 1)
				$mensaje = clearstring($TweetMessage[1])
				$TweetMSGArr[$i]=$mensaje
			Next
			$TweetDate = StringRegExp($htmltxt, '(?s)(?i)data-time="(.*?)"', 3)
			$TweetIDArr = StringRegExp($htmltxt, '(?s)(?i)data-tweet-id="(.*?)"', 3)
			$TweetArrAux = _mergeArray($TweetIDArr, $TweetMSGArr)
			$TweetArr = _mergeArray($TweetArrAux, $TweetDate)
	;~ 		_ArrayDisplay($TweetArr)
			return $TweetArr
		Else
			ConsoleWrite('!!!(' &  @ScriptLineNumber & ') : Error on  $MSGArr = ' & $MSGArr & @crlf )
			return 0
		endif
	EndFunc
#endregion
#region  ==== Bot Messages handeling ===================================================================
;~ 	Func isbot($jsonObj)
;~ 		ConsoleWrite('++isbot() = '& @crlf)
;~ 		$res = StripStrJS($jsonObj.jsonPath( "$.result..message.from.is_bot").stringify())
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : $res = ' & $res & @crlf )
;~ 		return $res
;~ 	EndFunc

	Func Get_BotOffSet()
;~ 		ConsoleWrite('++Get_BotOffSet() = '& @crlf)
		if NOT FileExists($OffsetFile) then
			$fileh = FileOpen($OffsetFile,1+8)
			If $fileh = -1 Then
				ConsoleWrite('   "Unable to open file 1.' & $OffsetFile )
				return 0
			endif
			FileClose($fileh)
		EndIf
		$fileh = FileOpen($OffsetFile,0)
		If $fileh = -1 Then
			ConsoleWrite('   "Unable to open file 2.' & $OffsetFile )
			return 0
		endif
		Local $offset = FileReadLine($fileh)
		if @error = -1 Then
			FileClose($fileh)
			return 0
		endif
		ConsoleWrite("Get OffSet:"& $offset)
		FileClose($fileh)
		return $offset
	EndFunc
	Func Set_BotOffSet($offset)
		ConsoleWrite('++Set_BotOffSet() = '&$offset& @crlf)
		if NOT FileExists($OffsetFile) then
			$fileh = FileOpen($OffsetFile,1+8)
			If $fileh = -1 Then
				ConsoleWrite('   "Unable to open file 3.' & $OffsetFile )
				return 0
			endif
			FileClose($fileh)
		EndIf
		$fileh = FileOpen($OffsetFile,2)
		If $fileh = -1 Then
			ConsoleWrite('   "Unable to open file 4.' & $OffsetFile )
			return 0
		endif
		FileWriteLine($fileh,$offset)
		if @error = -1 Then
			FileClose($fileh)
			return 0
		endif
		ConsoleWrite("    Set OffSet:"& $offset &@crlf)
		FileClose($fileh)
		return 1
	EndFunc
	func UpdateUsers()
		ConsoleWrite('  '&@HOUR & ':' & @MIN&'  Update users.  ' )
		local $s=GetBotUpdates()
		if $s then
			$s=ParseForUserUpdate($s)
			ConsoleWrite('@@ $s = ' & $s & @crlf )
			if $s then
				$oJSON = _OO_JSON_Init()
				$jsonObj = $oJSON.parse($s)
				if $jsonObj.ok  then
					if $jsonObj.jsonPath( "$.result").stringify() = "[[]]" then
						ConsoleWrite(' No Bot data ' & @crlf)
					Else
						ConsoleWrite('  Updating... ' & @crlf)
						$UpdateIDArr = StripIntJS($jsonObj.jsonPath( "$.result..update_id").stringify()  )
						$UserIDArr =   StripIntJS($jsonObj.jsonPath( "$.result..message.from.id").stringify())
						$FnameArr =    StripStrJS($jsonObj.jsonPath( "$.result..message.from.first_name").stringify())
						$LnameArr =    StripStrJS($jsonObj.jsonPath( "$.result..message.from.last_name").stringify())
						$epochArr =    StripIntJS($jsonObj.jsonPath( "$.result..message.date").stringify())
						$menssageArr = StripStrJS($jsonObj.jsonPath( "$.result..message.text").stringify())
						$IsBot =       StripIntJS($jsonObj.jsonPath( "$.result..message.from.is_bot").stringify())
						if $UserIDArr[0] = $UpdateIDArr[0] AND  $UserIDArr[0] = $FnameArr[0] AND _
							$UserIDArr[0] = $LnameArr[0]    AND  $UserIDArr[0] = $epochArr[0] AND _
							$UserIDArr[0] = $menssageArr[0] AND  $UserIDArr[0] = $IsBot[0]  then
							$retBad=0
							for $i=1 to $UserIDArr[0]
								if $IsBot[$i] <> "true" then
									$ret=SQLregister($UserIDArr[$i],$FnameArr[$i],$LnameArr[$i],$epochArr[$i],$menssageArr[$i])
									$ret1=ParseBotMessage($UserIDArr[$i],$FnameArr[$i],$LnameArr[$i],$epochArr[$i],$menssageArr[$i],$UpdateIDArr[$i])
									ConsoleWrite('>> $ret1 = ' & $ret1 & @crlf )
									if (Not $ret) or (Not $ret1)  then	$retBad+=1
									$UpdateID=$UpdateIDArr[$i]
								Else
									ConsoleWrite('+(' & @ScriptLineNumber & ') : $menssageArr[$i] = ' & $menssageArr[$i] & @crlf )
									ConsoleWrite('+(' & @ScriptLineNumber & ') : $IsBot[$i] = ' & $IsBot[$i] & @crlf )
									$retBad=1
								endif
							next
							if $retBad=0 then Set_BotOffSet($UpdateID+1)
						Else
							_printFromArray($UserIDArr)
							_printFromArray($FnameArr)
							_printFromArray($LnameArr)
							_printFromArray($epochArr)
							_printFromArray($menssageArr)
							ConsoleWrite('  Error in JS array . exiting..... ' & @crlf)
							exit 29
						endif
					endif
				endif
			endif
		endif
	EndFunc
	Func GetBotUpdates()
		$offset=Get_BotOffSet()
		$urlMSG="https://api.telegram.org/" & $token & "/getUpdates?offset="&$offset
		$sGet = HttpGetJson1($urlMSG)
;~ 		ConsoleWrite('@@ $sGet = ' & $sGet & @crlf )
		if $sGet<>"" then
			return $sGet
		Else
			$s_text="  Error getUpdates from Telegram = "
			ConsoleWrite('!! ' & $s_text & @crlf & "! " & $sGet)
			return false
		endif
	EndFunc
	Func StripStrJS($st)
		$st=StringReplace($st,'","',":::")
		$st=clearstring($st)
		$st=StringReplace($st,"[","")
		$st=StringReplace($st,"]","")
		$st=StringReplace($st,'"',"")
		$stArr=StringSplit($st,":::",1)
		return $stArr
	EndFunc
	Func StripIntJS($st)
		$st=StringReplace($st,',',":::")
		$st=clearstring($st)
		$st=StringReplace($st,"[","")
		$st=StringReplace($st,"]","")
		$st=StringReplace($st,'"',"")
		$stArr=StringSplit($st,":::",1)
		return $stArr
	EndFunc
	Func ParseForUserUpdate($s)
;~ 		if StringInStr($s,'"location":') Then
;~ 			$s='{"ok":true,"result":[]}'
;~ 			return $s
;~ 		endif
;~ 		eliminate location info
;~ "location":{"latitude":-34.631010,"longitude":-58.469731}}
		$s=StringRegExpReplace($s,'(?s)(?i)"location":{"latitude":(.*?),"longitude":(.*?)}'  ,  '"text": ""' )
;~ 		eliminate contact info
		$s=StringRegExpReplace($s,'(?s)(?i)"contact":(.*?)}'  ,  '"text": ""' )
;~ 		replace username last-name
		$s=StringReplace($s,'"username":','"last_name":')
;~ 		eliminate sticker info
		$s=StringRegExpReplace($s,'(?s)(?i)"sticker":(.*?)}(.*?)}'  ,  '"text": ""' )
		return $s
	EndFunc
	Func SQLregister($UserID,$Fname,$Lname,$epoch,$mensage)
;~ 	ConsoleWrite('++SQLregister() = '& @crlf)
		$existUser=0
		If SQLExistUser($UserID)=$userID then $existUser=1
		if $existUser=0 then
			$setactive=1
			$ret=SQLInsertUser($UserID,$Fname,$Lname,$epoch,$setactive)
			if $ret then
				$ret=TelegramSTOPMessage($UserID)
				if $ret=0 then return true
			else
				$ret=TelegramErrorMessage($UserID)
				if $ret=0 then return true
			endif
			return false
		endif

		$setactive=-1
		if AIMessage($mensage,"/START") then $setactive=1
		if AIMessage($mensage,"/STOP") then $setactive=0
		if $existUser=1 AND $setactive<>-1 then
			$ret=SQLUpdateUserActive($UserID,$Fname,$Lname,$setactive)
			if $ret and $setactive=0 then
				$ret=TelegramSTOPMessage($UserID)
				if $ret=0 then return true
			endif
			if $ret and $setactive=1 then
				$ret=TelegramSTARTMessage($UserID)
				if $ret=0 then return true
			endif
			if NOT $ret then TelegramErrorMessage($UserID)
			return false
		endif

		return true
	EndFunc
	Func SQLInsertUser($UserID,$Fname,$Lname,$epoch,$active=1)
		ConsoleWrite('  Nuevo usuario = '& $Fname & "  "  & $Lname  & @crlf)
		$query='INSERT INTO Users VALUES (' & $UserID & ',"' & $Fname & '","' & $Lname & '",' & $active &',0,' & $epoch & ') ;'
		if _SQLITErun($query,$dbfullPath,$quietSQLQuery) Then
			return true
		Else
			MsgBox(48+4096,"Error inserting User ErrNo 1011" & @CRLF & $query,0,0)
			Return false
		EndIf
	EndFunc
	Func SQLUpdateUserActive($UserID,$Fname,$Lname,$active=1)
		ConsoleWrite('    Usuario Activo 1/Start 0/Stop= '&$active& "  " & $Fname & "  "  & $Lname  & @crlf)
		$query='UPDATE  Users SET Active=' & $active &' WHERE UserID='& $UserID & ' ;'
		if _SQLITErun($query,$dbfullPath,$quietSQLQuery) Then
			return true
		Else
			ConsoleWrite("       Error updating active user User ErrNo 1012" & @CRLF & $query& @crlf)
			Return false
		EndIf
	EndFunc
	Func SQLExistUser($UserID)
;~ 	ConsoleWrite('++SQLExistUser() = '& @crlf)
		$query='SELECT UserID FROM Users WHERE UserID="'&$UserID &'";'
		_SQLITEqry($query,$dbfullPath)
		If  IsArray($qryResult) Then
			if UBound($qryResult)>1 then
				return $qryResult[1][0]
			EndIf
			return 0
		endif
		Return 0
	EndFunc
#endregion
#region   ===========================================================================
	func closeall()
		_SQLite_Close()
		_SQLite_Shutdown()
		exit 30
	EndFunc
#endregion
#region =====================================   Helpers functions  ===============================
	Func _mergeArray($array1, $array2)
		$array1 = _ArrayAdd_Column($array1)
		$size = UBound($array1)
		$newCol = UBound($array1, 2) - 1
		For $i = 0 To $size - 1
			$array1[$i][$newCol] = $array2[$i]
		Next
	;~   _ArrayDisplay($array1)
		Return $array1
	EndFunc   ;==>_mergeArray
	Func _ArrayAdd_Column($Array)
		Local $aTemp[UBound($Array)][UBound($Array, 0) + 1]
		For $i = 0 To UBound($Array) - 1

			For $j = 0 To UBound($Array, 0) - 1
				If UBound($Array, 0) = 1 Then $aTemp[$i][0] = $Array[$i]
				If UBound($Array, 0) > 1 Then $aTemp[$i][$j] = $Array[$i][$j]
			Next
		Next
		Return $aTemp
	EndFunc   ;==>_ArrayAdd_Column
	Func _ClearSciteConsole()
		ConsoleWrite('!!!!!!!!!!!_ClearSciteConsole Func General 92!!!!!!!!!!!!  ' & @CRLF)
		ControlSend("[CLASS:SciTEWindow]", "", "Scintilla2", "+{F5}")
	EndFunc   ;==>_ClearSciteConsole
	Func _GetDOSOutput($sCommand)
	 ConsoleWrite('++_GetDOSOutput $sCommand = ' & $sCommand & @crlf )
		Local $iPID, $sOutput = ""
		$iPID = Run('"' & @ComSpec & '" /c ' & $sCommand, "", @SW_HIDE, 2 + 4)
		While 1
			$sOutput &= StdoutRead($iPID, False, False)
			$err=@error
			If $err Then
				ConsoleWrite('!!  _GetDOSOutput $err = ' & $err & @crlf )
				ExitLoop
			EndIf
	;~ 	Sleep(10)
		WEnd
		ConsoleWrite('>> 	Output = ' & $sOutput & @crlf )
		Return $sOutput
	EndFunc   ;==>_GetDOSOutput
	Func _timeBetween($cTime, $sTime, $eTime)
		 If Not _DateIsValid('2000/01/01 ' & $cTime) Then Return -1
		 If Not _DateIsValid('2000/01/01 ' & $sTime) Then Return -2
		 If Not _DateIsValid('2000/01/01 ' & $eTime) Then Return -3
		 ;~  ConsoleWrite(_DateDiff('s', '2000/01/01 ' & $cTime & ':00', '2000/01/01 ' & $sTime & ':00') & @CRLF)
		 ;~  ConsoleWrite(_DateDiff('s', '2000/01/01 ' & $cTime & ':00', '2000/01/01 ' & $eTime & ':00') & @CRLF)
		 If _DateDiff('s', '2000/01/01 ' & $cTime & ':00', '2000/01/01 ' & $sTime & ':00') < 0 And _
			 _DateDiff('s', '2000/01/01 ' & $cTime & ':00', '2000/01/01 ' & $eTime & ':00') > 0 Then
			  Return 1
		 Else
			  Return 0
		 EndIf
	EndFunc  ; ==>_timeBetween
#endregion
#region time
	Func  Sec2Time($nr_sec)
		$sec2time_hour = Int($nr_sec / 3600)
		$sec2time_min = Int(($nr_sec - $sec2time_hour * 3600) / 60)
		$sec2time_sec = $nr_sec - $sec2time_hour * 3600 - $sec2time_min * 60
		Return StringFormat('%02d:%02d:%02d', $sec2time_hour, $sec2time_min, $sec2time_sec)
	EndFunc   ;==>Sec2Time
	Func _GetUnixTime($sDate = 0);Date Format: 2013/01/01 00:00:00 ~ Year/Mo/Da Hr:Mi:Se
		Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation()
		Local $utcTime = ""
		If Not $sDate Then $sDate = _NowCalc()
		If Int(StringLeft($sDate, 4)) < 1970 Then Return ""
		If $aSysTimeInfo[0] = 2 Then
			$utcTime = _DateAdd('n', $aSysTimeInfo[1] + $aSysTimeInfo[7], $sDate)
		Else
			$utcTime = _DateAdd('n', $aSysTimeInfo[1], $sDate)
		EndIf
		Return _DateDiff('s', "1970/01/01 00:00:00", $utcTime)
	EndFunc   ;==>_GetUnixTime
#endregion

#region ====INIT ===============================================================
	Func _ConfigInitial()

;~ 		ConsoleWrite('++ConfigDBInitial() = ' & @CRLF)
		_SQLite_down()
;~ 		_DBvarInit()
		; -------check if SQLIte SubteBA db exist
		SQLite_init()
		$SQLq = "SELECT name FROM sqlite_temp_master WHERE type='table';"
		_SQLITErun($SQLq, $dbfile, $quietSQLQuery)
	;~ 	;-------- Init Log
	;~ 	_initLog()
		;------------------------------------------------------------------------------
	EndFunc   ;==>_ConfigDBInitial
#endregion
#region  ==== SQL functions =======================================================================
	Func SQLInsertMessage($TweetID,$TweeMsg,$TweeDate)
;~ 		ConsoleWrite('++InsertMessageSQL() = '& @crlf)
		$query='INSERT INTO messages VALUES (' & $TweetID & ',"' & $TweeMsg & '" ,' & $TweeDate & ') ;'
		if _SQLITErun($query,$dbfullPath,$quietSQLQuery) Then
			return true
		Else
			MsgBox(48+4096,"Error inserting mesages ErrNo 1010" & @CRLF & $query,0,0)
			Return false
		EndIf
	EndFunc
	Func SQLInsertUserMessage($TweetID,$TweeMsg,$UserID,$Fname,$Lname,$TweeDate)
;~ 		ConsoleWrite('++InsertMessageSQL() = '& @crlf)
		$query='INSERT INTO UserMessages VALUES (' & $TweetID & ',"' & _
		$TweeMsg & '" ,' & $UserID & ',"' & $Fname &"_"& $Lname & '",' & $TweeDate & ') ;'
		if _SQLITErun($query,$dbfullPath,$quietSQLQuery) Then
			return true
		Else
			MsgBox(48+4096,"Error inserting mesages ErrNo 1010" & @CRLF & $query,0,0)
			Return false
		EndIf
	EndFunc
	Func SQLGetUsers()
;~ 		ConsoleWrite('++SQLGetUsers() = '& @crlf)
		$query='SELECT * FROM Users ;'
		_SQLITEqry($query,$dbfullPath)
	EndFunc
	Func SQLGetActiveUsers()
;~ 		ConsoleWrite('++SQLGetActiveUsers() = '& @crlf)
		$query='SELECT * FROM Users WHERE Active=1 ;'
		_SQLITEqry($query,$dbfullPath)
	EndFunc
	Func SQLGetDevUsers()
;~ 		ConsoleWrite('++SQLGetDevUsers() = '& @crlf)
		$query='SELECT * FROM Users WHERE Active=1 AND Dev=1 ;'
		_SQLITEqry($query,$dbfullPath)
	EndFunc
	Func SQLExist_Message($TweetID)
;~ 		ConsoleWrite('++Exist_Message() = '&$TweetID& @crlf)
		$query='SELECT id FROM messages WHERE id="'&$TweetID &'";'
		_SQLITEqry($query,$dbfullPath)
		If  IsArray($qryResult) Then
			if UBound($qryResult)>1 then
				return $qryResult[1][0]
			EndIf
			return 0
		endif
		Return 0
	EndFunc
#endregion
#region  ==== send messages =======================================================================
;~  	Func sendmessages($message)  ;~ from file of recipients
;~ 		Local $fileh = FileOpen("secret\recipients.txt", 0)
;~ 		If $fileh = -1 Then
;~ 			Exit 26
;~ 		EndIf
;~ 		While 1
;~ 			Local $chatidLine = FileReadLine($fileh)
;~ 			If @error = -1 Then ExitLoop
;~ 			$chatidArr = StringSplit($chatidLine, ',')
;~ 			$chatid = $chatidArr[1]
;~ 			if $chatID<>"" then
;~ 				ConsoleWrite('- $chatid = ' & $chatid & "  ->  " & $chatidArr[2] & @CRLF)
;~ 				$respuesta = SendTelegramexec($chatid,$message)
;~ 			$respuesta  0 is ok
;~ 			endif
;~ 		WEnd
;~ 		FileClose($fileh)
;~ 	EndFunc   ;==>_sendmessages
	Func TelegramInitialMessage($UserID)
;~ 	ConsoleWrite('++TelegramInitialMessage() = '& @crlf)
		$message ="SubteBA BOT , lee los informes de Subte BA en Twitter, y los manda por este canal. "
		$message&='Este canal no es official del subte de Buenos Aires Ni de Metrovias.'  & $nuevaLinea
		$message&= $nuevaLinea
		$message&='Commandos:'  & $nuevaLinea
		$message&='/START -> Activa la recepcion de alertas. '  & $nuevaLinea
		$message&='/STOP  -> Desactiva la recepcion de alertas. '  & $nuevaLinea
		$message&='/INFO -> Muestra este mensage'  & $nuevaLinea
		$message&= $nuevaLinea
		$message&='Futuros Comandos:'  & $nuevaLinea
		$message&='/ACTIVAR A B -> Recepcion de alertas de la Linea A, B (C, D, E, H, P, U)'  & $nuevaLinea
		$message&='/DESACTIVAR A B -> Recepcion de alertas de la Linea A, B (C, D, E, H, P, U)'  & $nuevaLinea
		$message&='/ESTACIONES A -> lista de estaciones de la linea A( B, C, D, E, H, P, U)'  & $nuevaLinea
		$message&='/HORARIOS  -> Horarios de actividad'  & $nuevaLinea
		$message&='/MAPA  -> Mapa de lineas de subte'  & $nuevaLinea
		$message&='/PROPUESTA propuesta -> Enviar propuestas'  & $nuevaLinea

		$respuesta = SendTelegramexec($UserID,$message)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : $respuestaInitialMessage = ' & $respuesta & @crlf )
	EndFunc
	Func TelegramSTOPMessage($UserID)
		$message ="Los mensajes de alertas han sido deshabilitados" & $nuevaLinea
		$message&='/START -> Para habilitar la recepcion de alertas'  & $nuevaLinea
		$message&='INFO -> para mas informacion.'  & $nuevaLinea

		$respuesta = SendTelegramexec($UserID,$message)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : TelegramSTOPMessage = ' & $respuesta & @crlf )
	EndFunc
	Func TelegramSTARTMessage($UserID)
		$message ="Los mensajes de alertas han sido habilitados" & $nuevaLinea
		$message&='/STOP-> Para deshabilitar la recepcion de alertas'  & $nuevaLinea
		$message&='INFO -> para mas informacion.'  & $nuevaLinea

		$respuesta = SendTelegramexec($UserID,$message)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : TelegramSTARTMessage = ' & $respuesta & @crlf )
	EndFunc
	Func TelegramErrorMessage($UserID)
		$message ="No se ha registrado el cambio requerido." & $nuevaLinea
		$message&='Reintente enviar el comando nuevamente.'  & $nuevaLinea
		$message&='INFO -> para mas informacion.'  & $nuevaLinea

		$respuesta = SendTelegramexec($UserID,$message)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : TelegramErrorMessage = ' & $respuesta & @crlf )
	EndFunc
	Func TelegramBaseMessage($TweetID,$USRmsg,$UserID,$Fname,$Lname,$epoch)
		$message ="No logro entender el mensaje."
		$message&='Reintente enviar el comando nuevamente.'  & $nuevaLinea
		$message&='INFO -> para mas informacion.'& $nuevaLinea & $nuevaLinea
		$message&="Su mensage:" & $nuevaLinea & $USRmsg
		$respuesta = SendTelegramexec($UserID,$message)
		SQLInsertUserMessage($TweetID,$USRmsg,$UserID,$Fname,$Lname,$epoch)
		return $respuesta
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : TelegramErrorMessage = ' & $respuesta & @crlf )
	EndFunc
	Func ReformatMessage($message)
;~ 	ConsoleWrite('++ReformatMessage() = '& @crlf)
		$msgArr=StringSplit($message,"Actualizado",1)
		$diaHoraArr=stringsplit(StringStripWS($msgArr[2],1+2)," ")
		$hora=$diaHoraArr[2]
		$dia=$diaHoraArr[1]
		$msg=""&$hora&""&"     " & $dia & $nuevaLinea & StringStripWS($msgArr[1],1+2)
		return $msg
	EndFunc
	Func sendmessages($message)
		$message=ReformatMessage($message)
		SQLGetActiveUsers()
		If  IsArray($qryResult) Then
			for $i=1 to UBound($qryResult)-1
				$isDev = $qryResult[$i][4]
				$chatid = $qryResult[$i][0]
				$ChatUser = $qryResult[$i][1] & " " & $qryResult[$i][2]
				if $chatID<>"" then
					select
						Case $SendToAll = 1
							ConsoleWrite('- $chatid = ' & $chatid & "  ->  " & $ChatUser & @CRLF)
							$respuesta = SendTelegramexec($chatid,$message)
						Case $isDev = 1 AND $SendToAll = 0
							ConsoleWrite('- $chatid = ' & $chatid & "  ->  " & $ChatUser & @CRLF)
							$respuesta = SendTelegramexec($chatid,$message)
					endSelect
					;~ $respuesta  0 is ok
				endif
			next
			return true
		endif
		Return false
	EndFunc   ;==>_sendmessages
	Func SendTelegramexec($chatid,$msgtext="testeo harcoded",$DisableNotification=True)
		$urlMSG="https://api.telegram.org/" & $token & "/sendMessage?chat_id=" & $chatid & _
		"&text=" & $msgtext & "&parse_mode=HTML"
		If $DisableNotification = True Then $urlMSG &= "&disable_notification=True"
		$sGet = HttpGet($urlMSG)

		if $sget<>"0"  then
			ConsoleWrite('Tlgm sent = ' & $msgtext & @crlf )
			return 0
		Else
			$s_text="Error sending message to Telegram = " & $sGet
			ConsoleWrite('!! ' & $s_text & @crlf )
			return 1
		endif
	EndFunc
#endregion
#region  ==== Tweeter scrapping ===================================================================
	Func TweeterMessages($Username)
		ConsoleWrite('++TweeterMessages() = '& $Username &@crlf)
		$htmltxt=_ScrapTweetMessages($Username)
		if $htmltxt<>"" then
			$TweetArr = _gettweetArr($htmltxt)
			if IsArray($TweetArr) then
				$newMessagesFlag=0
				_ArraySort($TweetArr, 0, 0, 0, 2)
				For $i = 0 To UBound($TweetArr) -1
					$TweetID = $TweetArr[$i][0]
					$TweeMsg = $TweetArr[$i][1]
					$TweeDate = $TweetArr[$i][2]
					if not SQLExist_Message($TweetID) then
						SQLInsertMessage($TweetID,$TweeMsg,$TweeDate)
						$TweetMinOld= (_GetUnixTime() - $TweeDate)/60
						if $TweetMinOld < 60 then
							sendmessages($TweeMsg)
							$newMessagesFlag=1
							ConsoleWrite('+ New messages ' & _NowTime(4) & "   ")
						Else
							ConsoleWrite('+ Old messages ' & $TweetMinOld & "   ")
						endif
					endif
					sleep(2000)
				Next
				if $newMessagesFlag=0 then ConsoleWrite('  No new messages ' & _NowTime(4) & @CRLF)
			endif
		endif
	EndFunc
	func _ScrapTweetMessages($Username)
		Local $sData = InetRead("https://twitter.com/"&$Username)
		Local $nBytesRead = @extended
		ConsoleWrite('@@ BytesRead = ' & $nBytesRead &"   ")
		$htmltxt = BinaryToString($sData)
		If $nBytesRead < 100000 or StringInStr($htmltxt,"subteba")<1 Then
			ConsoleWrite('  Connection issue contacting  ' & "https://twitter.com/"&$Username& @crlf)
			$htmltxt=""
			Return $htmltxt
		endif
		return $htmltxt
	EndFunc
	Func _gettweetArr($htmltxt)
		$MSGArr = StringRegExp($htmltxt, '(?s)(?i)
(.*?)
', 3)
		if IsArray($MSGArr) then
			dim  $TweetMSGArr[UBound($MSGArr)]
			For $i = 0 To UBound($MSGArr) -1
				$TweetMessage = StringRegExp($MSGArr[$i], '(?s)(?i)
(.*?)
', 1)
				$mensaje = clearstring($TweetMessage[1])
				$TweetMSGArr[$i]=$mensaje
			Next
			$TweetDate = StringRegExp($htmltxt, '(?s)(?i)data-time="(.*?)"', 3)
			$TweetIDArr = StringRegExp($htmltxt, '(?s)(?i)data-tweet-id="(.*?)"', 3)
			$TweetArrAux = _mergeArray($TweetIDArr, $TweetMSGArr)
			$TweetArr = _mergeArray($TweetArrAux, $TweetDate)
	;~ 		_ArrayDisplay($TweetArr)
			return $TweetArr
		Else
			ConsoleWrite('!!!(' &  @ScriptLineNumber & ') : Error on  $MSGArr = ' & $MSGArr & @crlf )
			return 0
		endif
	EndFunc
#endregion
#region  ==== Bot Messages handeling ===================================================================
;~ 	Func isbot($jsonObj)
;~ 		ConsoleWrite('++isbot() = '& @crlf)
;~ 		$res = StripStrJS($jsonObj.jsonPath( "$.result..message.from.is_bot").stringify())
;~ 		ConsoleWrite('@@(' & @ScriptLineNumber & ') : $res = ' & $res & @crlf )
;~ 		return $res
;~ 	EndFunc

	Func Get_BotOffSet()
;~ 		ConsoleWrite('++Get_BotOffSet() = '& @crlf)
		if NOT FileExists($OffsetFile) then
			$fileh = FileOpen($OffsetFile,1+8)
			If $fileh = -1 Then
				ConsoleWrite('   "Unable to open file 1.' & $OffsetFile )
				return 0
			endif
			FileClose($fileh)
		EndIf
		$fileh = FileOpen($OffsetFile,0)
		If $fileh = -1 Then
			ConsoleWrite('   "Unable to open file 2.' & $OffsetFile )
			return 0
		endif
		Local $offset = FileReadLine($fileh)
		if @error = -1 Then
			FileClose($fileh)
			return 0
		endif
		ConsoleWrite("Get OffSet:"& $offset)
		FileClose($fileh)
		return $offset
	EndFunc
	Func Set_BotOffSet($offset)
		ConsoleWrite('++Set_BotOffSet() = '&$offset& @crlf)
		if NOT FileExists($OffsetFile) then
			$fileh = FileOpen($OffsetFile,1+8)
			If $fileh = -1 Then
				ConsoleWrite('   "Unable to open file 3.' & $OffsetFile )
				return 0
			endif
			FileClose($fileh)
		EndIf
		$fileh = FileOpen($OffsetFile,2)
		If $fileh = -1 Then
			ConsoleWrite('   "Unable to open file 4.' & $OffsetFile )
			return 0
		endif
		FileWriteLine($fileh,$offset)
		if @error = -1 Then
			FileClose($fileh)
			return 0
		endif
		ConsoleWrite("    Set OffSet:"& $offset &@crlf)
		FileClose($fileh)
		return 1
	EndFunc
	func UpdateUsers()
		ConsoleWrite('  '&@HOUR & ':' & @MIN&'  Update users.  ' )
		local $s=GetBotUpdates()
		if $s then
			$s=ParseForUserUpdate($s)
			ConsoleWrite('@@ $s = ' & $s & @crlf )
			if $s then
				$oJSON = _OO_JSON_Init()
				$jsonObj = $oJSON.parse($s)
				if $jsonObj.ok  then
					if $jsonObj.jsonPath( "$.result").stringify() = "[[]]" then
						ConsoleWrite(' No Bot data ' & @crlf)
					Else
						ConsoleWrite('  Updating... ' & @crlf)
						$UpdateIDArr = StripIntJS($jsonObj.jsonPath( "$.result..update_id").stringify()  )
						$UserIDArr =   StripIntJS($jsonObj.jsonPath( "$.result..message.from.id").stringify())
						$FnameArr =    StripStrJS($jsonObj.jsonPath( "$.result..message.from.first_name").stringify())
						$LnameArr =    StripStrJS($jsonObj.jsonPath( "$.result..message.from.last_name").stringify())
						$epochArr =    StripIntJS($jsonObj.jsonPath( "$.result..message.date").stringify())
						$menssageArr = StripStrJS($jsonObj.jsonPath( "$.result..message.text").stringify())
						$IsBot =       StripIntJS($jsonObj.jsonPath( "$.result..message.from.is_bot").stringify())
						if $UserIDArr[0] = $UpdateIDArr[0] AND  $UserIDArr[0] = $FnameArr[0] AND _
							$UserIDArr[0] = $LnameArr[0]    AND  $UserIDArr[0] = $epochArr[0] AND _
							$UserIDArr[0] = $menssageArr[0] AND  $UserIDArr[0] = $IsBot[0]  then
							$retBad=0
							for $i=1 to $UserIDArr[0]
								if $IsBot[$i] <> "true" then
									$ret=SQLregister($UserIDArr[$i],$FnameArr[$i],$LnameArr[$i],$epochArr[$i],$menssageArr[$i])
									$ret1=ParseBotMessage($UserIDArr[$i],$FnameArr[$i],$LnameArr[$i],$epochArr[$i],$menssageArr[$i],$UpdateIDArr[$i])
									ConsoleWrite('>> $ret1 = ' & $ret1 & @crlf )
									if (Not $ret) or (Not $ret1)  then	$retBad+=1
									$UpdateID=$UpdateIDArr[$i]
								Else
									ConsoleWrite('+(' & @ScriptLineNumber & ') : $menssageArr[$i] = ' & $menssageArr[$i] & @crlf )
									ConsoleWrite('+(' & @ScriptLineNumber & ') : $IsBot[$i] = ' & $IsBot[$i] & @crlf )
									$retBad=1
								endif
							next
							if $retBad=0 then Set_BotOffSet($UpdateID+1)
						Else
							_printFromArray($UserIDArr)
							_printFromArray($FnameArr)
							_printFromArray($LnameArr)
							_printFromArray($epochArr)
							_printFromArray($menssageArr)
							ConsoleWrite('  Error in JS array . exiting..... ' & @crlf)
							exit 29
						endif
					endif
				endif
			endif
		endif
	EndFunc
	Func GetBotUpdates()
		$offset=Get_BotOffSet()
		$urlMSG="https://api.telegram.org/" & $token & "/getUpdates?offset="&$offset
		$sGet = HttpGetJson1($urlMSG)
;~ 		ConsoleWrite('@@ $sGet = ' & $sGet & @crlf )
		if $sGet<>"" then
			return $sGet
		Else
			$s_text="  Error getUpdates from Telegram = "
			ConsoleWrite('!! ' & $s_text & @crlf & "! " & $sGet)
			return false
		endif
	EndFunc
	Func StripStrJS($st)
		$st=StringReplace($st,'","',":::")
		$st=clearstring($st)
		$st=StringReplace($st,"[","")
		$st=StringReplace($st,"]","")
		$st=StringReplace($st,'"',"")
		$stArr=StringSplit($st,":::",1)
		return $stArr
	EndFunc
	Func StripIntJS($st)
		$st=StringReplace($st,',',":::")
		$st=clearstring($st)
		$st=StringReplace($st,"[","")
		$st=StringReplace($st,"]","")
		$st=StringReplace($st,'"',"")
		$stArr=StringSplit($st,":::",1)
		return $stArr
	EndFunc
	Func ParseForUserUpdate($s)
;~ 		if StringInStr($s,'"location":') Then
;~ 			$s='{"ok":true,"result":[]}'
;~ 			return $s
;~ 		endif
;~ 		eliminate location info
;~ "location":{"latitude":-34.631010,"longitude":-58.469731}}
		$s=StringRegExpReplace($s,'(?s)(?i)"location":{"latitude":(.*?),"longitude":(.*?)}'  ,  '"text": ""' )
;~ 		eliminate contact info
		$s=StringRegExpReplace($s,'(?s)(?i)"contact":(.*?)}'  ,  '"text": ""' )
;~ 		replace username last-name
		$s=StringReplace($s,'"username":','"last_name":')
;~ 		eliminate sticker info
		$s=StringRegExpReplace($s,'(?s)(?i)"sticker":(.*?)}(.*?)}'  ,  '"text": ""' )
		return $s
	EndFunc
	Func SQLregister($UserID,$Fname,$Lname,$epoch,$mensage)
;~ 	ConsoleWrite('++SQLregister() = '& @crlf)
		$existUser=0
		If SQLExistUser($UserID)=$userID then $existUser=1
		if $existUser=0 then
			$setactive=1
			$ret=SQLInsertUser($UserID,$Fname,$Lname,$epoch,$setactive)
			if $ret then
				$ret=TelegramSTOPMessage($UserID)
				if $ret=0 then return true
			else
				$ret=TelegramErrorMessage($UserID)
				if $ret=0 then return true
			endif
			return false
		endif

		$setactive=-1
		if AIMessage($mensage,"/START") then $setactive=1
		if AIMessage($mensage,"/STOP") then $setactive=0
		if $existUser=1 AND $setactive<>-1 then
			$ret=SQLUpdateUserActive($UserID,$Fname,$Lname,$setactive)
			if $ret and $setactive=0 then
				$ret=TelegramSTOPMessage($UserID)
				if $ret=0 then return true
			endif
			if $ret and $setactive=1 then
				$ret=TelegramSTARTMessage($UserID)
				if $ret=0 then return true
			endif
			if NOT $ret then TelegramErrorMessage($UserID)
			return false
		endif

		return true
	EndFunc
	Func SQLInsertUser($UserID,$Fname,$Lname,$epoch,$active=1)
		ConsoleWrite('  Nuevo usuario = '& $Fname & "  "  & $Lname  & @crlf)
		$query='INSERT INTO Users VALUES (' & $UserID & ',"' & $Fname & '","' & $Lname & '",' & $active &',0,' & $epoch & ') ;'
		if _SQLITErun($query,$dbfullPath,$quietSQLQuery) Then
			return true
		Else
			MsgBox(48+4096,"Error inserting User ErrNo 1011" & @CRLF & $query,0,0)
			Return false
		EndIf
	EndFunc
	Func SQLUpdateUserActive($UserID,$Fname,$Lname,$active=1)
		ConsoleWrite('    Usuario Activo 1/Start 0/Stop= '&$active& "  " & $Fname & "  "  & $Lname  & @crlf)
		$query='UPDATE  Users SET Active=' & $active &' WHERE UserID='& $UserID & ' ;'
		if _SQLITErun($query,$dbfullPath,$quietSQLQuery) Then
			return true
		Else
			ConsoleWrite("       Error updating active user User ErrNo 1012" & @CRLF & $query& @crlf)
			Return false
		EndIf
	EndFunc
	Func SQLExistUser($UserID)
;~ 	ConsoleWrite('++SQLExistUser() = '& @crlf)
		$query='SELECT UserID FROM Users WHERE UserID="'&$UserID &'";'
		_SQLITEqry($query,$dbfullPath)
		If  IsArray($qryResult) Then
			if UBound($qryResult)>1 then
				return $qryResult[1][0]
			EndIf
			return 0
		endif
		Return 0
	EndFunc
#endregion
#region   ===========================================================================
	func closeall()
		_SQLite_Close()
		_SQLite_Shutdown()
		exit 30
	EndFunc
#endregion
#region =====================================   Helpers functions  ===============================
	Func _mergeArray($array1, $array2)
		$array1 = _ArrayAdd_Column($array1)
		$size = UBound($array1)
		$newCol = UBound($array1, 2) - 1
		For $i = 0 To $size - 1
			$array1[$i][$newCol] = $array2[$i]
		Next
	;~   _ArrayDisplay($array1)
		Return $array1
	EndFunc   ;==>_mergeArray
	Func _ArrayAdd_Column($Array)
		Local $aTemp[UBound($Array)][UBound($Array, 0) + 1]
		For $i = 0 To UBound($Array) - 1

			For $j = 0 To UBound($Array, 0) - 1
				If UBound($Array, 0) = 1 Then $aTemp[$i][0] = $Array[$i]
				If UBound($Array, 0) > 1 Then $aTemp[$i][$j] = $Array[$i][$j]
			Next
		Next
		Return $aTemp
	EndFunc   ;==>_ArrayAdd_Column
	Func _ClearSciteConsole()
		ConsoleWrite('!!!!!!!!!!!_ClearSciteConsole Func General 92!!!!!!!!!!!!  ' & @CRLF)
		ControlSend("[CLASS:SciTEWindow]", "", "Scintilla2", "+{F5}")
	EndFunc   ;==>_ClearSciteConsole
	Func _GetDOSOutput($sCommand)
	 ConsoleWrite('++_GetDOSOutput $sCommand = ' & $sCommand & @crlf )
		Local $iPID, $sOutput = ""
		$iPID = Run('"' & @ComSpec & '" /c ' & $sCommand, "", @SW_HIDE, 2 + 4)
		While 1
			$sOutput &= StdoutRead($iPID, False, False)
			$err=@error
			If $err Then
				ConsoleWrite('!!  _GetDOSOutput $err = ' & $err & @crlf )
				ExitLoop
			EndIf
	;~ 	Sleep(10)
		WEnd
		ConsoleWrite('>> 	Output = ' & $sOutput & @crlf )
		Return $sOutput
	EndFunc   ;==>_GetDOSOutput
	Func _timeBetween($cTime, $sTime, $eTime)
		 If Not _DateIsValid('2000/01/01 ' & $cTime) Then Return -1
		 If Not _DateIsValid('2000/01/01 ' & $sTime) Then Return -2
		 If Not _DateIsValid('2000/01/01 ' & $eTime) Then Return -3
		 ;~  ConsoleWrite(_DateDiff('s', '2000/01/01 ' & $cTime & ':00', '2000/01/01 ' & $sTime & ':00') & @CRLF)
		 ;~  ConsoleWrite(_DateDiff('s', '2000/01/01 ' & $cTime & ':00', '2000/01/01 ' & $eTime & ':00') & @CRLF)
		 If _DateDiff('s', '2000/01/01 ' & $cTime & ':00', '2000/01/01 ' & $sTime & ':00') < 0 And _
			 _DateDiff('s', '2000/01/01 ' & $cTime & ':00', '2000/01/01 ' & $eTime & ':00') > 0 Then
			  Return 1
		 Else
			  Return 0
		 EndIf
	EndFunc  ; ==>_timeBetween
#endregion
#region time
	Func  Sec2Time($nr_sec)
		$sec2time_hour = Int($nr_sec / 3600)
		$sec2time_min = Int(($nr_sec - $sec2time_hour * 3600) / 60)
		$sec2time_sec = $nr_sec - $sec2time_hour * 3600 - $sec2time_min * 60
		Return StringFormat('%02d:%02d:%02d', $sec2time_hour, $sec2time_min, $sec2time_sec)
	EndFunc   ;==>Sec2Time
	Func _GetUnixTime($sDate = 0);Date Format: 2013/01/01 00:00:00 ~ Year/Mo/Da Hr:Mi:Se
		Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation()
		Local $utcTime = ""
		If Not $sDate Then $sDate = _NowCalc()
		If Int(StringLeft($sDate, 4)) < 1970 Then Return ""
		If $aSysTimeInfo[0] = 2 Then
			$utcTime = _DateAdd('n', $aSysTimeInfo[1] + $aSysTimeInfo[7], $sDate)
		Else
			$utcTime = _DateAdd('n', $aSysTimeInfo[1], $sDate)
		EndIf
		Return _DateDiff('s', "1970/01/01 00:00:00", $utcTime)
	EndFunc   ;==>_GetUnixTime
#endregion


Update Exemplo_001.au3

Update Exemplo_001.au3

#include-once
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GuiTreeView.au3>
#include <TreeViewConstants.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>

#include <GUICreateEx.au3> ; https://github.com/chechelaky/AutoIt/blob/master/GuiCreateEx/GuiCreateEx.au3
#include <JSMN.au3> ; https://github.com/chechelaky/AutoIt/blob/master/JSMN.au3
#include <object_dump.au3> ; https://github.com/chechelaky/AutoIt/blob/master/object_dump.au3

#cs
	Exemplo de uso com TreeView
	Implementando/refatorando código...

	Autor: Luismar Chechelaky
#ce

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1)
Opt("MustDeclareVars", 1)

OnAutoItExitRegister("OnExit")

HotKeySet("{F2}", "Key_Edit_Start")

Global $KEY_EDIT = False

Global $ID = 0

Global Const $SQLITE_DLL = _SQLite_Startup("sqlite3.dll", False, 0)
Global $DB = _SQLite_Open("base.db", $SQLITE_OPEN_READWRITE + $SQLITE_OPEN_CREATE, $SQLITE_ENCODING_UTF8)
Global $SQL

Global $hGui, $hTreeView, $Context, $hMenu
Global Enum $ONE = 0, $TWO, $TREE
Global $aName[3] = ["A", "B", "C"]
Global $a_TreeView[3]
Global $ah_TreeView[3]
Global $hTreeView_Focus, $TreeView_ID
Global $hTreeView_Focus_Item_Handle, $hTreeView_Focus_Item_Text, $hTreeView_Focus_Item_Param
Global $hLable_TreeView_Focus_Handle, $hLabel_TreeView_Focus_Text, $hLabel_TreeView_Focus_Param

Global $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)

$hGui = GUICreateEx("TreeView", 1266, 668); , 550, 0)
_GUICreateEx_SetShortCut("KEY_EDIT", "Key_Edit_End")

$a_TreeView[$ONE] = _GUICtrlTreeView_Create($hGui, 10, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$ONE] = ControlGetHandle($hGui, "", $a_TreeView[$ONE])

$a_TreeView[$TWO] = _GUICtrlTreeView_Create($hGui, 10 + 410, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$TWO] = ControlGetHandle($hGui, "", $a_TreeView[$TWO])

$a_TreeView[$TREE] = _GUICtrlTreeView_Create($hGui, 10 + 820, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$TREE] = ControlGetHandle($hGui, "", $a_TreeView[$TREE])

$hLable_TreeView_Focus_Handle = GUICtrlCreateLabel("", 10, 470, 80, 20, $SS_SUNKEN)
$hLabel_TreeView_Focus_Text = GUICtrlCreateLabel("", 10, 500, 80, 20, $SS_SUNKEN)
$hLabel_TreeView_Focus_Param = GUICtrlCreateLabel("", 10, 530, 80, 20, $SS_SUNKEN)

Global $hParent, $hItem

For $ii = 0 To 2
	$ID += 1
	_GUICtrlTreeView_BeginUpdate($a_TreeView[$ii])
	$hParent = _GUICtrlTreeView_Add($a_TreeView[$ii], 0, "root")
	_GUICtrlTreeView_SetItemParam($a_TreeView[$ii], $hParent, $ID)
	For $jj = 0 To 9
		$ID += 1
		$hItem = _GUICtrlTreeView_AddChild($a_TreeView[$ii], $hParent, $aName[$ii] & $jj)
		_GUICtrlTreeView_SetItemParam($a_TreeView[$ii], $hItem, $ID)
		_GUICtrlTreeView_Expand($a_TreeView[$ii], $hItem)
	Next
	_GUICtrlTreeView_EndUpdate($a_TreeView[$ii])
Next

Global $aButtons[4] = [3, 0, 0, 0]

Global $iDummy = GUICtrlCreateDummy()
$Context = GUICtrlCreateContextMenu($iDummy)
$hMenu = GUICtrlGetHandle($Context)
$aButtons[1] = GUICtrlCreateMenuItem("Add", $Context)
GUICtrlSetOnEvent($aButtons[1], "Add")
$aButtons[2] = GUICtrlCreateMenuItem("Rename", $Context)
GUICtrlSetOnEvent($aButtons[2], "Rename")
$aButtons[3] = GUICtrlCreateMenuItem("Del", $Context)
GUICtrlSetOnEvent($aButtons[3], "Del")

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $hGui)

While Sleep(20)

WEnd

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	OnExit
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func OnExit()
	_SQLite_Shutdown()
EndFunc   ;==>OnExit

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_Start
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Key_Edit_Start()
	ConsoleWrite("Key_Edit_Start()" & @LF)
	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	$KEY_EDIT = True
	HotKeySet("{ENTER}", "Key_Edit_Confirm")

	_GUICtrlTreeView_EditText($hTreeView_Focus, $hItem)
EndFunc   ;==>Key_Edit_Start

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_End
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Key_Edit_End()
	ConsoleWrite("Key_Edit_End()" & @LF)
	HotKeySet("{ENTER}")
	$KEY_EDIT = False
	_GUICtrlTreeView_EndEdit($hTreeView_Focus)
EndFunc   ;==>Key_Edit_End

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_Confirm
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; source.........: http://azjio.narod.ru/autoit3_docs/libfunctions/_guictrltreeview_endedit.htm
; ===============================================================================================================================
Func Key_Edit_Confirm()
	Local $hFocus = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	Local $hEdit = _GUICtrlTreeView_GetEditControl($hTreeView_Focus)
	_GUICtrlTreeView_SetText($hTreeView_Focus, $hItem, ControlGetText($hGui, "", $hEdit))
	HotKeySet("{ENTER}")
	$KEY_EDIT = False
	_GUICtrlTreeView_EndEdit($hTreeView_Focus)
EndFunc   ;==>Key_Edit_Confirm

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Add
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Add()
	ConsoleWrite("Add" & @LF)

	$ID += 1
	Local $h_Item
	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	If $hItem = 0x00000000 Then
		$h_Item = _GUICtrlTreeView_AddChildFirst($hTreeView_Focus, $hItem, $aName[$TreeView_ID] & $ID)
	Else
		$h_Item = _GUICtrlTreeView_AddChild($hTreeView_Focus, $hItem, $aName[$TreeView_ID] & $ID)
	EndIf
	ConsoleWrite("$hTreeView[ " & $hTreeView_Focus & " ] $hItem[ " & $hItem & " ]" & @LF)
	Local $item = _GUICtrlTreeView_SetItemParam($hTreeView_Focus, $h_Item, $ID)
	ConsoleWrite("item[" & $item & "] $ID[ " & $ID & " ]" & @LF)

	_GUICtrlTreeView_Expand($hTreeView_Focus, $hItem)

EndFunc   ;==>Add

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Rename
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Rename()
	ConsoleWrite("Rename" & @LF)
EndFunc   ;==>Rename

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Del
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Del()
	ConsoleWrite("Del" & @LF)

	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	ConsoleWrite("$hItem[ " & $hItem & " ] text[ " & _GUICtrlTreeView_GetText($hTreeView_Focus, $hItem) & " ]" & @LF)

;~ 	Local $sText = _GUICtrlTreeView_GetText($hTreeView_Focus, $hFocus)
;~ 	Local $iParam = _GUICtrlTreeView_GetItemParam($a_TreeView[$ID], $hFocus)

	Local $oo = oo()

	_DelRecursive($hItem, $oo)
	For $each In $oo
		_GUICtrlTreeView_Delete($hTreeView_Focus, $each)
	Next
	dump($oo)
EndFunc   ;==>Del

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_DelRecursive
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _DelRecursive($handle, ByRef $oo)
	Local $sText = _GUICtrlTreeView_GetText($hTreeView_Focus, $handle)
	Local $iParam = _GUICtrlTreeView_GetItemParam($hTreeView_Focus, $handle)
	Local $oItem = oo()
	$oItem.Add("name", $sText)
	$oItem.Add("param", $iParam)
	Local $hChild
	If _GUICtrlTreeView_GetChildren($hTreeView_Focus, $handle) Then
		$hChild = _GUICtrlTreeView_GetFirstChild($hTreeView_Focus, $handle)
		Do
;~ 			If _GUICtrlTreeView_GetChildren($hTreeView_Focus, $hChild) Then
			_DelRecursive($hChild, $oo)
;~ 			EndIf
			$hChild = _GUICtrlTreeView_GetNextChild($hTreeView_Focus, $hChild)
		Until $hChild = 0
	EndIf
	$oo.Add(Number($handle), $oItem)
EndFunc   ;==>_DelRecursive

;~ Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
;~ 	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $selitem

;~ 	$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
;~ 	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
;~ 	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
;~ 	$iCode = DllStructGetData($tNMHDR, "Code")
;~ 	Switch $hWndFrom
;~ 		Case $a_TreeView[$ONE]
;~ 			Switch $iCode
;~ 				Case $NM_RCLICK
;~ 					$clickPos = _WinAPI_GetMousePos(True, $hGui)
;~ 					$selitem = _GUICtrlTreeView_HitTestItem($a_TreeView[$ONE], DllStructGetData($clickPos, "X"), DllStructGetData($clickPos, "Y")-10)
;~ 					If $selitem = 0 Then Return $GUI_RUNDEFMSG
;~ 					_GUICtrlTreeView_SelectItem($a_TreeView[$ONE], $selitem)

;~ 					_GUICtrlMenu_TrackPopupMenu($hMenu, $hGui)
;~ 			EndSwitch
;~ 	EndSwitch

;~ 	Return $GUI_RUNDEFMSG
;~ EndFunc   ;==>WM_NOTIFY

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_GuiCtrlTreeView_FixFocus
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _GuiCtrlTreeView_FixFocus($ID, $item = 0)
	ConsoleWrite("_GuiCtrlTreeView_FixFocus()" & @LF)

	Local $hFocus = $item ? $item : _GUICtrlTreeView_GetSelection($a_TreeView[$ID])
	Local $sText = _GUICtrlTreeView_GetText($a_TreeView[$ID], $hFocus)
	Local $iParam = _GUICtrlTreeView_GetItemParam($a_TreeView[$ID], $hFocus)

	GUICtrlSetData($hLable_TreeView_Focus_Handle, $aName[$ID])
	GUICtrlSetData($hLabel_TreeView_Focus_Text, $sText)
	GUICtrlSetData($hLabel_TreeView_Focus_Param, $iParam)

EndFunc   ;==>_GuiCtrlTreeView_FixFocus

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_GuiCtrlTreeView_EvalAction
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _GuiCtrlTreeView_EvalAction($ID, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
	$TreeView_ID = $ID
	GUICtrlSetData($hLable_TreeView_Focus_Handle, $aName[$ID])
	$hTreeView_Focus = $ah_TreeView[$ID]
	Switch $iCode
		Case $NM_CLICK ; The user has clicked the left mouse button within the control
			_DebugPrint("$NM_CLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_DBLCLK ; The user has double-clicked the left mouse button within the control
			_DebugPrint("$NM_DBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_RCLICK ; The user has clicked the right mouse button within the control
			_DebugPrint("$NM_RCLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			_GUICtrlTreeView_SelectItem($hTreeView_Focus, $hTreeView_Focus_Item_Handle)
			_GuiCtrlTreeView_FixFocus($ID, $hTreeView_Focus_Item_Handle)
			_GUICtrlMenu_TrackPopupMenu($hMenu, $hGui)
			Return 0 ; zero to allow the default processing
		Case $NM_RDBLCLK ; The user has double-clicked the right mouse button within the control
			_DebugPrint("$NM_RDBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_KILLFOCUS ; control has lost the input focus
			_DebugPrint("$NM_KILLFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; No return value
		Case $NM_RETURN ; control has the input focus and that the user has pressed the key
			_DebugPrint("$NM_RETURN" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_SETCURSOR ; control is setting the cursor in response to a WM_SETCURSOR message
			Local $tInfo = DllStructCreate($tagNMMOUSE, $lParam)
			$hWndFrom = HWnd(DllStructGetData($tInfo, "hWndFrom"))
			$iIDFrom = DllStructGetData($tInfo, "IDFrom")
			$iCode = DllStructGetData($tInfo, "Code")

			$hTreeView_Focus_Item_Handle = DllStructGetData($tInfo, "ItemSpec")
			$hTreeView_Focus_Item_Text = _GUICtrlTreeView_GetText($hTreeView_Focus, $hTreeView_Focus_Item_Handle)
			$hTreeView_Focus_Item_Param = _GUICtrlTreeView_GetItemParam($hTreeView_Focus, $hTreeView_Focus_Item_Handle)

			_DebugPrint("$NM_SETCURSOR" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode & @CRLF & _
					"-->ItemSpec:" & @TAB & DllStructGetData($tInfo, "ItemSpec") & @CRLF & _
					"-->ItemData:" & @TAB & DllStructGetData($tInfo, "ItemData") & @CRLF & _
					"-->X:" & @TAB & DllStructGetData($tInfo, "X") & @CRLF & _
					"-->Y:" & @TAB & DllStructGetData($tInfo, "Y") & @CRLF & _
					"-->HitInfo:" & @TAB & DllStructGetData($tInfo, "HitInfo"))
			; Return 0 ; to enable the control to set the cursor
			Return 1 ; nonzero to prevent the control from setting the cursor
		Case $NM_SETFOCUS ; control has received the input focus
			_DebugPrint("$NM_SETFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; No return value
		Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW
			_DebugPrint("$TVN_BEGINDRAG")
		Case $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW
			_DebugPrint("$TVN_BEGINLABELEDIT")
		Case $TVN_BEGINRDRAGA, $TVN_BEGINRDRAGW
			_DebugPrint("$TVN_BEGINRDRAG")
		Case $TVN_DELETEITEMA, $TVN_DELETEITEMW
			_DebugPrint("$TVN_DELETEITEM")
		Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW

			ConsoleWrite("Edit Control Handle: 0x" & Hex(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)) & @CRLF & _
					"IsPtr = " & IsPtr(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)) & " IsHWnd = " & IsHWnd(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)))

			Local $tInfo = DllStructCreate($tagNMTVDISPINFO, $lParam)
			Local $sBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax"))
			ConsoleWrite("$sBuffer[ " & $sBuffer & " ]" & @LF)
			If Not _GUICtrlTreeView_GetUnicodeFormat($hWndFrom) Then $sBuffer = StringTrimLeft($sBuffer, 1)
			ConsoleWrite("$sBuffer[ " & $sBuffer & " ]" & @LF)
			DllStructSetData($sBuffer, "Text", DllStructGetData($tInfo, "Text"))

			If StringLen(DllStructGetData($sBuffer, "Text")) Then Return 1

			_DebugPrint("$TVN_ENDLABELEDIT $sBuffer[ " & $sBuffer & " ]")
		Case $TVN_GETDISPINFOA, $TVN_GETDISPINFOW
			_DebugPrint("$TVN_GETDISPINFO")
		Case $TVN_GETINFOTIPA, $TVN_GETINFOTIPW
			_DebugPrint("$TVN_GETINFOTIP")
		Case $TVN_ITEMEXPANDEDA, $TVN_ITEMEXPANDEDW
			_DebugPrint("$TVN_ITEMEXPANDED")
		Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
			_DebugPrint("$TVN_ITEMEXPANDING")
		Case $TVN_KEYDOWN
			_DebugPrint("$TVN_KEYDOWN")
		Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW
			_GuiCtrlTreeView_FixFocus($ID)
			_DebugPrint("$TVN_SELCHANGED")
		Case $TVN_SELCHANGINGA, $TVN_SELCHANGINGW
			_DebugPrint("$TVN_SELCHANGING")
		Case $TVN_SETDISPINFOA, $TVN_SETDISPINFOW
			_DebugPrint("$TVN_SETDISPINFO")
		Case $TVN_SINGLEEXPAND
			_DebugPrint("$TVN_SINGLEEXPAND")
	EndSwitch
EndFunc   ;==>_GuiCtrlTreeView_EvalAction

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:
; Author ........:
; Modified.......:
; Link ..........:
; ===============================================================================================================================
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $lParam
	Local $tNMHDR, $hWndFrom, $iIDFrom, $iCode

	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
	$iCode = DllStructGetData($tNMHDR, "Code")
	Switch $hWndFrom
		Case $ah_TreeView[$ONE]
			_GuiCtrlTreeView_EvalAction($ONE, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
		Case $ah_TreeView[$TWO]
			_GuiCtrlTreeView_EvalAction($TWO, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
		Case $ah_TreeView[$TREE]
			_GuiCtrlTreeView_EvalAction($TREE, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_DebugPrint
; Author ........:
; Modified.......:	2
; Link ..........:
; ===============================================================================================================================
Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber)
	Return
	ConsoleWrite( _
			"!===========================================================" & @CRLF & _
			"+======================================================" & @CRLF & _
			"-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _
			"+======================================================" & @CRLF)
EndFunc   ;==>_DebugPrint

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	oo
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func oo()
	Return ObjCreate($SD)
EndFunc   ;==>oo

#include-once
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GuiTreeView.au3>
#include <TreeViewConstants.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>

#include <GUICreateEx.au3>
#include <JSMN.au3>
#include <object_dump.au3>

#cs
	Exemplo de uso com TreeView
	Implementando/refatorando código...

	Autor: Luismar Chechelaky
#ce

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1)
Opt("MustDeclareVars", 1)

OnAutoItExitRegister("OnExit")

HotKeySet("{F2}", "Key_Edit_Start")

Global $KEY_EDIT = False

Global $ID = 0

Global Const $SQLITE_DLL = _SQLite_Startup("sqlite3.dll", False, 0)
Global $DB = _SQLite_Open("base.db", $SQLITE_OPEN_READWRITE + $SQLITE_OPEN_CREATE, $SQLITE_ENCODING_UTF8)
Global $SQL

Global $hGui, $hTreeView, $Context, $hMenu
Global Enum $ONE = 0, $TWO, $TREE
Global $aName[3] = ["A", "B", "C"]
Global $a_TreeView[3]
Global $ah_TreeView[3]
Global $hTreeView_Focus, $TreeView_ID
Global $hTreeView_Focus_Item_Handle, $hTreeView_Focus_Item_Text, $hTreeView_Focus_Item_Param
Global $hLable_TreeView_Focus_Handle, $hLabel_TreeView_Focus_Text, $hLabel_TreeView_Focus_Param

Global $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)

$hGui = GUICreateEx("TreeView", 1266, 668); , 550, 0)
_GUICreateEx_SetShortCut("KEY_EDIT", "Key_Edit_End")

$a_TreeView[$ONE] = _GUICtrlTreeView_Create($hGui, 10, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$ONE] = ControlGetHandle($hGui, "", $a_TreeView[$ONE])

$a_TreeView[$TWO] = _GUICtrlTreeView_Create($hGui, 10 + 410, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$TWO] = ControlGetHandle($hGui, "", $a_TreeView[$TWO])

$a_TreeView[$TREE] = _GUICtrlTreeView_Create($hGui, 10 + 820, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$TREE] = ControlGetHandle($hGui, "", $a_TreeView[$TREE])

$hLable_TreeView_Focus_Handle = GUICtrlCreateLabel("", 10, 470, 80, 20, $SS_SUNKEN)
$hLabel_TreeView_Focus_Text = GUICtrlCreateLabel("", 10, 500, 80, 20, $SS_SUNKEN)
$hLabel_TreeView_Focus_Param = GUICtrlCreateLabel("", 10, 530, 80, 20, $SS_SUNKEN)

Global $hParent, $hItem

For $ii = 0 To 2
	$ID += 1
	_GUICtrlTreeView_BeginUpdate($a_TreeView[$ii])
	$hParent = _GUICtrlTreeView_Add($a_TreeView[$ii], 0, "root")
	_GUICtrlTreeView_SetItemParam($a_TreeView[$ii], $hParent, $ID)
	For $jj = 0 To 9
		$ID += 1
		$hItem = _GUICtrlTreeView_AddChild($a_TreeView[$ii], $hParent, $aName[$ii] & $jj)
		_GUICtrlTreeView_SetItemParam($a_TreeView[$ii], $hItem, $ID)
		_GUICtrlTreeView_Expand($a_TreeView[$ii], $hItem)
	Next
	_GUICtrlTreeView_EndUpdate($a_TreeView[$ii])
Next

Global $aButtons[4] = [3, 0, 0, 0]

Global $iDummy = GUICtrlCreateDummy()
$Context = GUICtrlCreateContextMenu($iDummy)
$hMenu = GUICtrlGetHandle($Context)
$aButtons[1] = GUICtrlCreateMenuItem("Add", $Context)
GUICtrlSetOnEvent($aButtons[1], "Add")
$aButtons[2] = GUICtrlCreateMenuItem("Rename", $Context)
GUICtrlSetOnEvent($aButtons[2], "Rename")
$aButtons[3] = GUICtrlCreateMenuItem("Del", $Context)
GUICtrlSetOnEvent($aButtons[3], "Del")

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $hGui)

While Sleep(20)

WEnd

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	OnExit
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func OnExit()
	_SQLite_Shutdown()
EndFunc   ;==>OnExit

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_Start
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Key_Edit_Start()
	ConsoleWrite("Key_Edit_Start()" & @LF)
	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	$KEY_EDIT = True
	HotKeySet("{ENTER}", "Key_Edit_Confirm")

	_GUICtrlTreeView_EditText($hTreeView_Focus, $hItem)
EndFunc   ;==>Key_Edit_Start

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_End
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Key_Edit_End()
	ConsoleWrite("Key_Edit_End()" & @LF)
	HotKeySet("{ENTER}")
	$KEY_EDIT = False
	_GUICtrlTreeView_EndEdit($hTreeView_Focus)
EndFunc   ;==>Key_Edit_End

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_Confirm
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; source.........: http://azjio.narod.ru/autoit3_docs/libfunctions/_guictrltreeview_endedit.htm
; ===============================================================================================================================
Func Key_Edit_Confirm()
	Local $hFocus = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	Local $hEdit = _GUICtrlTreeView_GetEditControl($hTreeView_Focus)
	_GUICtrlTreeView_SetText($hTreeView_Focus, $hItem, ControlGetText($hGui, "", $hEdit))
	HotKeySet("{ENTER}")
	$KEY_EDIT = False
	_GUICtrlTreeView_EndEdit($hTreeView_Focus)
EndFunc   ;==>Key_Edit_Confirm

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Add
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Add()
	ConsoleWrite("Add" & @LF)

	$ID += 1
	Local $h_Item
	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	If $hItem = 0x00000000 Then
		$h_Item = _GUICtrlTreeView_AddChildFirst($hTreeView_Focus, $hItem, $aName[$TreeView_ID] & $ID)
	Else
		$h_Item = _GUICtrlTreeView_AddChild($hTreeView_Focus, $hItem, $aName[$TreeView_ID] & $ID)
	EndIf
	ConsoleWrite("$hTreeView[ " & $hTreeView_Focus & " ] $hItem[ " & $hItem & " ]" & @LF)
	Local $item = _GUICtrlTreeView_SetItemParam($hTreeView_Focus, $h_Item, $ID)
	ConsoleWrite("item[" & $item & "] $ID[ " & $ID & " ]" & @LF)

	_GUICtrlTreeView_Expand($hTreeView_Focus, $hItem)

EndFunc   ;==>Add

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Rename
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Rename()
	ConsoleWrite("Rename" & @LF)
EndFunc   ;==>Rename

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Del
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Del()
	ConsoleWrite("Del" & @LF)

	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	ConsoleWrite("$hItem[ " & $hItem & " ] text[ " & _GUICtrlTreeView_GetText($hTreeView_Focus, $hItem) & " ]" & @LF)

;~ 	Local $sText = _GUICtrlTreeView_GetText($hTreeView_Focus, $hFocus)
;~ 	Local $iParam = _GUICtrlTreeView_GetItemParam($a_TreeView[$ID], $hFocus)

	Local $oo = oo()

	_DelRecursive($hItem, $oo)
	For $each In $oo
		_GUICtrlTreeView_Delete($hTreeView_Focus, $each)
	Next
	dump($oo)
EndFunc   ;==>Del

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_DelRecursive
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _DelRecursive($handle, ByRef $oo)
	Local $sText = _GUICtrlTreeView_GetText($hTreeView_Focus, $handle)
	Local $iParam = _GUICtrlTreeView_GetItemParam($hTreeView_Focus, $handle)
	Local $oItem = oo()
	$oItem.Add("name", $sText)
	$oItem.Add("param", $iParam)
	Local $hChild
	If _GUICtrlTreeView_GetChildren($hTreeView_Focus, $handle) Then
		$hChild = _GUICtrlTreeView_GetFirstChild($hTreeView_Focus, $handle)
		Do
;~ 			If _GUICtrlTreeView_GetChildren($hTreeView_Focus, $hChild) Then
			_DelRecursive($hChild, $oo)
;~ 			EndIf
			$hChild = _GUICtrlTreeView_GetNextChild($hTreeView_Focus, $hChild)
		Until $hChild = 0
	EndIf
	$oo.Add(Number($handle), $oItem)
EndFunc   ;==>_DelRecursive

;~ Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
;~ 	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $selitem

;~ 	$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
;~ 	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
;~ 	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
;~ 	$iCode = DllStructGetData($tNMHDR, "Code")
;~ 	Switch $hWndFrom
;~ 		Case $a_TreeView[$ONE]
;~ 			Switch $iCode
;~ 				Case $NM_RCLICK
;~ 					$clickPos = _WinAPI_GetMousePos(True, $hGui)
;~ 					$selitem = _GUICtrlTreeView_HitTestItem($a_TreeView[$ONE], DllStructGetData($clickPos, "X"), DllStructGetData($clickPos, "Y")-10)
;~ 					If $selitem = 0 Then Return $GUI_RUNDEFMSG
;~ 					_GUICtrlTreeView_SelectItem($a_TreeView[$ONE], $selitem)

;~ 					_GUICtrlMenu_TrackPopupMenu($hMenu, $hGui)
;~ 			EndSwitch
;~ 	EndSwitch

;~ 	Return $GUI_RUNDEFMSG
;~ EndFunc   ;==>WM_NOTIFY

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_GuiCtrlTreeView_FixFocus
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _GuiCtrlTreeView_FixFocus($ID, $item = 0)
	ConsoleWrite("_GuiCtrlTreeView_FixFocus()" & @LF)

	Local $hFocus = $item ? $item : _GUICtrlTreeView_GetSelection($a_TreeView[$ID])
	Local $sText = _GUICtrlTreeView_GetText($a_TreeView[$ID], $hFocus)
	Local $iParam = _GUICtrlTreeView_GetItemParam($a_TreeView[$ID], $hFocus)

	GUICtrlSetData($hLable_TreeView_Focus_Handle, $aName[$ID])
	GUICtrlSetData($hLabel_TreeView_Focus_Text, $sText)
	GUICtrlSetData($hLabel_TreeView_Focus_Param, $iParam)

EndFunc   ;==>_GuiCtrlTreeView_FixFocus

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_GuiCtrlTreeView_EvalAction
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _GuiCtrlTreeView_EvalAction($ID, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
	$TreeView_ID = $ID
	GUICtrlSetData($hLable_TreeView_Focus_Handle, $aName[$ID])
	$hTreeView_Focus = $ah_TreeView[$ID]
	Switch $iCode
		Case $NM_CLICK ; The user has clicked the left mouse button within the control
			_DebugPrint("$NM_CLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_DBLCLK ; The user has double-clicked the left mouse button within the control
			_DebugPrint("$NM_DBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_RCLICK ; The user has clicked the right mouse button within the control
			_DebugPrint("$NM_RCLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			_GUICtrlTreeView_SelectItem($hTreeView_Focus, $hTreeView_Focus_Item_Handle)
			_GuiCtrlTreeView_FixFocus($ID, $hTreeView_Focus_Item_Handle)
			_GUICtrlMenu_TrackPopupMenu($hMenu, $hGui)
			Return 0 ; zero to allow the default processing
		Case $NM_RDBLCLK ; The user has double-clicked the right mouse button within the control
			_DebugPrint("$NM_RDBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_KILLFOCUS ; control has lost the input focus
			_DebugPrint("$NM_KILLFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; No return value
		Case $NM_RETURN ; control has the input focus and that the user has pressed the key
			_DebugPrint("$NM_RETURN" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_SETCURSOR ; control is setting the cursor in response to a WM_SETCURSOR message
			Local $tInfo = DllStructCreate($tagNMMOUSE, $lParam)
			$hWndFrom = HWnd(DllStructGetData($tInfo, "hWndFrom"))
			$iIDFrom = DllStructGetData($tInfo, "IDFrom")
			$iCode = DllStructGetData($tInfo, "Code")

			$hTreeView_Focus_Item_Handle = DllStructGetData($tInfo, "ItemSpec")
			$hTreeView_Focus_Item_Text = _GUICtrlTreeView_GetText($hTreeView_Focus, $hTreeView_Focus_Item_Handle)
			$hTreeView_Focus_Item_Param = _GUICtrlTreeView_GetItemParam($hTreeView_Focus, $hTreeView_Focus_Item_Handle)

			_DebugPrint("$NM_SETCURSOR" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode & @CRLF & _
					"-->ItemSpec:" & @TAB & DllStructGetData($tInfo, "ItemSpec") & @CRLF & _
					"-->ItemData:" & @TAB & DllStructGetData($tInfo, "ItemData") & @CRLF & _
					"-->X:" & @TAB & DllStructGetData($tInfo, "X") & @CRLF & _
					"-->Y:" & @TAB & DllStructGetData($tInfo, "Y") & @CRLF & _
					"-->HitInfo:" & @TAB & DllStructGetData($tInfo, "HitInfo"))
			; Return 0 ; to enable the control to set the cursor
			Return 1 ; nonzero to prevent the control from setting the cursor
		Case $NM_SETFOCUS ; control has received the input focus
			_DebugPrint("$NM_SETFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; No return value
		Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW
			_DebugPrint("$TVN_BEGINDRAG")
		Case $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW
			_DebugPrint("$TVN_BEGINLABELEDIT")
		Case $TVN_BEGINRDRAGA, $TVN_BEGINRDRAGW
			_DebugPrint("$TVN_BEGINRDRAG")
		Case $TVN_DELETEITEMA, $TVN_DELETEITEMW
			_DebugPrint("$TVN_DELETEITEM")
		Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW

			ConsoleWrite("Edit Control Handle: 0x" & Hex(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)) & @CRLF & _
					"IsPtr = " & IsPtr(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)) & " IsHWnd = " & IsHWnd(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)))

			Local $tInfo = DllStructCreate($tagNMTVDISPINFO, $lParam)
			Local $sBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax"))
			ConsoleWrite("$sBuffer[ " & $sBuffer & " ]" & @LF)
			If Not _GUICtrlTreeView_GetUnicodeFormat($hWndFrom) Then $sBuffer = StringTrimLeft($sBuffer, 1)
			ConsoleWrite("$sBuffer[ " & $sBuffer & " ]" & @LF)
			DllStructSetData($sBuffer, "Text", DllStructGetData($tInfo, "Text"))

			If StringLen(DllStructGetData($sBuffer, "Text")) Then Return 1

			_DebugPrint("$TVN_ENDLABELEDIT $sBuffer[ " & $sBuffer & " ]")
		Case $TVN_GETDISPINFOA, $TVN_GETDISPINFOW
			_DebugPrint("$TVN_GETDISPINFO")
		Case $TVN_GETINFOTIPA, $TVN_GETINFOTIPW
			_DebugPrint("$TVN_GETINFOTIP")
		Case $TVN_ITEMEXPANDEDA, $TVN_ITEMEXPANDEDW
			_DebugPrint("$TVN_ITEMEXPANDED")
		Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
			_DebugPrint("$TVN_ITEMEXPANDING")
		Case $TVN_KEYDOWN
			_DebugPrint("$TVN_KEYDOWN")
		Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW
			_GuiCtrlTreeView_FixFocus($ID)
			_DebugPrint("$TVN_SELCHANGED")
		Case $TVN_SELCHANGINGA, $TVN_SELCHANGINGW
			_DebugPrint("$TVN_SELCHANGING")
		Case $TVN_SETDISPINFOA, $TVN_SETDISPINFOW
			_DebugPrint("$TVN_SETDISPINFO")
		Case $TVN_SINGLEEXPAND
			_DebugPrint("$TVN_SINGLEEXPAND")
	EndSwitch
EndFunc   ;==>_GuiCtrlTreeView_EvalAction

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:
; Author ........:
; Modified.......:
; Link ..........:
; ===============================================================================================================================
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $lParam
	Local $tNMHDR, $hWndFrom, $iIDFrom, $iCode

	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
	$iCode = DllStructGetData($tNMHDR, "Code")
	Switch $hWndFrom
		Case $ah_TreeView[$ONE]
			_GuiCtrlTreeView_EvalAction($ONE, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
		Case $ah_TreeView[$TWO]
			_GuiCtrlTreeView_EvalAction($TWO, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
		Case $ah_TreeView[$TREE]
			_GuiCtrlTreeView_EvalAction($TREE, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_DebugPrint
; Author ........:
; Modified.......:	2
; Link ..........:
; ===============================================================================================================================
Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber)
	Return
	ConsoleWrite( _
			"!===========================================================" & @CRLF & _
			"+======================================================" & @CRLF & _
			"-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _
			"+======================================================" & @CRLF)
EndFunc   ;==>_DebugPrint

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	oo
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func oo()
	Return ObjCreate($SD)
EndFunc   ;==>oo