#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=Icons\TCLogfileViewer.ico
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_Comment=Discussion in Total Commander forum <http://www.ghisler.ch/board/index.php>
#AutoIt3Wrapper_Res_Description=Addon for filemanager Total Commander for browsing TC's logfiles.
#AutoIt3Wrapper_Res_Fileversion=0.3.0.0
#AutoIt3Wrapper_Res_LegalCopyright=Copyright (c) 2007-2009 van Dusen
#AutoIt3Wrapper_Res_Field=OriginalFilename|TCLogfileViewer.au3
#AutoIt3Wrapper_Res_Field=ProductName|TCLogfileViewer addon for filemanager Total Commander
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;*** TCLogfileViewer V0.3     , 29.04.2009 by van Dusen
;*** TCLogfileViewer V0.2     , 23.04.2009 by van Dusen
;*** TCLogfileViewer V0.1.Rev3, 10.12.2008 by van Dusen
;*** TCLogfileViewer V0.1.Rev2, 06.12.2008 by van Dusen
;*** TCLogfileViewer V0.1.Rev1, 22.08.2008 by van Dusen
;*** TCLogfileViewer V0.1     , 26.10.2007 by van Dusen

#include <Array.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <ComboConstants.au3>
#include <ButtonConstants.au3>
#include <ListViewConstants.au3>
#include <EditConstants.au3>
#include <UpDownConstants.au3>

#include <GuiListView.au3>
#include <GuiComboBox.au3>
#include <GuiImageList.au3>
#include <Date.au3>

AutoItSetOption("WinTitleMatchMode", 4)
AutoItSetOption("GUIOnEventMode", 1)

Const $ver = "TCLogfileViewer V0.3 (2009-04-29)"
If $CmdLine[0] = 0 Then
	$intLogfilesToRead = 1
Else
	$intLogfilesToRead = $CmdLine[1] * 1
	If $CmdLine[1] = "/All" Then $intLogfilesToRead = 0
EndIf
;~ $intLogfilesToRead = 0 ;debug

$strIniFile = @ScriptDir & "\TCLogfileViewer.ini"

#region Sprachunterstützung

;*** Fehlwert: Englisch (intern)
Global $strLocStr[108]
$strLocStr[0]=UBound($strLocStr)-1
$strLocStr[1]='Logfile|Line|Date|Time|Operation|Status|Source|Target'
$strLocStr[2]='Skip to next logfile'
$strLocStr[3]='Skip to next date'
$strLocStr[4]='Time, format hh:mm'
$strLocStr[5]='Skip to next operation'
$strLocStr[6]='Skip to next status'
$strLocStr[7]='Source or Target' ;obsolet
$strLocStr[8]='Source'
$strLocStr[9]='Target'
$strLocStr[10]='contains'
$strLocStr[11]='does not contain'
$strLocStr[12]='begins with'
$strLocStr[13]='does not begin with'
$strLocStr[14]='ends with'
$strLocStr[15]='does not end with'
$strLocStr[16]='If operator "=" or "!=" is choosen, then "*" can be used as placeholder'
$strLocStr[17]='Drag&Drop from listview to adjacent textbox:\nTransfer path (without filename) from listview column "Source"'
$strLocStr[18]='Drag&Drop from listview to adjacent textbox:\nTransfer filename (without path) from listview column "Source"'
$strLocStr[19]='Search'
$strLocStr[20]='Search term (placeholders are *not* supported); all columns will be searched'
$strLocStr[21]='Find next occurance of search term'
$strLocStr[22]='Filter'
$strLocStr[23]='Reset filter'
$strLocStr[24]='Sorting'
$strLocStr[25]='Reset sorting'
$strLocStr[26]='Check all checkboxes on *this* page'
$strLocStr[27]='Uncheck all checkboxes on *this* page'
$strLocStr[28]='Uncheck all checkboxes'
$strLocStr[29]='%n records selected'
$strLocStr[30]='Scroll upwards on this page\n(when the top of the page is reached, then the previous page will be loaded automatically)'
$strLocStr[31]='Scroll downwards on this page\n(when the bottom of the page is reached, then the next page will be loaded automatically)'
$strLocStr[32]='Skip to first page'
$strLocStr[33]='Skip to previous page'
$strLocStr[34]='Skip to next page'
$strLocStr[35]='Skip to last page'
$strLocStr[36]='Turn on/off realtime monitoring for the recent logfile'
$strLocStr[37]='Refresh\n(Recommended, when arrow symbol above this button flashes red)'
$strLocStr[38]='Undo selected operations'
$strLocStr[39]='Confirm each undo operation separately'
$strLocStr[40]='When checkbox is checked, then confirmation for each undo operation is necessary\nOtherwise: Do not demand confirmation for each undo operation, log errors in TC logfile'
$strLocStr[41]='Export all records, which match the current filter criterias,\nto a textfile'
$strLocStr[42]='Window allways on top'
$strLocStr[43]='Reorganize database'
$strLocStr[44]='Exit'
$strLocStr[45]='New database %b has been successfully created'
$strLocStr[46]='total'
$strLocStr[47]='Update database: Logfile rotation has happened, processing data from recent logfile...'
$strLocStr[48]='Update database: Logfile rotation has happened, processing all historical logfiles, which are not yet stored in database...'
$strLocStr[49]='Update database: Inserting new records from recent logfile into database...'
$strLocStr[50]='Rec  •  Page'
$strLocStr[51]='Program start'
$strLocStr[52]='Program shutdown'
$strLocStr[53]='Copy'
$strLocStr[54]='Move'
$strLocStr[55]='Rename'
$strLocStr[56]='Shortcut'
$strLocStr[57]='NewFolder'
$strLocStr[58]='Delete'
$strLocStr[59]='DeleteFolder'
$strLocStr[60]='Pack'
$strLocStr[61]='Unpack'
$strLocStr[62]='Test'
$strLocStr[63]='CreateFile'
$strLocStr[64]='LogfileComment'
$strLocStr[65]='Undelete'
$strLocStr[66]='No more matches for\n%s'
$strLocStr[67]='No more matches'
$strLocStr[68]='No logfile entries are selected'
$strLocStr[69]='Undo: %n operations?'
$strLocStr[70]='Undo'
$strLocStr[71]="This operation can't be revoked, because the folder\n%s\ncan't be accessed (e.g., folder doesn't exist any more)"
$strLocStr[72]='Shall the folder be deleted?'
$strLocStr[73]="This operation can't be revoked, because the folder\n%s\nis not empty"
$strLocStr[74]='The folder\n%s\ncould not be deleted'
$strLocStr[75]='Error:'
$strLocStr[76]='Delete failed'
$strLocStr[77]="This operation can't be revoked, because the folder\n%s\nalready exits"
$strLocStr[78]='Shall the folder be created?'
$strLocStr[79]='The folder\n%s\ncould not be created'
$strLocStr[80]='Failed'
$strLocStr[81]="This operation can't be revoked, because the target files\n%s\ndoesn't exists any more"
$strLocStr[82]='WARNING! A source file named\n%s\ndoes not exists any more!'
$strLocStr[83]="WARNING! The file \n%s\nisn't empty!"
$strLocStr[84]='Shall the file\n%s\nbe deleted anyhow?'
$strLocStr[85]='Shall the file\n%s\nbe deleted?'
$strLocStr[86]='The file\n%s\ncould not be deleted'
$strLocStr[87]="This operation can't be revoked, because an object (%x) named\n%s\nalready exists"
$strLocStr[88]="This operation can't be revoked, because the target object (%x)\n%s\ndoes not exist any more"
$strLocStr[89]='Shall the object (%x)\n%t\nbe moved/renamed to\n%s\n?'
$strLocStr[90]='The target object (%x)\n%s\ncould not be moved/renamed'
$strLocStr[91]='A file with this name already exists'
$strLocStr[92]='Shall the file be undeleted?'
$strLocStr[93]='The file could not be undeleted'
$strLocStr[94]="Unfortunately, this operation can't be revoked by %s :'-("
$strLocStr[95]='Not supported'
$strLocStr[96]='Export records'
$strLocStr[97]='All files (*.*)|Text files (*.txt;*.tab)'
$strLocStr[98]='Logfile|Row|Date|Time|Operation|Status|Source|Source (path)|Source (filename)|Target|Target (path)|Target (filename)|'
$strLocStr[99]='%n records has been exported to\n%s'
$strLocStr[100]='Reorganizing the database...'
$strLocStr[101]='Reorganization of the database has been finished successfully'
$strLocStr[102]='Message #'
$strLocStr[103]='Time difference (in seconds) to previous operation'
$strLocStr[104]='Skip to next checked line'
$strLocStr[105]='%x (Deletion DateTime Logfile)'
$strLocStr[106]='%x (Deletion DateTime RecyleBin)'
$strLocStr[107]='%ns Diff. (max. 60s accepted)'

;*** Sprache aus INI-Datei ermitteln
$strLanguage = IniRead($strIniFile, "Configuration", "Language", "AutoDetect")
If $strLanguage = "AutoDetect" And WinExists("classname=TTOTAL_CMD") Then
	$strTmp = IniRead(EnvGet("COMMANDER_INI"), "Configuration", "LanguageIni", "Wcmd_ENG.lng")
	$strTmp = StringSplit(StringMid($strTmp, StringInStr($strTmp, "_", 0, -1) + 1), "._-")
	$strLanguage = StringUpper($strTmp[1])
	$strTmp = ""
EndIf

;*** Prüfen, ob die INI-Section zur konfigurierten bzw. automatisch ermittelten Sprache existiert
$strTmp = IniReadSection($strIniFile, $strLanguage)

;*** Wenn die Sprach-INI-Section nicht existiert, dann Fehlermeldung ausgeben (Fehlwert Englisch (intern) wird verwendet)
If @error = 1 Then
	$strMsg = "Can't apply localized strings for language [" & $strLanguage & "]," & @LF
	$strMsg &= "because section [" & $strLanguage & "] is not found in TCLogfileViewer.ini!" & @LF
	$strMsg &= "Default language [ENG (internal)] is used instead." & @LF & @LF
	MsgBox(64, "TCLogfileViewer " & $ver, $strMsg)
	
