Ok bei einem tatsächlichen Netzlaufwerk (auf nen Samba-Server) bei mir bringt mir deine Funktion das:
Wäre das dann in der direkten Adressierung \\nas.lan\adm ?
Ok bei einem tatsächlichen Netzlaufwerk (auf nen Samba-Server) bei mir bringt mir deine Funktion das:
Wäre das dann in der direkten Adressierung \\nas.lan\adm ?
Nur eine Vermutung: Wenn du ein Netzlaufwerk eingerichtet hast, dann gilt das erst einmal nur für den User.
Stimmt genau, habe gerade mal eine Admin-Konsole geöffnet und versucht in das Laufwerk zu wechseln - wird nicht gefunden.
Das erklärt mir also warum das so ist. Zumindest kann ich das ja mit der Funktion aufdröseln.
Für mich war jetzt nur von Interesse, was passiert, wenn eine tatsächliche Netzlaufwerksverknüpfung durch _WinAPI_QueryDosDevice geschleust wird. Ich vermute mal ähnlich wie \Device\LanmanRedirector\;F:000000000009882e\localhost aber eben nicht mit localhost als Fortführung.
Hi,
wie ich feststellen musste, kommen nicht alle Programme mit Netzlaufwerksverknüpfungen auf lokale Ordner klar.
Ich habe z.B. gemappt: C:\Users\BugFix\Documents\_F auf Laufwerk F:
Ich habe mir nun eine Funktion erstellt, die den korrekten Pfad zurück gibt.
Habe leider keine echten Netzlaufwerke zum Testen, was dabei raus kommt. Wenn ihr bitte mal probieren könnt.
EDIT: Die Funktion ist jetzt so geändert, dass (hoffentlich) alle Mappings aufgelöst werden können.
#include <WinAPIFiles.au3>
; #FUNCTION# =======================================================================================
; Name ..........: _PathGetUnmapped
; Description ...: Resolving network links in paths to absolute paths
; Syntax ........: _PathGetUnmapped($_sPath)
; Parameters ....: $_sPath - The path to be checked.
; Return values .: The resolved path or the original path.
; Author ........: BugFix
; Remarks .......: Requires <WinAPIFiles.au3>
; ==================================================================================================
Func _PathGetUnmapped($_sPath)
If StringLeft($_sPath, 2) = '\\' Then Return $_sPath ; qualified network path
Local $aPath = StringRegExp($_sPath, '([A-Za-z]:)(.+)', 1)
Local $vReturn = _WinAPI_QueryDosDevice($aPath[0])
If StringRegExp($vReturn, '^\\Device\\LanmanRedirector') Then
If StringInStr($vReturn, 'localhost') Then
$vReturn = StringReplace(StringRegExpReplace($vReturn, '\\Device\\LanmanRedirector\\[^\\]+\\localhost\\', ''), '$', ':')
Else
$vReturn = '\' & StringRegExp($vReturn, '(\\Device\\LanmanRedirector\\;[^\\]+)(.+)', 1)[1]
EndIf
Return $vReturn & (UBound($aPath) = 2 ? $aPath[1] : '')
Else
$vReturn = StringRegExp($vReturn, '(\\Device\\[^\\]+\\;[^\\]+)(\\.+)', 1)
EndIf
If IsArray($vReturn) Then
Return '\' & $vReturn[1] & (UBound($aPath) = 2 ? $aPath[1] : '')
Else
Return $_sPath
EndIf
EndFunc
Alles anzeigen
Und Fehler sollten eigentlich von jedem Kommandozeilenprogramm nicht auf stdout ausgeben sondern auf stderr.
Es ist ja nicht so, dass mir das neu wäre. Aber es gibt so Tage... ![]()
git ist kein Befehl der cmd.exe sondern ein eigenständiges Programm. Es ist daher unsinnig es erst indirekt über den Umweg @comspec & "/c " aufzurufen.
War meinem C&P geschuldet, da ich die CmdLineRead-Funktion schon hatte. Aber klar, ohne Zweifel unsinnig.
Du musst StdOutRead() nicht unbedingt in einer Schleife ausführen. Es würde auch reichen den Prozess rödeln zu lassen und mit ProcessWaitClose() auf dessen Ende zu warten. Danach nur einmal StdOutRead() auf die Prozess-ID.
Passt. ![]()
2 Funktionen:
Ich führe in einer Konsole im Hintergrund git-Befehle aus und verwerte dann deren Rückgabe in die Konsole. Das klappt auch, solange ein Repo vorhanden ist.
Nun habe ich folgendes, für mich nicht erklärbares, Verhalten:
Wende ich eine git-Befehl in einem Ordner ohne Repository an, bekomme ich einen Fehler (ist auch gewünscht zur Auswertung) den ich jedoch nicht auffangen kann. Die Fehlermeldung landet in der Konsole des Aufrufs (SciTE) und die Return-Variable bleibt leer.
#include <AutoItConstants.au3>
; wechseln in Verzeichnis ohne Repo
FileChangeDir('C:\Users')
$Status = _GitStatus()
ConsoleWrite('<< Status >>' & @CRLF & $Status & @CRLF)
Func _GitStatus()
Return _CMDLineRead('git status')
EndFunc
Func _CMDLineRead($_sCMD)
Local $PID = Run(@ComSpec & " /c " & $_sCMD, "", @SW_HIDE, $STDOUT_CHILD)
Local $sLine, $sOutput = ''
While 1
$sLine = StdoutRead($PID)
If @error Then ExitLoop
$sOutput &= $sLine
WEnd
Return $sOutput
EndFunc
Alles anzeigen
Der Hook reagiert auch auf Scite
Ja, Danke.
Aber leider ist die Reaktion bei Verwendung des Split-Screen-Dialogs etwas ernüchternd:
Ohne Handle kann ich leider nicht erkennen, ob das von SciTE ausgelöst wurde.
EDIT: Als Alternative bliebe natürlich: Mit dem obigen Ergebnis könnte das von SciTE ausgelöst worden sein - Also löse ich eine Prüfung aus.
Aber ... nee, geht nicht - ich prüfe ja derzeit sowieso mit AdlibRegister im 350 ms Intervall und WinGetPos() liefert keine Änderung!
Also: Auf Verdacht neu zeichnen als letzte Alternative. ![]()
INFO: Habe das auch mal im EN-Forum gepostet https://www.autoitscript.com/forum/topic/21…ls_1529931_menu
vll hilft dieser beitrag von guiness https://www.autoitscript.com/forum/topic/15…napi-functions/
Hätte ich vllt. erwähnen sollen: Shellhook hatte ich bereits probiert. Ich habe dafür aber ausschließlich Bsp. für selbst erstellte Fenster gefunden (damit funktioniert das) - mit Fremdfenstern habe ich bisher keinen Erfolg gehabt. ![]()
Bei Win 11 kann ich mit Maus über Max-Button auf dem aufpoppenden Fenster auswählen, wie der Bildschirm geteilt wird und welche Position mein Fenster dann einnimmt. Das ist grundsätzlich erst mal schön.
Mein Problem:
Wie hier erwähnt, schreibe ich ein AddOn zur Nutzung von Git in SciTE. Unter anderem habe ich in die SciTE-Toolbar Icons integriert zur Anzeige von Status und Anzahl von untracked files (oder modified).
Sieht dann so aus
kein Repo vorhanden Repo ist aktuell Repo - 7 Dateien untracked Repo - >9 Dateien untracked

