OffTopic:
weil mich das schon länger irritiert:
Ab 19-10-22 ergänzt um:
Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)
OffTopic:
weil mich das schon länger irritiert:
Ab 19-10-22 ergänzt um:
Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)
Moin Peter S. Taler,
... eine DB habe ich genauso schnell aufgesetzt ...
Das wird auch nicht auf die Zehntelsekunde stimmen, aber schau mal da: Command Line Shell For SQLite
Es dauert zumindest nicht viel länger.
Moin,
wenn eine 32-Bit-Anwendung auf einem 64-Bit-Windows laufen soll, stellt das System dieser Anwendung eine spezielle 32-Bit-Umgebung zur Verfügung. Das nennt sich WOW (Windows on Windows). Dabei kann natürlich immer mal etwas schief laufen. Ich würde deshalb prinzipiell auf einem 64-Bit-System AutoIt64 benutzen, soweit es möglich ist.
Es gibt allerdings einige Kommunikationsprobleme zwischen 32- und 64-Bit-Anwendungen. Wenn man 32-Bit-Anwendungen nutzt, die man mit AutoIt steuern will, kann das mit AutoIt32 leichter sein.
#Region ;************ Includes ************
#include <Array.au3>
#include <WinAPIRes.au3>
#EndRegion ;************ Includes ************
; ~#AutoIt3Wrapper_UseX64=Y
MsgBox(0, "", "Is64-Bit: " & @AutoItX64)
Global $aINM, $LV, $LHT, $IHM
$IconFile = @ScriptDir & "\Extracted.ico"
FileDelete($IconFile)
_ExtractIconToFile(@SystemDir & "\shell32.dll", -42, $IconFile)
If Not FileExists($IconFile) Then MsgBox(0, 0, "Datei wurde nicht gespeichert")
; #FUNCTION# =============================================================================================
; Name...........: _ExtractIconToFile
; Description ...: Extract an icon resource from a cpl, dll, exe, icl, ocx to a *.ico file
; Syntax.........: _ExtractIconToFile($sInFile, $iIcon, $sOutIco[, $iPath = 0])
; Parameters ....: $sInFile - Path to file that contains the icon to extract.
; $iIcon - Icon Number to extract, eg; -1 (The first icon starts at -1)
; $sOutIco - Full path where to save the extracted icon to, eg; "C:\My Icons\new.ico"
; $iPath - If set to 1 then the extraction path will be created if it doesn't exist.
; If left as 0 then if the extraction path doesn't exist it won't be created.
; Return values .: Success - Return 1 and @error 0
; Failure - Return 0 and @error 1 ~ 12
; @error 1 = Invalid $sInFile parameter
; @error 2 = Invalid $iIcon parameter
; @error 3 = LoadLibrary failed to return a valid ptr
; @error 4 = $iIcon does not exist in the $sInFile
; @error 5 = Failed to Find RT_GROUP_ICON Resource
; @error 6 = Returned RT_GROUP_ICON Resource as 0 bytes
; @error 7 = Failed to Load RT_GROUP_ICON Resource
; @error 8 = Failed to Lock RT_GROUP_ICON Resource
; @error 9 = Failed to create DLL Struct for RT_GROUP_ICON data
; @error 10 = Data in DLL Struct is null
; @error 11 = Failed to Open output file path
; @error 12 = Failed to write file at output path
; (Most the error returns were for my own debug purpose)
; Author ........: smashly
; Modified.......:
; Remarks .......: A big Thank You to Siao for the heads up on _ResourceEnumNames & ___EnumResNameProc
; Also Thank You to WeaponX for his _StringSplitRegExp
; Related .......:
; Link ..........;
; Example .......; _ExtractIconToFile(@SystemDir & "\shell32.dll", -42, @HomeDrive & "\Extracted.ico")
; ========================================================================================================
Func _ExtractIconToFile($sInFile, $iIcon, $sOutIco, $iPath = 0)
Local $hInstance, $iGN = "", $hResource, $iSize, $hData, $pData, $tRes, $sDByte
Local $sData, $sHdr, $iOrd, $aHtail, $iCnt, $Offset, $FO, $iCrt = 18
If $iPath = 1 Then $iCrt = 26
If Not FileExists($sInFile) Then Return SetError(1, 0, 0)
If Not IsInt($iIcon) Then Return SetError(2, 0, 0)
$hInstance = _WinAPI_LoadLibraryEx($sInFile, $LOAD_LIBRARY_AS_DATAFILE)
If Not IsPtr($hInstance) Then Return SetError(3, 0, 0)
$aINM = _WinAPI_EnumResourceNames($hInstance, $RT_GROUP_ICON)
For $i = 1 To $aINM[0]
If $i = StringReplace($iIcon, "-", "") Then
$iGN = $aINM[$i]
ExitLoop
EndIf
Next
If $iGN = "" Then
_WinAPI_FreeLibrary($hInstance)
Return SetError(4, 0, 0)
EndIf
$hResource = _WinAPI_FindResource($hInstance, $RT_GROUP_ICON, $iGN)
If $hResource = 0 Then
_WinAPI_FreeLibrary($hInstance)
Return SetError(5, 0, 0)
EndIf
$iSize = _WinAPI_SizeOfResource($hInstance, $hResource)
If $iSize = 0 Then
_WinAPI_FreeLibrary($hInstance)
Return SetError(6, 0, 0)
EndIf
$hData = _WinAPI_LoadResource($hInstance, $hResource)
If $hData = 0 Then
_WinAPI_FreeLibrary($hInstance)
Return SetError(7, 0, 0)
EndIf
$pData = _WinAPI_LockResource($hData)
If $pData = 0 Then
_WinAPI_FreeLibrary($hInstance)
Return SetError(8, 0, 0)
EndIf
$tRes = DllStructCreate("byte[" & $iSize & "]", $pData)
If Not IsDllStruct($tRes) Then
_WinAPI_FreeLibrary($hInstance)
Return SetError(9, 0, 0)
EndIf
$sData = DllStructGetData($tRes, 1)
If $sData = "" Then
_WinAPI_FreeLibrary($hInstance)
Return SetError(10, 0, 0)
EndIf
$sHdr = StringLeft($sData, 14)
$iOrd = Dec(LTHR("0x" & StringRight(StringLeft($sData, 42), 4))) ;index start of icon in the library
$aHtail = _StringSplitRegExp(StringTrimLeft($sData, 14), '(.){28}', True)
$iCnt = $aHtail[0]
$Offset = ($iCnt * 16) + 6
For $r = 1 To $aHtail[0]
$sDByte = Dec(Hex(BitRotate("0x" & StringLeft(StringRight($aHtail[$r], 12), 4), -8), 4))
$aHtail[$r] = StringTrimRight($aHtail[$r], 4)
$sHdr &= $aHtail[$r] & LTHR($Offset) & "0000"
$Offset += $sDByte
Next
For $i = 1 To $iCnt
$hResource = _WinAPI_FindResource($hInstance, $RT_ICON, $iOrd)
$iSize = _WinAPI_SizeOfResource($hInstance, $hResource)
$hData = _WinAPI_LoadResource($hInstance, $hResource)
$pData = _WinAPI_LockResource($hData)
$tRes = DllStructCreate("byte[" & $iSize & "]", $pData)
$sHdr &= StringTrimLeft(DllStructGetData($tRes, 1), 2)
$iOrd += 1
Next
_WinAPI_FreeLibrary($hInstance)
Dim $aINM[1]
$FO = FileOpen($sOutIco, $iCrt)
If $FO = -1 Then Return SetError(11, 0, 0)
$FW = FileWrite($FO, $sHdr)
If $FW = 0 Then Return SetError(12, 0, 0)
FileClose($FO)
Return SetError(0, 0, 1)
EndFunc ;==>_ExtractIconToFile
; Helper Functions beyond this point
Func LTHR($sNum)
Return Hex(BitRotate($sNum, -8), 4)
EndFunc ;==>LTHR
Func _StringSplitRegExp($sString, $sPattern, $sIncludeMatch = False, $iCount = 0)
Local $sReservedPattern = Chr(0), $sTemp, $aResult
Local $sReplacePattern = $sReservedPattern
If $sIncludeMatch Then $sReplacePattern = "$0" & $sReplacePattern
$sTemp = StringRegExpReplace($sString, $sPattern, $sReplacePattern, $iCount)
If StringRight($sTemp, 1) = $sReservedPattern Then $sTemp = StringTrimRight($sTemp, 1)
$aResult = StringSplit($sTemp, $sReservedPattern, 1)
Return $aResult
EndFunc ;==>_StringSplitRegExp
Func _ResourceEnumNames($hModule, $iType)
Local $aRet, $IsPtr = IsPtr($hModule), $xCB
If $IsPtr Then
$xCB = DllCallbackRegister('___EnumResNameProc', 'int', 'int*;int*;int*;int*')
$aRet = DllCall('kernel32.dll', 'int', 'EnumResourceNamesW', 'ptr', $hModule, 'int', $iType, 'ptr', DllCallbackGetPtr($xCB), 'ptr', 0) ;Absturz bei 64bit!!!
DllCallbackFree($xCB)
EndIf
EndFunc ;==>_ResourceEnumNames
Func ___EnumResNameProc($hModule, $pType, $pName, $lParam)
Local $iSize = DllCall('kernel32.dll', 'int', 'GlobalSize', 'ptr', $pName), $tBuf
If $iSize Then
$tBuf = DllStructCreate('wchar[' & $iSize & ']', $pName)
ReDim $aINM[UBound($aINM) + 1]
$aINM[0] += 1
$aINM[UBound($aINM) - 1] = DllStructGetData($tBuf, 1)
Else
ReDim $aINM[UBound($aINM) + 1]
$aINM[0] += 1
$aINM[UBound($aINM) - 1] = "#" & $pName
EndIf
Return 1
EndFunc ;==>___EnumResNameProc
Alles anzeigen
Das klappt! (Win 10)
Moin,
die Funktion _ResourceEnumNames gibt es auch in einer _Winapi_-Version: _WinAPI_EnumResourceNames in #include <WinAPIRes.au3>.
Damit sollte es zuverlässiger laufen.
Moin,
wenn Du in SciTE F5 (Go) drückst, wird Folgendes aufgerufen:
# Commands to compile / run your script
command.go.$(au3)="$(SciteDefaultHome)\..\AutoIt3.exe" "$(SciteDefaultHome)\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "$(FilePath)" /UserParams $(1) $(2) $(3) $(4)
Auf meinem Rechner entspricht das:
"C:\Program Files (x86)\AutoIt3\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "%1"
Wenn Du das in der Registrierung unter HKEY_CLASSES_ROOT\AutoIt3Script\Shell\Open\Command ablegst, sollte bei Doppelklick der AutoIt3Wrapper die Ausführung gemäß der im Skript gefundenen Direktiven anstoßen.
Alternativ kannst Du das auch beim Run Schlüssel ablegen. Du musst das Skript dann aber über das Kontextmenü starten.
Ich habe das nicht probiert, weil ich bei Doppelklick das Script in SciTE anzeigen lasse.
Yepp!
Der dritte Parameter hat den Windows-Typ wParam. wParam hat ptr Größe. Er hat nur in 32-Bit Umgebungen dieselbe Größe wie long (4 Bytes). In 64-Bit Umgebungen sind es 8 Bytes.
DllCallbackRegister("_MyWindowProc", "ptr", "hwnd;uint;ptr;ptr") funktioniert auch, beschreibt die Parameter aber nicht so konkret.
Hallo Oscar ,
das ist eine von den 'Shell-Ausrichtungsfallen'. Die Struktur SHChangeNotifyEntry ist in ShlObj_core.h definiert. Da steht am Anfang ein
#include <pshpack1.h> /* Assume byte packing throughout */,
das auch für die Struktur gilt und ein 'Byte-Packing' erzwingt.
Deshalb:
Moin,
frohes neues Jahr! Hoffen wir mal, dass sich der Temperaturanstieg in 2025 gegenüber 2023 und 2024 wieder umkehrt und weniger Flächen überflutet werden.
Zum Thema:
For $i = 0 To UBound($aPaths) - 1
$aPaths[$i] = _WinAPI_ShellILCreateFromPath(_WinAPI_PathSearchAndQualify($aPaths[$i]))
DllStructSetData($tEntry, (@AutoItX64 ? 4 : 2) * $i + 1, $aPaths[$i]) ; bei 64Bit ist PIDLIST_ABSOLUTE = 64 Bit (4 Byte)
DllStructSetData($tEntry, (@AutoItX64 ? 4 : 2) * $i + 2, $bRecursive)
Next
Ich denke, dass sich der Feldindex (@AutoItX64 ? 4 : 2) * $i + 1 von 32- zu 64-Bit nicht ändert.
Moin Moombas,
Zunächst einmal machst du auch eine doppelte Erstellung einer Variable (Zeile 5 und 8). Zeile in Zeile 5 auf 0 setzen, Zeile 8 weg lassen.
Wenn man das macht, wird die jeweils erste Datei mit 0 geschrieben. Ich glaube nicht, dass das sein soll.
Dann bedenke bitte, wenn dies dein komplettes Skript ist, das "Local" hier die falsche Wahl ist, sondern "Global" genutzt werden muss, ...
"muss" ist falsch, weil "Lokale" Variable im "global scope" automatisch "Global" sind. Es schafft allerdings Klarheit.
Moin,
weil Du Dich noch in einem frühen Stadium befindest möchte ich Folgendes anmerken:
P202400001
Solltest Du vorhaben, das Jahr in die Nummer aufzunehmen, wäre das 'doppelt gemoppelt', weil das Jahr ja schon im Datum steht ($sDatum = (@YEAR & "-" & @MON & "-" & @MDAY)). Außerdem musst Du dann bedenken, dass Du die laufende Nummer beim ersten Start in 2025 wieder auf 1 setzen musst.
Wofür brauchst Du diese Nummer überhaupt?
Grüße, Velted
Das ist mir jetzt unklar. Was meinst du mit Speicherort?
Die sogenannte 'Control-ID' (ListView-Einträge sind nunmal keine Controls) wird im Feld lParam der LVITEM Struktur abgelegt, die dem Eintrag zugeordnet ist. Dieses Feld kann aus Sicht des ListView-Controls mit beliebigen Informationen belegt sein. In AutoIt sollte man sich aber hüten, den Inhalt zu verändern. Die interne Verbindung von ListViewItem und ListView ginge dann wohl verloren.
casi4712, ich möchte mich auch für die Offtopic-Nutzung Deines Beitrags entschuldigen. Das sollte sich jetzt auch erledigt haben.
Wer hat dir denn diesen Bären aufgebunden?
Moin,
das war ich selbst. Ich vergesse immer wieder, dass AutoIt die ListView-Einträge wie eigenständige Controls behandelt. Danke für den Hinweis.
Der Klick auf eine Zeile wird also tatsächlich signalisiert. Im OnEvent-Mode muss man aber jedem betroffenen 'Listvieweintragscontrol' eine eine Eventfunktion zugewiesen haben. Geliefert wird dann die Control-ID des Eintrags in @GUI_CtrlId. Die kann man in GUICtrlRead() benutzen, um den Inhalt der Zeile auszulesen. So weit, so gut.
Leider hat das eigentliche ListView-Control von alldem keine Ahnung. AutoIt speichert zwar die Control-ID im Eintrag, der Speicherort hat aber für das ListView-Control keine besondere Bedeutung. Wenn man den Index des Eintrags auslesen will, den man für die 'normale' Bearbeitung der ListVieweinträge braucht, muss man den 'per Hand' ermitteln, z.B. mit _GUICtrlListView_FindParam().
Listview sind die am effektivsten verwertbaren Control überhaupt.
Ich würde sagen, sie sind ebensogut verwertbar wie die anderen Controls, wenn man die zugehörigen UDFs einsetzt.
Für das, was casi4712 vorhaben mag, sollte es in jedem fall reichen.
Moin casi4712,
je intensiver ich mich mit deisem Beitrag beschäftige, als desto dürftiger entpuppen sich die Möglichkeiten, die AutoIt als native Funktionen anbietet, um auf Inhalte eines ListView-Controls zuzugreifen.
ListViews gehören zu den 'geschwätzigsten' Controls. Sie neigen dazu, das Elternfenster mit Nachrichten zu 'fluten'. Nun stellt sich heraus, dass AutoIt sich von all den vielen Nachrichten genau eine herausgreift, die dem Skript gemeldet wird: Den Klick auf eine Spaltenüberschrift im Header! Alles, was mit Klicks im ListView-Bereich zu tun hat, wird schnöde unter den Tisch gekehrt. Das gilt sowohl für den GetMsg- als auch für den OnEvent-Modus. Wenn Du also per GUIGetMsg() oder EventFunc() eine Nachricht vom ListView erhältst, kannst Du Dir sicher sein, dass der Benutzer sich gerade mit dem Header beschäftigt. Ich bin erschüttert.
Du hast nun das einzige 'Event' dafür verbraucht, die Spaltensortierungzu unterstützen. Mehr ist ohne 'Verrenkungen' auch nicht möglich. Was soll denn der Spaltenklick sonst noch auslösen?
Moin, in der Beschreibung zu Volatile steht:
ZitatCallback Funktion: Während der Ausführung der Funktion wird die Nachrichtenverarbeitung des Skripts nicht blockiert, wie es normalerweise für nicht-volatile Funktionen erfolgt.
Die Funktion wird damit "von einer Art Schutzschicht" befreit.
Wenn Du versuchst, das Progressfenster zu bewegen, werden entsprechende Nachrichten an das Skript gesendet. Windows wartet standardmäßig etwa 5 Sekunden darauf, dass diese Nachrichten verarbeitet werden. Das geschieht offenbar nicht rechtzeitig, weil die laufende Callbackfunktion die Nachrichtenbearbeitung verhindert. Nach Ablauf der 5 Sekunden erstellt Windows ein Geisterfenster (eine Bitmap des Fensters mit dem Zusatz "Not Responding") als Ersatz für das nicht reagierende Fenster. Dieses Fenster kann bewegt werden, tut aber sonst nichts.
Ergänzende Erläuterungen findest Du hier: IsHungAppWindow function
Man kann das anscheinend auch für den laufenden Prozess abschalten, siehe DisableProcessWindowsGhosting()
Moin,
ich weiß nicht so recht, was Du erreichen willst. Wie ich es verstehe, soll das Skript im Profilmanager nacheinander alle vorhandenen Profile auswählen. Ist es das, was Du willst?
; Alle Einträge kopieren, beginnend beim Startindex
For $i = $startIndex To UBound($dirList) - 1
ClipPut($dirList[$i])
Send("^v")
MouseClick("left", 1089, 722)
$startIndex = $i + 1 ; Aktualisieren des Startindex für den nächsten Durchlauf
Next
Diese Schleife wird mit maximaler Geschwindigkeit ausgeführt und soll nacheinander alle vorhandenen Verzeichnisnamen in den Profilmanager kopieren. AutoIt wartet nach dem Send("^v") nicht, und der Profilmanager braucht Zeit, um die Daten aus dem Clipboard zu holen. Im schlimmsten Fall werden alle Verzeichnisnamen sich überschreibend in das Clipboard gestellt, bevor der erste Name ausgelesen wird. Die äußere While-Schleife bringt dann nichts mehr, weil Startindex auf den letzten Eintrag im Array zeigt.
Mein Vorschlag wäre deshalb:
Nach Send("^v") etwas Zeit für die Verarbeitung einräumen.
Auf gutes Gelingen,
Velted
Ich würde aber gerne Opt("GUIOnEventMode", 1) aktiviert lassen.
Und wo ist das Problem?
Moin,
warum benutzt Du nicht $GUI_EVENT_DROPPED?
Ok, nach der Doku ist die 5 für Netzlaufwerke immer falsch.
Was passiert, wenn Du das Skript als normaler Benutzer laufen lässt?