;*** Wenn die Sprach-INI-Section existiert, dann lokalisierte Strings aus INI übernehmen
Else
	For $i = 1 To UBound($strLocStr)-1
		$strLocStr[$i] = IniRead($strIniFile, $strLanguage, $i, $strLocStr[$i])
	Next
	
	;*** Namen der Vorgänge und Fehlerbeschreibungen
	;*** TC-Sprachdatei einlesen (Keys 1800-1899: Namen der Vorgänge; Keys 1900-1999: Fehlertexte; Syntax im Logfile: {OperationName}[(Fehler: {ErrDesc})]
	;*** Die Fehlerstatus zur Auswahl in den ComboBoxen $cbxVorgangVal und $cbxStatusVal werden direkt den Logfiles entnommen (nur tatsächlich aufgetretene werden zur Auswahl gestellt)
	$strLngFile = IniRead(EnvGet("COMMANDER_INI"), "Configuration", "LanguageIni", "Wcmd_ENG.lng")
	$strLngFile = EnvGet("COMMANDER_PATH") & "\Language\" & $strLngFile
	$hfLngFile = FileOpen($strLngFile, 0)

;~ 	Dim $arrLogOperationNames[1]
;~ 	Dim $arrLogOperationErrDesc[1]
;~ 	$strLogOperationNames = ""
;~ 	$strLogOperationErrDesc = ""
	While 1
		$strLngFileItem = FileReadLine($hfLngFile)
		If @error = -1 Or @error = 1 Then ExitLoop
		$strLngFileItem = StringSplit($strLngFileItem, "=")
		If IsArray($strLngFileItem) Then
			Switch $strLngFileItem[1]*1
;~ 	 			Case 1800 To 1899
;~ 	 				$strLogOperationNames = $strLngFileItem[1] & @TAB & StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
;~ 	 				_ArrayAdd($arrLogOperationNames, $strLogOperationNames)
;~ 	 			Case 1900 To 1999
;~ 	 				$strLogOperationErrDesc = $strLngFileItem[1] & @TAB & StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
;~ 	 				_ArrayAdd($arrLogOperationErrDesc, $strLogOperationErrDesc)
				Case 1800 ;51=Programmstart
					$strLocStr[51]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1801 ;52=Programmende
					$strLocStr[52]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1802 ;53=Kopieren
					$strLocStr[53]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1803 ;54=Verschieben
					$strLocStr[54]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1804 ;56=Verknüpfen
					$strLocStr[56]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1805 ;57=NeuerOrdner
					$strLocStr[57]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1806 ;58=Löschen
					$strLocStr[58]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1807 ;59=OrdnerLöschen	
					$strLocStr[59]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1808 ;60=Packen
					$strLocStr[60]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1809 ;61=Entpacken
					$strLocStr[61]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1810 ;62=Testen
					$strLocStr[62]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1811 ;63=NeueDatei
					$strLocStr[63]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1900 ;75=Fehler
					$strLocStr[75]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1901 ;80=Fehlgeschlagen
					$strLocStr[80]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1911 ;76=Löschen fehlgeschlagen
					$strLocStr[76]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
				Case 1918 ;94=Nicht unterstützt
					$strLocStr[95]=StringTrimRight(StringTrimLeft($strLngFileItem[2], 1), 1)
			EndSwitch
		EndIf
	WEnd
	FileClose($hfLngFile)
	
EndIf
$strTmp = ""

;*** Zeilenumbrüche einfügen
For $i = 1 To UBound($strLocStr)-1
	$strLocStr[$i] = StringReplace($strLocStr[$i], "\n", @LF)
Next

#endregion Sprachunterstützung

$intListViewLimit = IniRead($strIniFile, "Configuration", "ListviewLinesPerPage", 100)

$intListviewFontSize = IniRead($strIniFile, "Configuration", "ListviewFontSize", 8)
$intListviewFontSize += 0.4
$intListviewFontWeight = IniRead($strIniFile, "Configuration", "ListviewFontWeight", 400)
$intListviewFontAttr = IniRead($strIniFile, "Configuration", "ListviewFontAttr", 0)
$strListviewFontName = IniRead($strIniFile, "Configuration", "ListviewFontName", "Tahoma")

$intColorRGBStd = IniRead($strIniFile, "Configuration", "ColorRGBStd", 0x000000)
$intColorRGBNotOK = IniRead($strIniFile, "Configuration", "ColorRGBNotOK", 0xFF0000)
$intColorRGBZeroSecTmDiff = IniRead($strIniFile, "Configuration", "ColorRGBZeroSecTmDiff", $intColorRGBStd)

$intColorRGBProgramStartAndShutdown = IniRead($strIniFile, "Configuration", "ColorRGBProgramStartAndShutdown", $intColorRGBStd)
$intColorRGBProgramShutdown = IniRead($strIniFile, "Configuration", "ColorRGBProgramShutdown", $intColorRGBStd)
$intColorRGBCopy = IniRead($strIniFile, "Configuration", "ColorRGBCopy", $intColorRGBStd)
$intColorRGBMove = IniRead($strIniFile, "Configuration", "ColorRGBMove", $intColorRGBStd)
$intColorRGBShortcut = IniRead($strIniFile, "Configuration", "ColorRGBShortcut", $intColorRGBStd)
$intColorRGBNewFolder = IniRead($strIniFile, "Configuration", "ColorRGBNewFolder", $intColorRGBStd)
$intColorRGBDelete = IniRead($strIniFile, "Configuration", "ColorRGBDelete", $intColorRGBStd)
$intColorRGBDeleteFolder = IniRead($strIniFile, "Configuration", "ColorRGBDeleteFolder", $intColorRGBStd)
$intColorRGBPack = IniRead($strIniFile, "Configuration", "ColorRGBPack", $intColorRGBStd)
$intColorRGBUnpack = IniRead($strIniFile, "Configuration", "ColorRGBUnpack", $intColorRGBStd)
$intColorRGBTest = IniRead($strIniFile, "Configuration", "ColorRGBTest", $intColorRGBStd)
$intColorRGBCreateFile = IniRead($strIniFile, "Configuration", "ColorRGBCreateFile", $intColorRGBStd)
$intColorRGBRename = IniRead($strIniFile, "Configuration", "ColorRGBRename", $intColorRGBStd)
$intColorRGBLogfileComment = IniRead($strIniFile, "Configuration", "ColorRGBLogfileComment", $intColorRGBStd)
$intColorRGBUndelete = IniRead($strIniFile, "Configuration", "ColorRGBUndelete", $intColorRGBStd)
$intColorRGBUnknown = IniRead($strIniFile, "Configuration", "ColorRGBUnknown", $intColorRGBStd)


#region Datums- und Uhrzeitformat aus der Registry auslesen
;*** Format für "Kurzes Datum" aus Registry auslesen
$strRegDateFmtDelim = RegRead("HKCU\Control Panel\International", "sDate")
$arrRegDateFmt = StringSplit(RegRead("HKCU\Control Panel\International", "sShortDate"), $strRegDateFmtDelim)

;*** Format für "Uhrzeit" aus Registry auslesen
;h=12 Stunden, H=24 Stunden; hh=vorangestellte Null, h=ohne führende Null; x=Vor-/Nachmittagssymbol
;mm=vorangestellte Null, m=ohne führende Null
;ss=vorangestellte Null, s=ohne führende Null
;~ $strRegTimeAM = RegRead("HKCU\Control Panel\International", "s1159") ;Vormittagssymbol
;~ $strRegTimePM = RegRead("HKCU\Control Panel\International", "s2359") ;Nachmittagssymbol
$strRegTimeFmtDelim = RegRead("HKCU\Control Panel\International", "sTime")
$arrRegTimeFmt = StringSplit(RegRead("HKCU\Control Panel\International", "sTimeFormat"), $strRegTimeFmtDelim)
#endregion Datums- und Uhrzeitformat aus der Registry auslesen


#region Dateipfad zum Logfile ermitteln, Namensbestandteile extrahieren
;*** LogFile-Dateipfad aufsplitten in Pfad, Logfile-Dateinamen, Logfile-Dateinamensstamm, Logfile-Dateinamenserweiterung
$strRecentLogfile = IniRead(EnvGet("COMMANDER_INI"), "Configuration", "LogFile", "")
If $strRecentLogfile = "" Then Exit

;*** Umgebungsvariablen (wie z.B. "%COMMANDER_PATH%") im Logfile-Dateipfad auflösen
While 1
	$arrLogfileEnvVars = StringRegExp($strRecentLogfile, "(?U)(%.+%)", 1)
	If @error = 0 Then
		$arrLogfileEnvVars[0] = StringTrimLeft(StringTrimRight($arrLogfileEnvVars[0], 1), 1)
		$strRecentLogfile = StringReplace($strRecentLogfile, "%" & $arrLogfileEnvVars[0] & "%", EnvGet($arrLogfileEnvVars[0]))
	Else
        ExitLoop
    EndIf
WEnd

$p = StringInStr($strRecentLogfile, "\", 0, -1)
$strRecentLogfilePath = StringLeft($strRecentLogfile, $p-1) ;Pfad ohne abschließenden "\"
$strRecentLogfileName = StringMid($strRecentLogfile, $p+1)
$p = StringInStr($strRecentLogfileName, ".", 0, -1)
If $p = 0 Then
	$strRecentLogfileNameStem = $strRecentLogfileName
	$strRecentLogfileNameExt = ""
Else
	$strRecentLogfileNameStem = StringLeft($strRecentLogfileName, $p-1)
	$strRecentLogfileNameExt = StringMid($strRecentLogfileName, $p) ;Dateinamenserweiterung MIT vorangestelltem Punkt!
EndIf

$booLogfileDBNew = True
If $intLogfilesToRead = 1 Then
	$strLogfileDB = ":memory:"
Else
;~ 	$strLogfileDB = $strRecentLogfilePath & "\" & $strRecentLogfileNameStem & ".db"
	$strLogfileDB = $strRecentLogfilePath & "\" & "TCLogfileViewer.db"
EndIf
If $strLogfileDB <> "" And FileExists($strLogfileDB) = 1 Then $booLogfileDBNew = False
#endregion Dateipfad zum Logfile ermitteln, Namensbestandteile extrahieren


#region Bei aktivierter Logfile-Rotation die Namen aller verfügbaren Logfiles ermitteln
$intTCProductVersion = _GetTCProductVersion() * 1

Dim $arrLogfileNames[2]
FileChangeDir($strRecentLogfilePath)

;*** BOM des Recent Logfile ermitteln
$fhLogfile = FileOpen($strRecentLogfileName, 16)
$strBOM = FileRead($fhLogfile, 3)
FileClose($fhLogfile)
#cs
Bytefolgen der BOM in verschiedenen Zeichenkodierungen
Kodierung              Bytefolge 
UTF-8                  EF BB BF    (239 187 191)
UTF-16 Big Endian      FE FF       (254 255)
UTF-16 Little Endian   FF FE       (255 254)
UTF-32 Big Endian      00 00 FE FF (000 000 254 255)
UTF-32 Little Endian   FF FE 00 00 (255 254 000 000)
#ce
If $strBOM = Chr(0xEF) & Chr(0xBB) & Chr(0xBF) Then
	$arrLogfileNames[1] = $strRecentLogfileName & @TAB & "UTF-8"
Else
	$arrLogfileNames[1] = $strRecentLogfileName & @TAB & "ANSI"
EndIf

$intLogfileCur = 1
$intLogfileSizeBTot = 0

$hsFile = FileFindFirstFile($strRecentLogfileNameStem & ".*" & $strRecentLogfileNameExt)
If $hsFile <> -1 Then
	While 1
		$strHistLogfile = FileFindNextFile($hsFile)
		If @error Then ExitLoop
		If Not StringInStr(FileGetAttrib($strHistLogfile), "D") Then
			$intLogfileCur += 1
			$intLogfileSizeBTot += FileGetSize($strHistLogfile)
			
			;*** BOM ermitteln
			$fhLogfile = FileOpen($strHistLogfile, 16)
			$strBOM = FileRead($fhLogfile, 3)
			FileClose($fhLogfile)
			#cs
			Bytefolgen der BOM in verschiedenen Zeichenkodierungen
			Kodierung              Bytefolge 
			UTF-8                  EF BB BF    (239 187 191)
			UTF-16 Big Endian      FE FF       (254 255)
			UTF-16 Little Endian   FF FE       (255 254)
			UTF-32 Big Endian      00 00 FE FF (000 000 254 255)
			UTF-32 Little Endian   FF FE 00 00 (255 254 000 000)
			#ce
			If $strBOM = Chr(0xEF) & Chr(0xBB) & Chr(0xBF) Then
				_ArrayAdd($arrLogfileNames, $strHistLogfile & @TAB & "UTF-8")
			Else
				_ArrayAdd($arrLogfileNames, $strHistLogfile & @TAB & "ANSI")
			EndIf
			
		EndIf
	WEnd
EndIf
FileClose($hsFile)

$arrLogfileNames[0] = $intLogfileCur
If $intLogfilesToRead = 0 Or $intLogfilesToRead > $arrLogfileNames[0] Then $intLogfilesToRead = $arrLogfileNames[0]

_ArraySort($arrLogfileNames, 1, 1) ;Absteigend sortiert (jüngstes Logfile zuerst)
$arrLogfileBOM = $arrLogfileNames

For $intLogfileCur = 1 To $arrLogfileNames[0]
	$p = StringInStr($arrLogfileNames[$intLogfileCur], @TAB)
	$arrLogfileNames[$intLogfileCur] = StringLeft($arrLogfileNames[$intLogfileCur], $p-1)
	$arrLogfileBOM[$intLogfileCur] = StringTrimLeft($arrLogfileBOM[$intLogfileCur], $p)
Next

#endregion Bei aktivierter Logfile-Rotation die Namen aller verfügbaren Logfiles ermitteln


#region Dialog erzeugen

FileInstall("D:\Eigene Dateien\Installation\Scripting\AutoIT\Scripte\TCLogfileViewer\FolderDelete.ico", @ScriptDir & "\FolderDelete.ico")
FileInstall("D:\Eigene Dateien\Installation\Scripting\AutoIT\Scripte\TCLogfileViewer\NewFile.ico", @ScriptDir & "\NewFile.ico")

$frmGUI = GUICreate($ver, 920, 720, Default, Default, $WS_OVERLAPPEDWINDOW)
GUISetFont($intListviewFontSize, $intListviewFontWeight, $intListviewFontAttr, $strListviewFontName, $frmGUI)

$arrListViewCols = StringSplit($strLocStr[1], "|")
$arrTabTCLogCols = StringSplit("Logfile,LogLine,OpDate,OpTime,Operation,OpStatus,OpSource,OpTarget", ",")

;*** Filter auf Logfile
GUICtrlCreateLabel($arrListViewCols[1], 10, 10+4, 55, 20, $SS_RIGHT) ;"Logfile"
GUICtrlSetResizing(-1, $GUI_DOCKALL)

$cbxLogfileOp = GUICtrlCreateCombo("=", 70, 10, 40, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetData(-1, "!=", "=")
GUICtrlSetOnEvent($cbxLogfileOp, "_cbxLogfileOp")

$cbxLogfileVal = GUICtrlCreateCombo("*", 115, 10, 140+25, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent($cbxLogfileVal, "_cbxLogfileVal")

$btnLogfileNext = GUICtrlCreateButton("8", 260+25, 10, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 9, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[2]) ;"Zu nächstem Logfile springen"
GUICtrlSetOnEvent($btnLogfileNext, "_btnNextGroup")

;*** Filter auf Datum
GUICtrlCreateLabel($arrListViewCols[3], 10, 35+4, 55, 20, $SS_RIGHT) ;"Datum"
GUICtrlSetResizing(-1, $GUI_DOCKALL)

$cbxDatumOp = GUICtrlCreateCombo("=", 70, 35, 40, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetData(-1, "!=|>|>=|<|<=", "=")
GUICtrlSetOnEvent($cbxDatumOp, "_cbxDatumOp")

$cbxDatumVal = GUICtrlCreateCombo("*", 115, 35, 80, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent($cbxDatumVal, "_cbxDatumVal")

$btnDatumNext = GUICtrlCreateButton("8", 260+25, 35, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 9, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[3]) ;"Zu nächstem Datum springen"
GUICtrlSetOnEvent($btnDatumNext, "_btnNextGroup")

;*** Filter auf Uhrzeit
$cbxUhrzeitOp = GUICtrlCreateCombo("<", 205, 35, 35, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetData(-1, ">", "<")
GUICtrlSetOnEvent($cbxUhrzeitOp, "_cbxUhrzeitOp")

$txtUhrzeitVal = GUICtrlCreateInput("*", 245, 35, 35, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetTip(-1, $strLocStr[4]) ;"Uhrzeit im Format hh:mm"
GUICtrlSetOnEvent($txtUhrzeitVal, "_txtUhrzeitVal")

;*** Filter auf DatumUhrzeit-Diff
GUICtrlCreateLabel(ChrW(0x0394), 310, 35+4, 15, 20, $SS_RIGHT)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$cbxDatumUhrzeitDiffOp = GUICtrlCreateCombo("=", 330, 35, 40, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetData(-1, ">|>=|<|<=", ">=")
GUICtrlSetOnEvent($cbxDatumUhrzeitDiffOp, "_cbxDatumUhrzeitDiffOp")

$txtDatumUhrzeitDiffVal = GUICtrlCreateInput(0, 375, 35, 35, 20, $ES_NUMBER)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetTip(-1, $strLocStr[103]) ;"Zeitdifferenz zur vorangegangenen Operation in Sekunden"
GUICtrlSetOnEvent($txtDatumUhrzeitDiffVal, "_txtDatumUhrzeitDiffVal")
;~ GUICtrlCreateUpdown($txtDatumUhrzeitDiffVal, $UDS_NOTHOUSANDS) ;*** Achtung! Endlos-Schleife i.V.m. GUICtrlSetOnEvent($txtDatumUhrzeitDiffVal,...)!
GUICtrlCreateLabel("s", 415, 35+4, 15, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)

;*** Filter auf Vorgang
GUICtrlCreateLabel($arrListViewCols[5], 10, 60+4, 55, 20, $SS_RIGHT) ;"Vorgang"
GUICtrlSetResizing(-1, $GUI_DOCKALL)

$cbxVorgangOp = GUICtrlCreateCombo("=", 70, 60, 40, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetData(-1, "!=", "=")
GUICtrlSetOnEvent($cbxVorgangOp, "_cbxVorgangOp")

$cbxVorgangVal = GUICtrlCreateCombo("*", 115, 60, 140+25, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent($cbxVorgangVal, "_cbxVorgangVal")

$btnVorgangNext = GUICtrlCreateButton("8", 260+25, 60, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 9, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[5]) ;"Zu nächstem Vorgang springen"
GUICtrlSetOnEvent($btnVorgangNext, "_btnNextGroup")

;*** Filter auf Status
GUICtrlCreateLabel($arrListViewCols[6], 10, 85+4, 55, 20, $SS_RIGHT) ;"Status"
GUICtrlSetResizing(-1, $GUI_DOCKALL)

$cbxStatusOp = GUICtrlCreateCombo("=", 70, 85, 40, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetData(-1, "!=", "=")
GUICtrlSetOnEvent($cbxStatusOp, "_cbxStatusOp")

$cbxStatusVal = GUICtrlCreateCombo("*", 115, 85, 140+25, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetOnEvent($cbxStatusVal, "_cbxStatusVal")

$btnStatusNext = GUICtrlCreateButton("8", 260+25, 85, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 9, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[6]) ;"Zu nächstem Status springen"
GUICtrlSetOnEvent($btnStatusNext, "_btnNextGroup")

;*** Filter auf Quelle/Ziel
$cbxQuelleOderZielFld = GUICtrlCreateCombo($strLocStr[8] & " ¦ " & $strLocStr[9], 305+45, 10, 100, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL) ;"Quelle ¦ Ziel"
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetData(-1, $strLocStr[8] & "|" & $strLocStr[9], $strLocStr[8] & " ¦ " & $strLocStr[9]) ;"Quelle|Ziel", "Quelle ¦ Ziel"
GUICtrlSetOnEvent($cbxQuelleOderZielFld, "_cbxQuelleOderZielOp")

$cbxQuelleOderZielOp = GUICtrlCreateCombo("=", 410+45, 10, 100, 20, $CBS_DROPDOWNLIST+$CBS_AUTOHSCROLL+$WS_VSCROLL)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetData(-1, "!=|" & $strLocStr[10] & "|" & $strLocStr[11] & "|" & $strLocStr[12] & "|" & $strLocStr[13] & "|" & $strLocStr[14] & "|" & $strLocStr[15], "=") ;"!=|enthält|enthält nicht|beginnt mit|beginnt nicht mit|endet mit|endet nicht mit"
GUICtrlSetOnEvent($cbxQuelleOderZielOp, "_cbxQuelleOderZielOp")

$txtQuelleOderZielVal = GUICtrlCreateInput("*", 515+45, 10, 300, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetTip(-1, $strLocStr[16]) ;'Bei Auswahl des Operators "=" oder "!=" kann "*" als Platzhalter verwendet werden'
GUICtrlSetState($txtQuelleOderZielVal, $GUI_DROPACCEPTED) ;@GUI_DRAGID, @GUI_DRAGFILE, @GUI_DROPID
GUICtrlSetOnEvent($txtQuelleOderZielVal, "_txtQuelleOderZielVal")

$chkQuelleOderZielDropPath = GUICtrlCreateCheckbox("P", 820+45, 10, 20, 20, $BS_PUSHLIKE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetTip(-1, $strLocStr[17]) ;Drag&Drop vom Listview in nebenstehendes Textfeld: Pfad (ohne Dateiname) aus Listview-Spalte "Quelle" übernehmen'
$chkQuelleOderZielDropFile = GUICtrlCreateCheckbox("N", 840+45, 10, 20, 20, $BS_PUSHLIKE)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetTip(-1, $strLocStr[18]) ;'Drag&Drop vom Listview in nebenstehendes Textfeld: Dateiname (ohne Pfad) aus Listview-Spalte "Quelle" übernehmen'
GUICtrlSetState($chkQuelleOderZielDropFile, $GUI_CHECKED)

;*** Suchbegriff
GUICtrlCreateLabel($strLocStr[19], 410+45, 35+4, 100, 20, $SS_RIGHT) ;"Suchen"
GUICtrlSetResizing(-1, $GUI_DOCKALL)

$txtSearchFor = GUICtrlCreateInput("", 515+45, 35, 300, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetTip(-1, $strLocStr[20]) ;"Suchbegriff (Platzhalter werden *nicht* unterstützt); alle Spalten werden durchsucht"
GUICtrlSetOnEvent($txtSearchFor, "_SearchFor")

$btnSearchForNext = GUICtrlCreateButton("8", 820+45, 35, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 9, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[21]) ;"Nächstes Auftreten des Suchbegriffs finden"
GUICtrlSetOnEvent($btnSearchForNext, "_SearchFor")

;*** Info Filter- und Sortierkriterien
GUICtrlCreateLabel($strLocStr[22], 10, 112, 55, 16, $SS_RIGHT) ;"Filter"
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$lblTabTCLogWhere = GUICtrlCreateLabel("", 70, 112, 900-210, 16, $SS_LEFTNOWORDWRAP)
GUICtrlSetResizing(-1, $GUI_DOCKMENUBAR+$GUI_DOCKLEFT+$GUI_DOCKRIGHT)
GUICtrlSetBkColor(-1, 0xE2DFD6)
$btnTabTCLogWhereReset = GUICtrlCreateButton($strLocStr[23], 900-135, 110, 140, 20) ;"Filter zurücksetzen"
GUICtrlSetResizing(-1, $GUI_DOCKMENUBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT)
GUICtrlSetOnEvent($btnTabTCLogWhereReset, "_btnTabTCLogWhereReset")

GUICtrlCreateLabel($strLocStr[24], 10, 132, 55, 16, $SS_RIGHT) ;"Sortierung"
GUICtrlSetResizing(-1, $GUI_DOCKALL)
$lblTabTCLogOrderBy = GUICtrlCreateLabel("", 70, 132, 900-210, 16, $SS_LEFTNOWORDWRAP)
GUICtrlSetResizing(-1, $GUI_DOCKMENUBAR+$GUI_DOCKLEFT+$GUI_DOCKRIGHT)
GUICtrlSetBkColor(-1, 0xE2DFD6)
$btnTabTCLogOrderByReset = GUICtrlCreateButton($strLocStr[25], 900-135, 130, 140, 20) ;"Sortierung zurücksetzen"
GUICtrlSetResizing(-1, $GUI_DOCKMENUBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT)
GUICtrlSetOnEvent($btnTabTCLogOrderByReset, "_btnTabTCLogOrderByReset")

;*** Label "Assoziationspfeil Buttons -> Listview-Checkboxen"
GUICtrlCreateLabel("É", 19, 160+1, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 14, Default, Default, "Wingdings")
GUICtrlSetColor(-1, 0x7A95A8)


;*** Button "Alle Checkboxen auf *dieser* Seite anwählen"
$btnCheckAllListviewItemsOnCurrPage = GUICtrlCreateButton("þ", 40, 160-3, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 11, Default, Default, "Wingdings")
GUICtrlSetTip(-1, $strLocStr[26]) ;"Alle Checkboxen auf *dieser* Seite anwählen"
GUICtrlSetOnEvent($btnCheckAllListviewItemsOnCurrPage, "_ToggleSelectionListviewItems")

;*** Button "Alle Checkboxen auf *dieser* Seite abwählen"
$btnUnCheckAllListviewItemsOnCurrPage = GUICtrlCreateButton("¨", 62, 160-3, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 11, Default, Default, "Wingdings")
GUICtrlSetTip(-1, $strLocStr[27]) ;"Alle Checkboxen auf *dieser* Seite abwählen"
GUICtrlSetOnEvent($btnUnCheckAllListviewItemsOnCurrPage, "_ToggleSelectionListviewItems")


;*** Button "Alle Checkboxen *markierter* Einträge auf *dieser* Seite anwählen"
$btnCheckAllSelectedListviewItems = GUICtrlCreateButton("þ", 92, 160-3, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 11, Default, Default, "Wingdings")
GUICtrlSetTip(-1, "Alle Checkboxen *markierter* Einträge auf *dieser* Seite anwählen") ;ToDo: Lokalisieren
GUICtrlSetOnEvent($btnCheckAllSelectedListviewItems, "_ToggleSelectionListviewItems")

;*** Button "Alle Checkboxen *markierter* Einträge auf *dieser* Seite abwählen"
$btnUnCheckAllSelectedListviewItems = GUICtrlCreateButton("¨", 114, 160-3, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 11, Default, Default, "Wingdings")
GUICtrlSetTip(-1, "Alle Checkboxen *markierter* Einträge auf *dieser* Seite abwählen") ;ToDo: Lokalisieren
GUICtrlSetOnEvent($btnUnCheckAllSelectedListviewItems, "_ToggleSelectionListviewItems")


;*** Button "Alle Checkboxen abwählen"
$btnUnCheckAllListviewItems = GUICtrlCreateButton("¨", 144, 160-3, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 11, Default, Default, "Wingdings")
GUICtrlSetTip(-1, $strLocStr[28]) ;"Alle Checkboxen abwählen"
GUICtrlSetOnEvent($btnUnCheckAllListviewItems, "_UnSelectAllListviewItems")

;*** Button "Zu nächstem selektierten Eintrag springen"
$btnCheckedNext = GUICtrlCreateButton("8", 174, 160-3, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetFont(-1, 9, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[104]) ;"Zu nächstem selektierten Eintrag springen"
GUICtrlSetOnEvent($btnCheckedNext, "_btnNextChecked")

;*** Label "Anzahl markierter Einträge"
$lblListviewItemCheckedCount = GUICtrlCreateLabel(StringReplace($strLocStr[29], "%n", 0), 199, 160+1, 100, 20)
GUICtrlSetResizing(-1, $GUI_DOCKALL)

#cs
;*** Button "Gruppieren" erstellen
$btnGroup = GUICtrlCreateButton("Gruppieren", 900-135, 160, 140, 20)
GUICtrlSetResizing(-1, $GUI_DOCKMENUBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT)
GUICtrlSetOnEvent($btnGroup, "_Group")
#ce

;*** ListView
$lvLogfile = GUICtrlCreateListView($strLocStr[1], 10, 180, 900, 435-20, $LVS_SHOWSELALWAYS, $LVS_EX_GRIDLINES+$LVS_EX_FULLROWSELECT+$LVS_EX_HEADERDRAGDROP+$LVS_EX_CHECKBOXES+$LVS_EX_DOUBLEBUFFER)
;~ $lvLogfile = GUICtrlCreateListView($strLocStr[1], 10, 180, 900, 435-20, Default, $LVS_EX_GRIDLINES+$LVS_EX_FULLROWSELECT+$LVS_EX_HEADERDRAGDROP+$LVS_EX_CHECKBOXES+$LVS_EX_DOUBLEBUFFER)
$hlvLogfile = GUICtrlGetHandle($lvLogfile)
GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)
GUICtrlSetColor(-1, $intColorRGBStd)
_GUICtrlListView_JustifyColumn($hlvLogfile, 1, 1)
GUICtrlSetOnEvent($lvLogfile, "_ListViewSort")
Global $strListviewItemChecked = ""
Global $intListviewItemCheckedCount = 0

;*** Imagelist fürs ListView
$strListviewIconfile = EnvGet("COMMANDER_PATH") & "\WCMICONS.DLL"
$hImageList = _GUIImageList_Create(16, 16, 5, 3, 16)
_GUIImageList_AddIcon($hImageList, EnvGet("COMMANDER_PATH") & "\TotalCmd.exe", 0) ; 0 "Programmstart", "Programmende"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 62)                      ; 1 "Kopieren", "FS:Kopieren", "XT:Kopieren"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 63)                      ; 2 "Verschieben", "FS:Verschieben", "XT:Verschieben"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 32)                      ; 3 "Umbenennen", "FS:Umbenennen", "XT:Umbenennen"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 65)                      ; 4 "Verknüpfen", "FS:Verknüpfen"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 29)                      ; 5 "NeuerOrdner", "FS:NeuerOrdner", "XT:NeuerOrdner"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 64)                      ; 6 "Löschen", "FS:Löschen", "XT:Löschen"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 0)                       ; 7 "XT:Wiederherstellen"
_GUIImageList_AddIcon($hImageList, @ScriptDir & "\FolderDelete.ico", 0)           ; 8 "OrdnerLöschen", "FS:OrdnerLöschen", "XT:OrdnerLöschen"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 30)                      ; 9 "Packen", "FS:Packen"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 31)                      ;10 "Entpacken", "FS:Entpacken"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 60)                      ;11 "Testen", "FS:Testen"
_GUIImageList_AddIcon($hImageList, @ScriptDir & "\NewFile.ico", 0)                ;12 "NeueDatei", "FS:NeueDatei"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 28)                      ;13 "LogfileKommentar"
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 55)                      ;14  Sonstige Operation (Typ unbekannt)
_GUIImageList_AddIcon($hImageList, $strListviewIconfile, 44)                      ;15 Neuer Eintrag (Typ unbestimmt)
_GUICtrlListView_SetImageList($hlvLogfile, $hImageList, 1)

;*** Einzeldatensatzanzeige
$lblSingleDS = GUICtrlCreateLabel("", 10, 625-20, 900, 45)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR)
GUICtrlSetBkColor(-1, 0xE2DFD6)

;*** Navigation scrollen nach oben
$btnScrollUp = GUICtrlCreateButton("5", 10, 683-20, 25, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 12, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[30]) ;"Auf dieser Seite nach oben scrollen (am Seitenkopf erfolgt automatischer Wechsel auf vorige Seite)"
GUICtrlSetOnEvent($btnScrollUp, "_btnScrollUp")

;*** Navigation scrollen nach unten
$btnScrollDown = GUICtrlCreateButton("6", 40, 683-20, 25, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 12, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[31]) ;"Auf dieser Seite nach unten scrollen (am Seitenfuß erfolgt automatischer Wechsel auf nächste Seite)"
GUICtrlSetOnEvent($btnScrollDown, "_btnScrollDown")

;*** Navigation erste Seite
$btnFirstPage = GUICtrlCreateButton("9", 85, 683-20, 25, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 12, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[32]); "Zur ersten Seite springen"
GUICtrlSetOnEvent($btnFirstPage, "_btnFirstPage")

;*** Navigation vorige Seite
$btnPrevPage = GUICtrlCreateButton("7", 115, 683-20, 50, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 12, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[33]) ;"Eine Seite zurückblättern"
GUICtrlSetOnEvent($btnPrevPage, "_btnPrevPage")

;*** Navigation nächste Seite
$btnNextPage = GUICtrlCreateButton("8", 170, 683-20, 50, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 12, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[34]) ;"Eine Seite vorwärtsblättern"
GUICtrlSetOnEvent($btnNextPage, "_btnNextPage")

;*** Navigation letzte Seite
$btnLastPage = GUICtrlCreateButton(":", 225, 683-20, 25, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 12, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[35]) ;"Zur letzten Seite springen"
GUICtrlSetOnEvent($btnLastPage, "_btnLastPage")

;*** Label ('Leuchtdiode') "Pause Auto-Aktualisieren" erstellen
$lblAutoRefreshPause = GUICtrlCreateLabel("l", 270, 670-20, 25, 13, $SS_CENTER) ;"l" ;Chr(0xAD)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 10, Default, Default, "Wingdings")
GUICtrlSetColor(-1, 0xECE9D8-0x200020)

;*** Button "Pause Auto-Aktualisieren"
$chkAutoRefreshPause = GUICtrlCreateCheckbox(";", 270, 683-20, 25, 25, $BS_PUSHLIKE)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 12, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[36]) ;"Echtzeitmonitoring des aktuellen Logfiles ein-/ausschalten"
GUICtrlSetOnEvent($chkAutoRefreshPause, "_chkAutoRefreshPause")
$booAutoRefreshPaused = False

;*** Button "Aktualisieren"
$btnRefresh = GUICtrlCreateButton("q", 310, 683-20, 25, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 16, Default, Default, "Webdings")
GUICtrlSetTip(-1, $strLocStr[37]) ;"Ansicht aktualisieren (Empfohlen, wenn Pfeil oberhalb dieses Buttons rot aufleuchtet)"
GUICtrlSetOnEvent($btnRefresh, "_ListViewRefresh")

;*** Label ('Leuchtdiode') "Aktualisierung erforderlich"
$lblRefreshNeeded = GUICtrlCreateLabel("È", 310, 670-20, 25, 13, $SS_CENTER)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 10, Default, Default, "Wingdings 3")
GUICtrlSetColor(-1, 0xECE9D8-0x002020)

;*** Button "Undo"
$btnUndo = GUICtrlCreateButton("O", 350, 683-20, 25, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetFont(-1, 12, Default, Default, "Wingdings 3")
GUICtrlSetTip(-1, $strLocStr[38]) ;"Selektierte Operationen rückgängigmachen"
GUICtrlSetOnEvent($btnUndo, "_Undo")

;*** Checkbox "Bestätigung für jede Undo-Operation anfordern"
$chkUndoCommit = GUICtrlCreateCheckbox($strLocStr[39], 380, 683-20, 220, 25) ;"Einzeln bestätigen"
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKLEFT)
GUICtrlSetTip(-1, $strLocStr[40]) ;"Wenn Checkbox gesetzt, dann Bestätigung des Benutzers für jede Rückgängig-Aktion einholen. Sonst: Keine Einzelbestätigung einholen, Fehler im TC-Logfile protokollieren"
GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)

;*** Button "Speichern" erstellen
$btnSave = GUICtrlCreateButton("<", 630, 683-20, 25, 25)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT)
GUICtrlSetFont(-1, 12, Default, Default, "Wingdings")
GUICtrlSetTip(-1, $strLocStr[41]) ;"Alle Datensätze, die die aktuellen Filterbedingungen erfüllen, in eine Textdatei exportieren"
GUICtrlSetOnEvent($btnSave, "_Save")

;*** Label ('Leuchtdiode') "Always on top" erstellen
$lblTopmost = GUICtrlCreateLabel("l", 665, 670-20, 25, 13, $SS_CENTER) ;"l" ;Chr(0xAD)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT)
GUICtrlSetFont(-1, 10, Default, Default, "Wingdings")
GUICtrlSetColor(-1, 0xECE9D8-0x200020)

;*** Button "Always on top" erstellen
$chkTopmost = GUICtrlCreateCheckbox("ë", 665, 683-20, 25, 25, $BS_PUSHLIKE)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT)
GUICtrlSetTip(-1, $strLocStr[42]) ;"Fenster immer im Vordergrund"
GUICtrlSetFont(-1, 16, Default, Default, "Webdings")
GUICtrlSetOnEvent($chkTopmost, "_TopmostToggle")

;*** Button "DB reorganisieren"
$btnDBReorganize = GUICtrlCreateButton($strLocStr[43], 700, 683-20, 120, 25) ;"DB reorganisieren"
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT)
GUICtrlSetOnEvent($btnDBReorganize, "_DBReorganize")

;*** Button "Beenden"
$btnExit = GUICtrlCreateButton($strLocStr[44], 830, 683-20, 80, 25) ;"Beenden"
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT)
GUICtrlSetOnEvent($btnExit, "_Exit")

;*** Statuszeile
$lblStatus = GUICtrlCreateLabel("", 3, 717-20, 884, 20, $SS_SUNKEN)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR)

$lblLight = GUICtrlCreateLabel("", 890, 717-20, 20, 20, $SS_SUNKEN)
GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH)
GUICtrlSetBkColor($lblLight, 0xFF0000)

GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUISetOnEvent($GUI_EVENT_DROPPED, "_DragDrop")

GUISetState(@SW_SHOW, $frmGUI)
GUISetCursor(1, 1, $frmGUI) ;"APPSTARTING"
GUIRegisterMsg($WM_NOTIFY, "My_WM_NOTIFY")


#endregion Dialog erzeugen

$booConvertUTF82ANSI = False
$booTopmost = False
$booTopmostDesired = False

Dim $strLogfileItemPat[11]
$strLogfileItemPat[0] = 10
$strLogfileItemPat[1] = "^(.+) (.+): (XT:.+\(.+\))\(.+: (.+)\): (.+) -> (.+)$" ;dd.dd.dddd tt:tt:tt: XT:ooo(ooo)(Fehler: eee): qqq -> zzz
$strLogfileItemPat[2] = "^(.+) (.+): (XT:.+\(.+\))\(.+: (.+)\): (.+)$"         ;dd.dd.dddd tt:tt:tt: XT:ooo(ooo)(Fehler: eee): qqq
$strLogfileItemPat[3] = "^(.+) (.+): (.+)\(.+: (.+)\): (.+) -> (.+)$"          ;dd.dd.dddd tt:tt:tt: ooo(Fehler: eee): qqq -> zzz
$strLogfileItemPat[4] = "^(.+) (.+): (.+)\((.+)\): (.+) -> (.+)$"              ;dd.dd.dddd tt:tt:tt: ooo(eee): qqq -> zzz
$strLogfileItemPat[5] = "^(.+) (.+): (XT:.+\(.+\))\(.+: (.+)\)$"               ;dd.dd.dddd tt:tt:tt: XT:ooo(ooo)(Fehler: eee)
$strLogfileItemPat[6] = "^(.+) (.+): (.+)\(.+: (.+)\): (.+)$"                  ;dd.dd.dddd tt:tt:tt: ooo(Fehler: eee): qqq
$strLogfileItemPat[7] = "^(.+) (.+): (.+)\((.+)\): (.+)$"                      ;dd.dd.dddd tt:tt:tt: ooo(eee): qqq
$strLogfileItemPat[8] = "^(.+) (.+): (.+): (.+) -> (.+)$"                      ;dd.dd.dddd tt:tt:tt: ooo: qqq -> zzz
$strLogfileItemPat[9] = "^(.+) (.+): (.+): (.+)$"                              ;dd.dd.dddd tt:tt:tt: ooo: qqq
$strLogfileItemPat[10] = "^(.+) (.+): (.+) \((.+)\)( UTF-8)*$"                  ;dd.dd.dddd tt:tt:tt: ooo (qqq) [mit qqq = %Username%/%COMPUTERNAME%]

Local $hqryTabTCLog, $arrTabTCLogRow

$errx = _SQLite_Startup()
$err = @error
_SQLiteErrHandler(16, $err, $errx, "_SQLite_Startup", "")

$hdbTCLog = _SQLite_Open($strLogfileDB)
$err = @error
$errx = @extended
_SQLiteErrHandler(16, $err, $errx, "_SQLite_Open", $strLogfileDB)
;~ _SQLite_Exec($hdbTCLog, 'PRAGMA encoding = "UTF-8";') ;*** http://sqlite.org/pragma.html ;Hat keinen Effekt

If $booLogfileDBNew Then
	
	$strSQL = "CREATE TABLE tabTCLogFiles (FilesLogfile,FilesZeilen INTEGER,FilesGroesse INTEGER);"
	$errx = _SQLite_Exec($hdbTCLog, $strSQL)
	$err = @error
	_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
	
;~ 	$strSQL = "CREATE TABLE tabTCLogDetails (Logfile,LogLine INTEGER,OpDate,OpTime,Operation,OpStatus,OpSource,OpTarget);"
	$strSQL = "CREATE TABLE tabTCLogDetails (Logfile,LogLine INTEGER,OpDate,OpTime,Operation,OpStatus,OpSource,OpTarget,OpDtTmDiff INTEGER);"
	$errx = _SQLite_Exec($hdbTCLog, $strSQL)
	$err = @error
	_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
	
	If $strLogfileDB <> ":memory:" Then _MsgBox(64, $ver, StringReplace($strLocStr[45], "%b", $strLogfileDB)) ;"Neue Datenbank $strLogfileDB erfolgreich angelegt."
	
EndIf

$intLogfileReadBTot = 0
$intLogfileLinesTot = 0

$intTabTCLogCount = 0
$intTabTCLogOffset = 0
$strTabTCLogWhereLogfile = ""
$strTabTCLogWhereDatum = ""
$strTabTCLogWhereUhrzeit = ""
$strTabTCLogWhereDtTmDiff = ""
$strTabTCLogWhereVorgang = ""
$strTabTCLogWhereStatus = ""
$strTabTCLogWhereQuelleOderZiel = ""
$strTabTCLogWhere = ""

$booTabTCLogOrderByUser = False
$strTabTCLogOrderByRaw = ""
$strTabTCLogOrderBy = " ORDER BY Logfile DESC, LogLine DESC " ;" ORDER BY Logfile DESC, Zeile DESC "

$booListViewInitialized = False
$intListViewCurSel = -1
$intListViewPrevSel = -1
Local $fhLogfile

$intLogfileSizeBMem = FileGetSize($strRecentLogfileName)
$intLogfileLinesMem = 0
$booLogfileReadFinished = False

