Moin.
Eingangsstring: "32 94 97 64 83 14 82 64 72" ; eigentliche Länge bis zu 200 zweistellige Zahlen.
Ausgangsstring: "32 06 97 36 83 86 82 36 72" ; so SOLL ES aussehen
Ich würde gerne jede zweite zweistellige Zahl "negativieren" (100 minus die Zahl). Ich benne es mal so. Hab keine Zeit mir ein anderes Wort auszudenken.
Dachte: StringReplace 01 mit 99 ; 02 mit 98 ; 03 mit 97 ; ...
Aber so werden alle zweistellige Zahlen genommen.
![](https://autoit.de/wcf/images/avatars/60/648-6030c7ee37cb8b3c1ceaa6ea8bb8a6f3683a3b4d.jpg)
StringReplace nur auf jede 2. Doppelziffe anwenden
-
Alina -
7. Oktober 2022 um 22:28 -
Erledigt
-
-
Alina
7. Oktober 2022 um 22:30 Hat den Titel des Themas von „StringReplace“ zu „StringReplace nur auf jede 2. Doppelziffe anwenden“ geändert. -
Eingangsstring: "32 94 97 64 83 14 82 64 72" ; eigentliche Länge bis zu 200 zweistellige Zahlen.
Ausgangsstring: "32 06 97 36 83 86 82 36 72" ; so SOLL ES aussehenIch würde gerne jede zweite zweistellige Zahl "negativieren" (100 minus die Zahl).
Hi Lina !
Hier mal ein Lösungsvorschlag.
Ich bin nicht sicher, ob Du die Leerzeichen zwischen den zweistelligen Zahlen benötigst, oder ob sie hier nur zur optischen Trennung dienen.
Daher enthält das Skript beide Varianten (die nicht gewünschte einfach auskommentieren) .
AutoIt
Alles anzeigen#include <String.au3> ; Variante 1 mit Leerzeichen -> $iOffset = 3 ; ------------------------------------------- Local $sInput = "32 94 97 64 83 14 82 64 72" Local $iOffset = 3 , $sSubStr ; Variante 2 ohne Leerzeichen -> $iOffset = 2 ; ------------------------------------------- ;Local $sInput = "329497648314826472" ; ohne Leerzeichen -> $iOffset = 2 ;Local $iOffset = 2 , $sSubStr ConsoleWrite("Vorher = " & $sInput & @CRLF) ; *** nur zur Anzeige For $i = (1 + $iOffset) To StringLen($sInput) Step ($iOffset * 2) ; falls $iOffset = 3 $sSubStr = StringFormat("%02s", String(100 - Number(StringMid($sInput, $i, $iOffset)))) & " " ; falls $iOffset = 2 ;$sSubStr = StringFormat("%02s", String(100 - Number(StringMid($sInput, $i, $iOffset)))) $sInput = StringMid($sInput, 1, $i - 1) & $sSubStr & StringMid($sInput, $i + $iOffset, StringLen($sInput)) Next ConsoleWrite("Nachher = " & $sInput & @CRLF) ; *** nur zur Anzeige
-
Hallo Alina ,
hier mein Vorschlag mit einem Array, erstellt aus dem Code von Musashi , der eine sehr gute Vorlage lieferte:
AutoIt
Alles anzeigenLocal _ $Source = '32 94 97 64 83 14 82 64 72', _ $Array, $Target ConsoleWrite('Vorher = ' & $Source & @CRLF) ; *** nur zur Anzeige $Source = StringRegExpReplace($Source, ' +', ' ') ; Nur jeweils ein Trennzeichen sicherstellen $Array = StringSplit($Source, ' ') ; String aufteilen und Array erstellen For $i = 1 To $Array[0] If Mod($i, 2) = 0 Then _ ; Jeder zweite Eintrag $Array[$i] = StringFormat('%02s', String(100 - Number($Array[$i]))) $Target &= $Array[$i] & ' ' ; String wieder zusammenbauen Next $Target = StringTrimRight($Target, 1) ; Letztes Leerzeichen entfernen $Array = '' ; Array freigeben ConsoleWrite('Danach = ' & $Target & @CRLF) ; *** nur zur Anzeige
Dieser Code könnte jedoch langsamer, aber vielleicht leichter verständlich sein.
Gruß, fee
-
Du kannst auch mit StringRegExp dich Schrittweise durch den String hangeln (z.B. über den Offset-Parameter).
Dann hättest du ein bisschen mehr Flexibilität - z.B. eine Lösung für die Variante mit und ohne Leerzeichen:AutoIt
Alles anzeigenGlobal $sString = "32 94 97 64 83 14 82 64 72" ; Global $sString = "329497648314826472" Global $iPos = 1, $aMatch, $iLen Do $aMatch = StringRegExp($sString, '\G\s?\d\d\s?\K(\d\d)', 1, $iPos) If @error Then ExitLoop $iPos = @extended $iLen = StringLen($aMatch[0]) $sString = StringFormat("%s%02d%s", StringLeft($sString, $iPos - $iLen - 1), 100 - $aMatch[0], StringTrimLeft($sString, $iPos - 1)) Until 0 ConsoleWrite($sString & @CRLF)
-
So geht es auch:
AutoIt
Alles anzeigen#include <StringConstants.au3> _Calc("32 94 97 64 83 14 82 64 72") ; ==>> 32 06 97 36 83 86 82 36 72 _Calc("329497648314826472") ; ==>> 320697368386823672 Func _Calc($sEingangsstring) Local $aRx = StringRegExp($sEingangsstring, '\d{2}', $STR_REGEXPARRAYGLOBALMATCH) Local $sAusgangsstring, $sSpace = StringInStr($sEingangsstring, ' ') ? ' ' : '' For $i = 0 To UBound($aRx) -1 Step 1 $sAusgangsstring &= StringFormat('%02i%s', (Mod($i, 2) ? 100 - $aRx[$i] : $aRx[$i]), $sSpace) Next ConsoleWrite('> $sEingangsstring : ' & $sEingangsstring & @CRLF) ConsoleWrite('- $sAusgangsstring : ' & $sAusgangsstring & @CRLF & @CRLF) Return $sAusgangsstring EndFunc
-
If Mod($i, 2) = 0 Then _ ; Jeder zweite Eintrag
Das kannst du auch direkt mit dem For erledigen...
For $i = 1 To $Array[0] Step 2
-
-
Na gut, bei so vielen Lösungen fehlt ja eigentlich nur noch der obligatorische Einzeiler:
-
Bitnugger : Und wie erledigst du dann die Umwandlung des Arrays in einen String ohne zweite Schleife, vor allem wenn die Anzahl der Doppelziffern ungerade ist? Deinen Vorschlag hatte ich nämlich auch erst so geschrieben.
-
Und wie erledigst du dann die Umwandlung des Arrays in einen String ohne zweite Schleife, vor allem wenn die Anzahl der Doppelziffern ungerade ist?
So würde ich es dann machen:
AutoIt
Alles anzeigen_Calc('32 94 97 64 83 14 82 64 72') _Calc('32 94 97 64 83 14 82 64') _Calc('329497648314826472') _Calc('3294976483148264') 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]) Next $sTarget = $i = UBound($aArray) ? $sTarget & $aArray[$i -1] : StringTrimRight($sTarget, 1) ConsoleWrite('> Vorher = ' & $sSource & @CRLF) ; *** nur zur Anzeige ConsoleWrite('- Danach = ' & $sTarget & @CRLF) ; *** nur zur Anzeige ConsoleWrite(@CRLF) Return $sTarget EndFunc
-
Bitnugger : Die verbleibende Doppelziffer nach der Schleife anzuhängen hatte ich mir ein kleines bisschen aufwändiger vorgestellt. Aber so ist es bestimmt schneller als dieses Mod-Gedöns und auch einfach zu verstehen. Sehr schöne Lösung!
-
1.000 Dank an alle !
Das spart mir nun den Weg das ganze über Excel.
Die Eingangsdaten sind im Ordner m:\reno_u_gusv_dk\*.rns mit Leerzeichen getrennt gespeichert.
Die Ausgangsdaten sind im Ordner m:\reno_u_gusv_dk\*.rnt mit Leerzeichen getrennt gespeichert.
Edit 1:
@Bitnugger den Aufruf von Dir , ohne Leerzeichen, den kann ich für das hier bestehende Problem nicht verwenden, aber ich kann es wo anders einsetzten.
Edit 2:
Und wenn ich es wieder anders rum benötige kann ich es genauso durchlaufen lassen. Weil die 100 ja ein fester Wert ist. fee wandelt die 100 in 00 um und auch umgekehrt ! Das ist ja auch richtig. Bei den anderen Lösungen wird auch die 100 in 00 umgewandelt, aber umgekehrt kommt dann nicht wieder 100 raus.
Auf die Idee hätte ich auch kommen können. Aber nie Bedarf nach gehabt, weil es ja über Excel eh vorlag.
Nur jetzt werde ich mal sehen, das ich es irgendwie hin bekomme, das wenn eine neue *.rns im Ordner ist, das die *.rnt auftomatisch erstellt wird.
Das habe ich schon mal gemacht und irgendwo habe ich also die Lösung auf Festplatte oder DVD. -
fee wandelt die 100 in 00 um und auch umgekehrt ! Das ist ja auch richtig. Bei den anderen Lösungen wird auch die 100 in 00 umgewandelt, aber umgekehrt kommt dann nicht wieder 100 raus.
Am Anfang schriebst du, dass die Eingabezeichenfolge nur zweistellige Zahlen enthält. Finde ich zwar schön, dass mein Vorschlag deine erweiterte Aufgabe richtig löst, was aber nicht von mir beabsichtigt und vor allem nicht ganz deine Aufgabenstellung war.
Naja, besser so als anders herum.
Bei der Ordnerüberwachung kann ich dir allerdings nicht helfen, das habe ich noch nie gebraucht/gemacht.
Edit: Den Mod()-Teil in meinem Vorschlag würde ich allerdings durch den Vorschlag von Bitnugger in Beitrag #10 ersetzen, also der For-Schleife ein Step 2 verpassen und danach die letzte Doppelziffer an ungerader Position (sofern vorhanden) verarbeiten. Spart Laufzeit, denn Modulo ist leistungshungrig.
-
Am Anfang schriebst du, dass die Eingabezeichenfolge nur zweistellige Zahlen enthält. ...
Genau...
Ordnerüberwachung ist auch nicht schwierig...
AutoIt
Alles anzeigen#include <APIShellExConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.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 OnAutoItExitRegister('OnAutoItExit') _Main() Func _Main() Local $hWnd = GUICreate('') GUISetState() Local $iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY') GUIRegisterMsg($iMsg, 'WM_SHELLCHANGENOTIFY') $g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd, $iMsg, $SHCNE_ALLEVENTS, BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $g_sPath, 1) If @error Then MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Fehler', 'Das Fenster wurde nicht registriert.') Exit EndIf While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd EndFunc ;==>_Main Func WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local Static $bCreate = False Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData(DllStructCreate('dword Item1; dword Item2', $wParam), 'Item1')) If $sPath Then If $bCreate And ($lParam = $SHCNE_UPDATEITEM) Then ; 0x00002000 - nach $SHCNE_CREATE folgt immer ein $SHCNE_UPDATEITEM! If StringRight($sPath, 4) = '.rns' Then ConsoleWrite('! Neue *.rns gefunden!' & @CRLF) ConsoleWrite('> Event: 0x' & Hex($lParam) & ' ($SHCNE_UPDATEITEM) | Pfad: ' & $sPath & @CRLF) EndIf EndIf $bCreate = $lParam = $SHCNE_CREATE ; 0x00000002 Else ConsoleWrite('@ Event: 0x' & Hex($lParam) & @CRLF) EndIf EndFunc ;==>WM_SHELLCHANGENOTIFY Func OnAutoItExit() If $g_iID Then _WinAPI_ShellChangeNotifyDeregister($g_iID) EndFunc ;==>OnAutoItExit
-
Da habe ich mich falsch ausgedrückt?
Ja, die Eingabezeichenfolge ist ja auch immer zweistellig ! Alles gut !
Alles läuft nun bestens ! ! !
Die Ordnerüberwachung sehe ich mir morgen an. Gleich geht es ins Bett !
Das mit dem Mod Teil sehe ich mir dann auch an !
DANKE EUCH ! ! ! -
Alina : Gern geschehen!
Bitnugger : Die Ordnerüberwachung wäre vermutlich toll, aber
- fehlt ein #include <GUIConstantsEx.au3> (nicht schlimm) und
- bekomme ich unter Win7 Pro x64 nur ein Event: 0x00040000 nach Hinzufügen einer RNS-Datei im Ordner.
Leider verstehe ich (noch) nicht, warum.Edit:
Bitnugger : So funktioniert es jetzt bei mir auf Win7 Pro x64, wenn ich eine RNS-Datei im zu überwachenden Ordner erstelle:
AutoIt
Alles anzeigen#include <APIShellExConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WinAPIShellEx.au3> #include <WinAPISysWin.au3> Opt('TrayAutoPause', 0) Global Const $g_sPath = @ScriptDir ; Zu überwachende Verzeichnisse (String oder Array) Global $g_idEdit, $g_iID OnAutoItExitRegister('_OnAutoItExit') Exit _Main() Func _Main() Local $hWnd = GUICreate('FolderMonitoring', 300, 400) $g_idEdit = GUICtrlCreateEdit('', 10, 10, 280, 380, BitOR($ES_MULTILINE, $ES_READONLY)) GUISetState() WinSetOnTop($hWnd, '', 1) Local $iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY') GUIRegisterMsg($iMsg, '_WM_SHELLCHANGENOTIFY') $g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd, $iMsg, BitOR($SHCNE_ASSOCCHANGED, _ $SHCNE_CREATE), BitOR($SHCNRF_INTERRUPTLEVEL, _ $SHCNRF_SHELLLEVEL), $g_sPath, 0) If @error Then MsgBox(BitOR($MB_OK, $MB_ICONERROR, $MB_SYSTEMMODAL), 'Fehler', _ 'Das Fenster wurde nicht registriert!') Return 1 EndIf Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Return 0 EndFunc ;==>_Main Func _WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData( _ DllStructCreate('dword Item1;dword Item2', $wParam), 'Item1')) If $sPath Then If StringRight($sPath, 4) = '.rns' Then ControlSend($hWnd, '', $g_idEdit, '^{End}') GUICtrlSetData($g_idEdit, _ 'Neue *.rns gefunden!' & @CRLF & _ 'Event: 0x' & Hex($lParam) & @CRLF & _ 'Pfad: ' & $sPath & @CRLF & @CRLF, 1) EndIf Else ControlSend($hWnd, '', $g_idEdit, '^{End}') GUICtrlSetData($g_idEdit, 'Event: 0x' & Hex($lParam) & @CRLF & @CRLF, 1) EndIf EndFunc ;==>_WM_SHELLCHANGENOTIFY Func _OnAutoItExit() If $g_iID Then _WinAPI_ShellChangeNotifyDeregister($g_iID) EndFunc ;==>_OnAutoItExit
Eine RNS-Datei in einen andernen Dateityp umbenennen würde erkannt werden, umgekehrt jedoch nicht. $SHCNE_ALLEVENTS kann somit vom Erkennungsumfang her auf BitOR($SHCNE_ASSOCCHANGED, $SHCNE_CREATE) reduziert werden. Die rekursive Erkennung habe ich auch entfernt, um Leistung einzusparen. $SHCNE_UPDATEITEM tritt laut Beschreibung nur bei Veränderung des Inhaltes eines Elementes auf, hier also nicht nötig. $SHCNE_CREATE habe ich aus der Funktion _WM_SHELLCHANGENOTIFY() entfernt.
Die Beschreibung zu SHChangeNotifyRegister empfiehlt statt BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL) den Wert $SHCNRF_NEWDELIVERY in der Funktion _WinAPI_ShellChangeNotifyRegister():
Messages received use shared memory. Call SHChangeNotification_Lock to access the actual data. Call SHChangeNotification_Unlock to release the memory when done.
Note: We recommend this flag because it provides a more robust delivery method. All clients should specify this flag.
Den ersten Zitatsatz weiß ich leider nicht vollständig umzusetzen. Macht aber nix, für mich funktioniert es auch so.
-
fehlt ein #include <GUIConstantsEx.au3>
Oh ja, habe ich nun hinzugefügt...
Eine RNS-Datei in einen andernen Dateityp umbenennen würde erkannt werden, umgekehrt jedoch nicht.
Ja, will man das, muss die Abfrage entsprechen angepasst werden... den alten Namen bekommst du mit "Item1", den neuen mit "Item2".
$SHCNE_UPDATEITEM tritt laut Beschreibung nur bei Veränderung des Inhaltes eines Elementes auf, hier also nicht nötig.
Wir benötigen ja nicht nur den Namen des Pfades, sondern vor allem auch den Inhalt der Datei... den es aber evtl. noch nicht gibt, nachdem die Datei erstellt wurde ($SHCNE_CREATE) - z.B. mit FileOpen("filename.rns", $FO_OVERWRITE) - hier greift dann $SHCNE_UPDATEITEM, nachdem die Daten geschrieben wurden!
Da die Aufgabenstellung nur das Erkennen von neuen *.rns vorgibt, brauchen wir $SHCNE_CREATE und $SHCNE_UPDATEITEM, jedoch kein $SHCNE_ASSOCCHANGED. Das kann man natürlich auch noch abfragen, genauso wie $SHCNE_RENAMEITEM, wenn die Datei umbenannt wurde und nun vielleicht keine *.rns mehr ist. Das war aber nicht gefragt.
Den ersten Zitatsatz weiß ich leider nicht vollständig umzusetzen.
So habe ich das verstanden:
Durch $SHCNRF_NEWDELIVERY wird für empfangene Nachrichten gemeinsam genutzter Speicher verwendet. SHChangeNotification_Lock rufst du auf, um auf die eigentlichen Daten zuzugreifen. SHChangeNotification_Unlock rufst du auf, um den Speicher wieder freizugeben, wenn du fertig sind.
Schau mal hier, wie KaFu das gelöst hat.
Ansonsten... sehr schön umgesetzt.
Hier noch meine Version - die *.rnt wird hiermit auch erstellt:
AutoIt
Alles anzeigen;-- TIME_STAMP 2022-10-09 21:25:24 ;~ #include <Array.au3> ; _ArrayToString #include <APIShellExConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.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_idDummy OnAutoItExitRegister('OnAutoItExit') _Main() Func _Main() Local $hWnd = GUICreate(@ScriptName) $g_idDummy = GUICtrlCreateDummy() GUISetState() 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), _ 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) FileClose($hFile) EndSwitch WEnd EndFunc ;==>_Main Func WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg 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. ConsoleWrite(@CRLF & 'Case $SHCNE_ASSOCCHANGED' & @CRLF) Case $SHCNE_CREATE ; 0x00000002 A non-folder item has been created. If StringRight($sPath1, 4) = '.rns' Then ConsoleWrite(@CRLF & '! Neue *.rns gefunden!' & @CRLF & _ '> Event: 0x' & Hex($plEvent) & ' ($SHCNE_CREATE) ' & @CRLF & _ '> Pfad1: ' & $sPath1 & @CRLF) _SendToDummy($g_idDummy, $sPath1) EndIf Case $SHCNE_RENAMEITEM ; 0x00000001 The name of a non-folder item has changed. ConsoleWrite(@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 ConsoleWrite(@CRLF & '! Geänderte *.rns gefunden!' & @CRLF & _ '> Event: 0x' & Hex($plEvent) & ' ($SHCNE_UPDATEITEM) ' & @CRLF & _ '> Pfad1: ' & $sPath1 & @CRLF) _SendToDummy($g_idDummy, $sPath1) EndIf ;~ 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 ConsoleWrite('+ _SendToDummy: Die Datei ist '&$iFileSize&' Bytes gross ==>> ' & $sPath & @CRLF & @CRLF) GUICtrlSendToDummy($g_idDummy, $sPath) Else ConsoleWrite('! _SendToDummy: Die Datei ist leer! ==>> ' & $sPath & @CRLF & @CRLF) EndIf EndFunc ;==>_SendToDummy 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) ConsoleWrite('> Vorher = ' & $sSource & @CRLF) ; *** nur zur Anzeige ConsoleWrite('- Danach = ' & $sTarget & @CRLF & @CRLF) ; *** nur zur Anzeige Return $sTarget EndFunc ;==>_Calc Func OnAutoItExit() If $g_iID Then _WinAPI_ShellChangeNotifyDeregister($g_iID) EndFunc ;==>OnAutoItExit
-
@Bitnugger
Also das Umwandeln funktioniert TOP.
Das Anzeigen das eine neue Datei im Ordner ist erfolgt bei mir nicht. Die GUI baut auf, aber sie füllt sich nicht, sobald eine weitere Datei in den Ordner kommt. -
den alten Namen bekommst du mit "Item1", den neuen mit "Item2".
Okay, das wusste ich nicht.
Wir benötigen ja nicht nur den Namen des Pfades, sondern vor allem auch den Inhalt der Datei... den es aber evtl. noch nicht gibt, nachdem die Datei erstellt wurde ($SHCNE_CREATE) - z.B. mit FileOpen("filename.rns", $FO_OVERWRITE) - hier greift dann $SHCNE_UPDATEITEM, nachdem die Daten geschrieben wurden!
Ups, das hatte ich nicht bedacht.
jedoch kein $SHCNE_ASSOCCHANGED.
Das habe ich mit reingenommen, weil in der Beschreibung steht:
This event should also be sent for registered protocols.
Muss ich dann wohl missverstanden haben. Ein Dateityp ist ja kein Protokoll, oder?
Schau mal hier, wie KaFu das gelöst hat.
Uff, den *_Lock und *_Unlock-Teil hätte ich vielleicht noch hinbekommen können, aber allerspätestens bei _WinAPI_ShellChangeNotifyRegisterEx wäre für mich Schluss gewesen.
Ansonsten... sehr schön umgesetzt.
Danke dir.
Deine neue Version ebenso!
Alina :
Das Anzeigen das eine neue Datei im Ordner ist erfolgt bei mir nicht. Die GUI baut auf, aber sie füllt sich nicht, sobald eine weitere Datei in den Ordner kommt.
Klar, weil Bitnugger kein Edit-Element wie ich in die GUI eingebaut hat und Meldungen zum Debuggen in der SciTE-Konsole ausgeben lässt, sofern das Skript von SciTE aus gestartet wurde.
-
-