Ich zeichne die Icon mit WinAPI-Funktionen in die Toolbar. Bei Neuzeichnen des SciTE-Fensters geht das natürlich verloren und muss ebenfalls neu gezeichnet werden.
Das kann ich grundsätzlich prima abfangen, indem ich einen Größenvergleich (pos/size) des Fensters durchführe und bei Änderung neu zeichne. Fenster verschieben / Größe ändern / Minimieren / Maximieren - alles führt zur Änderung bei WinGetPos.
Nur halt die Größenänderung über den Max-Button, wie anfangs beschrieben. ändert die auf diese Weise abgefragte Fenstergröße nicht. ![]()
Habt ihr eine Idee?
Hier mein Skript ( P.S. - Das Skript muss von Hand abgeschossen werden, ist zum Dauerlauf gedacht
)
#include <GuiToolbar.au3>
#include <WinAPIShellEx.au3>
;---------------------------------------------------------------------------------------------------
Global $ICO = @ScriptDir & '\ico\'
Global $mIcon[]
$mIcon['IsRepo'] = $ICO & 'git_hasrepo.ico'
$mIcon['NoRepo'] = $ICO & 'git_norepo.ico'
$mIcon['Changing'] = $ICO & 'git_repo-w-changings.ico'
For $i = 1 To 9
$mIcon[$i] = $ICO & $i & '_16.ico'
Next
$mIcon[99] = $ICO & '9+_16.ico' ; >9 files
;---------------------------------------------------------------------------------------------------
Global $gm_SciTE[]
$gm_SciTE.hWnd = 0
$gm_SciTE.ExistsLast = 0
$gm_SciTE.ExistsCurr = 0
$gm_SciTE.WinArrayLast = 0
$gm_SciTE.WinArrayCurr = 0
$gm_SciTE.bReDraw = False
$gm_SciTE.aStatusIcon = 0
$gm_SciTE.aCounterIcon = 0
$gm_SciTE.StatusIcon = Null
$gm_SciTE.CounterIcon = Null
;---------------------------------------------------------------------------------------------------
_SciTEToolBar_DrawIconGitStatus('Changing')
_SciTEToolBar_DrawIconGitCounter(99)
;---------------------------------------------------------------------------------------------------
_CheckSciTE()
AdlibRegister(_CheckSciTE, 1000)
While True
Sleep(5000)
WEnd
Func _End()
AdlibUnRegister(_CheckSciTE)
Exit
EndFunc
Func _CheckSciTE()
If ProcessExists("SciTE.exe") Then
Local $hScite, $hToolbar, $hStatusbar
_GetSciTEhWnd($hScite, $hToolbar, $hStatusbar)
$gm_SciTE.ExistsCurr = 1
If $gm_SciTE.ExistsLast = 0 Then
$gm_SciTE.ExistsLast = 1
$gm_SciTE.hWnd = $hScite
AdlibRegister(_CheckReDraw, 350)
EndIf
Else
$gm_SciTE.ExistsCurr = 0
If $gm_SciTE.ExistsLast = 1 Then
$gm_SciTE.ExistsLast = 0
$gm_SciTE.hWnd = 0
AdlibUnRegister(_CheckReDraw)
EndIf
EndIf
EndFunc
Func _CheckReDraw()
; check if size/pos has changed (after min/max the pos has also changed)
$gm_SciTE.WinArrayCurr = WinGetPos($gm_SciTE.hWnd)
Local $bChanged = False
If IsArray($gm_SciTE.WinArrayLast) Then
$bChanged = _WinSizeDiff() ; if Diff returns: True
Else
$bChanged = True
EndIf
$gm_SciTE.bReDraw = $bChanged
_ReDraw()
EndFunc
Func _WinSizeDiff()
If ($gm_SciTE.WinArrayLast[0] <> $gm_SciTE.WinArrayCurr[0]) Or _
($gm_SciTE.WinArrayLast[1] <> $gm_SciTE.WinArrayCurr[1]) Or _
($gm_SciTE.WinArrayLast[2] <> $gm_SciTE.WinArrayCurr[2]) Or _
($gm_SciTE.WinArrayLast[3] <> $gm_SciTE.WinArrayCurr[3]) Then
Return True
Else
Return False
EndIf
EndFunc
Func _ReDraw()
If Not $gm_SciTE.bReDraw Then
Return
Else
AdlibUnRegister(_CheckReDraw)
_SciTEToolBar_DrawIconGitStatus($gm_SciTE.StatusIcon)
_SciTEToolBar_DrawIconGitCounter($gm_SciTE.CounterIcon)
$gm_SciTE.WinArrayLast = $gm_SciTE.WinArrayCurr
AdlibRegister(_CheckReDraw, 350)
EndIf
EndFunc
Func _SciTEToolBar_DrawIconGitStatus($_sStatus) ; 'IsRepo', 'NoRepo', 'Changing'
$gm_SciTE.aStatusIcon = _SciTEToolBar_DrawIcon($mIcon[$_sStatus], True)
$gm_SciTE.StatusIcon = $_sStatus
EndFunc
Func _SciTEToolBar_DrawIconGitCounter($_iCounter) ; 1,2,3,4,5,6,7,8,9,99 0-Deletes the counter Icon
If $_iCounter = 0 Then
_SciTEToolBar_DeleteDrawedIcon($gm_SciTE.aCounterIcon)
$gm_SciTE.aCounterIcon = 0
$gm_SciTE.CounterIcon = Null
ElseIf $_iCounter = Null Then
Return
Else
$gm_SciTE.aCounterIcon = _SciTEToolBar_DrawIcon($mIcon[$_iCounter], True, 16)
$gm_SciTE.CounterIcon = $_iCounter
EndIf
EndFunc
Func _SciTEToolBar_DrawIcon($_sPathIcon, $_bDeleteBG=True, $_xRel2LastTBItem=Null)
Local $hScite, $hToolbar, $hStatusbar ; get SciTE handles
_GetSciTEhWnd($hScite, $hToolbar, $hStatusbar)
If @error Then Return SetError(1)
Local $aPadding = _GUICtrlToolbar_GetPadding($hToolbar)
Local $xPad = $aPadding[0]
Local $aLastItem = _GUICtrlToolbar_GetButtonRect($hToolbar, _
_GUICtrlToolbar_IndexToCommand($hToolbar, _GUICtrlToolbar_ButtonCount($hToolbar)-1))
Local $x = $_xRel2LastTBItem = Null ? $aLastItem[2] : ($aLastItem[2] + $xPad + $_xRel2LastTBItem)
Local $hDC = _WinAPI_GetDC($hToolbar)
If $_bDeleteBG Then ; Delete last icon by overwriting
Local $a[] = [$x+$xPad, 3, 16, 16]
_SciTEToolBar_DeleteDrawedIcon($a, $hDC)
EndIf
Local $hIcon = _WinAPI_ShellExtractIcon($_sPathIcon, 0, 16, 16)
Local $aIconDrawed[] = [$x+$xPad, 3, 16, 16]
_WinAPI_DrawIconEx($hDC, $x+$xPad, 3, $hIcon, 16, 16)
_WinAPI_DestroyIcon($hIcon)
_WinAPI_DeleteDC($hDC)
Return $aIconDrawed
EndFunc
Func _SciTEToolBar_DeleteDrawedIcon($_aIcon, $_hDC=Null) ; $_aIcon returned from _SciTEToolBar_DrawIcon
Local $tRect = DllStructCreate($tagRect), $bDelDC = False
$tRect.Left = $_aIcon[0]
$tRect.Top = $_aIcon[1]
$tRect.Right = $_aIcon[0] + $_aIcon[2]
$tRect.Bottom = $_aIcon[1] + $_aIcon[3]
If $_hDC = Null Then
Local $hScite, $hToolbar, $hStatusbar ; get SciTE handles
_GetSciTEhWnd($hScite, $hToolbar, $hStatusbar)
If @error Then Return SetError(1)
$_hDC = _WinAPI_GetDC($hToolbar)
$bDelDC = True
EndIf
Local $hBrush = _WinAPI_CreateSolidBrush(0xF0F0F0)
_WinAPI_FillRect($_hDC, $tRect, $hBrush)
_WinAPI_DeleteObject($hBrush)
If $bDelDC Then _WinAPI_DeleteDC($_hDC)
EndFunc
Func _GetSciTEhWnd(ByRef $_hScite, ByRef $_hToolbar, ByRef $_hStatusbar)
$hActive = WinGetHandle('[ACTIVE]')
$aResult = DllCall('user32.dll', "int", "GetClassNameW", "hwnd", $hActive, "wstr", "", "int", 4096)
If Not @error And $aResult[2] = 'SciTEWindow' Then
$_hScite = $hActive
$_hToolbar = ControlGetHandle($_hScite, '', '[CLASS:ToolbarWindow32; INSTANCE:1]')
$_hStatusbar = ControlGetHandle($_hScite, '', '[CLASS:msctls_statusbar32; INSTANCE:1]')
Return 1
Else
Return SetError(1)
EndIf
EndFunc
Alles anzeigen
![]()
Das sagt erst mal das Wesentliche dazu.
Für die SciTE-User:
Wenn git installiert ist, können alle Befehle in der SciTE-Konsole ausgeführt werden.
Ich werde mich mal ran setzen und eine rudimentäre Erweiterung für ScITE schreiben, die beim Speichern von Dateien erkennt
- ob diese zu einem Repository gehören
- ob daran Änderungen vorgenommen wurden - und dieses dann anzeigen (Konsole oder Statuszeile)
- evtl. die git-Kommandos noch ins Kontextmenü packen
- .... mir fällt sicher noch mehr ein
SciTE4AutoIt listet unter den Tools auf "Update Source in Version Repository". Da wird aber "TortoiseGit" verwendet. Es gibt dort Unterschiede zu git, ist wohl so ein bischen wie AutoIt und AHK, ![]()
Also ich habe es deshalb auch noch nicht verwendet.
Das Arbeiten mit der CMDLine geht doch mit AutoIt.
Func _CMDLineRead($_sCMD)
Local $PID = Run(@ComSpec & " /c " & $_sCMD, "", @SW_HIDE, $STDOUT_CHILD)
Local $sLine, $sOutput = ''
While 1
$sLine = StdoutRead($PID)
If @error Then ExitLoop
If StringStripWS($sLine, 8) <> '' Then $sOutput &= $sLine
WEnd
Return $sOutput
EndFunc
$group = _CMDLineRead("whoami /groups")
ConsoleWrite($group & @CRLF)
Alles anzeigen
Den Rückgabewert musst du natürlich noch auswerten.
Ich will mal noch einen Einzeiler in den Raum werfen... ![]()
$sektion = StringRegExp(FileRead($pathINI), '(?m)\[([^\]]+)\]\r\n[^\r\n]+\r\nPersnr=' & $sPersNr, 1)[0]
ConsoleWrite('+> Sektion: ' & $sektion & @CRLF)
Wobei hier zwingend ist, dass der Key "Persnr" der zweite Schlüssel unter dem Sektionsnamen ist. Anderenfalls muss für jede weiter Zeile vor "Persnr" eingefügt werden: [^\r\n]+\r\n
Manchmal komme ich mir vor, wie ein Schulanfänger. Nunja - Microsoft gibt sich ja auch viel Mühe, dass man sich so fühlt. ![]()
Allein die Namensgebung für die Funktionen in Excel sind zum Teil völlig von deren Wirkungsweise entkoppelt - ich vermute, dass einfach im Duden geblättert wurde und irgendwer bei Stop auf ein Wort zeigt. Bestes Bsp. - ich suchte eine Funktion, die einen Text in eine Zelladresse konvertiert. In meiner Einfalt habe ich vermutet "TextAlsAdresse" oder ähnlich. Da ich nichts fand, habe ich dann alle Funktionen quergelesen und bin fündig geworden bei "INDIREKT" !! ![]()
Also mit INDIREKT konnte ich, wenn auch recht umständlich, mein Problem lösen.
Ich habe ein Quelltabellenblatt, indem Daten erfasst werden, die relevanten Werte jeweils im Abstand von 53 Zeilen. Auf dem Zieltabellenblatt werden die Daten angezeigt im Abstand von 35 Zeilen. Ich möchte natürlich nur einmal den Zielbereich vorbereiten und dann im Block kopieren, wobei jeweils auf die korrekte nächste Zelle aus der Quelle zugegriffen wird. Ich hatte gehofft auf etwas in der Art: ReferenceShiftedRows(Quelle_Zelle, Shift, Ziel_Zelle, Shift).
Zum besseren Verständnis habe ich mal eine Abbildung der Situation erstellt. Ich kann mir nicht vorstellen, dass diese Situation ungewöhnlich ist, also vielleicht gibt es ja doch schon eine Funktion dafür und ich hab sie nur nicht entdeckt. - Wenns jemand weiß, bitte melden. ![]()
Die Funktionen müssen bereits mit allen gewünschten Varianten ausgestattet sein. Du könntest dann über eine INI zur Laufzeit steuern, welche Teile der Funktion ausgeführt werden.
Ich formuliere deine Frage mal um:
Um größtmögliche Verwirrung zu stiften, darf bei einer Ersetzungsoperation für die Ziffer 1 ein beliebiger Platzhalter aus der Gruppe [1,a,j,t] verwendet werden. Wie geht das?
Mein Tipp: Eine Funktion, die in einer Schleife nach den Vorkommen von "1" und sucht und mit Random aus der Gruppe das Ersetzungszeichen einfügt.
Jetzt habe ich die Funktion erweitert, sodass auch bei jedem Aufruf ein eindeutiger Wert erzeugt wird:
--[[
----------------------------------------------------------------------------------------------------
Creating a UUID using values from the SciTE registry table, os.clock and os.time
A unique value is generated for each call.
--------------------------------------------------------------------------------------------------]]
function GenerateSciTEUserUUID()
local GetHexRev = function(_s) return tonumber('0x'..tostring(_s):match('([A-F0-9]+)'):reverse()) end
local Dec2Hex = function(_d, _len, _raw)
local tNumstr = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}
local sRet, rest = '', 0
repeat
rest = (_d % 16) +1
sRet = tNumstr[rest]..sRet
_d = math.floor(_d/16)
until _d == 0
local len, lenret = _len or 8, sRet:len()
if lenret > len then sRet = sRet:sub(-1*len) end
if _raw ~= nil then return ('0'):rep(len-lenret)..sRet end
return tonumber('0x'..('0'):rep(len-lenret)..sRet)
end
local rTime = function()
local s, ms = tostring(os.clock()):match('(%d+)%.(%d+)')
local datedigits = os.date():gsub('%D','') return s*ms*datedigits
end
local Addend = function() return Dec2Hex(rTime()) end
local tReg = debug.getregistry()
local tVal = {GetHexRev(tReg['_IO_output'])+Addend(),GetHexRev(tReg['SciTE_MT_Props'])+Addend(),
GetHexRev(tReg['SciTE_InitialPackageState'])+Addend(),GetHexRev(tReg['LUABOX'])+Addend(),
GetHexRev(tReg['SciTE_MT_Pane'])+Addend(),GetHexRev(tReg['SciTE_BufferData_Array'])+Addend()}
local uuid =
tostring(Dec2Hex(tVal[1],8,1))..'-'..
tostring(Dec2Hex(tVal[2],4,1))..'-'..
tostring(Dec2Hex(tVal[3],4,1))..'-'..
tostring(Dec2Hex(tVal[4],4,1))..'-'..
tostring(Dec2Hex(tVal[5],8,1))..tostring(Dec2Hex(tVal[6],4,1))
return uuid
end -- GenerateSciTEUserUUID()
Alles anzeigen
Funktion dafür ist in SciTE4AutoIt bereits enthalten ( Common.lua; Common:ReplaceCharacters(p, r) ).
Jedes Vorkommen des über das Pattern p definierten Ausdrucks wird durch r ersetzt. Position des Carets und Ansicht im Editor werden beibehalten.
Meine Lösung ist vom Funktionsumfang her identisch. Ich habe nur einen anderen Weg gewählt, um die Caretposition und Anzeigezeile zu ermitteln und zu setzen. Dafür brauchte ich auch die Funktion: GenerateSciTEUserUUID()
--[[
----------------------------------------------------------------------------------------------------
Replaces each occurrence of an expression defined with a pattern with the passed string.
_pattern - the string pattern
_replacement - the replacement string
--------------------------------------------------------------------------------------------------]]
function ReplaceInEditor(_pattern, _replacement)
local pos = editor.CurrentPos
local line = editor:LineFromPosition(pos)
local column = editor.Column[pos]
local fvline = editor.FirstVisibleLine
local shiftline = line - fvline -- store difference from top
local uuid = GenerateSciTEUserUUID()
editor:BeginUndoAction()
editor:InsertText(pos, uuid) -- insert unique value to identify the caret position
local text = editor:GetText()
editor:SetText(text:gsub(_pattern, _replacement)) -- make the replacement(s)
pos = editor:GetText():find(uuid:gsub('%-', '%%-')) -1 -- search for the previous position of the cursor in the new text
local uuidline = editor:LineFromPosition(pos) -- current number from our marked line
local newfirstvisible = uuidline - shiftline -- to have the old distance
if newfirstvisible < 0 then newfirstvisible = 0 end
editor:SetSel(pos, pos + uuid:len())
editor:ReplaceSel('') -- remove the uuid
editor.FirstVisibleLine = newfirstvisible
editor:SetSel(pos, pos)
editor:EndUndoAction()
end -- ReplaceInEditor()
Alles anzeigen
Ich habs gerade gebraucht - falls noch jemand Bedarf hat:
--[[
----------------------------------------------------------------------------------------------------
Creating a UUID using values from the SciTE registry table
Parts that change their value:
W - after Windows has been (re)started
O - after SciTE was (re)opened
T - after the number of opened tabs has changed
--------------------------------------------------------------------------------------------------]]
function GenerateSciTEUserUUID()
local extract = function(s, count)
return tostring(s):match('([A-F0-9]+)'):reverse():sub(1, count)
end
local tSciTEREG = debug.getregistry()
local uuid =
tostring(extract(tSciTEREG['_IO_output'], 8)) .. '-' .. -- [W]
tostring(extract(tSciTEREG['SciTE_MT_Props'], 4)) .. '-' .. -- [W, O]
tostring(extract(tSciTEREG['SciTE_InitialPackageState'], 4)) .. '-' .. -- [W, O, T]
tostring(extract(tSciTEREG['LUABOX'], 4)) .. '-' .. -- [W, O]
tostring(extract(tSciTEREG['SciTE_MT_Pane'], 8)) .. -- [W, O, T]
tostring(extract(tSciTEREG['SciTE_BufferData_Array'], 4))
return uuid
end -- GenerateSciTEUserUUID()
Alles anzeigen
Beachten: Der Wert ändert sich nicht zwingend bei jedem Aufruf, sondern bei den angegebenen Ereignissen.
So ziemlich jeder Editor bietet das an, SciTE leider nicht.
Als kleine Neujahrsgabe wird diese Lücke hiermit gefüllt. Skript kompilieren, beim Windowsstart laden und dümpeln lassen. (zum Probieren mit F5: Zeile #7 Kommentar aufheben, dann habt ihr einen Hotkey zum Beenden.)
Die Geschwindigkeit könnt ihr variabel gestalten mit einer INI (EXE-Name.ini), 3 ist Standard, wenn keine INI vorhanden ist.
;-- TIME_STAMP 2024-01-02 15:58:13
#include <WinAPI.au3>
#include <WindowsConstants.au3>
OnAutoItExitRegister('OnAutoItExit')
;~ HotKeySet('^+q', '_Exit') ; Strg+Shift+Q - during testing
Global $iSpeed = 3 ; Factor for multiplying the wheel steps
Global $INI = StringTrimRight(@ScriptFullPath, 4) & '.ini'
If FileExists($INI) Then
$iSpeed = IniRead($INI, 'HScroll', 'speed', 3)
EndIf
Global $gSciTECmd
GUIRegisterMsg(74, "MY_WM_COPYDATA") ; $WM_COPYDATA = 74
Global Const $HC_ACTION = 0
Global $hStub_MouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam")
Global $hmod = _WinAPI_GetModuleHandle(0)
Global $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hStub_MouseProc), $hmod)
Global $hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
Global $hHookKey = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)
Global $gbShift = False, $gbCtrl = False
While True
Sleep(50)
WEnd
Func _MouseProc($nCode, $wParam, $lParam)
Local $tInfo, $wheelCount
$tInfo = DllStructCreate("int X;int Y;dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo", $lParam)
If $nCode < 0 Or _GetHwnd_SciTE() = Null Or $gbShift = False Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
If $nCode = $HC_ACTION Then
Switch $wParam
Case $WM_MOUSEWHEEL
$wheelCount = _WinAPI_HiWord($tInfo.mouseData)/120
SendSciTE_Command('extender:dostring do editor:LineScroll(' & $wheelCount*$iSpeed*(-1) & ',0) end')
EndSwitch
EndIf
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc
Func _KeyProc($nCode, $wParam, $lParam)
Local $tKEYHOOKS, $vkCode, $ID
$tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
If $nCode < 0 Or _GetHwnd_SciTE() = Null Then Return _WinAPI_CallNextHookEx($hHookKey, $nCode, $wParam, $lParam)
$vkCode = DllStructGetData($tKEYHOOKS, "vkCode")
If $wParam = $WM_KEYDOWN Then
If $vkCode = 0xA0 Or $vkCode = 0xA1 Then ; left or right shift-button pressed
$gbShift = True
ElseIf $vkCode = 0xA2 Or $vkCode = 0xA3 Then ; left or right ctrl-button pressed
$gbCtrl = True
EndIf
Else
Switch DllStructGetData($tKEYHOOKS, "flags")
Case 0x80, 0x81 ; 0x80= UP for 'normal' keys and left pairs, 0x81= UP for right pairs
If $vkCode = 0xA0 Or $vkCode = 0xA1 Then ; LShift, RShift
$gbShift = False
ElseIf $vkCode = 0xA2 Or $vkCode = 0xA3 Then ; LCtrl, RCtrl
$gbCtrl = False
EndIf
EndSwitch
EndIf
Return _WinAPI_CallNextHookEx($hHookKey, $nCode, $wParam, $lParam)
EndFunc
Func _Exit()
Exit
EndFunc
Func OnAutoItExit()
_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($hStub_MouseProc)
_WinAPI_UnhookWindowsHookEx($hHookKey)
DllCallbackFree($hStub_KeyProc)
EndFunc ;==>OnAutoItExit
Func _GetHwnd_SciTE()
Local $hScite = WinGetHandle('[ACTIVE]')
If _WinAPI_GetClassName($hScite) = 'SciTEWindow' Then
Return $hScite
Else
Return SetError(1, 0, Null)
EndIf
EndFunc
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
; by Jos
Func SendSciTE_Command($_sCmd, $Wait_For_Return_Info=0)
Local $WM_COPYDATA = 74
Local $Scite_hwnd = _GetHwndDirectorExtension() ; Get SciTE DIrector Handle
Local $My_Hwnd = GUICreate("AutoIt3-SciTE interface") ; Create GUI to receive SciTE info
Local $My_Dec_Hwnd = Dec(StringTrimLeft($My_Hwnd, 2)) ; Convert my Gui Handle to decimal
$_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('Ptr;DWord;Ptr')
DllStructSetData($COPYDATA, 1, 1)
DllStructSetData($COPYDATA, 2, StringLen($_sCmd) + 1)
DllStructSetData($COPYDATA, 3, DllStructGetPtr($CmdStruct))
$gSciTECmd = ''
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
Local $n = 0
While $gSciTECmd = '' Or $n < 10
Sleep(20)
$n += 1
WEnd
EndIf
Return $gSciTECmd
EndFunc ;==>SendSciTE_Command
Func MY_WM_COPYDATA($hWnd, $msg, $wParam, $lParam)
Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr', $lParam)
Local $gSciTECmdLen = DllStructGetData($COPYDATA, 2)
Local $CmdStruct = DllStructCreate('Char[' & $gSciTECmdLen+1 & ']',DllStructGetData($COPYDATA, 3))
$gSciTECmd = StringLeft(DllStructGetData($CmdStruct, 1), $gSciTECmdLen)
EndFunc ;==>MY_WM_COPYDATA
Alles anzeigen
Ich habe mal einen Anfang gemacht. Zu finden auf meinem Github-Acc.