$booBOMUTF8 = True
$booConvertUTF82ANSI = False
$booConvertUTF82ANSIMonitoredActivities = False

If $booLogfileDBNew Then
	
	;*** Jedes Logfile einlesen
	For $intLogfileCur = 1 To $intLogfilesToRead
		
		$intLogfileSizeB = FileGetSize($arrLogfileNames[$intLogfileCur])
		$intLogfileReadB = 0
		
		If $arrLogfileBOM[$intLogfileCur] = "UTF-8" Then
			$booBOMUTF8 = True
		Else
			$booBOMUTF8 = False
		EndIf
		
		$strLogfileContent = FileRead($arrLogfileNames[$intLogfileCur]) ;Logfile komplett einlesen
		$arrLogfileContent = StringSplit($strLogfileContent, @CRLF, 1) ;Logfile in Zeilen aufsplitten
		
		If $intLogfileCur = 1 Then $intLogfileLinesMem = $arrLogfileContent[0] - 1
		
		;*** Logfile zeilenweise einlesen
		$errx = _SQLite_Exec($hdbTCLog, "BEGIN TRANSACTION;")
		$strLogfileDtTmMem = ""
		For $intLogfileLines = 1 To $arrLogfileContent[0] - 1
			
			$strLogfileItem = $arrLogfileContent[$intLogfileLines]
			
			$intLogfileReadB += StringLen($strLogfileItem) + 2 ;Bereits gelesene Bytes (aktuelles Logfile)
			$intLogfileReadBTot += StringLen($strLogfileItem) + 2 ;Bereits gelesene Bytes (alle Logfiles)
			$intLogfileLinesTot += 1 ;Zeilennummer (alle Logfiles)
			
			;*** Statuszeile aktualisieren
			If Mod($intLogfileLines, 100) = 1 Then
				$strStatus = $arrLogfileNames[$intLogfileCur] & " (" & Int($intLogfileReadB/$intLogfileSizeB*100) & "%)  •  "
				$strStatus &= $intLogfileCur & "/" & $arrLogfileNames[0] & "  •  "
				$strStatus &= Int($intLogfileReadBTot/$intLogfileSizeBTot*100) & "% " & $strLocStr[46] ;[…] "% gesamt"
				GUICtrlSetData($lblStatus, $strStatus)
			EndIf
			
			;*** Datum und Uhrzeit separat extrahieren (für Berechnung Zeitdifferenz der aktuellen zur nächsten Operation)
			$intLogfileDtTmDiff = 0
			$arrLogfileSubItems = StringRegExp($strLogfileItem, "(?U)^(.+) (.+): .+$", 1); Datum und Uhrzeit lesen
			If @error = 0 Then ;$arrLogfileSubItems ist kein Array für Logfile-Zeilen ohne Datum+Uhrzeit (z.Z. nur Operation "Logfile-Kommentar")
				$strLogfileDate = _FormatDate($arrLogfileSubItems[0])
				$strLogfileTime = _FormatTime($arrLogfileSubItems[1])
				$strLogfileDtTm = StringRegExpReplace($strLogfileDate & $strLogfileTime, "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:\6")
				If $intLogfileLines > 1 Then
					$intLogfileDtTmDiff = Abs(_DateDiff("s", $strLogfileDtTmMem, $strLogfileDtTm))
;~ 				Else
;~ 					$intLogfileDtTmDiff = 0
				EndIf
				$strLogfileDtTmMem = $strLogfileDtTm
			EndIf
			
			;*** Logfile-Zeile parsen und in DB einfügen
			_ParseLogfileLine($strLogfileItem)
			If Mod($intLogfileLines, $intListViewLimit) = 0 Then
				$errx = _SQLite_Exec($hdbTCLog, "COMMIT TRANSACTION;")
				$errx = _SQLite_Exec($hdbTCLog, "BEGIN TRANSACTION;")
			EndIf
			
			;*** Initialbefüllung des ListViews, wenn *nicht* sämtliche DS in einen Chunk passen
			If $intLogfileLinesTot = $intListViewLimit + 1 Then
				$intListViewItemCount = $intListViewLimit
				$intTabTCLogCount = $intListViewLimit + 1
				Call("_ListViewRefresh")
				$booListViewInitialized = True
				GUICtrlSetColor($lblRefreshNeeded, 0xFF0000)
				GUICtrlSetBkColor($lblLight, 0xFFFF00)
			EndIf
			
			If Mod($intLogfileLinesTot, $intListViewLimit) = 0 Then
				Call("_cbxLogfileSetData") ;Filter-ComboBox "Logfile" populieren
				Call("_cbxOpDateSetData") ;Filter-ComboBox "Datum" populieren
				Call("_cbxOperationSetData") ;Filter-ComboBox "Vorgang" populieren
				Call("_cbxOpStatusSetData") ;Filter-ComboBox "Status" populieren
			EndIf
			
		Next
		$errx = _SQLite_Exec($hdbTCLog, "COMMIT TRANSACTION;")
		$intLogfileReadBTot += 2
		
		$strTabTCLogVals = ""
		$strTabTCLogVals &= _SQLite_Escape($arrLogfileNames[$intLogfileCur]) & ","
		$strTabTCLogVals &= _SQLite_Escape($intLogfileLines-1) & ","
		$strTabTCLogVals &= _SQLite_Escape(FileGetSize($arrLogfileNames[$intLogfileCur]))
		$strSQL = "INSERT INTO tabTCLogFiles(FilesLogfile,FilesZeilen,FilesGroesse) VALUES (" & $strTabTCLogVals & ");"
		$errx = _SQLite_Exec($hdbTCLog, $strSQL)
		
	Next
	
	$strLogfileContent = ""
	$arrLogfileContent = ""

	;*** Initialbefüllung des ListViews, wenn sämtliche DS in einen Chunk passen
	If $booListViewInitialized = False Then
		$intListViewItemCount = $intLogfileLinesTot
		$intTabTCLogCount = $intLogfileLinesTot
		Call("_ListViewRefresh")
		$booListViewInitialized = True
		GUICtrlSetColor($lblRefreshNeeded, 0xECE9D8-0x002020)
		GUICtrlSetBkColor($lblLight, 0xFFFF00)
	EndIf


Else ;DB aktualisieren
		
	Call("_ListViewRefresh")
	$booListViewInitialized = True
	GUICtrlSetColor($lblRefreshNeeded, 0xECE9D8-0x002020)

	;*** Prüfen, ob Logfile-Rotation stattgefunden hat (durch Suche nach Logfiles, die noch nicht in der DB gespeichert sind)
	$booLogfileRotation = False
	For $intLogfileCur = 1 To $intLogfilesToRead
		$strSQL = "SELECT * FROM tabTCLogFiles WHERE FilesLogfile = '" & $arrLogfileNames[$intLogfileCur] & "';"
		$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
		;*** Logfile ist noch nicht in der DB vorhanden (_SQLite_QuerySingleRow liefert $arrTabTCLogRow[0] = "" bei leerer Ergebnismenge)
		If $arrTabTCLogRow[0] = "" Then
			$booLogfileRotation = True
			ExitLoop
		EndIf
	Next
	GUICtrlSetData($lblStatus, "")
	
 	;*** Wenn Logfile-Rotation stattgefunden hat...
	If $booLogfileRotation Then
		
		$strStatus = $strLocStr[47] ;"DB aktualisieren: Logfile-Rotation hat stattgefunden, Daten aus aktuellem Logfile verarbeiten..."
		GUICtrlSetData($lblStatus, $strStatus)
		
		;*** DS aus aktuellem Logfile bearbeiten
		;*** DB-Eintrag mit Namen des RecentLogfile, Zeilennr. 1 ermitteln
		$strSQL = "SELECT * FROM tabTCLogDetails WHERE Logfile = '" & $strRecentLogfileName & "' AND LogLine = 1;"
		$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
		
		;*** Nach historischem Logfile suchen, welches in der DB noch unter dem Namen des RecentLogfile gespeichert ist
		$booHistLogfileFound = False
		For $intLogfileCur = 1 To $intLogfilesToRead
			$strLogfileItem = FileReadLine($arrLogfileNames[$intLogfileCur]) ;Die erste Zeile des derzeit untersuchten Logfiles einlesen
			$arrLogfileSubItems = StringRegExp($strLogfileItem, "(?U)^(.+) (.+): .+$", 1); Datum und Uhrzeit lesen
			$strLogfileDate = _FormatDate($arrLogfileSubItems[0])
			$strLogfileTime = _FormatTime($arrLogfileSubItems[1])
			
			;*** Historisches Logfile ist identifiziert, welches in der DB noch unter dem Namen des RecentLogfile gespeichert ist
			If $strLogfileDate = $arrTabTCLogRow[2] And $strLogfileTime = $arrTabTCLogRow[3] Then
				
				$booHistLogfileFound = True
				
				If $arrLogfileBOM[$intLogfileCur] = "UTF-8" Then
					$booBOMUTF8 = True
				Else
					$booBOMUTF8 = False
				EndIf
				
				;*** 1a. tabTCLogDetails.Logfile updaten: $strRecentLogfileName ändern in $arrLogfileNames[$intLogfileCur]
				$strSQL = "UPDATE tabTCLogDetails SET Logfile = '" & $arrLogfileNames[$intLogfileCur] & "' WHERE Logfile = '" & $strRecentLogfileName & "';" ;[…] SET Logfile = […] WHERE Logfile = […]
				$errx = _SQLite_Exec($hdbTCLog, $strSQL)
				$err = @error
				_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
				
				;*** 1b. tabTCLogFiles.FilesLogfile updaten: $strRecentLogfileName ändern in $arrLogfileNames[$intLogfileCur]
				$strSQL = "UPDATE tabTCLogFiles SET FilesLogfile = '" & $arrLogfileNames[$intLogfileCur] & "' WHERE FilesLogfile = '" & $strRecentLogfileName & "';"
				$errx = _SQLite_Exec($hdbTCLog, $strSQL)
				$err = @error
				_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
				
				;*** 2. Noch nicht in DB vorhandene DS aus $arrLogfileNames[$intLogfileCur] in DB einlesen
				$strSQL = "SELECT * FROM tabTCLogFiles WHERE FilesLogfile = '" & $arrLogfileNames[$intLogfileCur] & "';"
				$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow) ;[0]=FilesLogfile, [1]=FilesZeilen, [2]=FilesGroesse
				
				$intLogfileLinesMem = $arrTabTCLogRow[1] ;In der DB gespeicherte Anzahl Zeilen des ehemaligen RecentLogfile
				$intLogfileSizeBMem = $arrTabTCLogRow[2] ;In der DB gespeicherte Dateigröße des ehemaligen RecentLogfile
				$intLogfileSizeB = FileGetSize($arrLogfileNames[$intLogfileCur]) ;Aktuelle Dateigröße des ehemaligen RecentLogfile
				
				;*** Wenn das ehemalige RecentLogfile seit dem letzten DB-Update gewachsen ist, dann hinzugekommene DS in DB einfügen
				If $intLogfileSizeB > $intLogfileSizeBMem Then
					
					;*** Die aus dem Recent Logfile ergänzten DS müssen für TC-Version >= 7.5 stets von UTF-8 nach ANSI konvertiert werden
					;*** Anhaltspunkte: 1. Recent-Logfile hat UTF-8-BOM; 2. Aktuellste (letzte) Aktion "Programmstart" ist mit Zusatz "UTF-8" protokolliert
					;*** Hier wird nur Anhaltspunkt 1 geprüft, d.h., für Recent-Logfiles, unter TC <7.5 angelegt wurden und unter TC >=7.5 fortgeführt werden (Versionswechsel), wird's falsch
					If $arrLogfileBOM[1] = "UTF-8" Then
						$booBOMUTF8 = True
						$booConvertUTF82ANSIMonitoredActivities = True
					Else
						$booBOMUTF8 = False
						$booConvertUTF82ANSIMonitoredActivities = False
					EndIf

					$fhLogfile = _APIFileOpen($arrLogfileNames[$intLogfileCur])
					_APIFileSetPos($fhLogfile, $intLogfileSizeBMem)
					$strLogfileContent = _APIFileRead($fhLogfile, $intLogfileSizeB - $intLogfileSizeBMem, 0)
					_APIFileClose($fhLogfile)
					
					$intLogfileSizeBMem = $intLogfileSizeB
					$arrLogfileContent = StringSplit($strLogfileContent, @CRLF, 1) ;Logfile in Zeilen aufsplitten
					$errx = _SQLite_Exec($hdbTCLog, "BEGIN TRANSACTION;")
					
					;*** Datum+Uhrzeit der letzten in der DB gespeicherten Logfile-Zeile ermitteln (für Berechnung Zeitdifferenz der aktuellen zur nächsten Operation) 
					$strLogfileDtTmMem = ""
					If $intLogfileLinesMem > 1 Then
						$intLogfileLinesCur = $intLogfileLinesMem
						Do
							$strSQL = "SELECT * FROM tabTCLogDetails WHERE Logfile = '" & $arrLogfileNames[$intLogfileCur] & "' AND LogLine = " & $intLogfileLinesCur & ";"
							$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
							$strLogfileDate = $arrTabTCLogRow[2]
							$strLogfileTime = $arrTabTCLogRow[3]
							$intLogfileLinesCur -= 1
							$strLogfileDtTmMem = StringRegExpReplace($strLogfileDate & $strLogfileTime, "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:\6")
						Until @error = 0 Or $intLogfileLinesCur = 1
					EndIf

					For $intLogfileLines = $intLogfileLinesMem + 1 To $intLogfileLinesMem + $arrLogfileContent[0] - 1
						
						$strLogfileItem = $arrLogfileContent[$intLogfileLines-$intLogfileLinesMem]
						
						;*** Datum und Uhrzeit separat extrahieren(für Berechnung Zeitdifferenz der aktuellen zur nächsten Operation)
						$intLogfileDtTmDiff = 0
						$arrLogfileSubItems = StringRegExp($strLogfileItem, "(?U)^(.+) (.+): .+$", 1); Datum und Uhrzeit lesen
						If @error = 0 Then ;$arrLogfileSubItems ist kein Array für Logfile-Zeilen ohne Datum+Uhrzeit (z.Z. nur Operation "Logfile-Kommentar")
							$strLogfileDate = _FormatDate($arrLogfileSubItems[0])
							$strLogfileTime = _FormatTime($arrLogfileSubItems[1])
							$strLogfileDtTm = StringRegExpReplace($strLogfileDate & $strLogfileTime, "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:\6")
							If $strLogfileDtTmMem <> "" Then ;*** $strLogfileDtTmMem ist u.U. leer
								If $intLogfileLines > 1 Then
									$intLogfileDtTmDiff = Abs(_DateDiff("s", $strLogfileDtTmMem, $strLogfileDtTm))
;~ 								Else
;~ 									$intLogfileDtTmDiff = 0
								EndIf
							EndIf
							$strLogfileDtTmMem = $strLogfileDtTm
						EndIf

						$strListviewItem = _ParseLogfileLine($strLogfileItem)
						
					Next
					
					$errx = _SQLite_Exec($hdbTCLog, "COMMIT TRANSACTION;")
					$intLogfileLinesMem = $intLogfileLines - 1
					$intLogfileSizeBMem = $intLogfileSizeB
					
					;*** 3. tabTCLogFiles.FilesLogfile updaten: FilesZeilen und FilesGroesse updaten (FilesLogfile ist bereits "umbenannt"!)
					$strSQL = "UPDATE tabTCLogFiles SET FilesZeilen = " & $intLogfileLinesMem & " WHERE FilesLogfile = '" & $arrLogfileNames[$intLogfileCur] & "';"
					$errx = _SQLite_Exec($hdbTCLog, $strSQL)
					$err = @error
					_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
					
					$strSQL = "UPDATE tabTCLogFiles SET FilesGroesse = " & $intLogfileSizeBMem & " WHERE FilesLogfile = '" & $arrLogfileNames[$intLogfileCur] & "';"
					$errx = _SQLite_Exec($hdbTCLog, $strSQL)
					$err = @error
					_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
					
					GUICtrlSetColor($lblRefreshNeeded, 0xFF0000)
					
				EndIf
				
				ExitLoop
				
			EndIf
			
		Next
		
		;*** Historisches Logfile, welches in der DB noch unter dem Namen des RecentLogfile gespeichert ist, wurde nicht gefunden
		If $booHistLogfileFound = False Then
			
			$strHistLogfileName = $strRecentLogfileNameStem & "." & StringReplace($arrTabTCLogRow[2], "-", "") & $strRecentLogfileNameExt
			
			;*** 1a. tabTCLogDetails.Logfile updaten: $strRecentLogfileName ändern in $strHistLogfileName
			$strSQL = "UPDATE tabTCLogDetails SET Logfile = '" & $strHistLogfileName & "' WHERE Logfile = '" & $strRecentLogfileName & "';" ;[…] SET Logfile = […] WHERE Logfile = […]
			$errx = _SQLite_Exec($hdbTCLog, $strSQL)
			$err = @error
			_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
			
			;*** 1b. tabTCLogFiles.FilesLogfile updaten: $strRecentLogfileName ändern in $strHistLogfileName
			$strSQL = "UPDATE tabTCLogFiles SET FilesLogfile = '" & $strHistLogfileName & "' WHERE FilesLogfile = '" & $strRecentLogfileName & "';"
			$errx = _SQLite_Exec($hdbTCLog, $strSQL)
			$err = @error
			_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
			
			;*** 2. Noch nicht in DB vorhandene DS aus $strHistLogfileName in DB einlesen: ENTFÄLLT!
			;*** ToDo: Prüfen: Müssen die Werte folgender Variablen korrigiert werden?
			;    $intLogfileLinesMem (In der DB gespeicherte Anzahl Zeilen des ehemaligen RecentLogfile)
			;    $intLogfileSizeBMem (In der DB gespeicherte Dateigröße des ehemaligen RecentLogfile)
			;    $intLogfileSizeB (Aktuelle Dateigröße des ehemaligen RecentLogfile)
			
			;*** Wenn das ehemalige RecentLogfile seit dem letzten DB-Update gewachsen ist, dann hinzugekommene DS in DB einfügen: ENTFÄLLT!
			
		EndIf
		
		;*** Alle weiteren historischen Logfiles, die noch nicht in der DB gespeichert sind, sowie das aktuelle RecentLogfile in DB einlesen
		$strStatus = $strLocStr[48] ;"DB aktualisieren: Logfile-Rotation hat stattgefunden, alle historischen Logfiles, die noch nicht in der DB gespeichert sind, verarbeiten..."
		GUICtrlSetData($lblStatus, $strStatus)
		
		$intLogfileReadBTot = 0
		
		For $intLogfileCur = 1 To $intLogfilesToRead
			$strSQL = "SELECT * FROM tabTCLogFiles WHERE FilesLogfile = '" & $arrLogfileNames[$intLogfileCur] & "';"
			$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
			
			$intLogfileSizeB = FileGetSize($arrLogfileNames[$intLogfileCur])
			$intLogfileReadB = 0
			
			;*** Logfile ist noch nicht in der DB vorhanden (_SQLite_QuerySingleRow liefert $arrTabTCLogRow[0] = "" bei leerer Ergebnismenge)
			If $arrTabTCLogRow[0] = "" Then
				
				$booConvertUTF82ANSIMonitoredActivities = False
				If $arrLogfileBOM[$intLogfileCur] = "UTF-8" Then
					$booBOMUTF8 = True
				Else
					$booBOMUTF8 = False
				EndIf
				
				$strLogfileContent = FileRead($arrLogfileNames[$intLogfileCur]) ;Logfile komplett einlesen
				$arrLogfileContent = StringSplit($strLogfileContent, @CRLF, 1) ;Logfile in Zeilen aufsplitten
				
				If $intLogfileCur = 1 Then $intLogfileLinesMem = $arrLogfileContent[0] - 1
				
				;*** Logfile zeilenweise einlesen
				$errx = _SQLite_Exec($hdbTCLog, "BEGIN TRANSACTION;")
				$strLogfileDtTmMem = ""
				For $intLogfileLines = 1 To $arrLogfileContent[0] - 1
					
					$strLogfileItem = $arrLogfileContent[$intLogfileLines]
					$intLogfileReadB += StringLen($strLogfileItem) + 2 ;Bereits gelesene Bytes (aktuelles Logfile)
					$intLogfileReadBTot += StringLen($strLogfileItem) + 2 ;Bereits gelesene Bytes (alle Logfiles)
					
					;*** Statuszeile aktualisieren
					If Mod($intLogfileLines, 100) = 1 Then
						$strStatus = $arrLogfileNames[$intLogfileCur] & " (" & Int($intLogfileReadB/$intLogfileSizeB*100) & "%)  •  "
						$strStatus &= $intLogfileCur & "/" & $arrLogfileNames[0] & "  •  "
						$strStatus &= Int($intLogfileReadBTot/$intLogfileSizeBTot*100) & "% " & $strLocStr[46] ;"[…] % gesamt"
						GUICtrlSetData($lblStatus, $strStatus)
					EndIf
					
					;*** Datum und Uhrzeit separat extrahieren (für Berechnung Zeitdifferenz der aktuellen zur nächsten Operation)
					$intLogfileDtTmDiff = 0
					$arrLogfileSubItems = StringRegExp($strLogfileItem, "(?U)^(.+) (.+): .+$", 1); Datum und Uhrzeit lesen
					If @error = 0 Then ;$arrLogfileSubItems ist kein Array für Logfile-Zeilen ohne Datum+Uhrzeit (z.Z. nur Operation "Logfile-Kommentar")
						$strLogfileDate = _FormatDate($arrLogfileSubItems[0])
						$strLogfileTime = _FormatTime($arrLogfileSubItems[1])
						$strLogfileDtTm = StringRegExpReplace($strLogfileDate & $strLogfileTime, "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:\6")
						If $intLogfileLines > 1 Then
							$intLogfileDtTmDiff = Abs(_DateDiff("s", $strLogfileDtTmMem, $strLogfileDtTm))
;~ 						Else
;~ 							$intLogfileDtTmDiff = 0
						EndIf
						$strLogfileDtTmMem = $strLogfileDtTm
					EndIf
					
					;*** Logfile-Zeile parsen und in DB einfügen
					_ParseLogfileLine($strLogfileItem)
					If Mod($intLogfileLines, $intListViewLimit) = 0 Then
						$errx = _SQLite_Exec($hdbTCLog, "COMMIT TRANSACTION;")
						$errx = _SQLite_Exec($hdbTCLog, "BEGIN TRANSACTION;")
					EndIf
					
				Next
				$errx = _SQLite_Exec($hdbTCLog, "COMMIT TRANSACTION;")
				
				$strTabTCLogVals = ""
				$strTabTCLogVals &= _SQLite_Escape($arrLogfileNames[$intLogfileCur]) & ","
				$strTabTCLogVals &= _SQLite_Escape($intLogfileLines-1) & ","
				$strTabTCLogVals &= _SQLite_Escape(FileGetSize($arrLogfileNames[$intLogfileCur]))
				$strSQL = "INSERT INTO tabTCLogFiles(FilesLogfile,FilesZeilen,FilesGroesse) VALUES (" & $strTabTCLogVals & ");"
				$errx = _SQLite_Exec($hdbTCLog, $strSQL)
				
				GUICtrlSetColor($lblRefreshNeeded, 0xFF0000)
				
			;*** Logfile ist bereits in der DB vorhanden
			Else
				$intLogfileReadBTot += $intLogfileSizeB ;Bereits gelesene Bytes (alle Logfiles)
				$strStatus = $arrLogfileNames[$intLogfileCur] & " (" & Int($intLogfileReadB/$intLogfileSizeB*100) & "%)  •  "
				$strStatus &= $intLogfileCur & "/" & $arrLogfileNames[0] & "  •  "
				$strStatus &= Int($intLogfileReadBTot/$intLogfileSizeBTot*100) & "% " & $strLocStr[46] ;"]…] % gesamt"
				GUICtrlSetData($lblStatus, $strStatus)
				
			EndIf
		Next

	;*** Wenn *keine* Logfile-Rotation stattgefunden hat...
	Else

		$intLogfileCur = 1
		
		;*** Die aus dem Recent Logfile ergänzten DS müssen für TC-Version >= 7.5 stets von UTF-8 nach ANSI konvertiert werden
		;*** Anhaltspunkte: 1. Recent-Logfile hat UTF-8-BOM; 2. Aktuellste (letzte) Aktion "Programmstart" ist mit Zusatz "UTF-8" protokolliert
		;*** Hier wird nur Anhaltspunkt 1 geprüft, d.h., für Recent-Logfiles, unter TC <7.5 angelegt wurden und unter TC >=7.5 fortgeführt werden (Versionswechsel), wird's falsch
		If $arrLogfileBOM[1] = "UTF-8" Then
			$booBOMUTF8 = True
			$booConvertUTF82ANSIMonitoredActivities = True
		Else
			$booBOMUTF8 = False
			$booConvertUTF82ANSIMonitoredActivities = False
		EndIf
		
		$strSQL = "SELECT * FROM tabTCLogFiles WHERE FilesLogfile = '" & $strRecentLogfileName & "';"
		$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
		
		;*** ...prüfen, ob dem aktuellen Logfile DS hinzugefügt wurden
		;ToDo: Potentielle Fehlerquelle: Name des aktuellen Logfiles ist nicht in DB vorhanden (weil der User z.B. die Namenskonvention geändert hat)
		$intLogfileLinesMem = $arrTabTCLogRow[1]
		$intLogfileSizeBMem = $arrTabTCLogRow[2]
		$intLogfileSizeB = FileGetSize($strRecentLogfileName)
		
		If $intLogfileSizeB > $intLogfileSizeBMem Then
			
			$strStatus = $strLocStr[49] ;"DB aktualisieren: Neue DS aus aktuellem Logfile in DB einfügen..."
			GUICtrlSetData($lblStatus, $strStatus)
			
			$fhLogfile = _APIFileOpen($strRecentLogfile)
			_APIFileSetPos($fhLogfile, $intLogfileSizeBMem)
			$strLogfileContent = _APIFileRead($fhLogfile, $intLogfileSizeB - $intLogfileSizeBMem, 0)
			_APIFileClose($fhLogfile)
			$intLogfileSizeBMem = $intLogfileSizeB
			$arrLogfileContent = StringSplit($strLogfileContent, @CRLF, 1) ;Logfile in Zeilen aufsplitten
			
			;*** Datum+Uhrzeit der letzten in der DB gespeicherten Logfile-Zeile ermitteln (für Berechnung Zeitdifferenz der aktuellen zur nächsten Operation) 
			$strLogfileDtTmMem = ""
			If $intLogfileLinesMem > 1 Then
				$intLogfileLinesCur = $intLogfileLinesMem
				Do
					$strSQL = "SELECT * FROM tabTCLogDetails WHERE Logfile = '" & $strRecentLogfileName & "' AND LogLine = " & $intLogfileLinesCur & ";"
					$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
					$strLogfileDate = $arrTabTCLogRow[2]
					$strLogfileTime = $arrTabTCLogRow[3]
					$intLogfileLinesCur -= 1
					$strLogfileDtTmMem = StringRegExpReplace($strLogfileDate & $strLogfileTime, "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:\6")
				Until @error = 0 Or $intLogfileLinesCur = 1
			EndIf
			
			$errx = _SQLite_Exec($hdbTCLog, "BEGIN TRANSACTION;")
			For $intLogfileLines = $intLogfileLinesMem + 1 To $intLogfileLinesMem + $arrLogfileContent[0] - 1
				$strLogfileItem = $arrLogfileContent[$intLogfileLines-$intLogfileLinesMem]
				;*** Datum und Uhrzeit separat extrahieren (für Berechnung Zeitdifferenz der aktuellen zur nächsten Operation)
				$intLogfileDtTmDiff = 0
				$arrLogfileSubItems = StringRegExp($strLogfileItem, "(?U)^(.+) (.+): .+$", 1); Datum und Uhrzeit lesen
				If @error = 0 Then ;$arrLogfileSubItems ist kein Array für Logfile-Zeilen ohne Datum+Uhrzeit (z.Z. nur Operation "Logfile-Kommentar")
					$strLogfileDate = _FormatDate($arrLogfileSubItems[0])
					$strLogfileTime = _FormatTime($arrLogfileSubItems[1])
					$strLogfileDtTm = StringRegExpReplace($strLogfileDate & $strLogfileTime, "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:\6")
					If $strLogfileDtTmMem <> "" Then ;*** $strLogfileDtTmMem ist u.U. leer
						If $intLogfileLines > 1 Then
							$intLogfileDtTmDiff = Abs(_DateDiff("s", $strLogfileDtTmMem, $strLogfileDtTm))
