Guck mal in die Hilfe unter Makros. ![]()
Beiträge von BugFix
-
-
Ich glaube nicht das Scite so etwas aktuell hat, da müsstest du dann selber Tätig werden und alle Zwischenschritte manuell abspeichern und ggf. mit Versionen versehen.
SciTE bringt das nicht mit, aber ich habs gemacht: SciTE - neues Skript für Timestamp / Versionierung

-
Zitat
Was das Schlüsselwort Dim betrifft, so ist seine empfohlene Verwendung darauf beschränkt, ein bestehendes Array zu leeren
Igittigitt, wer kommt denn auf solch kranke Ideen. Wenn sowas notwendig ist, dann sicher nicht nur einmalig. Dafür erstellt man einmal ein Leerarray (das dann z. B. $g_aEmpty heißt) und weist dieses dann jedes mal zu.
-
das Dim nicht mehr benutzt werden sollte, obwohl in der AutoIt-Hilfe kein Wort diesbezüglich zu finden ist
Und das ist auch völlig richtig. Denn unabhängig, ob die Hilfe das empfiehlt oder nicht, ist es sinnvoll, wenn man sich für das Deklarieren von Variablen entscheidet, dieses im korrekten Scope zu tun. Dim ist und bleibt unkonkret wischiwaschi und ist aus Gründen eines guten Styles besser außen vor zu lassen.
Soweit mein Senf dazu.
-
neu Version 0.3, s. Startpost
-
ANSI? ==>> UTF-8!
Jein.
Ich kann damit (sicher) ausschließlich die Zeichen des ANSI Zeichensatzes identifizieren. Natürlich nutze ich dazu deren UTF-8 Darstellung. Aber eine Erkennung aller Zeichen des UTF-8 Bereiches ist damit nicht gesichert. Ich habe nicht analysiert, wie das Verhalten von erstem Byte und Zeichenlänge bei allen deren Zeichen ist. Für den ANSI Bereich hat dazu eine kleine Schleife gereicht.

