﻿;-- TIME_STAMP   2022-10-10 20:45:19

;~ #include <Array.au3> ; _ArrayToString
#include <APIShellExConstants.au3>
;~ #include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>
#include <WinAPIShellEx.au3>
#include <WinAPISysWin.au3>

Opt('TrayAutoPause', 0)

Global Const $g_sPath = @ScriptDir ; Die zu überwachenden Verzeichnisse (String oder Array)
Global $g_iID, $g_idEdit, $g_idDummy

OnAutoItExitRegister('OnAutoItExit')

_Main()

Func _Main()
	Local $hWnd = GUICreate(@ScriptName, 640, 420)
	Local $aCS = WinGetClientSize($hWnd)
	$g_idEdit = GUICtrlCreateEdit('', 0, 0, $aCS[0], $aCS[1], BitOR($ES_AUTOVSCROLL, $WS_VSCROLL, $ES_MULTILINE, $ES_READONLY))
	GUICtrlSetFont(-1, 11, 800, 0, 'Courier New')
	$g_idDummy = GUICtrlCreateDummy()
	GUISetState()
	WinSetOnTop($hWnd, '', 1)
	Local $iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY')
	GUIRegisterMsg($iMsg, 'WM_SHELLCHANGENOTIFY')
;~ 	$g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd, $iMsg, $SHCNE_ALLEVENTS, BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT, $SHCNRF_NEWDELIVERY), $g_sPath, 1)
	$g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd, $iMsg, _
			BitOR($SHCNE_ASSOCCHANGED, $SHCNE_CREATE, $SHCNE_RENAMEITEM, $SHCNE_UPDATEITEM), _ ; $SHCNE_CREATE ist eigtl. nur nötigt, wenn ausschließlich neue Dateien berücksichtig werden sollen!
			BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_NEWDELIVERY), _
			$g_sPath, 0)
	If @error Then
		MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Fehler', 'Das Fenster wurde nicht registriert.')
		Exit
	EndIf

	Local $sPath, $sCalc, $hFile
	While True
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				Exit
			Case $g_idDummy
				$sPath = GUICtrlRead($g_idDummy)
				$sCalc = _Calc(FileRead($sPath)) ; "32 94 97 64 83 14 82 64 72" ==>> "32 06 97 36 83 86 82 36 72"
				$hFile = FileOpen(StringRegExpReplace($sPath, '(?i)(.+)\.rns', '\1.rnt'), 2)
				FileWrite($hFile, $sCalc) ; Eine bereits vorhandene *.rnt wird hiermit überschrieben!
				FileClose($hFile)
		EndSwitch
	WEnd
EndFunc   ;==>_Main

Func WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg
	Local Static $bCreate = False
	Local $aRes = DllCall("shell32.dll", "HANDLE", "SHChangeNotification_Lock", "wparam", $wParam, "lparam", $lParam, "ptr*", "", "ulong*", "")
;~ 	ConsoleWrite(@LF & "> SHChangeNotification_Lock   $aRes --> " & _ArrayToString($aRes, '|') & @LF)
	Local $PIDLIST_ABSOLUTE = $aRes[3]
	Local $plEvent = $aRes[4]

	Local $tPIDL = DllStructCreate('dword Item1; dword Item2', $PIDLIST_ABSOLUTE)
	Local $sPath1 = _WinAPI_ShellGetPathFromIDList(DllStructGetData($tPIDL, 'Item1'))
	Local $sPath2 = _WinAPI_ShellGetPathFromIDList(DllStructGetData($tPIDL, 'Item2'))

;~ 	ConsoleWrite("@@_Debug_line" & @TAB & @TAB & @ScriptLineNumber & "   var: $sPath1 --> " & $sPath1 & @LF)
;~ 	ConsoleWrite("@@_Debug_line" & @TAB & @TAB & @ScriptLineNumber & "   var: $sPath2 --> " & $sPath2 & @LF)
	Switch $plEvent
		Case $SHCNE_ASSOCCHANGED ; 0x8000000  A file type association has changed.
			_AppendText(@CRLF & 'Case $SHCNE_ASSOCCHANGED' & @CRLF)
		Case $SHCNE_CREATE       ; 0x00000002 A non-folder item has been created.
			$bCreate = True
		Case $SHCNE_RENAMEITEM   ; 0x00000001 The name of a non-folder item has changed.
			_AppendText(@CRLF & '! Case $SHCNE_RENAMEITEM' & @CRLF & _
					'> Alter Name: ' & $sPath1 & @CRLF & _
					'> Neuer Name: ' & $sPath2 & @CRLF)
					; zugehörige *.rnt umbenennen
		Case $SHCNE_UPDATEITEM   ; 0x00002000 An existing non-folder item has changed, but the item still exists and has not been renamed.
			If StringRight($sPath1, 4) = '.rns' Then
				_AppendText(@CRLF & '! ' & ($bCreate ? 'Neue' : 'Geänderte') & ' *.rns gefunden!' & @CRLF & _
						'> Event: 0x' & Hex($plEvent) & ' ($SHCNE_UPDATEITEM) ' & @CRLF & _
						'> Pfad1: ' & $sPath1 & @CRLF)
				_SendToDummy($g_idDummy, $sPath1)
			EndIf
			$bCreate = False
;~ 		Case Else ; We don't care...
	EndSwitch

	$aRes = DllCall("shell32.dll", "int", "SHChangeNotification_Unlock", "HANDLE", $aRes[0])
;~ 	ConsoleWrite("> SHChangeNotification_Unlock $aRes --> " & _ArrayToString($aRes, '|') & @LF)
EndFunc   ;==>WM_SHELLCHANGENOTIFY

Func _SendToDummy($idDummy, $sPath)
	Local $iFileSize = FileGetSize($sPath)
	If $iFileSize Then
		_AppendText('+ Die Datei ist ' & $iFileSize & ' Bytes groß' & @CRLF & @CRLF)
		GUICtrlSendToDummy($g_idDummy, $sPath)
	Else
		_AppendText('! Die Datei ist leer!' & @CRLF & @CRLF)
	EndIf
EndFunc   ;==>_SendToDummy

; Convert *.rns to *.rnt
Func _Calc($sSource)
	Local $aArray = StringRegExp($sSource, '(\d{2})\s?', 3), $sSpace = StringInStr($sSource, ' ') ? ' ' : '', $sTarget
	For $i = 1 To UBound($aArray) - 1 Step 2
;~ 		$sTarget &= StringFormat('%02i' & $sSpace & '%02i' & $sSpace, $aArray[$i - 1], 100 - $aArray[$i])
		$sTarget &= StringFormat('%02i' & $sSpace & '%02i' & $sSpace, $aArray[$i - 1], StringRight(100 - $aArray[$i], 2))
	Next
	$sTarget = $i = UBound($aArray) ? $sTarget & $aArray[$i - 1] : StringTrimRight($sTarget, 1)
	_AppendText('> Vorher (*.rns) = ' & $sSource & @CRLF & '- Danach (*.rnt) = ' & $sTarget & @CRLF & @CRLF) ; *** nur zur Anzeige
	Return $sTarget
EndFunc   ;==>_Calc

Func _AppendText($sText)
	_GUICtrlEdit_AppendText($g_idEdit, $sText)
EndFunc

Func OnAutoItExit()
	If $g_iID Then _WinAPI_ShellChangeNotifyDeregister($g_iID)
EndFunc   ;==>OnAutoItExit