;~ 						Else
;~ 							$intLogfileDtTmDiff = 0
						EndIf
					EndIf
					$strLogfileDtTmMem = $strLogfileDtTm
				EndIf
				$strListviewItem = _ParseLogfileLine($strLogfileItem)
			Next
			$errx = _SQLite_Exec($hdbTCLog, "COMMIT TRANSACTION;")
			$intLogfileLinesMem = $intLogfileLines - 1
			
			;*** tabTCLogFiles.FilesLogfile updaten: FilesZeilen und FilesGroesse updaten (FilesLogfile ist bereits "umbenannt"!)
			$strSQL = "UPDATE tabTCLogFiles SET FilesZeilen = " & $intLogfileLinesMem & " WHERE FilesLogfile = '" & $strRecentLogfileName & "';"
			$errx = _SQLite_Exec($hdbTCLog, $strSQL)
			$err = @error
			_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
			
			$strSQL = "UPDATE tabTCLogFiles SET FilesGroesse = " & $intLogfileSizeBMem & " WHERE FilesLogfile = '" & $strRecentLogfileName & "';"
			$errx = _SQLite_Exec($hdbTCLog, $strSQL)
			$err = @error
			_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
			
			GUICtrlSetColor($lblRefreshNeeded, 0xFF0000)
			
		EndIf
		
	EndIf
	
EndIf

$booLogfileReadFinished = True
GUICtrlSetBkColor($lblLight, 0x00FF00)
GUICtrlSetData($lblStatus, "")

Call("_cbxLogfileSetData") ;Filter-ComboBox "Logfile" populieren
Call("_cbxOpDateSetData") ;Filter-ComboBox "Datum" populieren
Call("_cbxOperationSetData") ;Filter-ComboBox "Vorgang" populieren
Call("_cbxOpStatusSetData") ;Filter-ComboBox "Status" populieren

;*** Optimale Spaltenbreite einstellen
_ListViewSetColumnWidthAuto()

;*** Dateigröße und Anzahl DS des aktuellen RecentLogfile aus DB ermitteln sowie tatsächliche Dateigröße des aktuellen RecentLogfile ermitteln
$strSQL = "SELECT * FROM tabTCLogFiles WHERE FilesLogfile = '" & $strRecentLogfileName & "';"
$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
$intLogfileLinesMem = $arrTabTCLogRow[1]
$intLogfileSizeBMem = $arrTabTCLogRow[2]
$intLogfileSizeB = FileGetSize($strRecentLogfileName)

;*** Anzahl DS in DB ermitteln
$strSQL = "SELECT COUNT(*) FROM tabTCLogDetails;"
$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
$intTabTCLogCount = $arrTabTCLogRow[0]
$p = Int($intTabTCLogCount / $intListViewLimit)
If Mod($intTabTCLogCount, $intListViewLimit) > 0 Then $p += 1
$strStatus = $intTabTCLogCount & " " & $strLocStr[50] & " " & $intTabTCLogOffset / $intListViewLimit + 1 & "/" & $p ;"[…] DS  •  Seite […]"
GUICtrlSetData($lblStatus, $strStatus)

;*** Buttons "NextPage" und "LastPage" disablen, wenn sämtliche DS in einen Chunk passen
GUICtrlSetState($btnFirstPage, $GUI_DISABLE)
GUICtrlSetState($btnPrevPage, $GUI_DISABLE)
$intListViewItemCount = _GUICtrlListView_GetItemCount($hlvLogfile)
If $intListViewItemCount >= $intTabTCLogCount Then
	GUICtrlSetState($btnNextPage, $GUI_DISABLE)
	GUICtrlSetState($btnLastPage, $GUI_DISABLE)
EndIf

;================================================================================

;*** Dialogaktivität des Benutzers überwachen und auswerten
$booCbxLogfileDroppedMem = False
$booCbxDatumDroppedMem = False
$booCbxVorgangDroppedMem = False
$booCbxStatusDroppedMem = False
Global $booListViewGetNextItem = False
$intLogfileCur = 1

;*** Die in Echtzeit eingefügten DS müssen für TC-Version >= 7.5 stets von UTF-8 nach ANSI konvertiert werden
;*** Anhaltspunkte: 1. Recent-Logfile hat UTF-8-BOM; 2. Aktuellste (letzte) Aktion "Programmstart" ist mit Zusatz "UTF-8" protokolliert
;*** Hier wird nur Anhaltspunkt 1 geprüft, d.h., für Recent-Logfiles, unter TC <7.5 angelegt wurden und unter TC >=7.5 fortgeführt werden (Versionswechsel), wird's falsch
If $arrLogfileBOM[1] = "UTF-8" Then
	$booBOMUTF8 = True
	$booConvertUTF82ANSIMonitoredActivities = True
Else
	$booBOMUTF8 = False
	$booConvertUTF82ANSIMonitoredActivities = False
EndIf

;*** Datum+Uhrzeit der letzten in der DB gespeicherten Logfile-Zeile ermitteln (für Berechnung Zeitdifferenz der aktuellen zur nächsten Operation) 
$strLogfileDtTmMem = ""
If $intLogfileLinesMem > 1 Then
	$intLogfileLinesCur = $intLogfileLinesMem
	Do
		$strSQL = "SELECT * FROM tabTCLogDetails WHERE Logfile = '" & $strRecentLogfileName & "' AND LogLine = " & $intLogfileLinesCur & ";"
		$errx = _SQLite_QuerySingleRow($hdbTCLog, $strSQL, $arrTabTCLogRow)
		$strLogfileDate = $arrTabTCLogRow[2]
		$strLogfileTime = $arrTabTCLogRow[3]
		$intLogfileLinesCur -= 1
		$strLogfileDtTmMem = StringRegExpReplace($strLogfileDate & $strLogfileTime, "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:\6")
	Until @error = 0 Or $intLogfileLinesCur = 1
EndIf

While 1
	
	;*** Einzeldatensatzansicht aktualisieren
	$intListViewCurSel = _GUICtrlListView_GetNextItem($hlvLogfile)
	If $intListViewPrevSel <> $intListViewCurSel Then
		$intListViewPrevSel = $intListViewCurSel
		$arrListViewRow = _GUICtrlListView_GetItemTextArray($hlvLogfile)
		$strStatus = ""
		If IsArray($arrListViewRow) Then
			$strStatus &= $arrListViewRow[1] & " · " & $arrListViewRow[2] & "  •  "
			$strStatus &= $arrListViewRow[3] & " " & $arrListViewRow[4] & "  •  "
			$strStatus &= $arrListViewRow[5] & " (" & $arrListViewRow[6] & ")" & @LF
			$strStatus &= $arrListViewRow[7] & @LF & $arrListViewRow[8]
		EndIf
		GUICtrlSetData($lblSingleDS, $strStatus)
	EndIf
	
	;*** ComboBoxen (Filterkriterien Logfile, Datum, Vorgang, Status) überwachen
	$booCbxLogfileDroppedCur = _GUICtrlComboBox_GetDroppedState($cbxLogfileVal)
	$booCbxDatumDroppedCur = _GUICtrlComboBox_GetDroppedState($cbxDatumVal)
	$booCbxVorgangDroppedCur = _GUICtrlComboBox_GetDroppedState($cbxVorgangVal)
	$booCbxStatusDroppedCur = _GUICtrlComboBox_GetDroppedState($cbxStatusVal)
	
	$strTabTCLogColName = ""
	If $booCbxLogfileDroppedCur And $booCbxLogfileDroppedCur <> $booCbxLogfileDroppedMem Then $strTabTCLogColName = "Logfile"
	If $booCbxDatumDroppedCur And $booCbxDatumDroppedCur <> $booCbxDatumDroppedMem Then $strTabTCLogColName = "OpDate"
	If $booCbxVorgangDroppedCur And $booCbxVorgangDroppedCur <> $booCbxVorgangDroppedMem Then $strTabTCLogColName = "Operation"
	If $booCbxStatusDroppedCur And $booCbxStatusDroppedCur <> $booCbxStatusDroppedMem Then $strTabTCLogColName = "OpStatus"
	
	$booCbxLogfileDroppedMem = $booCbxLogfileDroppedCur
	$booCbxDatumDroppedMem = $booCbxDatumDroppedCur
	$booCbxVorgangDroppedMem = $booCbxVorgangDroppedCur
	$booCbxStatusDroppedMem = $booCbxStatusDroppedCur
	
	If $strTabTCLogColName <> "" Then
		$strTabTCLogWhere = ""
		If $strTabTCLogColName <> "Logfile"   Then $strTabTCLogWhere &= " AND " & $strTabTCLogWhereLogfile
		If $strTabTCLogColName <> "OpDate"    Then $strTabTCLogWhere &= " AND " & $strTabTCLogWhereDatum
		If $strTabTCLogColName <> "Operation" Then $strTabTCLogWhere &= " AND " & $strTabTCLogWhereVorgang
		If $strTabTCLogColName <> "OpStatus"  Then $strTabTCLogWhere &= " AND " & $strTabTCLogWhereStatus
		$strTabTCLogWhere &= " AND " & $strTabTCLogWhereQuelleOderZiel
		$strTabTCLogWhere &= " AND " & $strTabTCLogWhereDtTmDiff
		While StringInStr($strTabTCLogWhere, " AND  AND ") > 0
			$strTabTCLogWhere = StringReplace($strTabTCLogWhere, " AND  AND ", " AND ")
		WEnd
		While StringLeft($strTabTCLogWhere, 5) = " AND "
			$strTabTCLogWhere = StringTrimLeft($strTabTCLogWhere, 5)
		WEnd
		While StringRight($strTabTCLogWhere, 5) = " AND "
			$strTabTCLogWhere = StringTrimRight($strTabTCLogWhere, 5)
		WEnd
		If StringReplace($strTabTCLogWhere, " ", "") <> "" Then $strTabTCLogWhere = " WHERE " & $strTabTCLogWhere
		$strTabTCLogWhere &= " "
		Call("_cbx" & $strTabTCLogColName & "SetData")
	EndIf
	
	;*** Logfile überwachen
	If Not $booAutoRefreshPaused Then
		
		$intLogfileSizeB = FileGetSize($strRecentLogfileName)
		
		If $intLogfileSizeB > $intLogfileSizeBMem Then
			
			$fhLogfile = _APIFileOpen($strRecentLogfile)
			_APIFileSetPos($fhLogfile, $intLogfileSizeBMem)
			$strLogfileContent = _APIFileRead($fhLogfile, $intLogfileSizeB - $intLogfileSizeBMem, 0)
			_APIFileClose($fhLogfile)
			$intLogfileSizeBMem = $intLogfileSizeB
			
			$arrLogfileContent = StringSplit($strLogfileContent, @CRLF, 1) ;Logfile in Zeilen aufsplitten
			$errx = _SQLite_Exec($hdbTCLog, "BEGIN TRANSACTION;")
			For $intLogfileLines = $intLogfileLinesMem + 1 To $intLogfileLinesMem + $arrLogfileContent[0] - 1
				
				$strLogfileItem = $arrLogfileContent[$intLogfileLines-$intLogfileLinesMem]
				
				;*** Datum und Uhrzeit separat extrahieren(für Berechnung Zeitdifferenz der aktuellen zur nächsten Operation)
				$intLogfileDtTmDiff = 0
				$arrLogfileSubItems = StringRegExp($strLogfileItem, "(?U)^(.+) (.+): .+$", 1); Datum und Uhrzeit lesen
				If @error = 0 Then ;$arrLogfileSubItems ist kein Array für Logfile-Zeilen ohne Datum+Uhrzeit (z.Z. nur Operation "Logfile-Kommentar")
					$strLogfileDate = _FormatDate($arrLogfileSubItems[0])
					$strLogfileTime = _FormatTime($arrLogfileSubItems[1])
					$strLogfileDtTm = StringRegExpReplace($strLogfileDate & $strLogfileTime, "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:\6")
					If $strLogfileDtTmMem <> "" Then ;*** $strLogfileDtTmMem ist u.U. leer
						If $intLogfileLines > 1 Then
							$intLogfileDtTmDiff = Abs(_DateDiff("s", $strLogfileDtTmMem, $strLogfileDtTm))
;~ 						Else
;~ 							$intLogfileDtTmDiff = 0
						EndIf
					EndIf
					$strLogfileDtTmMem = $strLogfileDtTm
				EndIf
				
				$strListviewItem = _ParseLogfileLine($arrLogfileContent[$intLogfileLines-$intLogfileLinesMem])
				
				$arrListViewRow = StringSplit($strListviewItem, "|")
				_GUICtrlListView_DeleteItem($hlvLogfile, $intListViewLimit)
				_GUICtrlListView_InsertItem($hlvLogfile, "", 0, 15)
				For $intListViewCol = 0 To $arrListViewRow[0]-1
					_GUICtrlListView_SetItemText($hlvLogfile, 0, _Cv($arrListViewRow[$intListViewCol+1], "r"), $intListViewCol)
				Next
			Next
			
			$errx = _SQLite_Exec($hdbTCLog, "COMMIT TRANSACTION;")
			$intLogfileLinesMem = $intLogfileLines - 1
			
			$strSQL = "UPDATE tabTCLogFiles SET FilesZeilen = " & $intLogfileLinesMem & " WHERE FilesLogfile = '" & $strRecentLogfileName & "';"
			$errx = _SQLite_Exec($hdbTCLog, $strSQL)
			$err = @error
			_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
			
			$strSQL = "UPDATE tabTCLogFiles SET FilesGroesse = " & $intLogfileSizeBMem & " WHERE FilesLogfile = '" & $strRecentLogfileName & "';"
			$errx = _SQLite_Exec($hdbTCLog, $strSQL)
			$err = @error
			_SQLiteErrHandler(16, $err, $errx, "_SQLite_Exec", $strSQL)
			
			GUICtrlSetColor($lblRefreshNeeded, 0xFF0000)
			_ListViewSetColumnWidthAuto()
			$intLogfileLinesMem = $intLogfileLines - 1
			
		EndIf
		
	EndIf
	
	Sleep(250)
	
WEnd

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _MsgBox($intMsgBoxFlag, $strMsgBoxTitle, $strMsgBoxText)
	
	;*** Wenn Topmost-Flag des Hauptfensters gesetzt ist, dann werden Messageboxes durch das Hauptfenster verborgen: Topmost-Flag vorübergehend ausschalten
	If $booTopmost = True Then
		$booTopmostDesired = True
		_Topmost("Off")
	EndIf
	
	$intRC = MsgBox($intMsgBoxFlag, $strMsgBoxTitle, $strMsgBoxText)
	
	If $booTopmostDesired = True Then _Topmost("On")
	
	Return $intRC
	
EndFunc

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _AllGUICtrlSetState($intGUICtrlState) ;$intGUICtrlState: $GUI_ENABLE, $GUI_DISABLE
	
	If $intGUICtrlState = $GUI_DISABLE Then GUISetCursor(15, 1, $frmGUI) ;"WAIT"
	
	GUICtrlSetState($cbxLogfileOp, $intGUICtrlState)
	GUICtrlSetState($cbxLogfileVal, $intGUICtrlState)
	GUICtrlSetState($btnLogfileNext, $intGUICtrlState)
	GUICtrlSetState($cbxDatumOp, $intGUICtrlState)
	GUICtrlSetState($cbxDatumVal, $intGUICtrlState)
	GUICtrlSetState($btnDatumNext, $intGUICtrlState)
	GUICtrlSetState($cbxUhrzeitOp, $intGUICtrlState)
	GUICtrlSetState($txtUhrzeitVal, $intGUICtrlState)
	GUICtrlSetState($cbxDatumUhrzeitDiffOp, $intGUICtrlState)
	GUICtrlSetState($txtDatumUhrzeitDiffVal, $intGUICtrlState)
	GUICtrlSetState($cbxVorgangOp, $intGUICtrlState)
	GUICtrlSetState($cbxVorgangVal, $intGUICtrlState)
	GUICtrlSetState($btnVorgangNext, $intGUICtrlState)
	GUICtrlSetState($cbxStatusOp, $intGUICtrlState)
	GUICtrlSetState($cbxStatusVal, $intGUICtrlState)
	GUICtrlSetState($btnStatusNext, $intGUICtrlState)
	GUICtrlSetState($cbxQuelleOderZielFld, $intGUICtrlState)
	GUICtrlSetState($cbxQuelleOderZielOp, $intGUICtrlState)
	GUICtrlSetState($txtQuelleOderZielVal, $intGUICtrlState)
	GUICtrlSetState($chkQuelleOderZielDropPath, $intGUICtrlState)
	GUICtrlSetState($chkQuelleOderZielDropFile, $intGUICtrlState)
	GUICtrlSetState($txtSearchFor, $intGUICtrlState)
	GUICtrlSetState($btnSearchForNext, $intGUICtrlState)
	GUICtrlSetState($btnTabTCLogWhereReset, $intGUICtrlState)
	GUICtrlSetState($btnTabTCLogOrderByReset, $intGUICtrlState)
	GUICtrlSetState($btnCheckAllListviewItemsOnCurrPage, $intGUICtrlState)
	GUICtrlSetState($btnUnCheckAllListviewItemsOnCurrPage, $intGUICtrlState)	
	GUICtrlSetState($btnCheckAllSelectedListviewItems, $intGUICtrlState)
	GUICtrlSetState($btnUnCheckAllSelectedListviewItems, $intGUICtrlState)
	GUICtrlSetState($btnUnCheckAllListviewItems, $intGUICtrlState)
	GUICtrlSetState($btnCheckedNext, $intGUICtrlState)
	GUICtrlSetState($btnScrollUp, $intGUICtrlState)
	GUICtrlSetState($btnScrollDown, $intGUICtrlState)
	GUICtrlSetState($btnFirstPage, $intGUICtrlState)
	GUICtrlSetState($btnPrevPage, $intGUICtrlState)
	GUICtrlSetState($btnNextPage, $intGUICtrlState)
	GUICtrlSetState($btnLastPage, $intGUICtrlState)
	GUICtrlSetState($chkAutoRefreshPause, $intGUICtrlState)
	GUICtrlSetState($btnRefresh, $intGUICtrlState)
	GUICtrlSetState($btnUndo, $intGUICtrlState)
	GUICtrlSetState($chkUndoCommit, $intGUICtrlState)
	GUICtrlSetState($btnSave, $intGUICtrlState)
	GUICtrlSetState($chkTopmost, $intGUICtrlState)
	GUICtrlSetState($btnDBReorganize, $intGUICtrlState)
	
	If $intGUICtrlState = $GUI_ENABLE Then
		GUICtrlSetBkColor($lblLight, 0x00FF00)
		$intListViewItemCount = _GUICtrlListView_GetItemCount($hlvLogfile)
		If $intTabTCLogOffset = 0 Then
			GUICtrlSetState($btnFirstPage, $GUI_DISABLE)
			GUICtrlSetState($btnPrevPage, $GUI_DISABLE)
		EndIf
		If $intTabTCLogOffset + $intListViewItemCount >= $intTabTCLogCount Then
			GUICtrlSetState($btnNextPage, $GUI_DISABLE)
			GUICtrlSetState($btnLastPage, $GUI_DISABLE)
		EndIf
		GUISetCursor(-1, 0, $frmGUI) ;Standard ("ARROW")
	Else
		GUICtrlSetBkColor($lblLight, 0xFF0000)
	EndIf
	
EndFunc ;_AllGUICtrlSetState

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _Cv($strString, $strMode)
	If $strMode = "r" Then Return BinaryToString($strString, 4)
	If $strMode = "w" Then Return BinaryToString(StringToBinary($strString, 4), 1)
EndFunc

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _FormatDate($strLogfileDate)
	;*** Datum entsprechend kurzem Datumsformat (Registry "sShortDate") aufbereiten
	$arrLogfileDate = StringSplit($strLogfileDate, $strRegDateFmtDelim)
	Dim $arrTemp[4]
	For $i = 1 To $arrRegDateFmt[0]
		If StringLeft($arrRegDateFmt[$i], 1) = "y" Then $arrTemp[1] = $arrLogfileDate[$i] ;Achtung! yy wird nicht auf ccyy expandiert 
		If StringLeft($arrRegDateFmt[$i], 1) = "M" Then $arrTemp[2] = $arrLogfileDate[$i] ;Achtung! M / MMM|MMMM werden nicht auf MM expandiert / reduziert
		If StringLeft($arrRegDateFmt[$i], 1) = "d" Then $arrTemp[3] = $arrLogfileDate[$i] ;Achtung! d / ddd/dddd werden nicht auf dd expandiert / reduziert
	Next
	$strLogfileDate = $arrTemp[1] & "-" & $arrTemp[2] & "-" & $arrTemp[3]
	$arrTemp = ""
	Return $strLogfileDate
EndFunc ;_FormatDate

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _FormatTime($strLogfileTime)
	;*** Uhrzeit entsprechend ... (Registry "...") aufbereiten
	$arrLogfileTime = StringSplit($strLogfileTime, $strRegTimeFmtDelim)
	
	If $arrLogfileTime[0] = 3 Then
		Dim $arrTemp[4]
		For $i = 1 To $arrRegTimeFmt[0]
			If StringLeft($arrRegTimeFmt[$i], 1) = "H" Then $arrTemp[1] = $arrLogfileTime[$i] ;Achtung! H wird nicht auf HH expandiert 
			If StringLeft($arrRegTimeFmt[$i], 1) = "m" Then $arrTemp[2] = $arrLogfileTime[$i] ;Achtung! m wird nicht auf mm expandiert 
			If StringLeft($arrRegTimeFmt[$i], 1) = "s" Then $arrTemp[3] = $arrLogfileTime[$i] ;Achtung! s wird nicht auf ss expandiert 
		Next
		$strLogfileTime = $arrTemp[1] & ":" & $arrTemp[2] & ":" & $arrTemp[3]
	EndIf
	
	If $arrLogfileTime[0] = 2 Then
		Dim $arrTemp[3]
		For $i = 1 To $arrRegTimeFmt[0]
			If StringLeft($arrRegTimeFmt[$i], 1) = "H" Then $arrTemp[1] = $arrLogfileTime[$i] ;Achtung! H wird nicht auf HH expandiert 
			If StringLeft($arrRegTimeFmt[$i], 1) = "m" Then $arrTemp[2] = $arrLogfileTime[$i] ;Achtung! m wird nicht auf mm expandiert 
		Next
		$strLogfileTime = $arrTemp[1] & ":" & $arrTemp[2] & ":00"
	EndIf
	
	$arrTemp = ""
	Return $strLogfileTime