EDIT:
Ich habe mal die Kodierungsregeln für UTF8 näher angeschaut. Das lässt sich doch einfacher als vermutet umsetzen. Werde dann die Funktionen noch anpassen für den gesamten UTF8 Bereich.
-
Die erste Version der Toolsammlung hatte ich hier gepostet.
Da ich das aber sicher Schritt für Schritt erweitern werde, erstelle ich nun einen eigenen Thread dafür.
OVERVIEW
Code
Alles anzeigenUSAGE load module: module = require "ModuleName" function call: module:FunctionName() for nested module (like "StringOr") function call: module.StringOr:FunctionName() or assign nested module: strOr = module.StringOr function call: strOr:FunctionName() or load nested module only: strOr = (require "CommonTools").StringOr function call: strOr:FunctionName() REQUIRES module "conversion.lua" ( https://github.com/BugFix/Conversion/blob/master/conversion.lua ) ( https://autoit.de/thread/86555-konvertieren-zwischen-zahlensystemen-in-lua/?postID=695947#post695947 ) Content SYSTEM FileExists Checks if a file exists FolderCreate Creates a folder (if not exists) FolderExists Checks if a folder exists GetCurrentDir Returns the script directory GetFilesRecursive Returns a table with all recursive files (full path name) from given root. You can use filter for file type and attributes. GetFolderRecursive Returns a table with all recursive sub folders (full path name) from given root. You can use filter for attributes. OSNow Returns a table with date & time fields from now OSDate Returns a string with the current date as "YYYY-MM-DD" OSTime Returns a string with the current time as "hh:mm:ss" require_protected Load library protected EDITOR EditorCodingCookieLine Checks the current buffer for coding cookie. Returns the line number from this or nil. EditorDeleteLine Deletes the passed line number from editor. Returns line content if success. EditorGetCommentChar Returns the character(s) for a line comment of the passed file type (or default: from current buffer), if defined. EditorGetEOL Returns length, mode of EOL and the EOL character(s) in current SciTE buffer EditorMoveLine Moves a line in editor up/down by param count (negative=up/positive=down). EditorTabColPosInLine Returns column and position of previous/next TAB in passed line EditorTabReplace Replaces all TAB in the file currently open in SciTE MISC ASCIIcompare Comparison of two ASCII strings, optionally case-insensitive (default: case-sensitive), descending (default: ascending). Return of both strings in sorted order. EscapeMagic Escapes all magic characters in a string: ( ) . % + - * ? [ ^ $ InSensePattern Creates an insensitive pattern string ("Hallo" --> "[Hh][Aa][Ll][Ll][Oo]"). Ascii chars only! LineTabReplace Replaces TAB in a line with the number of spaces corresponding to the column. Power2And Checks if a passed uint value contains a given power of 2. PropExt Asks for propertie specified by filter.extension or extension Split Splits a string by the passed delimiter into a table (each character as one element only with ASCII characters) StringOr A nested module with string functions: .find / .gmatch / .gsub / .match Lua patterns do not support alternations. Therefore, these functions can be called here with a list of patterns applied to the string. The pattern works: "patt1 or patt2 or patt_n" StringOr.find Returns start/end of the first occurence of the first matching pattern. StringOr.gmatch Returns a table with all occurences of each matching pattern. StringOr.gsub Returns a string in which all (or _n) occurrences of each matching pattern are replaced. StringOr.match Returns the first occurence of the first matching pattern. StripSpaceChar Strip space characters (%s) from a string. StringUTF8Len Get the number of characters (not the number of bytes, like string.len) of a string with UTF8 characters StringUTF8Split Splits a string by the passed delimiter into a table (each character as one element with UTF8 characters too) Ternary The ternary operator as function (condition, if_true, if_false) Trim Trim a count of chars from a strings left or right side UrlEncode Returns the given string encoded for use in URL AU3 - SPECIFIC GetIncludePathes Returns a table with locations of AU3 - include files in the systemVersion 0.7 - 0.8
Codev 0.8 NEU: gekapseltes Modul: StringOr ( .find() / .gmatch() / .gsub() / .match() ) Lua-Stringpattern ermöglichen keine ODER-Pattern. In diesen Funktionen können dafür mehrere Pattern als Table übergeben werden. NEU: LineTabReplace() - Ersetzen von TAB mit Leerzeichen in einer Textzeile NEU: EditorTabReplace() - Ersetzen aller TAB in der aktuell in SciTE geöffneten Datei GEÄNDERT: Optionale Parameter ASCIIcompare(), (in)sensitiver Vergleich / Reihenfolge auf-/absteigend. Standard: sensitiv aufsteigend (nil, nil) v0.7 NEU: ASCIIcompare() - Vergleich zweier ASCII-StringsVersion 0.6
CodeNEU: PropExt() - Liest den Wert einer dateispezifischen Eigenschaft von "PROP.$(file.pattern.EXT)" od. "PROP.EXT" GEÄNDERT: Erkennung der Tabweite über die dateispezifische Eigenschaft "tab.size.filter_ext/ext" anstatt der allgemeingültigen "tabsize"Version 0.5
Da ich nicht extra eine Bit-Bibliothek einbinden wollte, habe ich eine BitAnd-ähnliche Funktion zum Prüfen von 2-er Potenzen in Summenwerten erstellt.
CodeNEU: Power2And() Prüft, ob ein Summenwert eine übergebene 2-er Potenz enthält (wie BitAnd, aber liefert true/false) GEÄNDERT: StripSpaceChar() Verwendet jetzt Power2And() zum Prüfen der FlagsVersion 0.4
CodeNEU: EditorTabColPosInLine() Ermittelt Spalte und Position des vorigen/nächsten Tab in übergebener/aktueller Zeile NEU: StripSpaceChar() Entfernt Leerzeichen von Strings, Flags adäquat zu AutoIt: StringStripWS GEÄNDERT: Split() Zusätzlicher Parameter um mögliche führende und folgende Leerzeichen von den gesplitteten Werten zu entfernenVersion 0.3
Statt der Begrenzung auf den ANSI Zeichensatz, wird für die neuen Funktionen jedes UTF8 Zeichen erkannt.
Dazu erforderlich: conversion.lua
Version 0.2
Ich habe mich schon oft geärgert, dass man Probleme mit den Stringfunktionen bekommt, wenn ANSI Zeichen im String sind. Die Funktion string.len ermittelt die Länge anhand der Bytes. Bei ASCII Zeichen passt das, aber nicht bei ANSI. Dort sind die Zeichen 2 oder 3 Byte lang. Meine Funktion StringAnsiLen ermittelt neben der korrekten Anzahl der Zeichen auch deren Byte-Position (Start,Ende) im String. Das ist besonders dann von Interesse, wenn ich mich im Editor zeichenweise bewegen möchte.
Auch beim Splitten eines Strings mit ANSI Zeichen in ein Table mit einzelnen Zeichen hat man die Probleme mit der Bytelänge. Das habe ich hier mit StringAnsiSplit gelöst.
Als weitere Funktion habe ich GetIncludePathes erstellt, da ich in verschiedenen Anwendungen die Speicherorte der Includes benötige.
geändert:
CodeStringUTF8Len Ermittelt die Anzahl der Zeichen (nicht - wie String.Len - die Anzahl der Bytes) bei Strings, die UTF8 Zeichen enthalten StringUTF8Split Splittet einen String und ohne Trennzeichen wird auch jedes UTF8 Zeichen korrekt als einzelner Eintrag erfasstCode ist jetzt zu viel für den Thread - nur als DL (oder auf Git - s. Signatur)
DL before: 13
-
Es geht nur um eine INFO-MSGBOX die am Programmanfang direkt aufgeht. Zu diesem Zeitpunkt hat der User die Maus wegen des Proggi-Starts sowieso noch in der Hand und bräuchte nur klicken, damit das Proggi weiter macht...
Wenn der Inhalt der MsgBox ohne jeden Einfluß auf das Programm ist, setze doch ein Timeout von 1s (oder länger, wenn mehr zu Lesen ist).
Es ist nicht möglich die Position des Buttons abzufragen und die Maus dorthin zu bewegen, weil das Skript pausiert, bis die MsgBox wieder verschwindet.
Alternative: Bastele dir eine eigene MsgBox, wenn dir die Mausposition so wichtig ist.
Du kannst natürlich die User auch animieren mal über den Tellerrand zu gucken und festzustellen, dass es eine Tastatur gibt, bei der mit einem ENTER die MsgBox zugeht.

-
Ich verwende in meinem SciTE ja ein Lua-Skript um den TimeStamp automatisch beim Speichern einzutragen.
Der TimeStamp hat eine durch Property festgelegte Zeile, in der er eingefügt wird.
Wenn ich jedoch ein Skript kompiliere, grätscht der Au3Wrapper ungefragt dazwischen, indem er
a) seine Direktiven im Skript hinterlegt (was ich nicht will und erst nach dem Kompilieren passiert und somit nicht erforderlich ist)
b) Diese Einträge werden einfach an den Skriptanfang gesetzt. Der User hat da andere Vorstellungen? - Ja leck mich, als Wrapper bin ich Chef!
Dadurch wandert natürlich der TimeStamp im Skript unter die Zeilen mit den Wrappereinträgen. Ich kann natürlich nach dem Kompilieren einfach nochmal Speichern und dann wird das mit meinem Lua-Skript korrigiert - viel schöner wäre es doch, wenn man das mittels AutoIt automatisiert. Der Wrapper kann per INI gesteuert werden und enthält einen Schlüssel zum Ausführen danach:
Nun habe ich ein Skript geschrieben, das mittels SciTE-Interface den Pfad der zum Kompilieren in SciTE geöffneten Datei holt, diese Datei in ein Array einliest und im Array die Zeilen an die gewollte Position verschiebt. Das funktioniert auch soweit, wie gewollt.
Jedoch das Rückschreiben in die Datei ist wirkungslos. Ich hatte eigentlich erwartet, dass "Run_After" auch tatsächlich erst nach Beendigung des Wrappers läuft. Aber dem scheint nicht so zu sein. Die letzte Aktion des Wrappers ist, wenn ich dessen Code jetzt richtig verstanden habe, dass die Änderungen, die er intern an einer Tmp-Datei durchführt, im Skript landen und der Inhalt anschließend in den Editor eingefügt wird. Somit sind meine zwischenzeitlichen Änderungen am Skript wieder futsch.
Die Bezeichnung "Run_After" ist somit m.M.n. irreführend und sollte heißen: "Run_After_Compile", ich hatte es nämlich als "Run_After_Wrapper" interpretiert.
Falls ihr aber eine Idee habt, wie man NACH Beendigung des Wrappers automatisch ein Skript startet - lasst hören.
Hier übrigens das Skript:
AutoIt: Au3WrapperRunAfter_MoveRegion.au3
Alles anzeigen;-- TIME_STAMP 2021-10-19 09:51:42 #cs • Au3Wrapper manipulates the file with AutoIt. The SciTE events doesn't work there. TimeStamp doesn't run and is moved by inserting the wrapper region. • This script runs after the Au3Wrapper, searches the start of the Wrapper region (#pragmas too) and moves all wrapper lines downwards, starting at line behind the TimeStamp The TimeStamp will moved to its right line from property: "TimeStamp.Type.Line" • Required: "\AutoIt3Wrapper\AutoIt3Wrapper.ini" [Other] Run_After="C:\CODE\AutoIt\Au3WrapperRunAfter_MoveRegion.exe" From "Help - SciTE4AutoIt3": Default AutoIt3Wrapper options can be set in AutoIt3Wrapper.ini which is stored in the %LOCALAPPDATA%\AutoIt v3\SciTE\AutoIt3Wrapper folder for the Installer version and ...\AutoIt3\SciTE\AutoIt3Wrapper folder for the portable version. There is an example ini file in the folder to serve as a template: ' This INI sets the Defaults for AutoIt3Wrapper which can be overridden by the Compiler Directives ' Use 1/y for Yes and 0/n for No on options like Run_AU3Check ' See documentation for an explanation on purpose of the fields and their values ' AutoIt section for Aut2Exe and AutoIt3 [Autoit] Aut2Exe= Icon= OutfileType= Compression= UseUpx= ' Resource update section [Res] Language= Comment= Description= Fileversion= LegalCopyright= Field1Name= Field1Value= Field2Name= Field2Value= [Other] Run_AU3Check= AU3Check_Stop_OnWarning= AU3Check_Parameter= Run_Before= Run_After= TempDir= ShowProgress= SciTE_STOPEXECUTE=^{END} SciTE_RESTART=^!{END} #ce #include <File.au3> #include <WinAPIConv.au3> #include <WinAPIConstants.au3> Global $g_SciTECmd GUIRegisterMsg(74, "MY_WM_COPYDATA") ; $WM_COPYDATA = 74 ; die vom Au3Wrapper geänderte Datei muss gelesen werden ; im Editor ist zu diesem Zeitpunkt noch der Inhalt vor der Wrapper-Ausführung ; Pfad der aktuell zum Kompilieren in SciTE geöffneten Datei Global $sFileCurr = _GetCurrentFile() ; ################ Direkter TEST des Skriptes mit <F5> und einer beliebigen au3-Datei mit Wrappereinträgen & verschobenem TimeStamp ;~ Global $sFileCurr = 'C:\CODE\AutoIt\Test\TestWrapper.au3' ; ################ ; in welcher Zeile muss der TimeStamp stehen (ohne Property Eintrag: 1) Global $propTimeStampLine = _GetProperty('TimeStamp.Type.Line') If $propTimeStampLine = '' Then $propTimeStampLine = 'au3=1' Global $iLineTimeStamp = StringRegExp($propTimeStampLine, '(?i)au3=(\d)', 1)[0] If $iLineTimeStamp < 1 Then $iLineTimeStamp = 1 ; die Wrapper-Region soll in die Zeile nach dem TimeStamp verschoben werden Global $iLineWrapper = $iLineTimeStamp +1 ; aktuelle Zeilennummern nach Ausführung des Wrappers Global $iCurrTimeStamp = Null, $iCurrPragmaStart = Null, $iCurrPragmaEnd = Null, $iCurrWrapperStart = Null Global $iCurrWrapperEnd = Null, $iCurrInclStart = Null, $iCurrInclEnd = Null ; Einlesen der Datei Global $aRead _FileReadToArray($sFileCurr, $aRead, 0) ; Zeilen mit Wrapper Start/End und TimeStamp suchen (Wrapper-Start od. pragma od. "Start added" ist immer in erster Zeile, wenn eingefügt) For $i = 0 To UBound($aRead) -1 If $iCurrInclStart = Null Then If StringRegExp($aRead[$i], '^; \*\*\* Start added by AutoIt3Wrapper \*\*\*') Then $iCurrInclStart = $i EndIf If $iCurrInclEnd = Null Then If StringRegExp($aRead[$i], '^; \*\*\* End added by AutoIt3Wrapper \*\*\*') Then $iCurrInclEnd = $i EndIf If $iCurrPragmaStart = Null Then If StringRegExp($aRead[$i], '^#pragma') Then $iCurrPragmaStart = $i Else If StringRegExp($aRead[$i], '^#pragma') Then $iCurrPragmaEnd = $i EndIf If $iCurrWrapperStart = Null Then If StringRegExp($aRead[$i], '^#Region ;\*\*\*\* Directives created by AutoIt3Wrapper_GUI \*\*\*\*') Then $iCurrWrapperStart = $i EndIf EndIf If $iCurrWrapperEnd = Null Then If StringRegExp($aRead[$i], '^#EndRegion ;\*\*\*\* Directives created by AutoIt3Wrapper_GUI \*\*\*\*') Then $iCurrWrapperEnd = $i EndIf EndIf If $iCurrTimeStamp = Null Then If StringRegExp($aRead[$i], '^;-- TIME_STAMP') Then $iCurrTimeStamp = $i $sTimeStamp = $aRead[$i] EndIf EndIf ; Bedingungen zum schnellstmöglichen Beenden der Suche (Skript wird nicht bis zum Ende durchsucht) If ($iCurrTimeStamp <> Null And $iCurrWrapperStart <> Null And $iCurrWrapperEnd <> Null) Or _ ; Wrapper-Region und TimeStamp vorhanden ($iCurrPragmaStart <> Null And $iCurrTimeStamp <> Null) Or _ ; Pragma und TimeStamp ($iCurrInclStart <> Null And $iCurrTimeStamp <> Null) Or _ ; Include und TimeStamp ($iCurrTimeStamp <> Null And $iCurrWrapperStart = Null) Or _ ; keine Wrapper-Region eingefügt aber TimeStamp ($iCurrTimeStamp = Null And $iCurrWrapperEnd <> Null And $i > ($iCurrWrapperEnd + $iLineTimeStamp)) Or _ ; Wrapper-Region aber kein TimeStamp (($iCurrWrapperStart = Null And $iCurrPragmaStart = Null And $iCurrInclStart = Null) And _ ; keine Wrapper/Pragma/Include-Region, kein TimeStamp $i > $iLineTimeStamp And $iCurrTimeStamp = Null) Then ExitLoop EndIf Next ; der tatsächlich belegte Wrapperbereich Global $iWrapperStart = $iCurrInclStart <> Null ? $iCurrInclStart : ($iCurrPragmaStart <> Null ? $iCurrPragmaStart : $iCurrWrapperStart) $iCurrPragmaEnd = $iCurrPragmaEnd <> Null ? $iCurrPragmaEnd : $iCurrPragmaStart Global $iWrapperEnd = $iCurrWrapperEnd <> Null ? $iCurrWrapperEnd : ($iCurrPragmaEnd <> Null ? $iCurrPragmaEnd : $iCurrInclEnd) Global $nWrapperLines = $iWrapperStart <> Null ? $iWrapperEnd - $iWrapperStart : 0 If $iWrapperStart = Null Then ; es wurde keine Wrapper-Region eingefügt Exit Else ; im Array den Wrapperbereich verschieben Global $iLineLast = $nWrapperLines + ($iLineWrapper -1) If $iLineLast < $iCurrTimeStamp Then $iLineLast = $iCurrTimeStamp Global $aLinesToMove[$iLineLast - $iWrapperEnd] Global $n = 0 ; zu verschiebene Zeile(n) unterhalb Wrapper-Region sammeln For $i = $iWrapperEnd +1 To $iLineLast $aLinesToMove[$n] = $aRead[$i] $n += 1 Next ; Wrapper-Region zeilenweise nach unten verschieben, beim letzten Eintrag beginnen For $i = $iLineLast To UBound($aLinesToMove) Step -1 $aRead[$i] = $aRead[$i - UBound($aLinesToMove)] Next ; evtl. Zeile des TimeStamp korrigieren Switch UBound($aLinesToMove) Case 1 ; alles OK - nur ein Eintrag, das ist der TimeStamp Case Else Global $iTmp, $sTmp $iTmp = $iCurrTimeStamp -$iWrapperEnd -1 ; Index TimeStamp in Array If $iTmp = $iLineTimeStamp -1 Then ; TimeStamp an richtigem Index ; do nothing Else If $iTmp = 0 Then $sTmp = $aLinesToMove[1] $aLinesToMove[1] = $aLinesToMove[0] $aLinesToMove[0] = $sTmp Else $sTmp = $aLinesToMove[$iTmp-1] $aLinesToMove[$iTmp-1] = $aLinesToMove[$iTmp] $aLinesToMove[$iTmp] = $sTmp EndIf EndIf EndSwitch ; Zeilen bis zum TimeStamp an richtiger Position eintragen For $i = 0 To UBound($aLinesToMove) -1 $aRead[$i] = $aLinesToMove[$i] Next ; ############################################################## TEST - nur Anzeige Array-Inhalt ;~ ConsoleWrite('+ =================================================================' & @CRLF) ;~ ConsoleWrite('+ Neuer Array-Inhalt bis incl. der Zeile, in der der TimeStamp war:' & @CRLF) ;~ ConsoleWrite('+ =================================================================' & @CRLF) ;~ For $i = 0 To $iLineLast ;~ ConsoleWrite($aRead[$i] & @CRLF) ;~ Next ; ############################################################################################## ; Datei mit den Änderungen der Reihenfolge aus Array überschreiben Global $hFileCurr = FileOpen($sFileCurr, 2+128) ; $FO_OVERWRITE (2), $FO_UTF8 (128) _FileWriteFromArray($hFileCurr, $aRead) FileClose($hFileCurr) EndIf ;=============================================================================== ; Function Name....: _GetCurrentFile ; Description......: Gibt den Pfad der aktuell im Editor geöffneten Datei zurück ; Parameter(s).....: keine ; Return Value(s)..: Dateipfad ; Author(s)........: BugFix ;=============================================================================== Func _GetCurrentFile() SendSciTE_Command("askfilename:", 1) Return StringReplace(StringTrimLeft($g_SciTECmd,StringInStr($g_SciTECmd, ':', 1, 3)), '\\', '\') EndFunc ;=============================================================================== ; Function Name....: _GetProperty ; Description......: Gibt den Wert für eine Property zurück ; Parameter(s).....: Property ; Return Value(s)..: Wert der Property ; Docu.............: http://www.scintilla.org/SciTEDoc.html od. "SciTE-Hilfe" --> "SciTE Documentation" ; Author(s)........: BugFix ;=============================================================================== Func _GetProperty($_sProperty) SendSciTE_Command("askproperty:" & $_sProperty, 1) Return StringTrimLeft($g_SciTECmd,StringInStr($g_SciTECmd, ':', 1, 4)) EndFunc #cs --> Diese Versionen sind für die Verwendung mit Umlauten gedacht. In meinem SciTE liefern sie jedoch immer nur '0' zurück. ;=============================================================================== ; Function Name....: _GetCurrentFile ; Description......: Gibt den Pfad der aktuell im Editor geöffneten Datei zurück ; Parameter(s).....: keine ; Return Value(s)..: Dateipfad ; Author(s)........: BugFix, Modified: Bitnugger ;=============================================================================== Func _GetCurrentFile() SendSciTE_Command("askfilename:", 1) Return StringReplace(StringTrimLeft(_WinAPI_MultiByteToWideChar(String($g_SciTECmd), 65001, $MB_PRECOMPOSED, True), StringInStr($g_SciTECmd, ':', 1, 1)), '\\', '\') EndFunc ;==>_GetCurrentFile ;=============================================================================== ; Function Name....: _GetProperty ; Description......: Gibt den Wert für eine Property zurück ; Parameter(s).....: Property ; Return Value(s)..: Wert der Property ; Docu.............: http://www.scintilla.org/SciTEDoc.html od. "SciTE-Hilfe" --> "SciTE Documentation" ; Author(s)........: BugFix, Modified: Bitnugger ;=============================================================================== Func _GetProperty($_sProperty) SendSciTE_Command("askproperty:" & $_sProperty, 1) ConsoleWrite('StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd... ' & StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd, ':', 1, 4)) & @CRLF) ;~ Return StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd, ':', 1, 4)) Return _WinAPI_MultiByteToWideChar(StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd, ':', 1, 4)), 65001, $MB_PRECOMPOSED, True) EndFunc ;==>_GetProperty #ce ; by BugFix Func _GetHwndDirectorExtension() Local $hActive = WinGetHandle('[ACTIVE]') Local $PIDActive = WinGetProcess($hActive) Local $aExtension = WinList("DirectorExtension") Local $PIDExt For $i = 1 To $aExtension[0][0] $PIDExt = WinGetProcess($aExtension[$i][1]) If $PIDExt = $PIDActive Then Return $aExtension[$i][1] Next EndFunc ;==>_GetHwndDirectorExtension ; by Jos Func SendSciTE_Command($_sCmd, $Wait_For_Return_Info = 0) Local Static $My_Hwnd = GUICreate("AutoIt3-SciTE interface") ; Create GUI to receive SciTE info Local Static $My_Dec_Hwnd = Dec(StringTrimLeft($My_Hwnd, 2)) ; Convert my Gui Handle to decimal Local Const $SCI_GETLINE = 0x0869 ; 2153 Local Const $WM_COPYDATA = 0x004A ; 74 Local Const $WM_GETTEXT = 0x000D ; 13 Local Const $WM_GETTEXTLENGTH = 0xE224 ; 57892 Local $Scite_hwnd = _GetHwndDirectorExtension() ; Get SciTE DIrector Handle $_sCmd = ":" & $My_Dec_Hwnd & ":" & $_sCmd ; Add dec my gui handle to commandline to tell SciTE where to send the return info Local $CmdStruct = DllStructCreate('CHAR[' & StringLen($_sCmd) + 1 & ']') DllStructSetData($CmdStruct, 1, $_sCmd) Local $COPYDATA = DllStructCreate('ULONG_PTR;DWORD;PTR') DllStructSetData($COPYDATA, 1, 1) DllStructSetData($COPYDATA, 2, StringLen($_sCmd) + 1) DllStructSetData($COPYDATA, 3, DllStructGetPtr($CmdStruct)) $g_SciTECmd = "" DllCall('User32.dll', 'None', 'SendMessage', _ 'HWnd', $Scite_hwnd, _ 'Int', $WM_COPYDATA, _ 'HWnd', $My_Hwnd, _ 'Ptr', DllStructGetPtr($COPYDATA)) ;~ GUIDelete($My_Hwnd) If $Wait_For_Return_Info Then For $x = 1 To 10 If $g_SciTECmd <> "" Then ExitLoop Sleep(20) Next $g_SciTECmd = StringTrimLeft($g_SciTECmd, StringLen(":" & $My_Dec_Hwnd & ":")) $g_SciTECmd = StringReplace($g_SciTECmd, "macro:stringinfo:", "") Return $g_SciTECmd EndIf EndFunc ;==>SendSciTE_Command ;~ https://docs.microsoft.com/en-us/windows/desktop/api/Winuser/ns-winuser-tagcopydatastruct ;~ typedef struct tagCOPYDATASTRUCT { ;~ ULONG_PTR dwData; --> ULONG_PTR ;~ DWORD cbData; --> DWORD ;~ PVOID lpData; --> PTR ;~ } COPYDATASTRUCT, *PCOPYDATASTRUCT; Func MY_WM_COPYDATA($hWnd, $msg, $wParam, $lParam) Local $COPYDATA = DllStructCreate('ULONG_PTR;DWORD;PTR', $lParam) Local $SciTECmdLen = DllStructGetData($COPYDATA, 2) Local $CmdStruct = DllStructCreate('CHAR[255]', DllStructGetData($COPYDATA, 3)) $g_SciTECmd = StringLeft(DllStructGetData($CmdStruct, 1), $SciTECmdLen) EndFunc ;==>MY_WM_COPYDATA -
Ich kompiliere ausschließlich 32bit. Das lief und läuft problemlos auf allen Systemen. Bei 64bit war (und ist?) das nicht immer der Fall. Und doppeltes Kompilieren mit Abfrage Systemumgebung ist mir zu overdressed. Ich habe auch noch keine Anwendung gefunden, die 64bit erfordert hätte. Und solange ich keinen echten Mehrwert davon habe, ändere ich das auch nicht.
Bei der Installation wähle ich ebenfalls 32bit.
-
Worauf bist du konkret gestoßen dass du dir überhaupt diesen Gedanken machst da eine Unterscheidung machen zu müssen?
Hmm, ich hatte eigentlich gedacht, dass mein Code-Bsp. das recht verständlich aufzeigt.
Ich versuche nochmal das zu abstrahieren:
Die UDF beinhaltet Funktionen, mit denen der Anwender GUI-Elemente in seiner GUI erstellt. Diese Ctrl haben durch die UDF festgelegte Eigenschaften, die von den Standards abweichen. Zu diesem Zweck muss die Auswertung dieser Ctrl auch innerhalb der UDF passieren, da sonst die UDF-spezifischen Eigenschaften der Ctrl nicht zum Tragen kommen.
Und da spielt es schon eine Rolle, welcher Event-Modus genutzt wird. Die alternative Nutzung des direkten Message Queues hatte ich ja ebenfalls als Möglichkeit erwähnt.
-
Bei CommonTools.FolderExists prüfst du ja nicht wirklich, ob _Folder ein Verzeichnis ist... weil du kein BitAND in Lua hast?
Ich prüfe nicht über die Attribute, sondern (genauso wirksam) über try-and error, indem ich versuche eine Datei in diesem Ordner zum Schreiben zu öffnen:
Lualocal file = _folder..'/CommonTools_Folder.Exists' local fh = io.open(file, 'w+') -- try to write to passed folder if fh ~= nil then fh:close() os.remove(file) return true else return false endApropos Bit-Library - ich hatte mir mal eine etwas veraltete Biblothek auf neuere Lua-Syntax angepasst (dort wurde noch table.getn verwendet) und funktional etwas erweitert:
Code
Alles anzeigen-- TIME_STAMP 2019-08-16 10:14:42 v 0.1 --[[--------------- LuaBit v0.4 ------------------- a bitwise operation lib for lua. http://luaforge.net/projects/bit/ How to use: ------------------- bit.bnot(n) -- bitwise not (~n) bit.band(m, n) -- bitwise and (m & n) bit.bor(m, n) -- bitwise or (m | n) bit.bxor(m, n) -- bitwise xor (m ^ n) bit.brshift(n, bits) -- right shift (n >> bits) bit.blshift(n, bits) -- left shift (n << bits) bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>) Please note that bit.brshift and bit.blshift only support number within 32 bits. 2 utility functions are provided too: bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence) -- high bits first bit.tonumb(bit_tbl) -- convert a bit table into a number ------------------- Under the MIT license. copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com) 2016 - The function table.getn is deprecated! added: table_getn instead of table.getn by @BugFix (autoit@bug-fix.info) changed: bit.band, bit.bor, bit.bxor now accepts more than two parameters by @BugFix (autoit@bug-fix.info) --]]--------------- do local function table_getn(_t) local n = 0 for _, __ in pairs(_t) do n = n + 1 end return n end ------------------------ -- bit lib implementions local function check_int(n) -- checking not float if(n - math.floor(n) > 0) then error("trying to use bitwise operation on non-integer!") end end local function to_bits(n) check_int(n) if(n < 0) then -- negative return to_bits(bit.bnot(math.abs(n)) + 1) end -- to bits table local tbl = {} local cnt = 1 while (n > 0) do local last = math.mod(n,2) if(last == 1) then tbl[cnt] = 1 else tbl[cnt] = 0 end n = (n-last)/2 cnt = cnt + 1 end return tbl end local function tbl_to_number(tbl) -- local n = table.getn(tbl) local n = table_getn(tbl) local rslt = 0 local power = 1 for i = 1, n do rslt = rslt + tbl[i]*power power = power*2 end return rslt end local function expand(tbl_m, tbl_n) local big = {} local small = {} -- if(table.getn(tbl_m) > table.getn(tbl_n)) then if(table_getn(tbl_m) > table_getn(tbl_n)) then big = tbl_m small = tbl_n else big = tbl_n small = tbl_m end -- expand small -- for i = table.getn(small) + 1, table.getn(big) do for i = table_getn(small) + 1, table_getn(big) do small[i] = 0 end end local function bit_or(m, n) local tbl_m = to_bits(m) local tbl_n = to_bits(n) expand(tbl_m, tbl_n) local tbl = {} -- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) local rslt = math.max(table_getn(tbl_m), table_getn(tbl_n)) for i = 1, rslt do if(tbl_m[i]== 0 and tbl_n[i] == 0) then tbl[i] = 0 else tbl[i] = 1 end end return tbl_to_number(tbl) end local function bit_or_multi(...) local args = {...} if #args == 1 then return args[1] end local res = args[1] for i = 2, #args do res = bit_or(res, args[i]) end return res end local function bit_and(m, n) local tbl_m = to_bits(m) local tbl_n = to_bits(n) expand(tbl_m, tbl_n) local tbl = {} -- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) local rslt = math.max(table_getn(tbl_m), table_getn(tbl_n)) for i = 1, rslt do if(tbl_m[i]== 0 or tbl_n[i] == 0) then tbl[i] = 0 else tbl[i] = 1 end end return tbl_to_number(tbl) end local function bit_and_multi(...) local args = {...} if #args == 1 then return args[1] end local res = args[1] for i = 2, #args do res = bit_and(res, args[i]) end return res end local function bit_not(n) local tbl = to_bits(n) -- local size = math.max(table.getn(tbl), 32) local size = math.max(table_getn(tbl), 32) for i = 1, size do if(tbl[i] == 1) then tbl[i] = 0 else tbl[i] = 1 end end return tbl_to_number(tbl) end local function bit_xor(m, n) local tbl_m = to_bits(m) local tbl_n = to_bits(n) expand(tbl_m, tbl_n) local tbl = {} -- local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) local rslt = math.max(table_getn(tbl_m), table_getn(tbl_n)) for i = 1, rslt do if(tbl_m[i] ~= tbl_n[i]) then tbl[i] = 1 else tbl[i] = 0 end end --table.foreach(tbl, print) return tbl_to_number(tbl) end local function bit_xor_multi(...) local args = {...} if #args == 1 then return args[1] end local res = args[1] for i = 2, #args do res = bit_xor(res, args[i]) end return res end local function bit_rshift(n, bits) check_int(n) local high_bit = 0 if(n < 0) then -- negative n = bit_not(math.abs(n)) + 1 high_bit = 2147483648 -- 0x80000000 end for i=1, bits do n = n/2 n = bit_or(math.floor(n), high_bit) end return math.floor(n) end -- logic rightshift assures zero filling shift local function bit_logic_rshift(n, bits) check_int(n) if(n < 0) then -- negative n = bit_not(math.abs(n)) + 1 end for i=1, bits do n = n/2 end return math.floor(n) end local function bit_lshift(n, bits) check_int(n) if(n < 0) then -- negative n = bit_not(math.abs(n)) + 1 end for i=1, bits do n = n*2 end return bit_and(n, 4294967295) -- 0xFFFFFFFF end local function bit_xor2(m, n) local rhs = bit_or(bit_not(m), bit_not(n)) local lhs = bit_or(m, n) local rslt = bit_and(lhs, rhs) return rslt end -------------------- -- bit lib interface bit = { -- bit operations bnot = bit_not, -- band = bit_and, band = bit_and_multi, -- bor = bit_or, bor = bit_or_multi, -- bxor = bit_xor, bxor = bit_xor_multi, brshift = bit_rshift, blshift = bit_lshift, bxor2 = bit_xor2, blogic_rshift = bit_logic_rshift, -- utility func tobits = to_bits, tonumb = tbl_to_number, } return bit end --[[ for i = 1, 100 do for j = 1, 100 do if(bit.bxor(i, j) ~= bit.bxor2(i, j)) then error("bit.xor failed.") end end end --]] -
Edit: Bekomme folgenden Fehler angezeigt...
f:\\AutoIt\\AutoIt3_LuaScripts\TimeStampBackup.lua:76: bad argument #1 to 'PositionFromLine' (number expected, got nil)
OK, das kann nur passieren wenn "'TimeStamp.Type.Line'" nicht gesetzt ist. Da muss ich wohl die Fehlerabfrage erweitern.
Jetzt nervt mich nur, dass die AutoIt3Wrapper_GUI die eingefügten Zeilen an den Anfang des Scripts setzt und der TimeStamp dann nicht mehr in der gewünschten Zeile steht.
Ja, das stimmt - ist nervig. Ich reagiere ja auf "OnBeforeSave". Anscheinend nutzt der Wrapper auch das Event. Somit muss ich mal versuchen, ob ich zusätzlich "OnSave" auswerten kann um auf Einträge des Wrappers zu reagieren. Ich hoffe nur, dass sich da nichts beißt und ich in einem Loop lande.

Ich würde gerne Verzeichnisse/Dateinamen angeben, bei denen kein TimeStamp eingefügt und auch kein Backup gemacht wird. Das hatte ich mir in der alten Version eingebaut.
Werde ich mit aufnehmen in der nächsten Version.
Zudem, denke ich, musst du dein Script Au3OptMustDeclareVars.lua anpassen... denn das verschiebt den TimeStamp evtl. wieder in die erste Zeile, oder in eine andere, falls beim Speichern bereits Text eingegeben wurde.
Da hast du leider Recht.
-
Ich hatte ja bereits ein Skript (AutoStampSaveVersion) zum Einfügen eines TimeStamp und dem Erstellen eines Versionsbackups gefertigt.
Das habe ich nun nochmal komplett überarbeitet. Wesentliche Funktionen, die auch für andere Skripte nutzbar sind, habe ich in das Modul "CommonTools.lua" ausgelagert.
Das Skript kommt ohne die shell.dll aus (falls vorhanden - und von der verwendeten SciTE-Version ladbar - wird sie aber genutzt).
Vesion 0.3
Version 0.2
CodeNEU: CheckExclude() Prüft vor Backup ob Ausnahmen für bestimmte Ordner-/Dateinamen bestehen. (s. Properties)Einige Properties haben neue Namen und Wirkungsweisen, hier mal mein Properties-Block für TimeStamp:
Code: SciTEUser.properties
Alles anzeigen#======================================================================== TIMESTAMP & BACKUP ======= #~ TimeStamp, which file type and line in script: type=#line-number TimeStamp.Type.Line=au3=1|lua=1|py=3 #~ Coding-Cookie (if exists) should use which line (1 or 2) #~ will moved after setting time stamp to its correct line Coding.Cookie=lua=2|py=2 #~ Use version-backup for following file types: EXT|EXT.. Version.BackUp.Files=au3|lua #~ Ignore backup for files from these folders/drives (pipe-delimited list) #~ not case sensitive #~ i.e.: =C:\Program Files|C:\Program Files (x86)|E: Version.Backup.Exclude.Dirs= #~ Ignore backup for files with these names (or string pattern), (pipe-delimited list) #~ not case sensitive #~ i.e. #~ file name starts with 'Test': "^Test" #~ file name ends with 'Test': "Test$" #~ If the exception is to apply only to a specific file type, append suffix. This is checked separately. #~ i.e. #~ Lua - file name starts with 'Test': "^Test.lua" --> checks file name for find("^Test") and compares the file type "lua" Version.Backup.Exclude.Files= #~ optional general prefix for backup folder Version.Prefix=BUVer_ #~ Path for version backup folder [VER_DIR]: #~ URGENT!: Path NOT in quotation! #~ NO following backslash! #~ "Version.Path.*=default" - creates subdirectory in current script folder (likewise if property does not exist or has no value) #~ Folder name: $(Version.Path.ext)\$(Version.Prefix)FILENAME.EXT\ #~ File name: \FILENAME[Version-Number].EXT Version.Path.au3=C:\Code\VersionBackup\au3 Version.Path.lua=C:\Code\VersionBackup\lua #======================================================================== \TIMESTAMP & BACKUP ======Es wird also die gewünschte Zeile für den TimeStamp des Dateityps angegeben. Sollte die Datei noch leer sein landet der TimeStamp in Zeile 1, wird beim Speichern der Datei mit Inhalt dann aber verschoben, falls anders angegeben.
Es werden jetzt die korrekten EOL für die aktuelle Datei ausgelesen und verwendet. Dadurch stimmt nun auch die Cursorposition nach dem Speichern.
Wenn die Datei ein Coding-Cookie enthält, welches beim Einfügen des TimeStamp aus dem Erkennungsbereich (Zeile 1 & 2) verschoben wurde, wird das Cookie in die Zeile 2 verschoben.
Der TimeStamp kann grundsätzlich in jeder Zeile stehen. Falls ein Cooding-Cooking vorhanden ist und dieses sich in der Zielzeile des TimeStamp befindet, genießt das Coding-Cookie Priorität und der TimeStamp wird danach platziert.
Beim Speichern sprang die Ansicht immer zur Cursorposition - jetzt bleibt sie unverändert.
Nochmals kurz zur Installation (ausführlich habe ich das in einem eigenen Post beschrieben):
- Moduldatei "CommonTools.lua" speichern (in eigenem Lua-Skripte Ordner - diesen dann in der "SciTEStartup.lua" den package.path zufügen - oder in "..\SciTE\Lua"
- "TimeStampBackup.lua" speichern
- Die Datei muss beim SciTE-Start geladen werden, dazu diese in der "SciTEStartup.lua" eintragen (LoadLuaFile).
Wie geht's?
- Bei jedem Speichern wird der TimeStamp in der vordefinierten Zeile eingetragen/aktualisiert
- Ist der Dateityp für das Backup registriert, wird beim ersten Speichern der TimeStamp mit der Versionsnummer "v 0.1" eingetragen und die Datei als Backup mit dieser Version gespeichert.
- Möchte man für die aktuelle Datei das Backup vermeiden, obwohl es für den Dateityp aktiv ist, muss man an die erste Position im Editor ein Asterisk * eintragen (wird beim Speichern wieder entfernt). Es wird dann nur der TimeStamp ohne Versionierung eingetragen.
- Um ein erneutes Speichern eines Backups zu erreichen, muss hinter den vorhandenen TimeStamp ein Marker gesetzt werden:
• "v" Beim Speichern wird die SubVersion hochgezählt, die Mainversion wird beibehalten.
• "V" Beim Speichern wird die MainVersion hochgezählt, die Subversion wird zurück auf "0" gesetzt.
• "n" Eine neue Versionsnummer wird von Hand vergeben, indem man die vorhandene vor dem Speichern überschreibt (z.B. für Versionssprung)
- Soll eine Datei, die nur einen TimeStamp enthält ohne Versionsnummer jetzt in das Backup übernommen werden, braucht einfach nur die Zeile mit dem TimeStamp gelöscht werden.
Code: TimeStampBackup.lua
Alles anzeigen-- TIME_STAMP 2021-11-12 10:16:58 v 0.3 -- coding:utf-8 --[[ event: OnBeforeSave SciTEUser.properties: #======================================================================== TIMESTAMP & BACKUP ======= #~ TimeStamp, which file type and line in script: type=#line-number TimeStamp.Type.Line=au3=1|lua=1|py=3 #~ Coding-Cookie (if exists) should use which line (1 or 2) #~ will moved after setting time stamp to its correct line Coding.Cookie=lua=2|py=2 #~ Use version-backup for following file types: EXT|EXT.. Version.BackUp.Files=au3|lua #~ Ignore backup for files from these folders/drives (pipe-delimited list) #~ not case sensitive #~ i.e.: =C:\Program Files|C:\Program Files (x86)|E: Version.Backup.Exclude.Dirs= #~ Ignore backup for files with these names (or string pattern), (pipe-delimited list) #~ not case sensitive #~ i.e. #~ file name starts with 'Test': "^Test" #~ file name ends with 'Test': "Test$" #~ If the exception is to apply only to a specific file type, append suffix. This is checked separately. #~ i.e. #~ Lua - file name starts with 'Test': "^Test.lua" --> checks file name for find("^Test") and compares the file type "lua" Version.Backup.Exclude.Files= #~ optional general prefix for backup folder Version.Prefix=BUVer_ #~ Path for version backup folder [VER_DIR]: #~ URGENT!: Path NOT in quotation! #~ NO following backslash! #~ "Version.Path.*=default" - creates subdirectory in current script folder (likewise if property does not exist or has no value) #~ Folder name: $(Version.Path.ext)\$(Version.Prefix)FILENAME.EXT\ #~ File name: \FILENAME[Version-Number].EXT Version.Path.au3=C:\Code\VersionBackup\au3 Version.Path.lua=C:\Code\VersionBackup\lua #======================================================================== \TIMESTAMP & BACKUP ====== ]] -- v 0.3 fixed: Incorrect use of Lua comments with additional characters ("--~" or others) -- v 0.2 added: CheckExclude() local ct = require "CommonTools" -- min v 0.4 TimeStamp = EventClass:new(Common) TimeStamp.OnBeforeSave = function(self, _file) local tFile = {Dir = props['FileDir'], Name = props['FileName'], Ext = props['FileExt']:lower()} local tSetStamp, tCookie = {}, {} -- File types to set time-stamp/move coding-cookie for ext, line in (props['TimeStamp.Type.Line']):gmatch('([^|=]+)=([^|]+)') do tSetStamp[ext] = line -1 end for ext, line in (props['Coding.Cookie']):gmatch('([^|=]+)=([^|]+)') do tCookie[ext] = line -1 end local tWriteBackup = {} -- File types to write version backup for ext in (props['Version.BackUp.Files']):gmatch('([^|]+)') do tWriteBackup[ext] = true end -- check excludes if self:CheckExclude(tFile) then tWriteBackup[tFile.Ext] = nil end -- check conditions to call the function if tFile.Ext == nil or (tSetStamp[tFile.Ext] == nil and tWriteBackup[tFile.Ext] == nil) then return nil end -- call function self:Insert(tFile, tSetStamp[tFile.Ext], tCookie[tFile.Ext], (tWriteBackup[tFile.Ext] ~= nil)) return nil end TimeStamp.CheckExclude = function(self, _tFile) local propExDirs, tExDirs = props['Version.Backup.Exclude.Dirs'], {} if propExDirs ~= '' then tExDirs = ct:Split(propExDirs, '|', true) end local propExFiles, tExFiles = props['Version.Backup.Exclude.Files'], {} if propExFiles ~= '' then tExFiles = ct:Split(propExFiles, '|', true) end if #tExDirs > 0 then for i=1, #tExDirs do if tExDirs[i]:lower():find('^'.._tFile.Dir:lower()) then return true end end end if #tExFiles > 0 then for i=1, #tExFiles do local ext = tExFiles[i]:lower():match('%.(%w+)$') if ext ~= nil then if ext == _tFile.Ext then local name = tExFiles[i]:lower():match('^(.+)%.'..ext..'$') if _tFile.Name:lower():find(name) then return true end end else if _tFile.Name:lower():find(tExFiles[i]:lower()) then return true end end end end return false end TimeStamp.SaveToVersionFolder = function (self, _tFile, _sVer) local sSaveFolder = props['Version.Path.'.._tFile.Ext]:lower() if sSaveFolder == '' then sSaveFolder = 'default' end local sPrefix = props['Version.Prefix'] local sVerFolder = sPrefix.._tFile.Name..'.'.._tFile.Ext..'\\' local sVerFile = _tFile.Name..'['.._sVer:sub(3, _sVer:len())..']'..'.'.._tFile.Ext if sSaveFolder == 'default' then sSaveFolder = _tFile.Dir..'\\' end local len = sSaveFolder:len() if sSaveFolder:sub(len, len) ~= '\\' then sSaveFolder = sSaveFolder..'\\' end if not ct:FileExists(sSaveFolder..sVerFolder) then ct:FolderCreate(sSaveFolder..sVerFolder) end if ct:FileExists(sSaveFolder..sVerFolder..sVerFile) then return nil end local fh = io.open(sSaveFolder..sVerFolder..sVerFile, "wb") local text = editor:GetText() fh:write(text) fh:close() return end TimeStamp.Insert = function (self, _tFile, _lineStamp, _lineCookie, _bBackup) local firstVisible, lineDiff = editor.FirstVisibleLine, 0 local sCmntChar = ct:EditorGetCommentChar(_tFile.Ext) if sCmntChar:find('^--') then sCmntChar = '' end -- the time stamps starts as default with "--" local pattCmntChar = ct:EscapeMagic(sCmntChar) if _tFile.Ext == 'au3' then sCmntChar = ';' pattCmntChar = ';' end -- avoid multi char comment like ";~" local len_eol, _, eol = ct:EditorGetEOL() local caret = editor.CurrentPos -- Checks (for max. 50 lines) if TimeStamp and/or coding-cookie exists and stores the informations local lineNum, lineText, lineLen, lineHome, lineCookie for l = 0, 49 do lineText, lineLen = editor:GetLine(l) if lineLen == nil then break end lineHome = editor:PositionFromLine(l) local a, y = lineText:find("^"..pattCmntChar.."%-+ TIME_STAMP.*()"..eol) if y ~= nil then lineNum = l break end end if lineNum == nil then -- none time stamp exists lineText = '' lineLen = 0 lineHome = editor:PositionFromLine(_lineStamp) end if _tFile.Ext ~= 'au3' then lineCookie = ct:EditorCodingCookieLine(50) end editor:BeginUndoAction() local mustSave, space, bStampNew, bFirst = 0, ' ', false, false local sVer, sVerMain, sVerSub = '', 0, 0 if lineNum ~= nil then -- if time stamp exists, check for main/sub number sVerMain, sVerSub = lineText:match('%s-v%s(%d+)%.(%d+)') if _bBackup == true then local verMark = lineText:match("([vVn])"..eol) if sVerMain ~= nil then if verMark == 'V' then sVer = 'v '..tostring(tonumber(sVerMain) +1)..'.0' elseif verMark == 'v' then sVer = 'v '..sVerMain..'.'..tostring(tonumber(sVerSub) +1) elseif verMark == 'n' or verMark == nil then sVer = 'v '..sVerMain..'.'..sVerSub end mustSave = 1 else -- time stamp has no version number space = '' end end else -- none time stamp exists bStampNew = true lineNum = _lineStamp if _bBackup == false then space = '' else -- first backup editor:SetSel(0,1) -- is it marked to avoid backup in this case? if editor:GetSelText() == '*' then -- with asterisk at first editor position: no backup will saved, only time stamp are print space = '' editor:ReplaceSel('') bFirst = true else sVer = 'v 0.1' mustSave = 1 end end end local stamp = sCmntChar.."-- TIME_STAMP "..ct:OSDate().." "..ct:OSTime()..space..sVer..eol if bFirst == true then caret = caret - stamp:len() end if bStampNew == true then lineDiff = 1 editor:InsertText(editor:PositionFromLine(lineNum), stamp) else local stampLineEnd = lineHome + lineLen editor:SetSel(lineHome, stampLineEnd) editor:ReplaceSel(stamp) end -- is TimeStamp in line from property --> if not, move it if lineNum ~= _lineStamp then ct:EditorMoveLine(lineNum, _lineStamp-lineNum) -- target.line - current.line = count_to_move (-up/+down) end -- if coding cookie exists, be sure it has the line as set in properties, cookie has priority if lineCookie ~= nil then lineCookie = ct:EditorCodingCookieLine(50) -- might have been moved --> search again if (lineCookie ~= _lineCookie) then ct:EditorMoveLine(lineCookie, _lineCookie-lineCookie) end end editor.FirstVisibleLine = firstVisible + lineDiff if mustSave == 1 then self:SaveToVersionFolder(_tFile, sVer) end if lineDiff == 1 then caret = caret + stamp:len() end editor:SetSel(caret,caret) editor:EndUndoAction() end -
Oh nee, diese UDF ist mal gar nicht up to date. Da sind sicher etliche Dinge verbesserungswürdig. Aber ob ich da noch mal dran gehe....
-
Das Script zum Schreiben der Textdateien hat leider nicht funktioniert. SciTE meckerte immer beim zweiten Apostroph irgendwas von falscher Anzahl von Args an.
Oops, na klar. Habe das "On The Fly" runtergeschrieben ohne Syntaxtest. Es fehlt natürlich das WAS zu schreiben ist, ist hier dann wumpe und kann ein Leerstring sein.

-
Könntest Du mir ein Beispiel schreiben mit allgemeinen Parametern, welches ich mir dann apassen kann? Vielleicht für 2 Programmstarts, damit ich sehe, wie die Hirarchie aufgebaut sein muss.
Ist wirklich einfach:
AutoIt
Alles anzeigen; PC auf dem Programme gestartet werden sollen ; Skript als Task bei PC-Start ausführen ; Freigabe $Share = "\\PC1\Run\" While True Sleep(5000) If FileExists($Share & 'P1.txt') Then _Run_Prog('P1') ElseIf FileExists($Share & 'P2.txt') Then _Run_Prog('P2') EndIf WEnd Func _Run_Prog($_p) ; zu startende Programme (Bsp.) Local $P1 = 'notepad.exe' Local $P2 = 'calc.exe' Switch $_p Case 'P1' ShellExecute($P1) ; oder Run() mit Parametern - z.B. SW_HIDE Case 'P2' ShellExecute($P2) EndSwitch FileDelete($Share & $_p & '.txt') EndFunc -
Bisher wird der Text eben abgeschnitten wenn das Fenster verkleinert wird anstatt angepasst..
Das Resizing hat nur Einfluss auf die Abmessung des Labels, die Fontgröße hat damit nichts zu tun. Wenn du das zusätzlich anpassen möchtest, musst du WM_SIZING auswerten und im Verhältnis zur Größenänderung die Schriftgröße anpassen.
Aber den Zahn kann ich dir gleich ziehen - denn das funktioniert einfach nicht!
Ursache: Durch das Ermitteln des Verhältnisses musst du zwangsläufig runden. Die Rundungsdifferenzen führen dazu, dass bei mehrfacher Größenänderung du niemals zurück zur Anfangsgröße gelangst. Irgendwann wird die Schrift dann überproportional groß oder klein. Habe ich schon mal probiert.
-
Ich hatte mal in einem Netzwerk irgendwelche Rechteprobleme und es war mir zu blöd da meine Zeit zu verschwenden. Ich habe eine recht simple Lösung gefunden, da der Zugriff auf Freigaben funktionierte:
Auf dem PC, wo ein Programm gestartet werden soll, dümpelt ein AutoIt Skript und prüft jede Sekunde ob eine Datei "start.txt" in der Freigabe existiert. Wenn ja - lokal das gewünschte Programm starten und die Datei wieder löschen. Du musst also vom Remote PC nur diese Datei in die Freigabe schreiben.
Das erspart das Gefrickel mit Client-Server Konstrukten und funktioniert problemlos.
[OT]
Dieses Jahr trete ich auch dem Club der "60" bei.

[/OT]
-
Nachtrag:
In der Version im vorigen Post hatte ich die Reihenfolge der Fenster aus WinList ausgelesen, musste nun aber feststellen, dass WinList diese Liste ungeordnet erstellt. Somit wurde bei gleicher Klasse immer auf das zuerst erstellte Fenster zugegriffen.
Habe ich in dieser Version korrigiert. Zusätzlich noch einen Fehler beim Auslesen aus Rootlaufwerken (Backslash wurde als Pfad mit übernommen).
AutoIt: _GetSelectionFromTopMostExplorer
Alles anzeigen#include <WinAPIProc.au3> #include <WinAPISys.au3> #cs #include <Array.au3> $aTest = _GetSelectionFromTopMostExplorer() _ArrayDisplay($aTest) $aTest = _GetSelectionFromTopMostExplorer(False) _ArrayDisplay($aTest) #ce ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GetSelectionFromTopMostExplorer ; Description ...: Gets an array with selected files from the top most explorer window ; Syntax ........: _GetSelectionFromTopMostExplorer([$_bDir = True]) ; Parameters ....: $_bDir - [optional] Returns the full path (Default 'True'). With 'False' will only the filename returned. ; Return values .: Array with selected files. Counter at $ar[0] ; Requires.......: _GetTopmostHwndFromProcess() ; Author ........: BugFix ; =============================================================================================================================== Func _GetSelectionFromTopMostExplorer($_bDir=True) Local $oShell = ObjCreate("Shell.Application") Local $oIE, $sPath = '', $oShellWindows = $oShell.Windows Local $oDoc, $bIE = False, $oFV For $i = 0 To $oShellWindows.Count -1 ; all opened explorer and internet explorer windows $oIE = $oShellWindows($i) $oDoc = $oIE.Document If _GetTopmostHwndFromProcess('explorer.exe', 'CabinetWClass') = $oIE.Hwnd Then If StringRegExp(ObjName($oDoc), "IShellFolderViewDual.") Then ; be sure it's the explorer object $sPath = StringReplace(StringReplace(StringTrimLeft($oIE.LocationURL, 8), '%20', ' '), '/', '\') ; extract windows path from file-url $sPath = StringRegExpReplace($sPath, '(\\)$', '') ; "C:\" --> "C:" $bIE = True ; flag: found explorer EndIf EndIf Next Local $aSelection[500] = [0] If $bIE Then $oFV = $oIE.Document ; File-Browser (ShellFolderView) If Not $_bDir Then $sPath = '' For $oFI In $oFV.SelectedItems ; selected elements there $aSelection[0] += 1 If $aSelection[0] > UBound($aSelection) Then ReDim $aSelection[UBound($aSelection) +500] $aSelection[$aSelection[0]] = StringFormat('%s%s%s', $sPath, ($_bDir ? '\' : ''), $oFI.Name) Next EndIf If $aSelection[0] = 0 Then ReDim $aSelection[1] Else ReDim $aSelection[$aSelection[0]+1] EndIf Return $aSelection EndFunc ;==>_GetSelectionFromTopMostExplorer ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GetTopmostHwndFromProcess ; Description ...: Returns the handle of the top most window of a specific process ; Syntax ........: _GetTopmostHwndFromProcess($_vProcess) ; Parameters ....: $_vProcess The Process name or PID ; $_sClass The classname of windows that will created by the specific process ; Return values .: Success The handle of the top most window ; Failure 0, set @error = 1 (process does not exists) ; @error = 2 (there is no window for this) ; Author ........: BugFix ; =============================================================================================================================== Func _GetTopmostHwndFromProcess($_vProcess, $_sClass) Local $aProc[2][2] = [[1],['',$_vProcess]] If IsString($_vProcess) Then $aProc = ProcessList($_vProcess) If $aProc[0][0] = 0 Then Return SetError(1,0,0) EndIf Else If Not ProcessExists($_vProcess) Then Return SetError(1,0,0) EndIf ; get the highest z-order Local $hWnd = 0, $aWin = _WinAPI_EnumDesktopWindows(_WinAPI_GetThreadDesktop(_WinAPI_GetCurrentThreadId()), False) For $i = 1 To $aWin[0][0] If $aWin[$i][1] = $_sClass Then ; first found window of this class has the highest z-order $hWnd = $aWin[$i][0] ExitLoop EndIf Next If $hWnd = 0 Then Return SetError(2,0,0) Local $tPID = DllStructCreate("int PID") For $i = 1 To $aProc[0][0] DllCall("user32.dll", "int", "GetWindowThreadProcessId", "hwnd", $hWnd, "ptr", DllStructGetPtr($tPID)) If $tPID.PID = $aProc[$i][1] Then Return $hWnd Next Return 0 EndFunc ;==>_GetTopmostHwndFromProcess