EndFunc ;_FormatTime

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _ParseLogfileLine($strLogfileItem)
	
	$strLogfileDate = ""
	$strLogfileTime = ""
	$strLogfileOperation = ""
	$strLogfileErrDesc = ""
	$strLogfileSource = ""
	$strLogfileTarget = ""
	$booLogfilePatMatched = False
	
	For $intLogfilePat = 1 To $strLogfileItemPat[0]
		
		$arrLogfileSubItems = StringRegExp($strLogfileItem, $strLogfileItemPat[$intLogfilePat], 1)
		If @error = 0 Then
			
			$booLogfilePatMatched = True
			
			;*** Datum entsprechend kurzem Datumsformat (Registry "sShortDate") aufbereiten
			$strLogfileDate = _FormatDate($arrLogfileSubItems[0])
			
			;*** Uhrzeit entsprechend kurzem Uhrzeitformat (Registry "sTimeFormat") aufbereiten
			$strLogfileTime = _FormatTime($arrLogfileSubItems[1])
			
			$strLogfileOperation = $arrLogfileSubItems[2]
			
			Switch $intLogfilePat
				Case 1, 3, 4
					$strLogfileErrDesc = $arrLogfileSubItems[3]
					$strLogfileSource = $arrLogfileSubItems[4]
					$strLogfileTarget = $arrLogfileSubItems[5]
				Case 5
					$strLogfileErrDesc = $arrLogfileSubItems[3]
					$strLogfileSource = ""
					$strLogfileTarget = ""
				Case 2, 6, 7
					$strLogfileErrDesc = $arrLogfileSubItems[3]
					$strLogfileSource = $arrLogfileSubItems[4]
					$strLogfileTarget = ""
				Case 8
					$strLogfileErrDesc = "OK"
					$strLogfileSource = $arrLogfileSubItems[3]
					$strLogfileTarget = $arrLogfileSubItems[4]
				Case 9
					$strLogfileErrDesc = "OK"
					$strLogfileSource = $arrLogfileSubItems[3]
					$strLogfileTarget = ""
				Case 10
					$strLogfileErrDesc = "OK"
					$strLogfileSource = $arrLogfileSubItems[3]
					$strLogfileTarget = ""
					;*** Enthält ein Logfile *ohne* BOM einen Programmstart-Eintrag mit Zusatz "UTF-8", konvertiert AutoIt *nicht*. In diesem Fall muss die Konvertierung UTF-8 nach ANSI manuell angestoßen werden.
					If $strLogfileOperation = $strLocStr[51] Then ;"Programmstart" ("Programmende" nicht auswerten)
						$booConvertUTF82ANSI = False
						If UBound($arrLogfileSubItems) >= 5 And $booBOMUTF8 = False Then $booConvertUTF82ANSI = True
					EndIf
			EndSwitch
			ExitLoop
		EndIf
	Next
	
	If Not $booLogfilePatMatched Then
		$strLogfileDate = ""
		$strLogfileTime = ""
		$strLogfileOperation = $strLocStr[64] ;"LogfileKommentar"
		$strLogfileErrDesc = "--"
		$strLogfileSource = $strLogfileItem
		$strLogfileTarget = ""
	EndIf
	
	;*** Konvertierung UTF8 ---> ANSI
	If $booConvertUTF82ANSI = True Or $booConvertUTF82ANSIMonitoredActivities = True Then
		$strLogfileOperation = BinaryToString($strLogfileOperation, 4)
		$strLogfileErrDesc = BinaryToString($strLogfileErrDesc, 4)
		$strLogfileSource = BinaryToString($strLogfileSource, 4)
		$strLogfileTarget = BinaryToString($strLogfileTarget, 4)
	EndIf
	
	$strLogfileOperation = _Cv($strLogfileOperation, "w")
	$strLogfileErrDesc = _Cv($strLogfileErrDesc, "w")
	$strLogfileSource = _Cv($strLogfileSource, "w")
	$strLogfileTarget = _Cv($strLogfileTarget, "w")
	
	If $strLogfileOperation = $strLocStr[54] And StringLeft($strLogfileSource, StringInStr($strLogfileSource, "\", 0, -1)) = StringLeft($strLogfileTarget, StringInStr($strLogfileTarget, "\", 0, -1)) Then ;"[…] Verschieben […]"
		$strLogfileOperation = $strLocStr[55] ;"Umbenennen"
	EndIf
	
	$strTabTCLogVals = ""
	$strTabTCLogVals &= _SQLite_Escape($arrLogfileNames[$intLogfileCur]) & ","
	$strTabTCLogVals &= _SQLite_Escape($intLogfileLines) & ","
	$strTabTCLogVals &= _SQLite_Escape($strLogfileDate) & ","
	$strTabTCLogVals &= _SQLite_Escape($strLogfileTime) & ","
	$strTabTCLogVals &= _SQLite_Escape($strLogfileOperation) & ","
	$strTabTCLogVals &= _SQLite_Escape($strLogfileErrDesc) & ","
	$strTabTCLogVals &= _SQLite_Escape($strLogfileSource) & ","
	$strTabTCLogVals &= _SQLite_Escape($strLogfileTarget) & ","
	$strTabTCLogVals &= _SQLite_Escape($intLogfileDtTmDiff)

	$strSQL = "INSERT INTO tabTCLogDetails(Logfile,LogLine,OpDate,OpTime,Operation,OpStatus,OpSource,OpTarget,OpDtTmDiff) VALUES (" & $strTabTCLogVals & ");"
	$errx = _SQLite_Exec($hdbTCLog, $strSQL)

	Return $strRecentLogfileName & "|" & $intLogfileLines & "|" & $strLogfileDate & "|" & $strLogfileTime & "|" & $strLogfileOperation & "|" & $strLogfileErrDesc & "|" & $strLogfileSource & "|" & $strLogfileTarget

EndFunc ;_ParseLogfileLine

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _ListViewSort()
	
	$intListViewCol = GUICtrlGetState($lvLogfile)
	
	$booListViewColSorted = False
	
	If $booTabTCLogOrderByUser Then
		$arrTabTCLogOrderByRaw = StringSplit($strTabTCLogOrderByRaw, "=|") ;n=o|…: n=SpaltenNr des ListViews, o=Sortierreihenfolge (0=ASC, 1=DESC)
		$strTabTCLogOrderByRaw = ""
		For $i=1 To $arrTabTCLogOrderByRaw[0] Step 2
			$strTabTCLogOrderByRaw &= $arrTabTCLogOrderByRaw[$i] & "="
			If $intListViewCol = $arrTabTCLogOrderByRaw[$i]*1 Then
				$arrTabTCLogOrderByRaw[$i+1] = Abs($arrTabTCLogOrderByRaw[$i+1]*1 - 1) ;Sortierreihenfolge umkehren 0->1 / 1->0
				$booListViewColSorted = True
			EndIf
			$strTabTCLogOrderByRaw &= $arrTabTCLogOrderByRaw[$i+1] & "|"
		Next
	Else
		$booTabTCLogOrderByUser = True
	EndIf

	If Not $booListViewColSorted Then $strTabTCLogOrderByRaw &= $intListViewCol & "=0|"
	$strTabTCLogOrderByRaw = StringTrimRight($strTabTCLogOrderByRaw, 1)
	
	$strTabTCLogOrderBy = " ORDER BY "
	$arrTabTCLogOrderByRaw = StringSplit($strTabTCLogOrderByRaw, "=|")
	For $i=1 To $arrTabTCLogOrderByRaw[0] Step 2
		$strTabTCLogOrderBy &= $arrTabTCLogCols[$arrTabTCLogOrderByRaw[$i]+1]
		If $arrTabTCLogOrderByRaw[$i+1] = 0 Then
			$strTabTCLogOrderBy &= " ASC, "
			_GUICtrlListView_SetColumn($hlvLogfile, ($arrTabTCLogOrderByRaw[$i]+1)-1, $arrListViewCols[$arrTabTCLogOrderByRaw[$i]+1] & ":" & ($i+1)/2 & "<")
		Else
			$strTabTCLogOrderBy &= " DESC, "
			_GUICtrlListView_SetColumn($hlvLogfile, ($arrTabTCLogOrderByRaw[$i]+1)-1, $arrListViewCols[$arrTabTCLogOrderByRaw[$i]+1] & ":" & ($i+1)/2 & ">")
		EndIf
	Next
	$strTabTCLogOrderBy = StringTrimRight($strTabTCLogOrderBy, 2) & " "
	
	Call("_CreateTableView")
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
	
EndFunc ;_ListViewSort

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _BuildSQLWhereClause()
	$strTabTCLogWhere = $strTabTCLogWhereLogfile
	$strTabTCLogWhere &= " AND " & $strTabTCLogWhereDatum
	$strTabTCLogWhere &= " AND " & $strTabTCLogWhereUhrzeit
	$strTabTCLogWhere &= " AND " & $strTabTCLogWhereDtTmDiff
	$strTabTCLogWhere &= " AND " & $strTabTCLogWhereVorgang
	$strTabTCLogWhere &= " AND " & $strTabTCLogWhereStatus
	$strTabTCLogWhere &= " AND " & $strTabTCLogWhereQuelleOderZiel
	
	While StringInStr($strTabTCLogWhere, " AND  AND ") > 0
		$strTabTCLogWhere = StringReplace($strTabTCLogWhere, " AND  AND ", " AND ")
	WEnd
	While StringLeft($strTabTCLogWhere, 5) = " AND "
		$strTabTCLogWhere = StringTrimLeft($strTabTCLogWhere, 5)
	WEnd
	While StringRight($strTabTCLogWhere, 5) = " AND "
		$strTabTCLogWhere = StringTrimRight($strTabTCLogWhere, 5)
	WEnd
	If StringReplace($strTabTCLogWhere, " ", "") <> "" Then $strTabTCLogWhere = " WHERE " & $strTabTCLogWhere
	$strTabTCLogWhere &= " "
EndFunc ;_BuildSQLWhereClause

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _CreateTableView()
	Local $hqryViewTCLog
	_BuildSQLWhereClause()
	$strSQL = "SELECT * FROM tabTCLogDetails" & $strTabTCLogWhere & $strTabTCLogOrderBy
	$strSQL = "CREATE TEMP VIEW viewTCLogDetails AS " & $strSQL & ";"
	$strStatus = $strSQL
	GUICtrlSetData($lblStatus, $strStatus)
	$errx = _SQlite_Query($hdbTCLog, $strSQL, $hqryViewTCLog)
	$err = @error
	_SQLiteErrHandler(48, $err, $errx, "_SQlite_Query", $strSQL)
	_SQLite_QueryFinalize($hqryViewTCLog)
EndFunc ;_CreateTableView

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _ListViewRefresh()
	
	_AllGUICtrlSetState($GUI_DISABLE)
	_BuildSQLWhereClause()

	$strSQL = "SELECT * FROM tabTCLogDetails" & $strTabTCLogWhere & $strTabTCLogOrderBy & "LIMIT " & $intListViewLimit & " OFFSET " & $intTabTCLogOffset & ";"
	
	GUICtrlSetBkColor($lblLight, 0xFF0000)
	$strStatus = $strSQL
	GUICtrlSetData($lblStatus, $strStatus)
	
	_GUICtrlListView_EnsureVisible($hlvLogfile, 0, 1)
	_GUICtrlListView_DeleteAllItems($hlvLogfile)
	
	$errx = _SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
	$err = @error

	While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
		$strLogfileItem = ""
		For $intTabTCLogCol = 0 To UBound($arrTabTCLogRow)-2 ;Letzte in der DB gespeicherte Spalte (OpDtTmDiff) nicht mit einlesen
			Switch $intTabTCLogCol
				#cs
				Case 2, 3
					If $arrTabTCLogRow[8] = 0 Then
						$strLogfileItem &= "|"
					Else
						$strLogfileItem &= $arrTabTCLogRow[$intTabTCLogCol] & "|"
					EndIf
				#ce
;~ 				Case 4, 5, 7
				Case 4, 5, 6, 7
					$strLogfileItem &= _Cv($arrTabTCLogRow[$intTabTCLogCol], "r") & "|"
;~ 				Case 6
;~ 					$strLogfileItem &= "(" & $arrTabTCLogRow[8] & ") " & _Cv($arrTabTCLogRow[$intTabTCLogCol], "r") & "|";debug
				Case Else
					$strLogfileItem &= $arrTabTCLogRow[$intTabTCLogCol] & "|"
			EndSwitch
		Next
		$strLogfileItem = StringTrimRight($strLogfileItem, 1)
		$lvitemLogfile = GUICtrlCreateListViewItem($strLogfileItem, $lvLogfile)
		
		;0=Logfile, 1=Zeile, 2=Datum, 3=Uhrzeit, 4=Vorgang, 5=Status, 6=Quelle, 7=Ziel (, 8=DatumUhrzeitDifferenz)
		Switch _Cv($arrTabTCLogRow[4], "r")
			
			;*** 1800="Programmstart", 1801="Programmende": "Programmstart", "Programmende"
			Case $strLocStr[51], $strLocStr[52]
				$intListviewColor = $intColorRGBProgramStartAndShutdown
				$intListviewIcon = 0
				
			;*** 1802="Kopieren": "Kopieren", "FS:Kopieren", "XT:Kopieren"
			Case $strLocStr[53], "FS:" & $strLocStr[53], "XT:" & $strLocStr[53]
				$intListviewColor = $intColorRGBCopy
				$intListviewIcon = 1
			
			;*** 1803="Verschieben": "Verschieben", "FS:Verschieben", "XT:Verschieben"
			Case $strLocStr[54], "FS:" & $strLocStr[54], "XT:" & $strLocStr[54]
				$intListviewColor = $intColorRGBMove
				$intListviewIcon = 2
			
			;*** 1803="Verschieben": "Umbenennen", "FS:Umbenennen", "XT:Umbenennen"
			Case $strLocStr[55], "FS:" & $strLocStr[55], "XT:" & $strLocStr[55]
				$intListviewColor = $intColorRGBRename
				$intListviewIcon = 3
			
			;*** 1804="Verknüpfen": "Verknüpfen", "FS:Verknüpfen"
			Case $strLocStr[56], "FS:" & $strLocStr[56]
				$intListviewColor = $intColorRGBShortcut
				$intListviewIcon = 4
			
			;*** 1805="NeuerOrdner": "NeuerOrdner", "FS:NeuerOrdner", "XT:NeuerOrdner"
			Case $strLocStr[57], "FS:" & $strLocStr[57], "XT:" & $strLocStr[57]
				$intListviewColor = $intColorRGBNewFolder
				$intListviewIcon = 5
			
			;*** 1806="Löschen": "Löschen", "FS:Löschen", "XT:Löschen"
			Case $strLocStr[58], "FS:" & $strLocStr[58], "XT:" & $strLocStr[58]
				$intListviewColor = $intColorRGBDelete
				$intListviewIcon = 6
				
			;*** "XT:Wiederherstellen"
			Case "XT:" & $strLocStr[65]
				$intListviewColor = $intColorRGBUndelete
				$intListviewIcon = 7
			
			;*** 1807="OrdnerLöschen": "OrdnerLöschen", "FS:OrdnerLöschen", "XT:OrdnerLöschen"
			Case $strLocStr[59], "FS:" & $strLocStr[59], "XT:" & $strLocStr[59]
				$intListviewColor = $intColorRGBDeleteFolder
				$intListviewIcon = 8
			
			;*** 1808="Packen": "Packen", "FS:Packen"
			Case $strLocStr[60], "FS:" & $strLocStr[60]
				$intListviewColor = $intColorRGBPack
				$intListviewIcon = 9
			
			;*** 1809="Entpacken": "Entpacken", "FS:Entpacken"
			Case $strLocStr[61], "FS:" & $strLocStr[61]
				$intListviewColor = $intColorRGBUnpack
				$intListviewIcon = 10
			
			;*** 1810="Testen": "Testen", "FS:Testen"
			Case $strLocStr[62], "FS:" & $strLocStr[62]
				$intListviewColor = $intColorRGBTest
				$intListviewIcon = 11
			
			;*** 1811="NeueDatei": "NeueDatei", "FS:NeueDatei"
			Case $strLocStr[63], "FS:" & $strLocStr[63]
				$intListviewColor = $intColorRGBCreateFile
				$intListviewIcon = 12
				
			;*** "LogfileKommentar"
			Case $strLocStr[64]
				$intListviewColor = $intColorRGBLogfileComment
				$intListviewIcon = 13
				
			;*** Sontige Operation (Typ unbekannt)
			Case Else
				$intListviewColor = $intColorRGBUnknown
				$intListviewIcon = 14
				
		EndSwitch
		_GUICtrlListView_SetItemImage($lvLogfile, _GUICtrlListView_GetItemCount($lvLogfile)-1, $intListviewIcon)
		
		If StringInStr($strListviewItemChecked, $strLogfileItem) > 0 Then GUICtrlSetState($lvitemLogfile, $GUI_CHECKED)
		
		Switch $arrTabTCLogRow[5]
			Case "OK"
				If $intListviewColor <> $intColorRGBStd Then GUICtrlSetColor(-1, $intListviewColor)
				If $intColorRGBZeroSecTmDiff <> $intColorRGBStd And $arrTabTCLogRow[8]*1 = 0 And $arrTabTCLogRow[1]*1 > 1 Then GUICtrlSetColor(-1, $intColorRGBZeroSecTmDiff)
			Case "--"
				GUICtrlSetColor(-1, $intColorRGBLogfileComment)
			Case Else
				GUICtrlSetColor(-1, $intColorRGBNotOK)
		EndSwitch
		
	WEnd
	
;~ 	$errx = _SQLite_QueryReset($hqryTabTCLog)
;~ 	$err = @error

;~ 	$errx = _SQLite_QueryFinalize($hqryTabTCLog)
;~ 	$err = @error
	
	;*** DS-Anzahl frisch ermitteln
	$strSQL = "SELECT COUNT(*) FROM tabTCLogDetails " & $strTabTCLogWhere & ";"
	$errx = _SQLite_QuerySingleRow ($hdbTCLog, $strSQL, $arrTabTCLogRow)
	$err = @error

	$intTabTCLogCount = $arrTabTCLogRow[0]
	$p = Int($intTabTCLogCount / $intListViewLimit)
	If Mod($intTabTCLogCount, $intListViewLimit) > 0 Then $p += 1
	$strStatus = $intTabTCLogCount & " " & $strLocStr[50] & " " & $intTabTCLogOffset / $intListViewLimit + 1 & "/" & $p ;"[…] DS  •  Seite […]"

	GUICtrlSetData($lblStatus, $strStatus)
	GUICtrlSetData($lblTabTCLogWhere, _Cv($strTabTCLogWhere, "r"))
	GUICtrlSetData($lblTabTCLogOrderBy, $strTabTCLogOrderBy)

	_AllGUICtrlSetState($GUI_ENABLE)
	
	_ListViewSetColumnWidthAuto()
	
	If $booLogfileReadFinished Then
		GUICtrlSetBkColor($lblLight, 0x00FF00)
		GUICtrlSetColor($lblRefreshNeeded, 0xECE9D8-0x002020)
	Else
		GUICtrlSetBkColor($lblLight, 0xFFFF00)
		GUICtrlSetColor($lblRefreshNeeded, 0xFF0000)
	EndIf
	
EndFunc ;_ListViewRefresh

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _ListViewSetColumnWidthAuto()
	For $i = 0 to 7
		_GUICtrlListView_SetColumnWidth($hlvLogfile, $i, $LVSCW_AUTOSIZE)
	Next
EndFunc ;_ListViewSetColumnWidthAuto

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _DragDrop()
	If @GUI_DropId = $txtQuelleOderZielVal And GUICtrlRead($txtQuelleOderZielVal) <> "" Then
		$arrTemp = StringSplit(GUICtrlRead($txtQuelleOderZielVal), "|")
		If GUICtrlRead($cbxQuelleOderZielFld) = $strLocStr[9] Then ;"Ziel"
			$strTabTCLogWhereQuelleOderZiel = _Cv($arrTemp[8], "w")
		Else
			$strTabTCLogWhereQuelleOderZiel = _Cv($arrTemp[7], "w")
		EndIf
		$p = StringInStr($strTabTCLogWhereQuelleOderZiel, "\", 0, -1)
		If GUICtrlRead($chkQuelleOderZielDropPath) <> GUICtrlRead($chkQuelleOderZielDropFile) Then
			If GUICtrlRead($chkQuelleOderZielDropPath) = $GUI_CHECKED Then $strTabTCLogWhereQuelleOderZiel = StringLeft($strTabTCLogWhereQuelleOderZiel, $p) & "*"
			If GUICtrlRead($chkQuelleOderZielDropFile) = $GUI_CHECKED Then $strTabTCLogWhereQuelleOderZiel = "*" & StringMid($strTabTCLogWhereQuelleOderZiel, $p)
		EndIf
		GUICtrlSetData($txtQuelleOderZielVal, _Cv($strTabTCLogWhereQuelleOderZiel, "r"))
		Call("_txtQuelleOderZielVal")
	EndIf
EndFunc ;_DragDrop

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxQuelleOderZielOp()
	If GUICtrlRead($txtQuelleOderZielVal) <> "*" And GUICtrlRead($txtQuelleOderZielVal) <> "" Then Call("_txtQuelleOderZielVal")
EndFunc ;_cbxQuelleOderZielOp

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _txtQuelleOderZielVal()
	$strQuelleOderZielVal = _Cv(GUICtrlRead($txtQuelleOderZielVal), "w")
	
	If $strQuelleOderZielVal = "*" Or $strQuelleOderZielVal = "" Then
		$strTabTCLogWhereQuelleOderZiel = ""
		GUICtrlSetData($cbxQuelleOderZielOp, "=")
		
	Else
		If GUICtrlRead($cbxQuelleOderZielFld) = $strLocStr[8] & " ¦ " & $strLocStr[9] Then ;"Quelle ¦ Ziel"
			Switch GUICtrlRead($cbxQuelleOderZielOp)
				
				Case "="
					If StringInStr($strQuelleOderZielVal, "*") > 0 Then
						$strTabTCLogWhereQuelleOderZiel = "(OpSource LIKE " & _SQLite_Escape(StringReplace($strQuelleOderZielVal, "*", "%"))
						$strTabTCLogWhereQuelleOderZiel &= " OR OPTarget LIKE " & _SQLite_Escape(StringReplace($strQuelleOderZielVal, "*", "%")) & ")"

					Else
						$strTabTCLogWhereQuelleOderZiel = "(OpSource = " & _SQLite_Escape($strQuelleOderZielVal)
						$strTabTCLogWhereQuelleOderZiel &= " OR OpTarget = " & _SQLite_Escape($strQuelleOderZielVal) & ")"

					EndIf
					
				Case "!="
					If StringInStr($strQuelleOderZielVal, "*") > 0 Then
						$strTabTCLogWhereQuelleOderZiel = "(OpSource NOT LIKE " & _SQLite_Escape(StringReplace($strQuelleOderZielVal, "*", "%"))
						$strTabTCLogWhereQuelleOderZiel &= " AND OpTarget NOT LIKE " & _SQLite_Escape(StringReplace($strQuelleOderZielVal, "*", "%")) & ")"

					Else
						$strTabTCLogWhereQuelleOderZiel = "(OpSource != " & _SQLite_Escape($strQuelleOderZielVal)
						$strTabTCLogWhereQuelleOderZiel &= " AND OpTarget != " & _SQLite_Escape($strQuelleOderZielVal) & ")"
					EndIf
					
				Case $strLocStr[10] ;"enthält"
					$strTabTCLogWhereQuelleOderZiel = "(OpSource LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal & "%")
					$strTabTCLogWhereQuelleOderZiel &= " OR OpTarget LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal & "%") & ")"
					
				Case $strLocStr[11] ;"enthält nicht"
					$strTabTCLogWhereQuelleOderZiel = "(OpSource NOT LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal & "%")
					$strTabTCLogWhereQuelleOderZiel &= " AND OpTarget NOT LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal & "%") & ")"
					
				Case $strLocStr[12] ;"beginnt mit"
					$strTabTCLogWhereQuelleOderZiel = "(OpSource LIKE " & _SQLite_Escape($strQuelleOderZielVal & "%")
					$strTabTCLogWhereQuelleOderZiel &= " OR OpTarget LIKE " & _SQLite_Escape($strQuelleOderZielVal & "%") & ")"
					
				Case $strLocStr[13] ;"beginnt nicht mit"
					$strTabTCLogWhereQuelleOderZiel = "(OpSource NOT LIKE " & _SQLite_Escape($strQuelleOderZielVal & "%")
					$strTabTCLogWhereQuelleOderZiel &= " AND OpTarget NOT LIKE " & _SQLite_Escape($strQuelleOderZielVal & "%") & ")"
					
				Case $strLocStr[14] ;"endet mit"
					$strTabTCLogWhereQuelleOderZiel = "(OpSource LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal)
					$strTabTCLogWhereQuelleOderZiel &= " OR OpTarget LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal) & ")"
					
				Case $strLocStr[15] ;"endet nicht mit"
					$strTabTCLogWhereQuelleOderZiel = "(OpSource NOT LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal)
					$strTabTCLogWhereQuelleOderZiel &= " AND OpTarget NOT LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal) & ")"
					
			EndSwitch
			
		Else
			If GUICtrlRead($cbxQuelleOderZielFld) = $strLocStr[8] Then
				$strQuelleOderZielFld = "OpSource"
			Else
				$strQuelleOderZielFld = "OpTarget"
			EndIf
			Switch GUICtrlRead($cbxQuelleOderZielOp)
				Case "="
					If StringInStr($strQuelleOderZielVal, "*") > 0 Then
						$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " LIKE " & _SQLite_Escape(StringReplace($strQuelleOderZielVal, "*", "%"))
					Else
						$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " = " & _SQLite_Escape($strQuelleOderZielVal)
					EndIf
				Case "!="
					If StringInStr($strQuelleOderZielVal, "*") > 0 Then
						$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " NOT LIKE " & _SQLite_Escape(StringReplace($strQuelleOderZielVal, "*", "%"))
					Else
						$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " != " & _SQLite_Escape($strQuelleOderZielVal)
					EndIf
				;Case "enthält"
				Case $strLocStr[10]
					$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal & "%")
				;Case "enthält nicht"
				Case $strLocStr[11]
					$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " NOT LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal & "%")
				;Case "beginnt mit"
				Case $strLocStr[12]
					$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " LIKE " & _SQLite_Escape($strQuelleOderZielVal & "%")
				;Case "beginnt nicht mit"
				Case $strLocStr[13]
					$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " NOT LIKE " & _SQLite_Escape($strQuelleOderZielVal & "%")
				;Case "endet mit"
				Case $strLocStr[14]
					$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal)
				;Case "endet nicht mit"
				Case $strLocStr[15]
					$strTabTCLogWhereQuelleOderZiel = $strQuelleOderZielFld & " NOT LIKE " & _SQLite_Escape("%" & $strQuelleOderZielVal)
			EndSwitch
			
		EndIf
		
	EndIf
	
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
	
EndFunc ;_txtQuelleOderZielVal

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxLogfileOp()
	If GUICtrlRead($cbxLogfileVal) <> "*" And GUICtrlRead($cbxLogfileVal) <> "" Then Call("_cbxLogfileVal")
EndFunc ;_cbxLogfileOp

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxLogfileVal()
	If GUICtrlRead($cbxLogfileVal) = "*" Then
		$strTabTCLogWhereLogfile = ""
		GUICtrlSetData($cbxLogfileOp, "=")
	Else
		$strTabTCLogWhereLogfile = "Logfile " & GUICtrlRead($cbxLogfileOp) & " '" & GUICtrlRead($cbxLogfileVal) & "'"
	EndIf
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
EndFunc ;_cbxLogfileVal

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxLogfileSetData()
	$strStatus = GUICtrlRead($cbxLogfileVal)
	$strSQL = "SELECT DISTINCT Logfile FROM tabTCLogDetails" & $strTabTCLogWhere & " ORDER BY Logfile DESC;" ;"SELECT DISTINCT Logfile […] ORDER BY Logfile […]"
	_SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
	;ToDo: Errorhandling
	$strLogfileItem = ""
	While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
		;ToDo: Errorhandling
		For $intTabTCLogCol = 0 To UBound($arrTabTCLogRow)-1
			$strLogfileItem &= $arrTabTCLogRow[$intTabTCLogCol] & "|"
		Next
	WEnd
	$strLogfileItem = StringTrimRight($strLogfileItem, 1)
	GUICtrlSetData($cbxLogfileVal, "")
	GUICtrlSetData($cbxLogfileVal, "*|" & $strLogfileItem, $strStatus)
EndFunc ;_cbxLogfileSetData

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxDatumOp()
	If GUICtrlRead($cbxDatumVal) <> "*" And GUICtrlRead($cbxDatumVal) <> "" Then Call("_cbxDatumVal")
EndFunc ;_cbxDatumOp

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxDatumVal()
	If GUICtrlRead($cbxDatumVal) = "*" Then
		$strTabTCLogWhereDatum = ""
		GUICtrlSetData($cbxDatumOp, "=")
	Else
		$strTabTCLogWhereDatum = "OpDate " & GUICtrlRead($cbxDatumOp) & " '" & GUICtrlRead($cbxDatumVal) & "'"
	EndIf
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
EndFunc ;_cbxDatumVal

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxOpDateSetData()
	$strStatus = GUICtrlRead($cbxDatumVal)
	$strSQL = "SELECT DISTINCT OpDate FROM tabTCLogDetails" & $strTabTCLogWhere & " ORDER BY OpDate DESC;" ;"SELECT DISTINCT Datum […] ORDER BY Datum […]"
	_SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
	;ToDo: Errorhandling
	$strLogfileItem = ""
	While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
		;ToDo: Errorhandling
		For $intTabTCLogCol = 0 To UBound($arrTabTCLogRow)-1
			$strLogfileItem &= $arrTabTCLogRow[$intTabTCLogCol] & "|"
		Next
	WEnd
	$strLogfileItem = StringTrimRight($strLogfileItem, 1)
	GUICtrlSetData($cbxDatumVal, "")
	GUICtrlSetData($cbxDatumVal, "*|" & $strLogfileItem, $strStatus)
EndFunc ;_cbxOpDateSetData

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxUhrzeitOp()
	If GUICtrlRead($txtUhrzeitVal) <> "*" And GUICtrlRead($txtUhrzeitVal) <> "" Then Call("_txtUhrzeitVal")
EndFunc ;_cbxUhrzeitOp

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _txtUhrzeitVal()
	If GUICtrlRead($txtUhrzeitVal) = "*" Then
		$strTabTCLogWhereUhrzeit = ""
		GUICtrlSetData($cbxUhrzeitOp, "<")
	Else
		$strTabTCLogWhereUhrzeit = "OpTime " & GUICtrlRead($cbxUhrzeitOp) & " " & _SQLite_Escape(StringLeft(GUICtrlRead($txtUhrzeitVal) & ":00", 8))
	EndIf
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
EndFunc ;_txtUhrzeitVal

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxDatumUhrzeitDiffOp()
	If GUICtrlRead($txtDatumUhrzeitDiffVal) <> "*" And GUICtrlRead($txtDatumUhrzeitDiffVal) <> "" Then Call("_txtDatumUhrzeitDiffVal")
EndFunc ;_cbxDatumUhrzeitDiffOp

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _txtDatumUhrzeitDiffVal()
	If GUICtrlRead($cbxDatumUhrzeitDiffOp) = ">=" And GUICtrlRead($txtDatumUhrzeitDiffVal) = "0" Then
		$strTabTCLogWhereDtTmDiff = ""
	Else
		$strTabTCLogWhereDtTmDiff = "OpDtTmDiff " & GUICtrlRead($cbxDatumUhrzeitDiffOp) & " " & GUICtrlRead($txtDatumUhrzeitDiffVal)
	EndIf
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
EndFunc ;_txtDatumUhrzeitDiffVal

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxVorgangOp()
	If GUICtrlRead($cbxVorgangVal) <> "*" And GUICtrlRead($cbxVorgangVal) <> "" Then Call("_cbxVorgangVal")
EndFunc ;_cbxVorgangOp

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxVorgangVal()
	If GUICtrlRead($cbxVorgangVal) = "*" Then
		$strTabTCLogWhereVorgang = ""
		GUICtrlSetData($cbxVorgangOp, "=")
	Else
		$strTabTCLogWhereVorgang = "Operation " & GUICtrlRead($cbxVorgangOp) & " '" & _Cv(GUICtrlRead($cbxVorgangVal), "w") & "'"
	EndIf
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
EndFunc ;_cbxVorgangVal

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _SearchFor()
	If GUICtrlRead($txtSearchFor) = "" Or GUICtrlRead($txtSearchFor) = "*" Then Return
	$booListViewGetNextItem = True
	$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile)
	If $intListViewItemIndex = -1 Then
		$intListViewItemIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
		_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex)
		$booListViewGetNextItem = False
	EndIf
	If @GUI_CTRLID = $txtSearchFor Then GUICtrlSetState($btnSearchForNext, $GUI_FOCUS)
	If @GUI_CTRLID = $btnSearchForNext Then Call("_SearchForNext")
EndFunc ;_SearchFor

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _SearchForNext()
	
	$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile)
	
	$booFound = False
	
	While $intListViewItemIndex <> -1
		
		If $booListViewGetNextItem Then
			$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile, $intListViewItemIndex, 2, 0)
		Else
			$booListViewGetNextItem = True
		EndIf
		
		If $intListViewItemIndex <> -1 Then
			$strListviewItem = _GUICtrlListView_GetItemTextString($hlvLogfile, $intListViewItemIndex)
			If StringInStr($strListviewItem, GUICtrlRead($txtSearchFor)) > 0 Then
				_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex)
				$intListViewItemEnsureVisible = $intListViewItemIndex + Int(_GUICtrlListView_GetCounterPage($hlvLogfile) / 2)
				If $intListViewItemEnsureVisible > $intListViewLimit-1 Then $intListViewItemEnsureVisible = $intListViewLimit-1
				_GUICtrlListView_EnsureVisible($hlvLogfile, $intListViewItemEnsureVisible, True)
				$booFound = True
				ExitLoop
			EndIf
		EndIf
		
		If $intListViewItemIndex = -1 And $intTabTCLogOffset + _GUICtrlListView_GetItemCount($hlvLogfile) < $intTabTCLogCount Then
			
			_AllGUICtrlSetState($GUI_DISABLE)
			
			$intTabTCLogOffset += $intListViewLimit
			_BuildSQLWhereClause()
			$strSQL = "SELECT * FROM tabTCLogDetails" & $strTabTCLogWhere & $strTabTCLogOrderBy & "LIMIT -1 OFFSET " & $intTabTCLogOffset & ";"
			GUICtrlSetData($lblStatus, $strSQL)
			$errx = _SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
			$err = @error
			
			$intTabTCLogCount = $intTabTCLogOffset
			
			$booFound = False
			While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
				$intTabTCLogCount += 1
				$strListviewItem = ""
				For $intTabTCLogCol = 0 To UBound($arrTabTCLogRow)-1
					$strListviewItem &= $arrTabTCLogRow[$intTabTCLogCol] & "|"
				Next
				If Mod($intTabTCLogCount, $intListViewLimit) = 0 Then GUICtrlSetData($lblStatus, $intTabTCLogCount) ;debug
				If StringInStr($strListviewItem, _Cv(GUICtrlRead($txtSearchFor), "w")) > 0 Then
					$booFound = True
					$errx = _SQLite_QueryFinalize($hqryTabTCLog)
					$err = @error
					$intTabTCLogOffset = Int($intTabTCLogCount / $intListViewLimit) * $intListViewLimit
					If Mod($intTabTCLogCount, $intListViewLimit) = 0 Then $intTabTCLogOffset -= $intListViewLimit
					ExitLoop
				EndIf
			WEnd
			
			If $booFound = True Then
				Call("_ListViewRefresh")
				$intListViewItemIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
				_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex)
				$booListViewGetNextItem = False
			Else
				$errx = _SQLite_QueryFinalize($hqryTabTCLog)
				$err = @error
				$intTabTCLogOffset -= $intListViewLimit
;~ 				MsgBox(64, $ver, StringReplace($strLocStr[66], "%s", GUICtrlRead($txtSearchFor))) ;"Keine weitere Fundstelle für {Suchstring}"
				ExitLoop
			EndIf
			
		EndIf
		
	WEnd
	
	If $booFound = False Then
		_MsgBox(64, $ver, StringReplace($strLocStr[66], "%s", GUICtrlRead($txtSearchFor))) ;"Keine weitere Fundstelle für {Suchstring}"
	EndIf
	
	GUICtrlSetState($btnSearchForNext, $GUI_FOCUS)
	If $booLogfileReadFinished Then
		GUICtrlSetBkColor($lblLight, 0x00FF00)
	Else
		GUICtrlSetBkColor($lblLight, 0xFFFF00)
	EndIf
	
	_AllGUICtrlSetState($GUI_ENABLE)
	
EndFunc ;_SearchForNext

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnNextGroup()
	
	$intListViewCol = 1
	Switch @GUI_CTRLID
		Case $btnLogfileNext
			$intListViewCol = 0
		Case $btnDatumNext
			$intListViewCol = 2
		Case $btnVorgangNext
			$intListViewCol = 4
		Case $btnStatusNext
			$intListViewCol = 5
	EndSwitch

	$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile)
	If $intListViewItemIndex = -1 Then
		$intListViewItemIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
		_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex, True)
		_GUICtrlListView_EnsureVisible($hlvLogfile, $intListViewItemIndex, True)
		$strListViewSubItemText = ""
	Else
		$strListViewSubItemText = _GUICtrlListView_GetItemText($hlvLogfile, $intListViewItemIndex, $intListViewCol)
	EndIf
	
	While $intListViewItemIndex <> -1
		
		If $strListViewSubItemText <> _GUICtrlListView_GetItemText($hlvLogfile, $intListViewItemIndex, $intListViewCol) Then
			_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex, True, True)
			$intListViewItemEnsureVisible = $intListViewItemIndex + Int(_GUICtrlListView_GetCounterPage($hlvLogfile) / 2)
			If $intListViewItemEnsureVisible > $intListViewLimit-1 Then $intListViewItemEnsureVisible = $intListViewLimit-1
			_GUICtrlListView_EnsureVisible($hlvLogfile, $intListViewItemEnsureVisible, True)
			ExitLoop
		Else
			_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex, False)
		EndIf
		
		$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile, $intListViewItemIndex, 2, 0)
		If $intListViewItemIndex = -1 And $intTabTCLogOffset + _GUICtrlListView_GetItemCount($hlvLogfile) < $intTabTCLogCount Then
			
			_AllGUICtrlSetState($GUI_DISABLE)
			
			$intTabTCLogOffset += $intListViewLimit
			_BuildSQLWhereClause()
			$strSQL = "SELECT * FROM tabTCLogDetails" & $strTabTCLogWhere & $strTabTCLogOrderBy & "LIMIT -1 OFFSET " & $intTabTCLogOffset & ";"
			GUICtrlSetData($lblStatus, $strSQL)
			$errx = _SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
			$err = @error
			$intTabTCLogCol = $intListViewCol
			$intTabTCLogCount = $intTabTCLogOffset
			
			$booFound = False
			While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
				$intTabTCLogCount += 1
				If Mod($intTabTCLogCount, $intListViewLimit) = 0 Then GUICtrlSetData($lblStatus, $intTabTCLogCount) ;debug
				If $strListViewSubItemText <> $arrTabTCLogRow[$intTabTCLogCol] Then
					$booFound = True
					$errx = _SQLite_QueryFinalize($hqryTabTCLog)
					$err = @error
					$intTabTCLogOffset = Int($intTabTCLogCount / $intListViewLimit) * $intListViewLimit
					If Mod($intTabTCLogCount, $intListViewLimit) = 0 Then $intTabTCLogOffset -= $intListViewLimit
					ExitLoop
				EndIf
			WEnd
			
			If $booFound = False Then
				$errx = _SQLite_QueryFinalize($hqryTabTCLog)
				$err = @error
				Call("_ListViewRefresh")
				_MsgBox(64, $ver, $strLocStr[67]) ;"Keine weitere Fundstelle"
				ExitLoop
			EndIf
			
			Call("_ListViewRefresh")
			$intListViewItemIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
			_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex, True)

		EndIf
	WEnd
	
	_AllGUICtrlSetState($GUI_ENABLE)
	
EndFunc ;_btnNextGroup

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnNextChecked()
	
	If $strListviewItemChecked = "" Then
		_MsgBox(48, $ver, $strLocStr[68]) ;"Es sind keine Operationen selektiert"
		Return
	EndIf
	
	$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile)
	If $intListViewItemIndex = -1 Then
		$intListViewItemIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
		_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex, True)
		_GUICtrlListView_EnsureVisible($hlvLogfile, $intListViewItemIndex, True)
	EndIf
	
	$booFirstLoop = True
	While $intListViewItemIndex <> -1
		If _GUICtrlListView_GetItemChecked($hlvLogfile, $intListViewItemIndex) = True And $booFirstLoop = False Then
			_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex, True)
			$intListViewItemEnsureVisible = $intListViewItemIndex + Int(_GUICtrlListView_GetCounterPage($hlvLogfile) / 2)
			If $intListViewItemEnsureVisible > $intListViewLimit-1 Then $intListViewItemEnsureVisible = $intListViewLimit-1
			_GUICtrlListView_EnsureVisible($hlvLogfile, $intListViewItemEnsureVisible, True)
			ExitLoop
		Else
			_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex, False)
		EndIf
		
		$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile, $intListViewItemIndex, 2, 0)
		$booFirstLoop = False
		If $intListViewItemIndex = -1 And $intTabTCLogOffset + _GUICtrlListView_GetItemCount($hlvLogfile) < $intTabTCLogCount Then
			
			_AllGUICtrlSetState($GUI_DISABLE)
			
			$intTabTCLogOffset += $intListViewLimit
			_BuildSQLWhereClause()
			$strSQL = "SELECT * FROM tabTCLogDetails" & $strTabTCLogWhere & $strTabTCLogOrderBy & "LIMIT -1 OFFSET " & $intTabTCLogOffset & ";"
			GUICtrlSetData($lblStatus, $strSQL)
			$errx = _SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
			$err = @error
			$intTabTCLogCount = $intTabTCLogOffset
			
			$booFound = False
			While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
				$intTabTCLogCount += 1
				If Mod($intTabTCLogCount, $intListViewLimit) = 0 Then GUICtrlSetData($lblStatus, $intTabTCLogCount) ;debug

				$strLogfileItem = ""
				For $intTabTCLogCol = 0 To UBound($arrTabTCLogRow)-2 ;Letzte in der DB gespeicherte Spalte (OpDtTmDiff) nicht mit einlesen
					Switch $intTabTCLogCol
						#cs
						Case 2, 3
							If $arrTabTCLogRow[8] = 0 Then
								$strLogfileItem &= "|"
							Else
								$strLogfileItem &= $arrTabTCLogRow[$intTabTCLogCol] & "|"
							EndIf
						#ce
;~ 						Case 4, 5, 7
						Case 4, 5, 6, 7
							$strLogfileItem &= _Cv($arrTabTCLogRow[$intTabTCLogCol], "r") & "|"
;~ 						Case 6
;~ 							$strLogfileItem &= "(" & $arrTabTCLogRow[8] & ") " & _Cv($arrTabTCLogRow[$intTabTCLogCol], "r") & "|";debug
						Case Else
							$strLogfileItem &= $arrTabTCLogRow[$intTabTCLogCol] & "|"
					EndSwitch
				Next
				$strLogfileItem = StringTrimRight($strLogfileItem, 1)
				
				If StringInStr($strListviewItemChecked, $strLogfileItem) > 0 Then
					$booFound = True
					$errx = _SQLite_QueryFinalize($hqryTabTCLog)
					$err = @error
					$intTabTCLogOffset = Int($intTabTCLogCount / $intListViewLimit) * $intListViewLimit
					If Mod($intTabTCLogCount, $intListViewLimit) = 0 Then $intTabTCLogOffset -= $intListViewLimit
					ExitLoop
				EndIf
			WEnd
			
			If $booFound = False Then
				$errx = _SQLite_QueryFinalize($hqryTabTCLog)
				$err = @error
				Call("_ListViewRefresh")
				_MsgBox(64, $ver, $strLocStr[67]) ;"Keine weitere Fundstelle"
				ExitLoop
			EndIf
			
			Call("_ListViewRefresh")
			$intListViewItemIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
			_GUICtrlListView_SetItemSelected($hlvLogfile, $intListViewItemIndex, True)
			
		EndIf
	WEnd
	
	_AllGUICtrlSetState($GUI_ENABLE)
	
EndFunc ;_btnNextChecked

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxOperationSetData()
	$strStatus = GUICtrlRead($cbxVorgangVal)
	$strSQL = "SELECT DISTINCT Operation FROM tabTCLogDetails" & $strTabTCLogWhere & " ORDER BY Operation;" ;"SELECT DISTINCT Vorgang […] ORDER BY Vorgang;"
	$errx = _SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
	$err = @error
	_SQLiteErrHandler(16, $err, $errx, "_SQlite_Query", $strSQL)
	$strLogfileItem = ""
	While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
		;ToDo: Errorhandling
		For $intTabTCLogCol = 0 To UBound($arrTabTCLogRow)-1
			$strLogfileItem &= _Cv($arrTabTCLogRow[$intTabTCLogCol], "r") & "|"
		Next
	WEnd
	$strLogfileItem = StringTrimRight($strLogfileItem, 1)
	GUICtrlSetData($cbxVorgangVal, "")
	GUICtrlSetData($cbxVorgangVal, "*|" & $strLogfileItem, $strStatus)
EndFunc ;_cbxOperationSetData

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxStatusOp()
	If GUICtrlRead($cbxStatusVal) <> "*" And GUICtrlRead($cbxStatusVal) <> "" Then Call("_cbxStatusVal")
EndFunc ;_cbxStatusOp

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxStatusVal()
	If GUICtrlRead($cbxStatusVal) = "*" Then
		$strTabTCLogWhereStatus = ""
		GUICtrlSetData($cbxStatusOp, "=")
	Else
		$strTabTCLogWhereStatus = "OpStatus " & GUICtrlRead($cbxStatusOp) & " '" & _Cv(GUICtrlRead($cbxStatusVal), "w") & "'"
	EndIf
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
EndFunc ;_cbxStatusVal

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _cbxOpStatusSetData()
	$strStatus = GUICtrlRead($cbxStatusVal)
	$strSQL = "SELECT DISTINCT OpStatus FROM tabTCLogDetails" & $strTabTCLogWhere & " ORDER BY OpStatus;" ;"SELECT DISTINCT Status […] ORDER BY Status;"
	_SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
	;ToDo: Errorhandling
	$strLogfileItem = ""
	While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
		;ToDo: Errorhandling
		For $intTabTCLogCol = 0 To UBound($arrTabTCLogRow)-1
			$strLogfileItem &= _Cv($arrTabTCLogRow[$intTabTCLogCol], "r") & "|"
		Next
	WEnd
	$strLogfileItem = StringTrimRight($strLogfileItem, 1)
	GUICtrlSetData($cbxStatusVal, "")
	GUICtrlSetData($cbxStatusVal, "*|" & $strLogfileItem, $strStatus)
EndFunc ;_cbxOpStatusSetData

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnScrollDown()
	$intListViewTopIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
	$intListViewCounterPage = _GUICtrlListView_GetCounterPage($hlvLogfile)
	
	;*** Button ScrollDown am Ende der Liste gedrückt? NextPage!
	If $intListViewTopIndex + $intListViewCounterPage + 1 >= $intListViewLimit And $intTabTCLogOffset + $intListViewItemCount < $intTabTCLogCount Then
		$intTabTCLogOffset += $intListViewLimit
		Call("_ListViewRefresh")
	ElseIf $intListViewTopIndex + 2 * $intListViewCounterPage > $intListViewItemCount-1 Then
		_GUICtrlListView_EnsureVisible($hlvLogfile, $intListViewItemCount-1, 1)
	Else
		_GUICtrlListView_EnsureVisible($hlvLogfile, $intListViewTopIndex + 2 * $intListViewCounterPage - 1, 1)
	EndIf
EndFunc ;_btnScrollDown

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnScrollUp()
	$intListViewTopIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
	$intListViewCounterPage = _GUICtrlListView_GetCounterPage($hlvLogfile)
	
	;*** Button ScrollUp am Beginn der Liste gedrückt? PrevPage!
	If $intListViewTopIndex = 0 And $intTabTCLogOffset > 0 Then
		$intTabTCLogOffset -= $intListViewLimit
		Call("_ListViewRefresh")
	ElseIf $intListViewTopIndex - $intListViewCounterPage - 1 < 0 Then
		_GUICtrlListView_EnsureVisible($hlvLogfile, 0, 1)
	Else
		_GUICtrlListView_EnsureVisible($hlvLogfile, $intListViewTopIndex - $intListViewCounterPage - 1, 1)
	EndIf
EndFunc ;_btnScrollUp

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnFirstPage()
	$intTabTCLogOffset = 0
	Call("_ListViewRefresh")
EndFunc ;_btnFirstPage

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnPrevPage()
	$intTabTCLogOffset -= $intListViewLimit
	Call("_ListViewRefresh")
EndFunc ;_btnPrevPage

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnNextPage()
	$intTabTCLogOffset += $intListViewLimit
	Call("_ListViewRefresh")
EndFunc ;_btnNextPage

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnLastPage()
	$p = Int($intTabTCLogCount / $intListViewLimit)
	If Mod($intTabTCLogCount, $intListViewLimit) = 0 Then $p -= 1
	$intTabTCLogOffset = $p * $intListViewLimit
	Call("_ListViewRefresh")
EndFunc ;_btnLastPage

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _chkAutoRefreshPause()
	$booAutoRefreshPaused = Not $booAutoRefreshPaused
	If $booAutoRefreshPaused Then
		GUICtrlSetColor($lblAutoRefreshPause, 0x00FF00)
	Else
		GUICtrlSetColor($lblAutoRefreshPause, 0xACC998) ;0xCCC9B8
	EndIf
EndFunc ;_chkAutoRefreshPause

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnTabTCLogWhereReset()
	
	$strTabTCLogWhere = ""
	
	$strTabTCLogWhereLogfile = ""
	GUICtrlSetData($cbxLogfileOp, "=")
	GUICtrlSetData($cbxLogfileVal, "*")
	
	$strTabTCLogWhereDatum = ""
	GUICtrlSetData($cbxDatumOp, "=")
	GUICtrlSetData($cbxDatumVal, "*")
	
	$strTabTCLogWhereUhrzeit = ""
	GUICtrlSetData($cbxUhrzeitOp, "<")
	GUICtrlSetData($txtUhrzeitVal, "*")
	
	$strTabTCLogWhereDtTmDiff = ""
	GUICtrlSetData($cbxDatumUhrzeitDiffOp, ">=")
	GUICtrlSetData($txtDatumUhrzeitDiffVal, 0)
	
	$strTabTCLogWhereVorgang = ""
	GUICtrlSetData($cbxVorgangOp, "=")
	GUICtrlSetData($cbxVorgangVal, "*")
	
	$strTabTCLogWhereStatus = ""
	GUICtrlSetData($cbxStatusOp, "=")
	GUICtrlSetData($cbxStatusVal, "*")
	
	$strTabTCLogWhereQuelleOderZiel = ""
	GUICtrlSetData($cbxQuelleOderZielFld, $strLocStr[8] & " ¦ " & $strLocStr[9]) ;"Quelle ¦ Ziel"
	GUICtrlSetData($cbxQuelleOderZielOp, "=")
	GUICtrlSetData($txtQuelleOderZielVal, "*")
	
	Call("_ListViewRefresh")
	
EndFunc ;_btnTabTCLogWhereReset

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _btnTabTCLogOrderByReset()
	$booTabTCLogOrderByUser = False
	$strTabTCLogOrderByRaw = ""
	$strTabTCLogOrderBy = " ORDER BY Logfile DESC, LogLine DESC " ;" ORDER BY Logfile DESC, Zeile DESC "
	$intTabTCLogOffset = 0
	For $i = 0 To 7
		_GUICtrlListView_SetColumn($hlvLogfile, $i, $arrListViewCols[$i+1])
	Next
	Call("_ListViewRefresh")
EndFunc ;_btnTabTCLogOrderByReset

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _APIFileOpen($sFile)
	Local $GENERIC_READ = 0x80000000, $GENERIC_WRITE = 0x40000000, $OPEN_ALWAYS = 4, $FILE_ATTRIBUTE_NORMAL = 0x00000080
	Local $AFO_h
	$AFO_h = DllCall("kernel32.dll", "hwnd", "CreateFile", "str", $sFile, "long", BitOR($GENERIC_READ, $GENERIC_WRITE), "long", 0, "ptr", 0, "long", $OPEN_ALWAYS, "long", $FILE_ATTRIBUTE_NORMAL, "long", 0)
	Return $AFO_h[0]
EndFunc ;_APIFileOpen

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _APIFileClose($hfFile)
	Local $AFC_r
	$AFC_r = DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hfFile)
	Return $AFC_r[0]
EndFunc ;_APIFileClose

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#cs
Func _APIFileRead($hfFile, $nBytes, $Option = 0)
	Local $AFR_r, $AFR_n, $AFR_str, $AFR_ret = ""
	If $Option = 0 Then
		$AFR_str = DllStructCreate("char[" & $nBytes & "]")
	Else
		$AFR_str = DllStructCreate("byte[" & $nBytes & "]")
	EndIf
	$AFR_r = DllCall("kernel32.dll", "int", "ReadFile", "hwnd", $hfFile, "ptr", DllStructGetPtr($AFR_str), "long", $nBytes, "long_ptr", 0, "ptr", 0)
	If $Option = 0 Then
		$AFR_ret = StringLeft(DllStructGetData($AFR_str, 1), $AFR_r[4])
	Else
		For $AFR_n = 1 to $AFR_r[4]
			$AFR_ret = $AFR_ret & Hex(DllStructGetData($AFR_str, 1, $AFR_n), 2) & ","
		Next
		$AFR_ret = StringTrimRight($AFR_ret, 1)
	EndIf
	SetError($AFR_r[0])
;~ 	DllStructDelete($AFR_str)
	$AFR_str = 0
	Return $AFR_ret
EndFunc ;_APIFileRead
#ce

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _APIFileRead($hfFile, $nBytes, $Option = 0)
	Local $aResult, $tBuffer, $pBuffer, $pRead, $tRead
	$tBuffer = DllStructCreate("char[" & $nBytes & "]")
	$pBuffer = DllStructGetPtr($tBuffer)
	$tRead = DllStructCreate("int Read")
	$pRead = DllStructGetPtr($tRead)
	$aResult = DllCall("Kernel32.dll", "int", "ReadFile", "hwnd", $hfFile, "ptr", $pBuffer, "int", $nBytes, "ptr", $pRead, "ptr", 0)
	$iRead = DllStructGetData($tRead, "Read")
;~ 	Return SetError(_WinAPI_GetLastError(), 0, $aResult[0] <> 0)
	Return StringLeft(DllStructGetData($tBuffer, 1), $aResult[4])
EndFunc ;_APIFileRead

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _APIFileSetPos($hfFile, $nPos)
	Local $FILE_BEGIN = 0 
	Local $AFSP_r = DllCall("kernel32.dll", "long", "SetFilePointer", "hwnd", $hfFile, "long", $nPos, "long_ptr", 0, "long", $FILE_BEGIN)
	Return $AFSP_r[0]		
EndFunc ;_APIFileSetPos

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _SQLiteErrHandler($errsev, $err, $errx, $strFunc, $strFuncArgs)
	If $err <> 0 Then
		_MsgBox($errsev, $ver, "Fehler bei Funktionsaufruf " & $strFunc & @LF & $strFuncArgs & @LF & $errx & " (" & _SQLite_ErrMsg($hdbTCLog) & ")")
		If $errsev = 16 Then Exit
	EndIf
EndFunc ;_SQLiteErrHandler

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _UnSelectAllListviewItems()
	GUICtrlSetBkColor($lblLight, 0xFF0000)
	$intListViewItemIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
	While $intListViewItemIndex <> -1
		_GUICtrlListView_SetItemChecked($hlvLogfile, $intListViewItemIndex, 0)
		$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile, $intListViewItemIndex, 2, 0)
	WEnd
	$strListviewItemChecked = ""
	GUICtrlSetData($lblListviewItemCheckedCount, StringReplace($strLocStr[29], "%n", 0))
	Call("_ListViewRefresh")
	GUICtrlSetBkColor($lblLight, 0x00FF00)
EndFunc ;_UnSelectAllListviewItems

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _ToggleSelectionListviewItems()
	GUICtrlSetBkColor($lblLight, 0xFF0000)
	$intListViewItemIndex = _GUICtrlListView_GetTopIndex($hlvLogfile)
	While $intListViewItemIndex <> -1
		$strListviewItem = _GUICtrlListView_GetItemTextString($hlvLogfile, $intListViewItemIndex)
		$p = StringInStr($strListviewItemChecked, $strListviewItem)
		Switch @GUI_CtrlId
			Case $btnCheckAllSelectedListviewItems
				If _GUICtrlListView_GetItemSelected($hlvLogfile, $intListViewItemIndex) = True Then
					_GUICtrlListView_SetItemChecked($hlvLogfile, $intListViewItemIndex, 1)
					If $p = 0 Then $strListviewItemChecked &= $strListviewItem & @LF
				EndIf
			Case $btnUnCheckAllSelectedListviewItems
				If _GUICtrlListView_GetItemSelected($hlvLogfile, $intListViewItemIndex) = True Then
					_GUICtrlListView_SetItemChecked($hlvLogfile, $intListViewItemIndex, 0)
					If $p > 0 Then $strListviewItemChecked = StringReplace($strListviewItemChecked, $strListviewItem & @LF, "")
				EndIf
			Case $btnCheckAllListviewItemsOnCurrPage
				_GUICtrlListView_SetItemChecked($hlvLogfile, $intListViewItemIndex, 1)
				If $p = 0 Then $strListviewItemChecked &= $strListviewItem & @LF
			Case $btnUnCheckAllListviewItemsOnCurrPage
				_GUICtrlListView_SetItemChecked($hlvLogfile, $intListViewItemIndex, 0)
				If $p > 0 Then $strListviewItemChecked = StringReplace($strListviewItemChecked, $strListviewItem & @LF, "")
		EndSwitch
		$intListViewItemIndex = _GUICtrlListView_GetNextItem($hlvLogfile, $intListViewItemIndex, 2, 0)
	WEnd
	
	$strListviewItemChecked = StringReplace($strListviewItemChecked, @LF, @LF)
	$intListviewItemCheckedCount = @extended
	GUICtrlSetData($lblListviewItemCheckedCount, StringReplace($strLocStr[29], "%n", $intListviewItemCheckedCount))
	
	GUICtrlSetBkColor($lblLight, 0x00FF00)
	
EndFunc ;_ToggleSelectionListviewItems

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _Undo()
	
	If GUICtrlRead($chkUndoCommit) = $GUI_CHECKED Then
		$booUndoCommit = True
	Else
		$booUndoCommit = False
	EndIf
	
	If $intListviewItemCheckedCount = 0 Then
		$strMsg = $strLocStr[68] ;"Rückgängig: Es sind keine Operationen selektiert"
		_MsgBox(48, $ver, $strMsg) ;[OK]
		GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
		Return
	EndIf
	
	$strMsg = StringReplace($strLocStr[69], "%n", $intListviewItemCheckedCount) ;"Rückgängig: {n} Operationen?"
	$errsev = 32
	If _MsgBox($errsev+4+256, $ver, $strMsg) = 7 Then Return ;[Ja] [*Nein]: Button [Nein] wurde angeklickt
		
		$arrListviewItemChecked = StringSplit($strListviewItemChecked, @LF)
		
		;*** Selektierte DS absteigend sortieren nach Datum & Uhrzeit & Zeile
		;*** Sortierschlüssel bilden und voranstellen
		For $intListviewItemChecked = 1 To $arrListviewItemChecked[0]-1
			;*** 0=Anzahl Elemente, 1=Logfile, 2=Zeile, 3=Datum, 4=Uhrzeit, 5=Vorgang, 6=Status, 7=Quelle, 8=Ziel
			$arrListViewRow = StringSplit($arrListviewItemChecked[$intListviewItemChecked], "|")
			$arrListviewItemChecked[$intListviewItemChecked] = $arrListViewRow[3] & $arrListViewRow[4] & StringRight("0000000" & $arrListViewRow[2], 7) & @TAB & $arrListviewItemChecked[$intListviewItemChecked]
		Next
		;*** Sortieren
		_ArraySort($arrListviewItemChecked, 1, 1)
		;*** Sortierschlüssel wieder entfernen
		For $intListviewItemChecked = 1 To $arrListviewItemChecked[0]-1
			$p = StringInStr($arrListviewItemChecked[$intListviewItemChecked], @TAB)
			$arrListviewItemChecked[$intListviewItemChecked] = StringTrimLeft($arrListviewItemChecked[$intListviewItemChecked], $p)
		Next
		
		For $intListviewItemChecked = 1 To $arrListviewItemChecked[0]-1
			
			$booUndoPossible = False
			;*** 0=Anzahl Elemente, 1=Logfile, 2=Zeile, 3=Datum, 4=Uhrzeit, 5=Vorgang, 6=Status, 7=Quelle, 8=Ziel
			$arrListViewRow = StringSplit($arrListviewItemChecked[$intListviewItemChecked], "|")
			$strMsgBoxTitle = $strLocStr[70] & " (" & $intListviewItemChecked & "/" & $arrListviewItemChecked[0]-1 & "): " & $arrListViewRow[5] ;"Rückgängig […]"
			$intMsgCd = 0
			
			If $arrListViewRow[6] <> "OK" Then ContinueLoop
			
			If FileGetAttrib($arrListViewRow[8]) = "" Then
				$strFileType = "Datei oder Ordner"
			Else
				If StringInStr(FileGetAttrib($arrListViewRow[8]), "D") = 0 Then
					$strFileType = "Datei"
				Else
					$strFileType = "Ordner"
				EndIf
			EndIf
			
			Switch $arrListViewRow[5]
				
				Case $strLocStr[57], "XT:" & $strLocStr[57] ;*** "NeuerOrdner", "XT:NeuerOrdner" ;Undo = Ordner wie in Quelldatei angegeben löschen
					$strMsg = $arrListViewRow[7] & @LF & @LF
					
					;*** Prüfen: Kann in den Ordner gewechselt werden?
					If FileChangeDir($arrListViewRow[7]) = 0 Then
						$intMsgCd = 71
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[71], "%s", $arrListViewRow[7]) & @LF & @LF ;"Die Operation kann nicht rückgängig gemacht werden, da auf den Ordner {Ordner} nicht zugegriffen werden kann (weil er z.B. nicht mehr vorhanden ist)"
						$strMsg &= $strMsgTmp
						$errsev = 48
					Else
						$hsFile = FileFindFirstFile("*")
						;*** Prüfen: Ist der Ordner leer?
						If @error = 1 Then
							$booUndoPossible = True
							$intMsgCd = 72
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & $strLocStr[72] & @LF & @LF ;"Soll der Ordner gelöscht werden?"
							$strMsg &= $strMsgTmp
							$errsev = 32
						Else
							$intMsgCd = 73
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[73], "%s", $arrListViewRow[7]) & @LF & @LF ;"Die Operation kann nicht rückgängig gemacht werden, da der Ordner {Ordner} nicht leer ist"
							$strMsg &= $strMsgTmp
							$errsev = 48
						EndIf
						FileClose($hsFile)
						;*** Arbeitsverzeichnis wechseln, da der Ordner sonst nicht gelöscht werden kann
						FileChangeDir($strRecentLogfilePath)
					EndIf
					
					If $errsev = 32 Then
						If $booUndoCommit Then
							$err = _MsgBox($errsev+3+256, $strMsgBoxTitle, $strMsg) ;[Ja] [*Nein] [Abbrechen]
						Else
							$err = 6
						EndIf
						If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
							GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
							Call("_ListViewRefresh")
							Return
						EndIf
						If $err = 6 Then ;Button [Ja] wurde angeklickt
							If FileRecycle($arrListViewRow[7]) = 0 Then
								$intMsgCd = 74
								$strMsg = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[74], "%s", $arrListViewRow[7]) & @LF & @LF ;"Der Ordner {Ordner} konnte nicht gelöscht werden"
								If $booUndoCommit Then _MsgBox(48, $strMsgBoxTitle, $strMsg)
							Else
								;*** Undo in RecentLogfile eintragen
								;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
								$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
								$strLogfileItem &= "XT:" & $strLocStr[59] & ": " & $arrListViewRow[7] ;"XT:OrdnerLöschen: […]"
								FileWriteLine($strRecentLogfile, $strLogfileItem)
							EndIf
						EndIf
						
					Else
						If $booUndoCommit Then
							$err = _MsgBox($errsev+1+0, $strMsgBoxTitle, $strMsg) ;[*OK] [Abbrechen]
							If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
								GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
								Call("_ListViewRefresh")
								Return
							EndIf
						Else
							;*** Fehlgeschlagenes Undo in RecentLogfile eintragen
							;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
							$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
							$strLogfileItem &= "XT:" & $strLocStr[59] & "(" & $strLocStr[75] & " " & $strLocStr[76] & "): " & $arrListViewRow[7] ;"XT:OrdnerLöschen(Fehler: Löschen fehlgeschlagen): […]
							FileWriteLine($strRecentLogfile, $strLogfileItem)
						EndIf
						
					EndIf
					
					
				Case $strLocStr[59], "XT:" & $strLocStr[59] ;*** "OrdnerLöschen", "XT:OrdnerLöschen" ;Undo = Ordner wie in Quelldatei angegeben anlegen
					$strMsg = $arrListViewRow[7] & @LF & @LF
					
					;*** Prüfen: Existiert der Ordner wieder?
					If FileChangeDir($arrListViewRow[7]) = 1 Then
						$intMsgCd = 77
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[77], "%s", $arrListViewRow[7]) & @LF & @LF ;"Die Operation kann nicht rückgängig gemacht werden, da der Ordner {Ordner} bereits vorhanden ist"
						$strMsg &= $strMsgTmp
						$errsev = 48
					Else
						$intMsgCd = 78
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & $strLocStr[78] & @LF & @LF ;"Soll der Ordner angelegt werden?"
						$strMsg &= $strMsgTmp
						$errsev = 32
					EndIf
					
					If $errsev = 32 Then
						If $booUndoCommit Then
							$err = _MsgBox($errsev+3+256, $strMsgBoxTitle, $strMsg) ;[Ja] [*Nein] [Abbrechen]
						Else
							$err = 6
						EndIf
						If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
							GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
							Call("_ListViewRefresh")
							Return
						EndIf
						If $err = 6 Then ;Button [Ja] wurde angeklickt
							If DirCreate($arrListViewRow[7]) = 0 Then
								$intMsgCd = 79
								$strMsg = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[79], "%s", $arrListViewRow[7]) & @LF & @LF ;"Der Ordner {Ordner} konnte nicht angelegt werden"
								If $booUndoCommit Then _MsgBox(48, $strMsgBoxTitle, $strMsg) ;[OK]
							Else
								;*** Undo in RecentLogfile eintragen
								;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
								$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
								$strLogfileItem &= "XT:" & $strLocStr[57] & ": " & $arrListViewRow[7] ;"XT:NeuerOrdner: […]"
								FileWriteLine($strRecentLogfile, $strLogfileItem)
							EndIf
						EndIf
						
					Else
						If $booUndoCommit Then
							$err = _MsgBox($errsev+1+0, $strMsgBoxTitle, $strMsg) ;[*OK] [Abbrechen]
							If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
								GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
								Call("_ListViewRefresh")
								Return
							EndIf
						Else
							;*** Fehlgeschlagenes Undo in RecentLogfile eintragen
							;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
							$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
							$strLogfileItem &= "XT:" & $strLocStr[57] & "(" & $strLocStr[75] & " " & $strLocStr[80] & "): " & $arrListViewRow[7]
							FileWriteLine($strRecentLogfile, $strLogfileItem)
						EndIf
						
					EndIf
					
					
				Case $strLocStr[53] ;*** "Kopieren" ;Undo = Zieldatei löschen
					$strMsg = $arrListViewRow[7] & @LF & "->" & @LF & $arrListViewRow[8] & @LF & @LF
					
					;*** Prüfen: Existiert die Zieldatei noch?
					If FileExists($arrListViewRow[8]) = 0 Then
						$intMsgCd = 81
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[81], "%s", $arrListViewRow[8]) & @LF & @LF ;"Die Operation kann nicht rückgängig gemacht werden, da die Datei {Zieldatei} nicht mehr vorhanden ist"
						$strMsg &= $strMsgTmp
						$errsev = 48
					Else
						If FileExists($arrListViewRow[7]) = 0 Then ;Warnung hinzufügen, wenn die (ursprüngliche?) Quelldatei nicht mehr existiert
							$intMsgCd = 82
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[82], "%s", $arrListViewRow[7]) & @LF & @LF ;"ACHTUNG! Eine Quelldatei namens {Quelldatei} ist nicht mehr vorhanden!"
							$strMsg &= $strMsgTmp
							$intMsgCd = 84
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[84], "%s", $arrListViewRow[8]) & @LF & @LF ;"Soll die Datei {Zieldatei} trotzdem gelöscht werden?"
							$strMsg &= $strMsgTmp
							$errsev = 32
						Else
							$intMsgCd = 85
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[85], "%s", $arrListViewRow[8]) & @LF & @LF ;"Soll die Datei {Zieldatei} gelöscht werden?"
							$strMsg &= $strMsgTmp
							$errsev = 32
						EndIf
					EndIf
					
					If $errsev = 32 Then
						If $booUndoCommit Then
							$err = _MsgBox($errsev+3+256, $strMsgBoxTitle, $strMsg) ;[Ja] [*Nein] [Abbrechen]
						Else
							$err = 6
						EndIf
						If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
							GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
							Call("_ListViewRefresh")
							Return
						EndIf
						If $err = 6 Then ;Button [Ja] wurde angeklickt
							If FileRecycle($arrListViewRow[8]) = 0 Then
								$intMsgCd = 86
								$strMsg = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[86], "%s", $arrListViewRow[8]) & @LF & @LF ;"Die Datei {Zieldatei} konnte nicht gelöscht werden"
								If $booUndoCommit Then _MsgBox(48, $strMsgBoxTitle, $strMsg) ;[OK]
							Else
								;*** Undo in RecentLogfile eintragen
								;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
								$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
								$strLogfileItem &= "XT:" & $strLocStr[58] & ": " & $arrListViewRow[8] ;"XT:Löschen: […]"
								FileWriteLine($strRecentLogfile, $strLogfileItem)
							EndIf
						EndIf
						
					Else
						If $booUndoCommit Then
							$err = _MsgBox($errsev+1+0, $strMsgBoxTitle, $strMsg) ;[*OK] [Abbrechen]
							If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
								GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
								Call("_ListViewRefresh")
								Return
							EndIf
						Else
							;*** Fehlgeschlagenes Undo in RecentLogfile eintragen
							;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
							$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
							$strLogfileItem &= "XT:" & $strLocStr[58] & "(" & $strLocStr[75] & " " & $strLocStr[76] & "): " & $arrListViewRow[8] ;"XT:Löschen(Fehler: Löschen fehlgeschlagen): […]"
							FileWriteLine($strRecentLogfile, $strLogfileItem)
						EndIf
						
					EndIf
					
					
				Case $strLocStr[54], "XT:" & $strLocStr[54], $strLocStr[55], "XT:" & $strLocStr[55] ;*** "Verschieben", "XT:Verschieben", "Umbenennen", "XT:Umbenennen" ;Undo = Zieldatei in Quelldatei umbenennen bzw. Zieldatei nach Quelldatei verschieben
					$strMsg = $arrListViewRow[7] & @LF & "->" & @LF & $arrListViewRow[8] & @LF & @LF
					
					;*** Prüfen: Existiert die Quelldatei wieder?
					If FileExists($arrListViewRow[7]) = 1 Then
						$booUndoPossible = False
						$intMsgCd = 87
						$strMsgTmp = StringReplace($strLocStr[87], "%x", $strFileType)
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strMsgTmp, "%s", $arrListViewRow[7]) & @LF & @LF ;"Die Operation kann nicht rückgängig gemacht werden, da ein Objekt (Ordner|Datei) namens {Quelldatei} bereits vorhanden ist"
						$strMsg &= $strMsgTmp 
						$errsev = 48
					Else
						$booUndoPossible = True
					EndIf
					
					;*** Prüfen: Existiert die Zieldatei noch?
					If FileExists($arrListViewRow[8]) = 0 Then
						$booUndoPossible = False
						$intMsgCd = 88
						$strMsgTmp = StringReplace($strLocStr[88], "%x", $strFileType)
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strMsgTmp, "%s", $arrListViewRow[8]) & @LF & @LF ;"Die Operation kann nicht rückgängig gemacht werden, da das Zielobjekt (Ordner oder Datei) {Zieldatei} nicht mehr vorhanden ist"
						$strMsg &= $strMsgTmp
						$errsev = 48
;~ 		 			Else
;~ 		 				$booUndoPossible = True
					EndIf
					
					If $booUndoPossible Then
						$intMsgCd = 89
						$strMsgTmp = StringReplace($strLocStr[89], "%x", $strFileType)
						$strMsgTmp = StringReplace($strMsgTmp, "%s", $arrListViewRow[7])
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strMsgTmp, "%t", $arrListViewRow[8]) & @LF & @LF ;"Soll das Objekt (Ordner|Datei) {Zieldatei} nach {Quelldatei} verschoben/umbenannt werden?"
						$strMsg &= $strMsgTmp
						$errsev = 32
					EndIf
					
					If $booUndoPossible And $errsev = 32 Then
						If $booUndoCommit Then
							$err = _MsgBox($errsev+3+256, $strMsgBoxTitle, $strMsg) ;[Ja] [*Nein] [Abbrechen]
						Else
							$err = 6
						EndIf
						If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
							GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
							Call("_ListViewRefresh")
							Return
						EndIf
						If $err = 6 Then ;Button [Ja] wurde angeklickt
							If $strFileType = "Datei" Then
								$err = FileMove($arrListViewRow[8], $arrListViewRow[7], 0)
							Else
								$err = DirMove($arrListViewRow[8], $arrListViewRow[7], 0)
							EndIf
							
							If $err = 0 Then
								$intMsgCd = 90
								$strMsg = StringReplace($strLocStr[90], "%x", $strFileType)
								$strMsg = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strMsg, "%s", $arrListViewRow[8]) & @LF & @LF ;"Das Zielobjekt (Ordner|Datei) {Zieldatei} konnte nicht verschoben/umbenannt werden"
								If $booUndoCommit Then _MsgBox(48, $strMsgBoxTitle, $strMsg) ;[OK]
							Else
								;*** Undo in RecentLogfile eintragen
								;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
								$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
								;*** "Verschieben", "XT:Verschieben"
								If $arrListViewRow[5] = $strLocStr[54] Or $arrListViewRow[5] = "XT:" & $strLocStr[54] Then
									$strLogfileItem &= "XT:" & $strLocStr[54] & ": " ;"XT:Verschieben: "
								Else
									$strLogfileItem &= "XT:" & $strLocStr[55] & ": " ;"XT:Umbenennen: "
								EndIf
								$strLogfileItem &= $arrListViewRow[8] & " -> " & $arrListViewRow[7]
								FileWriteLine($strRecentLogfile, $strLogfileItem)
							EndIf
							
						EndIf
						
					Else
						If $booUndoCommit Then
							$err = _MsgBox($errsev+1+0, $strMsgBoxTitle, $strMsg) ;[*OK] [Abbrechen]
							If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
								GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
								Call("_ListViewRefresh")
								Return
							EndIf
						Else
							;*** Fehlgeschlagenes Undo in RecentLogfile eintragen
							;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
							$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
							;*** "Verschieben", "XT:Verschieben"
							If $arrListViewRow[5] = $strLocStr[54] Or $arrListViewRow[5] = "XT:" & $strLocStr[54] Then
								$strLogfileItem &= "XT:" & $strLocStr[54] & "(" & $strLocStr[75] & " " & $strLocStr[80] & "): " ;"XT:Verschieben(Fehler: Fehlgeschlagen): "
							Else
								$strLogfileItem &= "XT:" & $strLocStr[55] & "(" & $strLocStr[75] & " " & $strLocStr[80] & "): " ;"XT:Umbenennen(Fehler: Fehlgeschlagen): "
							EndIf
							$strLogfileItem &= $arrListViewRow[8] & " -> " & $arrListViewRow[7]
							FileWriteLine($strRecentLogfile, $strLogfileItem)
						EndIf
						
					EndIf
					
					
				Case $strLocStr[58], "XT:" & $strLocStr[58] ;*** "Löschen", "XT:Löschen"
					$strMsg = $arrListViewRow[7] & @LF & @LF
					
					Local $objShell, $objFolder, $objFolderItem, $colItems
					$objShell = ObjCreate("Shell.Application")
					;Local Const $RECYCLE_BIN = 10
					;$objFolder = $objShell.Namespace($RECYCLE_BIN)
					$objFolder = $objShell.Namespace(10)
					$objFolderItem = $objFolder.Self
					$colItems = $objFolder.Items
					
					If IsObj($objShell) And Not @error Then
						For $objItem In $colItems
							If $arrListViewRow[7] = $objFolder.GetDetailsOf($objItem, 1) & "\" & $objItem.Name Then
								
								#cs
								$strStatus = " - (name): " & $objItem.Name & @LF
								$strStatus &= " 1 (original location): " & $objFolder.GetDetailsOf($objItem, 1) & @LF
								$strStatus &= " 2 (date deleted): " & $objFolder.GetDetailsOf($objItem, 2) & @LF
								$strStatus &= " 3 (size): " & $objFolder.GetDetailsOf($objItem, 3) & @LF
								$strStatus &= " 4 (file type): " & $objFolder.GetDetailsOf($objItem, 4) & @LF
								$strStatus &= " 5 (date modified): " & $objFolder.GetDetailsOf($objItem, 5) & @LF
								$strStatus &= " 6 (date created?): " & $objFolder.GetDetailsOf($objItem, 6) & @LF
								$strStatus &= " 7 (date accessed?): " & $objFolder.GetDetailsOf($objItem, 7) & @LF
								$strStatus &= " 8 (file attribs): " & $objFolder.GetDetailsOf($objItem, 8) & @LF
								$strStatus &= " 9 (status): " & $objFolder.GetDetailsOf($objItem, 9) & @LF
								$strStatus &= "10 (owner): " & $objFolder.GetDetailsOf($objItem, 10) & @LF
								MsgBox(0, $ver, $arrListviewItemChecked[$intListviewItemChecked] & @LF & @LF & $strStatus)
								#ce
								
								$strListviewItemDateTime = StringRegExpReplace($arrListViewRow[3] & $arrListViewRow[4], "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:00")
								$arrRecycleBinSubItems = StringSplit($objFolder.GetDetailsOf($objItem, 2), " "); Datum und Uhrzeit lesen
								$strRecycleBinDateTime = StringRegExpReplace(_FormatDate($arrRecycleBinSubItems[1]) & _FormatTime($arrRecycleBinSubItems[2]), "(....)-(..)-(..)(..):(..):(..)", "\1/\2/\3 \4:\5:00")
								$intDateDiff = Abs(_DateDiff("s", $strListviewItemDateTime, $strRecycleBinDateTime))
								
								If $intDateDiff < 61 Then
									$booUndoPossible = True
									;*** Prüfen: Existiert die Quelldatei wieder?
									If FileExists($arrListViewRow[7]) = 1 Then
										$booUndoPossible = False
										$intMsgCd = 91
										$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & $strLocStr[91] & @LF & @LF ;"Eine Datei dieses Namens existiert bereits"
										$strMsg &= $strMsgTmp
										$errsev = 48
									EndIf
									ExitLoop
								Else
									$strMsgTmp  = StringReplace($strLocStr[105], "%x", $strListviewItemDateTime) & @LF ;"%x (Löschdatum/-uhrzeit gemäß Logfile)"
									$strMsgTmp &= StringReplace($strLocStr[106], "%x", $strRecycleBinDateTime) & @LF   ;"%x (Löschdatum/-uhrzeit gemäß Papierkorb)"
									$strMsgTmp &= StringReplace($strLocStr[107], "%n", $intDateDiff) & @LF & @LF       ;"%ns Diff. (max. 60s toleriert)"
									$strMsg &= $strMsgTmp
								EndIf
								
							EndIf
						Next
					EndIf
					
					If $booUndoPossible Then
						$intMsgCd = 92
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & $strLocStr[92] & @LF & @LF ;"Soll die Datei wiederhergestellt werden?"
						$strMsg &= $strMsgTmp
						$errsev = 32
						If $booUndoCommit Then
							$err = _MsgBox($errsev+3+256, $strMsgBoxTitle, $strMsg) ;[Ja] [*Nein] [Abbrechen]
						Else
							$err = 6
						EndIf
						
						If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
							GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
							Call("_ListViewRefresh")
							Return
						EndIf
						If $err = 6 Then ;Button [Ja] wurde angeklickt
							Run(EnvGet("SystemRoot") & '\Explorer.exe "::{645FF040-5081-101B-9F08-00AA002F954E}"')
							If WinWait(RegRead("HKLM\SOFTWARE\Classes\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}", ""), "", 3) = 1 Then
								$hwRecycleBin = WinGetHandle(RegRead("HKLM\SOFTWARE\Classes\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}", ""))
								ControlListView($hwRecycleBin, "", "SysListView321", "ViewChange", "details")
								$p = StringInStr($arrListViewRow[7], "\", 0, -1)
								$p = ControlListView($hwRecycleBin, "", "SysListView321", "FindItem", StringMid($arrListViewRow[7], $p+1))
								ControlListView($hwRecycleBin, "", "SysListView321", "Select", $p, $p)
								If $arrListViewRow[7] = ControlListView($hwRecycleBin, "", "SysListView321", "GetText", $p, 1) & "\" & ControlListView($hwRecycleBin, "", "SysListView321", "GetText", $p, 0) Then
									Send("{APPSKEY}{DOWN}{ENTER}")
									;*** Undo in RecentLogfile eintragen
									;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
									$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
									$strLogfileItem &= "XT:" & $strLocStr[65] & ": " & $arrListViewRow[7] ;"XT:Wiederherstellen: […]"
									FileWriteLine($strRecentLogfile, $strLogfileItem)
								EndIf
								WinClose($hwRecycleBin)
							EndIf
						EndIf
						
						;*** Untauglicher Versuch, das WinHandle des soeben geöffneten Explorerfensters (Papierkorb) zu ermitteln
						;$intTimerInit = TimerInit()
						;While TimerDiff($intTimerInit) < 3000
						;	$arrWinList = WinList() ;[x][0] = WinTitle, [x][1] = WinHandle
						;	For $i = 1 To $arrWinList[0][0]
						;		If $pid = WinGetProcess($arrWinList[$i][1]) Then
						;			$hwRecycleBin = $arrWinList[$i][1]
						;			MsgBox(0, $strMsgBoxTitle, WinGetTitle($hwRecycleBin))
						;			$arrWinList = ""
						;			ExitLoop
						;		EndIf
						;	Next
						;	Sleep(250)
						;WEnd
						
					Else
						If $booUndoCommit Then
							$intMsgCd = 93
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & $strLocStr[93] & @LF & @LF ;"Die Datei kann nicht wiederhergestellt werden"
							$strMsg &= $strMsgTmp
							$err = _MsgBox(48+1+0, $strMsgBoxTitle, $strMsg) ;[*OK] [Abbrechen]
							If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
								GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
								Call("_ListViewRefresh")
								Return
							EndIf
						Else
							;*** Undo in RecentLogfile eintragen
							;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
							$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
							$strLogfileItem &= "XT:" & $strLocStr[65] & "(" & $strLocStr[75] & " " & $strLocStr[80] & "): " & $arrListViewRow[7] ;"XT:Wiederherstellen(Fehler: Fehlgeschlagen): […]"
							FileWriteLine($strRecentLogfile, $strLogfileItem)
						EndIf
						
					EndIf
					
					
				Case $strLocStr[63] ;*** "NeueDatei" ;Undo = Datei wie in Quelldatei angegeben löschen
					$strMsg = $arrListViewRow[7] & @LF & @LF
					
					;*** Prüfen: Existiert die Quelldatei noch?
					If FileExists($arrListViewRow[7]) = 0 Then
						$intMsgCd = 81
						$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[81], "%s", $arrListViewRow[7]) & @LF & @LF ;"Die Operation kann nicht rückgängig gemacht werden, da die Datei {Quelldatei} nicht mehr vorhanden ist"
						$strMsg &= $strMsgTmp
						$errsev = 48
					Else
						If FileGetSize($arrListViewRow[7]) > 0 Then ;Warnung hinzufügen, wenn die Quelldatei nicht leer ist
							$intMsgCd = 83
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[83], "%s", $arrListViewRow[7]) & @LF & @LF ;"ACHTUNG! Die Datei {Quelldatei} ist nicht leer!"
							$strMsg &= $strMsgTmp
							$intMsgCd = 84
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[84], "%s", $arrListViewRow[7]) & @LF & @LF ;"Soll die Datei {Quelldatei} trotzdem gelöscht werden?"
							$strMsg &= $strMsgTmp
							$errsev = 32
						Else
							$intMsgCd = 85
							$strMsgTmp = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[85], "%s", $arrListViewRow[7]) & @LF & @LF ;"Soll die Datei {Quelldatei} gelöscht werden?"
							$strMsg &= $strMsgTmp
							$errsev = 32
						EndIf
					EndIf
					
					If $errsev = 32 Then
						If $booUndoCommit Then
							$err = _MsgBox($errsev+3+256, $strMsgBoxTitle, $strMsg) ;[Ja] [*Nein] [Abbrechen]
						Else
							$err = 6
						EndIf
						If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
							GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
							Call("_ListViewRefresh")
							Return
						EndIf
						If $err = 6 Then ;Button [Ja] wurde angeklickt
							If FileRecycle($arrListViewRow[7]) = 0 Then
								$intMsgCd = 86
								$strMsg = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[86], "%s", $arrListViewRow[7]) & @LF & @LF ;"Die Datei {Quelldatei} konnte nicht gelöscht werden"
								If $booUndoCommit Then _MsgBox(48, $strMsgBoxTitle, $strMsg) ;[OK]
							Else
								;*** Undo in RecentLogfile eintragen
								;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
								$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
								$strLogfileItem &= "XT:" & $strLocStr[58] & ": " & $arrListViewRow[7] ;"XT:Löschen: […]"
								FileWriteLine($strRecentLogfile, $strLogfileItem)
							EndIf
						EndIf
						
					Else
						If $booUndoCommit Then
							$err = _MsgBox($errsev+1+0, $strMsgBoxTitle, $strMsg) ;[*OK] [Abbrechen]
							If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
								GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
								Call("_ListViewRefresh")
								Return
							EndIf
						Else
							;*** Fehlgeschlagenes Undo in RecentLogfile eintragen
							;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
							$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
							$strLogfileItem &= "XT:" & $strLocStr[58] & "(" & $strLocStr[75] & " " & $strLocStr[76] & "): " & $arrListViewRow[7] ;"XT:Löschen(Fehler: Löschen fehlgeschlagen): […]"
							FileWriteLine($strRecentLogfile, $strLogfileItem)
						EndIf
						
					EndIf					
					
					
				Case Else
					If $booUndoCommit Then
						$intMsgCd = 94
						$strMsg = $strLocStr[102] & $intMsgCd & @LF & @LF & StringReplace($strLocStr[94], "%s", @ScriptName) & @LF & @LF ;"Dieser Vorgang kann von {TCLogfileViewer} leider nicht rückgängig gemacht werden :'-("
						$err = _MsgBox(48+1+0, $strMsgBoxTitle, $strMsg) ;[*OK] [Abbrechen]
						If $err = 2 Then ;Button [Abbrechen] wurde angeklickt
							GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
							Call("_ListViewRefresh")
							Return
						EndIf
					Else
						;*** Fehlgeschlagenes Undo in RecentLogfile eintragen
						;ToDo: Datums-/Zeitstring entsprechend Lokalisierung bilden
						$strLogfileItem = @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & ": "
						$strLogfileItem &= "XT:" & $strLocStr[70] & "(" & $arrListViewRow[5] & ")(" & $strLocStr[75] & " " & $strLocStr[95] & ")" ;"XT:Rückgängig({Vorgang})(Fehler: Nicht unterstützt)"
						If $arrListViewRow[7] <> "" Then $strLogfileItem &= ": " & $arrListViewRow[7]
						If $arrListViewRow[8] <> "" Then $strLogfileItem &= " -> " & $arrListViewRow[8]
						FileWriteLine($strRecentLogfile, $strLogfileItem)
					EndIf
					
			EndSwitch
			
			;*** Eintrag aus $strListviewItemChecked entfernen (und somit Listview-Checkbox unchecken)
			$strListviewItemChecked = StringReplace($strListviewItemChecked, $arrListviewItemChecked[$intListviewItemChecked] & @LF, "")
			$strListviewItemChecked = StringReplace($strListviewItemChecked, @LF, @LF)
			$intListviewItemCheckedCount = @extended
			GUICtrlSetData($lblListviewItemCheckedCount, StringReplace($strLocStr[29], "%n", $intListviewItemCheckedCount))
			
		Next
		
		GUICtrlSetState($chkUndoCommit, $GUI_CHECKED)
		Call("_ListViewRefresh")
		
;~ 	EndIf

EndFunc ;_Undo

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#cs Func _Restoration()
Func _Restoration()
	
	$strListViewSubItemText = _GUICtrlListViewGetItemText($lvLogfile, -1, 6)
	If $strListViewSubItemText <> "" Then
		
		$strDriveList = DriveGetDrive("ALL")
		$strDriveRequested = StringLeft($strListViewSubItemText, 2)
		For $i = 1 To $strDriveList[0]
			If $strDriveList[$i] = $strDriveRequested Then ExitLoop
		Next
		
		;*** Prüfen, ob Laufwerk in Restoration-Combobox überhaupt verfügbar ist.
		If $i > $strDriveList[0] Then
			MsgBox(48, $ver, "Laufwerk " & $strDriveRequested & " ist nicht verfügbar")
			Return
		EndIf
		
	EndIf
	
	If FileExists("C:\Programme\Restoration\Restoration.exe") Then
		Run("C:\Programme\Restoration\Restoration.exe")
		WinWait("Restoration")
		WinActivate("Restoration")
		
		;*** Restoration-Editbox "All or part of the file" mit dem Dateinamen aus Spalte "Quelle" des Listviews belegen
		$p = StringInStr($strListViewSubItemText, "\", 0, -1)
		ControlSetText("Restoration", "", "Edit1", StringMid($strListViewSubItemText, $p+1))
		
		;*** Aus Restoration-Combobox "Drives" Laufwerk aus Spalte "Quelle" des Listviews auswählen
		ControlFocus("Restoration", "", "ComboBox1")
		Send("{HOME}")
		For $i = 1 To $strDriveList[0]
			If $strDriveList[$i] = $strDriveRequested Then
				ExitLoop
			Else
				If $strDriveList[$i] <> "CDROM" Then Send("{DOWN}")
			EndIf
		Next
		
		ControlClick("Restoration", "", "Button1") ;Button "Search deleted files"
		If WinWait("Restoration", "File No:", 5) = 1 Then WinWaitClose("Restoration", "File No:")
		If WinWait("Restoration", "No files were found", 1) = 1 Then ;Meldungsdialog "No files were found" wird angezeigt)
			ControlClick("Restoration", "No files were found", "Button1") ;Button "OK" anklicken
		Else
			MsgBox(0, $ver, ControlGetText("Restoration", "", "Static9")) ;Anzahl gefundener Dateien
		EndIf
		ControlClick("Restoration", "", "Button5") ;Button "Exit" anklicken
		
	EndIf
	
EndFunc ;_Restoration
#ce
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#cs Func _Group()
Func _Group()
	$intListViewItemsInGroupCount = 0
	$arrListViewRowMem = ""
	For $intListViewItemIndex = _GUICtrlListView_GetItemCount($hlvLogfile)-1 To 1 Step -1
		$arrListViewRow = _GUICtrlListView_GetItemTextArray($hlvLogfile, $intListViewItemIndex)
		$arrListViewRowPrev = _GUICtrlListView_GetItemTextArray($hlvLogfile, $intListViewItemIndex-1)
		
		$intListviewItemTime = 1000 * StringLeft($arrListViewRow[4], 2) / 24
		$intListviewItemTime += 1000 * StringMid($arrListViewRow[4], 4, 2) / (24*60)
		$intListviewItemTime += 1000 * StringRight($arrListViewRow[4], 2) / (24*60*60)
		
		$intListviewItemTimePrev = 1000 * StringLeft($arrListViewRowPrev[4], 2) / 24
		$intListviewItemTimePrev += 1000 * StringMid($arrListViewRowPrev[4], 4, 2) / (24*60)
		$intListviewItemTimePrev += 1000 * StringRight($arrListViewRowPrev[4], 2) / (24*60*60)
		
		$intListViewItemsInGroupCount += 1
;~ 		If StringReplace($arrListViewRowPrev[4], ":", "")*1 - StringReplace($arrListViewRow[4], ":", "")*1 > 1 Then
		If $intListviewItemTimePrev - $intListviewItemTime > 0.02 Then
			If $intListViewItemsInGroupCount > 1 Then
				$strListviewItem = "==========|==|" & $arrListViewRow[3] & "|" & $arrListViewRow[4] & "|" & $intListViewItemsInGroupCount & " Vorgänge|==|==========|=========="
				$err = _GUICtrlListView_InsertItem($hlvLogfile, $intListViewItemIndex, $strListviewItem)
			EndIf
			$intListViewItemsInGroupCount = 0
		EndIf
	Next
EndFunc ;_Group
#ce
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _Save()
	
	$strSaveFilename = FileSaveDialog($strLocStr[96], $strRecentLogfilePath, $strLocStr[97], 16) ;"Datensätze exportieren", "Alle Dateien (*.*)|Textdateien (*.txt;*.tab)"
	If @error = 1 Then Return
	$hfSaveFile = FileOpen($strSaveFilename, 2)
	
	_BuildSQLWhereClause()
	$strSQL = "SELECT * FROM tabTCLogDetails" & $strTabTCLogWhere & $strTabTCLogOrderBy & ";"
	GUICtrlSetData($lblStatus, $strSQL)
	$errx = _SQlite_Query($hdbTCLog, $strSQL, $hqryTabTCLog)
	$err = @error
	
	;*** Überschriftenzeile
	$strListviewItem = $strLocStr[98] ;"Logfile|Zeile|Datum|Uhrzeit|Vorgang|Status|Quelle|Quelle (Pfad)|Quelle (Dateiname)|Ziel|Ziel (Pfad)|Ziel (Dateiname)|"
	$strListviewItem = StringReplace(StringTrimRight($strListviewItem, 1), "|", @TAB)
	FileWriteLine($hfSaveFile, $strListviewItem)
	
	$intTabTCLogCount = 0
	While _SQLite_FetchData($hqryTabTCLog, $arrTabTCLogRow) = $SQLITE_OK
		$intTabTCLogCount += 1
		$strListviewItem = ""
		
		;Logfile, Zeile, Datum, Uhrzeit, Vorgang, Status, Quelle, Ziel
		For $intTabTCLogCol = 0 To UBound($arrTabTCLogRow)-1
			$strListviewItem &= $arrTabTCLogRow[$intTabTCLogCol] & "|"
			
			;*** Quelle zusätzlich in Pfad und Dateiname aufsplitten
			If $intTabTCLogCol = 6 Then
				$p = StringInStr($arrTabTCLogRow[$intTabTCLogCol], "\", 0, -1)
				If $p = 0 Then
					$strListviewItem &= "||"
				Else
					$strListviewItem &= StringLeft($arrTabTCLogRow[$intTabTCLogCol], $p-1) & "|"
					$strListviewItem &= StringMid($arrTabTCLogRow[$intTabTCLogCol], $p+1) & "|"
				EndIf
			EndIf
			
			;*** Ziel zusätzlich in Pfad und Dateiname aufsplitten
			If $intTabTCLogCol = 7 Then
				$p = StringInStr($arrTabTCLogRow[$intTabTCLogCol], "\", 0, -1)
				If $p = 0 Then
					$strListviewItem &= "||"
				Else
					$strListviewItem &= StringLeft($arrTabTCLogRow[$intTabTCLogCol], $p-1) & "|"
					$strListviewItem &= StringMid($arrTabTCLogRow[$intTabTCLogCol], $p+1) & "|"
				EndIf
			EndIf
			
		Next
		$strListviewItem = StringReplace(StringTrimRight($strListviewItem, 1), "|", @TAB)
		FileWriteLine($hfSaveFile, $strListviewItem)
		If Mod($intTabTCLogCount, $intListViewLimit) = 0 Then GUICtrlSetData($lblStatus, $intTabTCLogCount) ;debug
	WEnd
	
	FileClose($hfSaveFile)
	_MsgBox(64, $ver, StringReplace(StringReplace($strLocStr[99], "%s", $strSaveFilename), "%n", $intTabTCLogCount)) ;"{n} DS wurden nach {Datei} exportiert"
	
EndFunc ;_Save

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _TopmostToggle()
	WinSetOnTop($frmGUI, "", Mod(GUICtrlRead($chkTopmost), 4))
	If GUICtrlRead($chkTopmost) = $GUI_CHECKED Then
		GUICtrlSetColor($lblTopmost, 0x00FF00)
		$booTopmost = True
		$booTopmostDesired = True
	Else
		GUICtrlSetColor($lblTopmost, 0xECE9D8-0x200020)
		$booTopmost = False
		$booTopmostDesired = False
	EndIf
EndFunc ;_TopmostToggle

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _Topmost($strFlag)
	Switch $strFlag
		Case "On"
			WinSetOnTop($frmGUI, "", 1)
			GUICtrlSetState($chkTopmost, $GUI_CHECKED)
			GUICtrlSetColor($lblTopmost, 0x00FF00)
			$booTopmost = True
		Case "Off"
			WinSetOnTop($frmGUI, "", 0)
			GUICtrlSetState($chkTopmost, $GUI_UNCHECKED)
			GUICtrlSetColor($lblTopmost, 0xECE9D8-0x200020)
			$booTopmost = False
	EndSwitch
EndFunc ;_Topmost

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _DBReorganize()
	;ToDo: Steuerelemente deaktivieren
	GUICtrlSetData($lblStatus, $strLocStr[100]) ;"Reorganisiere die Datenbank..."
	$strSQL = "VACUUM;"
	$errx = _SQLite_Exec($hdbTCLog, $strSQL)
	$err = @error
	If $err = 0 Then
	GUICtrlSetData($lblStatus, $strLocStr[101]) ;"Reorganisieren der Datenbank erfolgreich abgeschlossen"
	Else
		_SQLiteErrHandler(48, $err, $errx, "_SQLite_Exec", $strSQL)
	EndIf
	;ToDo: Steuerelemente wieder aktivieren
EndFunc ;_DBReorganize

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#cs
Func _ListviewItemEvent()
	
	$strListviewItem = GUICtrlRead(@GUI_CTRLID, 0)
	$p = StringInStr($strListviewItemChecked, $strListviewItem)
	
	If $p = 0 And GUICtrlRead(@GUI_CTRLID, 1) = $GUI_CHECKED Then
		$strListviewItemChecked &= $strListviewItem & @LF
		$intListviewItemCheckedCount += 1
	EndIf
	If $p > 0 And GUICtrlRead(@GUI_CTRLID, 1) = $GUI_UNCHECKED Then
		$strListviewItemChecked = StringReplace($strListviewItemChecked, $strListviewItem & @LF, "")
		$intListviewItemCheckedCount -= 1
	EndIf
	
	;$strListviewItemChecked = StringReplace($strListviewItemChecked, @LF, @LF)
	;GUICtrlSetData($lblStatus, @extended & " DS ausgewählt")
	GUICtrlSetData($lblStatus, $intListviewItemCheckedCount & " DS ausgewählt")
	
EndFunc ;_ListviewItemEvent
#ce

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;*** In angepasster Form übernommen von: http://www.autoitscript.com/forum/index.php?act=Attach&type=post&id=8616
;~ Func _GetExtProperty($strDir, $strFile, $strProperty)
Func _GetTCProductVersion()
	#cs
	 0 = Name             / Name               
	 1 = Size             / Größe              
	 2 = Type             / Typ                
	 3 = DateModified     / Geändert am        
	 4 = DateCreated      / Erstellt am        
	 5 = DateAccessed     / Letzter Zugriff am 
	 6 = Attributes       / Attribute          
	 7 = Status           / Status             
	 8 = Owner            / Besitzer           
	 9 = Author           / Autor              
	10 = Title            / Titel              
	11 = Subject          / Thema              
	12 = Category         / Kategorie          
	13 = Pages            / Seiten             
	14 = Comments         / Kommentare         
	15 = Copyright        / Copyright          
	16 = Artist           / Interpret          
	17 = AlbumTitle       / Albumtitel         
	18 = Year             / Jahr               
	19 = TrackNumber      / Titelnummer        
	20 = Genre            / Genre              
	21 = Duration         / Dauer              
	22 = BitRate          / Bitrate            
	23 = Protected        / Geschützt          
	24 = CameraModel      / Kameramodell       
	25 = DatePictureTaken / Bild aufgenommen am
	26 = Dimensions       / Abmessungen        
	27 = Width            / Folgenname *Breite?
	28 = Height           / Sdg.beschrb. *Höhe?
	29 =                  /                    
	30 =                  /                    
	31 =                  /                    
	32 = SamplingSize     / Abtastgröße        
	33 = SamplingRate     / Abtastrate         
	34 = Channels         / Kanäle             
	35 = Company          / Firma              
	36 = Description      / Beschreibung       
	37 = FileVersion      / Dateiversion       
	38 = ProductName      / Produktname        
	39 = ProductVersion   / Produktversion     
	40 = Keywords         / Keywords           
	#ce
;~ 	Local $objShellApp, $objDir, $objFile, $intProperty
	Local $objShellApp, $objDir, $objFile
;~ 	If StringInStr($strProperties, $strProperty) = 0 Then Return ""
;~ 	$intProperty = (StringInStr($strProperties, $strProperty) - 1) / 18
	$objShellApp = ObjCreate("shell.application")
;~ 	$objDir = $objShellApp.NameSpace($strDir)
	$objDir = $objShellApp.NameSpace(EnvGet("COMMANDER_PATH"))
;~ 	$objFile = $objDir.Parsename($strFile)
	$objFile = $objDir.Parsename("TotalCmd.exe")
;~ 	Return $objDir.GetDetailsOf($objFile, $intProperty)
	Return $objDir.GetDetailsOf($objFile, 39) ;Produktversion
EndFunc

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func My_WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg, $iwParam
;~ 	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
	Local $hWndFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
	$hWndListView = $hlvLogfile
	If Not IsHWnd($hlvLogfile) Then $hWndListView = GUICtrlGetHandle($hlvLogfile)

	$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
;~ 	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
	$iCode = DllStructGetData($tNMHDR, "Code")
	
	If $iCode = $NM_CLICK And $hWndFrom = $hWndListView Then
		$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
		
		$intListViewItemIndex = DllStructGetData($tInfo, "Index")
		$strListviewItem = _GUICtrlListView_GetItemTextString($hlvLogfile, $intListViewItemIndex)
;~ 		$strListviewItem = StringReplace($strListviewItem, "|*", "|", 1)
		
		;*** Prüfen, ob die Checkbox angeklickt wurde (oder ob zwar in der Zeile, aber außerhalb der Checkbox geklickt wurde)
		If $intListViewItemIndex <> -1 Then
			
			Local $iX = DllStructGetData($tInfo, "X")
			Local $iPart = 1
			If _GUICtrlListView_GetView($hWndListView) = 1 Then $iPart = 2 ;for large icons view
			Local $aIconRect = _GUICtrlListView_GetItemRect($hWndListView, $intListViewItemIndex, $iPart)
			
			If $iX < $aIconRect[0] And $iX >= 5 Then
				$p = StringInStr($strListviewItemChecked, $strListviewItem)
				If $p = 0 And _GUICtrlListView_GetItemChecked($hlvLogfile, $intListViewItemIndex) = False Then
					$strListviewItemChecked &= $strListviewItem & @LF
				EndIf
				If $p > 0 And _GUICtrlListView_GetItemChecked($hlvLogfile, $intListViewItemIndex) = True Then
					$strListviewItemChecked = StringReplace($strListviewItemChecked, $strListviewItem & @LF, "")
				EndIf
				
				$strListviewItemChecked = StringReplace($strListviewItemChecked, @LF, @LF)
				$intListviewItemCheckedCount = @extended
				GUICtrlSetData($lblListviewItemCheckedCount, StringReplace($strLocStr[29], "%n", $intListviewItemCheckedCount))
				Return 0
			EndIf
			
		EndIf

		
	EndIf
	
	#cs
	If $hWndFrom = $hWndListView Then
		Switch $iCode
			
			Case $LVN_COLUMNCLICK ; A column was clicked
				$tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
				MsgBox(0, "$LVN_COLUMNCLICK", DllStructGetData($tInfo, "SubItem")) ;debug
				;No return value
			
			Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
				$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
				;MsgBox(0, "$NM_CLICK", DllStructGetData($tInfo, "Index")) ;debug
				OpenEditTagDialog(DllStructGetData($tInfo, "Index"))
				;No return value
			
			Case $NM_DBLCLK ; Sent by a list-view control when the user double-clicks an item with the left mouse button
				$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
				;MsgBox(0, "$NM_DBLCLK", DllStructGetData($tInfo, "Index")) ;debug
				OpenEditTagDialog(DllStructGetData($tInfo, "Index"))
				;No return value
				
			Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
				$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
				MsgBox(0, "$NM_RCLICK", DllStructGetData($tInfo, "Index")) ;debug
				;Return 1 ; not to allow the default processing
				Return 0 ; allow the default processing
			
			Case $NM_RDBLCLK ; Sent by a list-view control when the user double-clicks an item with the right mouse button
				$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
				MsgBox(0, "$NM_RDBLCLK", DllStructGetData($tInfo, "Index")) ;debug
				;No return value
			
		EndSwitch
		
	EndIf
	#ce
	
	Return $GUI_RUNDEFMSG
;~ 	Return
	
EndFunc

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _Exit() ;$GUI_EVENT_CLOSE
	$errx = _SQLite_QueryFinalize($hqryTabTCLog)
	;ToDo: Errorhandling
	If $strLogfileDB = "" Then $errx = _SQLite_Exec ($hdbTCLog, "DROP TABLE tabTCLogDetails;")
	;ToDo: Errorhandling
	$errx = _SQLite_Close($hdbTCLog)
	;ToDo: Errorhandling
	_SQLite_Shutdown()
	;ToDo: Errorhandling
	Exit
EndFunc ;_Exit
